Back to index

php5  5.3.10
Classes | Defines | Typedefs | Functions | Variables
pcre.h File Reference
#include <stdlib.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  pcre_extra
struct  pcre_callout_block

Defines

#define PCRE_MAJOR   8
#define PCRE_MINOR   12
#define PCRE_PRERELEASE
#define PCRE_DATE   2011-01-15
#define PCRE_EXP_DECL   extern
#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 */
#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 */
#define PCRE_UTF8   0x00000800 /* Compile */
#define PCRE_NO_AUTO_CAPTURE   0x00001000 /* Compile */
#define PCRE_NO_UTF8_CHECK   0x00002000 /* Compile, exec, DFA exec */
#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 */
#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 */
#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 */
#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)
#define PCRE_ERROR_BADUTF8_OFFSET   (-11)
#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_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_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_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_SPTR   const char *

Typedefs

typedef struct real_pcre
typedef struct pcre_extra pcre_extra
typedef struct pcre_callout_block pcre_callout_block

Functions

PCRE_EXP_DECL pcre * pcre_compile (const char *, 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 int pcre_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 pcre_copy_substring (const char *, int *, int, int, char *, 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 pcre_exec (const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int)
PCRE_EXP_DECL void pcre_free_substring (const char *)
PCRE_EXP_DECL void pcre_free_substring_list (const char **)
PCRE_EXP_DECL int pcre_fullinfo (const pcre *, const pcre_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 pcre_get_stringnumber (const pcre *, const char *)
PCRE_EXP_DECL int pcre_get_stringtable_entries (const pcre *, const char *, char **, char **)
PCRE_EXP_DECL int pcre_get_substring (const char *, int *, int, int, const char **)
PCRE_EXP_DECL int pcre_get_substring_list (const char *, int *, int, const char ***)
PCRE_EXP_DECL int pcre_info (const pcre *, int *, int *)
PCRE_EXP_DECL const unsigned char * pcre_maketables (void)
PCRE_EXP_DECL int pcre_refcount (pcre *, int)
PCRE_EXP_DECL pcre_extrapcre_study (const pcre *, int, const char **)
PCRE_EXP_DECL const char * pcre_version (void)

Variables

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

Class Documentation

struct pcre_extra

Definition at line 227 of file pcre.h.

Class Members
void * callout_data
unsigned long int flags
unsigned char ** mark
unsigned long int match_limit
unsigned long int match_limit_recursion
void * study_data
const unsigned char * tables
struct pcre_callout_block

Definition at line 242 of file pcre.h.

Class Members
void * callout_data
int callout_number
int capture_last
int capture_top
int current_position
int next_item_length
int * offset_vector
int pattern_position
int start_match
PCRE_SPTR subject
int subject_length
int version

Define Documentation

#define PCRE_ANCHORED   0x00000010 /* Compile, exec, DFA exec */

Definition at line 107 of file pcre.h.

#define PCRE_AUTO_CALLOUT   0x00004000 /* Compile */

Definition at line 117 of file pcre.h.

#define PCRE_BSR_ANYCRLF   0x00800000 /* Compile, exec, DFA exec */

Definition at line 129 of file pcre.h.

#define PCRE_BSR_UNICODE   0x01000000 /* Compile, exec, DFA exec */

Definition at line 130 of file pcre.h.

#define PCRE_CASELESS   0x00000001 /* Compile */

Definition at line 103 of file pcre.h.

#define PCRE_CONFIG_BSR   8

Definition at line 198 of file pcre.h.

#define PCRE_CONFIG_LINK_SIZE   2

Definition at line 192 of file pcre.h.

#define PCRE_CONFIG_MATCH_LIMIT   4

Definition at line 194 of file pcre.h.

Definition at line 197 of file pcre.h.

#define PCRE_CONFIG_NEWLINE   1

Definition at line 191 of file pcre.h.

Definition at line 193 of file pcre.h.

#define PCRE_CONFIG_STACKRECURSE   5

Definition at line 195 of file pcre.h.

Definition at line 196 of file pcre.h.

#define PCRE_CONFIG_UTF8   0

Definition at line 190 of file pcre.h.

#define PCRE_DATE   2011-01-15

Definition at line 47 of file pcre.h.

#define PCRE_DFA_RESTART   0x00020000 /* DFA exec */

Definition at line 121 of file pcre.h.

#define PCRE_DFA_SHORTEST   0x00010000 /* DFA exec */

Definition at line 120 of file pcre.h.

#define PCRE_DOLLAR_ENDONLY   0x00000020 /* Compile */

Definition at line 108 of file pcre.h.

#define PCRE_DOTALL   0x00000004 /* Compile */

Definition at line 105 of file pcre.h.

#define PCRE_DUPNAMES   0x00080000 /* Compile */

Definition at line 123 of file pcre.h.

#define PCRE_ERROR_BADCOUNT   (-15)

Definition at line 155 of file pcre.h.

#define PCRE_ERROR_BADMAGIC   (-4)

Definition at line 143 of file pcre.h.

#define PCRE_ERROR_BADNEWLINE   (-23)

Definition at line 163 of file pcre.h.

#define PCRE_ERROR_BADOFFSET   (-24)

Definition at line 164 of file pcre.h.

#define PCRE_ERROR_BADOPTION   (-3)

Definition at line 142 of file pcre.h.

#define PCRE_ERROR_BADPARTIAL   (-13)

Definition at line 153 of file pcre.h.

#define PCRE_ERROR_BADUTF8   (-10)

Definition at line 150 of file pcre.h.

#define PCRE_ERROR_BADUTF8_OFFSET   (-11)

Definition at line 151 of file pcre.h.

#define PCRE_ERROR_CALLOUT   (-9) /* Never used by PCRE itself */

Definition at line 149 of file pcre.h.

#define PCRE_ERROR_DFA_RECURSE   (-20)

Definition at line 160 of file pcre.h.

#define PCRE_ERROR_DFA_UCOND   (-17)

Definition at line 157 of file pcre.h.

#define PCRE_ERROR_DFA_UITEM   (-16)

Definition at line 156 of file pcre.h.

#define PCRE_ERROR_DFA_UMLIMIT   (-18)

Definition at line 158 of file pcre.h.

#define PCRE_ERROR_DFA_WSSIZE   (-19)

Definition at line 159 of file pcre.h.

#define PCRE_ERROR_INTERNAL   (-14)

Definition at line 154 of file pcre.h.

#define PCRE_ERROR_MATCHLIMIT   (-8)

Definition at line 148 of file pcre.h.

#define PCRE_ERROR_NOMATCH   (-1)

Definition at line 140 of file pcre.h.

#define PCRE_ERROR_NOMEMORY   (-6)

Definition at line 146 of file pcre.h.

#define PCRE_ERROR_NOSUBSTRING   (-7)

Definition at line 147 of file pcre.h.

#define PCRE_ERROR_NULL   (-2)

Definition at line 141 of file pcre.h.

#define PCRE_ERROR_NULLWSLIMIT   (-22) /* No longer actually used */

Definition at line 162 of file pcre.h.

#define PCRE_ERROR_PARTIAL   (-12)

Definition at line 152 of file pcre.h.

#define PCRE_ERROR_RECURSIONLIMIT   (-21)

Definition at line 161 of file pcre.h.

#define PCRE_ERROR_SHORTUTF8   (-25)

Definition at line 165 of file pcre.h.

#define PCRE_ERROR_UNKNOWN_NODE   (-5) /* For backward compatibility */

Definition at line 145 of file pcre.h.

#define PCRE_ERROR_UNKNOWN_OPCODE   (-5)

Definition at line 144 of file pcre.h.

#define PCRE_EXP_DECL   extern

Definition at line 74 of file pcre.h.

#define PCRE_EXTENDED   0x00000008 /* Compile */

Definition at line 106 of file pcre.h.

#define PCRE_EXTRA   0x00000040 /* Compile */

Definition at line 109 of file pcre.h.

#define PCRE_EXTRA_CALLOUT_DATA   0x0004

Definition at line 205 of file pcre.h.

#define PCRE_EXTRA_MARK   0x0020

Definition at line 208 of file pcre.h.

#define PCRE_EXTRA_MATCH_LIMIT   0x0002

Definition at line 204 of file pcre.h.

#define PCRE_EXTRA_MATCH_LIMIT_RECURSION   0x0010

Definition at line 207 of file pcre.h.

#define PCRE_EXTRA_STUDY_DATA   0x0001

Definition at line 203 of file pcre.h.

#define PCRE_EXTRA_TABLES   0x0008

Definition at line 206 of file pcre.h.

#define PCRE_FIRSTLINE   0x00040000 /* Compile */

Definition at line 122 of file pcre.h.

#define PCRE_INFO_BACKREFMAX   3

Definition at line 172 of file pcre.h.

#define PCRE_INFO_CAPTURECOUNT   2

Definition at line 171 of file pcre.h.

#define PCRE_INFO_DEFAULT_TABLES   11

Definition at line 181 of file pcre.h.

#define PCRE_INFO_FIRSTBYTE   4

Definition at line 173 of file pcre.h.

#define PCRE_INFO_FIRSTCHAR   4 /* For backwards compatibility */

Definition at line 174 of file pcre.h.

#define PCRE_INFO_FIRSTTABLE   5

Definition at line 175 of file pcre.h.

#define PCRE_INFO_HASCRORLF   14

Definition at line 184 of file pcre.h.

#define PCRE_INFO_JCHANGED   13

Definition at line 183 of file pcre.h.

#define PCRE_INFO_LASTLITERAL   6

Definition at line 176 of file pcre.h.

#define PCRE_INFO_MINLENGTH   15

Definition at line 185 of file pcre.h.

#define PCRE_INFO_NAMECOUNT   8

Definition at line 178 of file pcre.h.

#define PCRE_INFO_NAMEENTRYSIZE   7

Definition at line 177 of file pcre.h.

#define PCRE_INFO_NAMETABLE   9

Definition at line 179 of file pcre.h.

#define PCRE_INFO_OKPARTIAL   12

Definition at line 182 of file pcre.h.

#define PCRE_INFO_OPTIONS   0

Definition at line 169 of file pcre.h.

#define PCRE_INFO_SIZE   1

Definition at line 170 of file pcre.h.

#define PCRE_INFO_STUDYSIZE   10

Definition at line 180 of file pcre.h.

#define PCRE_JAVASCRIPT_COMPAT   0x02000000 /* Compile */

Definition at line 131 of file pcre.h.

#define PCRE_MAJOR   8

Definition at line 44 of file pcre.h.

#define PCRE_MINOR   12

Definition at line 45 of file pcre.h.

#define PCRE_MULTILINE   0x00000002 /* Compile */

Definition at line 104 of file pcre.h.

#define PCRE_NEWLINE_ANY   0x00400000 /* Compile, exec, DFA exec */

Definition at line 127 of file pcre.h.

#define PCRE_NEWLINE_ANYCRLF   0x00500000 /* Compile, exec, DFA exec */

Definition at line 128 of file pcre.h.

#define PCRE_NEWLINE_CR   0x00100000 /* Compile, exec, DFA exec */

Definition at line 124 of file pcre.h.

#define PCRE_NEWLINE_CRLF   0x00300000 /* Compile, exec, DFA exec */

Definition at line 126 of file pcre.h.

#define PCRE_NEWLINE_LF   0x00200000 /* Compile, exec, DFA exec */

Definition at line 125 of file pcre.h.

#define PCRE_NO_AUTO_CAPTURE   0x00001000 /* Compile */

Definition at line 115 of file pcre.h.

#define PCRE_NO_START_OPTIMISE   0x04000000 /* Synonym */

Definition at line 133 of file pcre.h.

#define PCRE_NO_START_OPTIMIZE   0x04000000 /* Compile, exec, DFA exec */

Definition at line 132 of file pcre.h.

#define PCRE_NO_UTF8_CHECK   0x00002000 /* Compile, exec, DFA exec */

Definition at line 116 of file pcre.h.

#define PCRE_NOTBOL   0x00000080 /* Exec, DFA exec */

Definition at line 110 of file pcre.h.

#define PCRE_NOTEMPTY   0x00000400 /* Exec, DFA exec */

Definition at line 113 of file pcre.h.

#define PCRE_NOTEMPTY_ATSTART   0x10000000 /* Exec, DFA exec */

Definition at line 135 of file pcre.h.

#define PCRE_NOTEOL   0x00000100 /* Exec, DFA exec */

Definition at line 111 of file pcre.h.

#define PCRE_PARTIAL   0x00008000 /* Backwards compatible synonym */

Definition at line 119 of file pcre.h.

#define PCRE_PARTIAL_HARD   0x08000000 /* Exec, DFA exec */

Definition at line 134 of file pcre.h.

#define PCRE_PARTIAL_SOFT   0x00008000 /* Exec, DFA exec */

Definition at line 118 of file pcre.h.

#define PCRE_PRERELEASE

Definition at line 46 of file pcre.h.

#define PCRE_SPTR   const char *

Definition at line 220 of file pcre.h.

#define PCRE_UCP   0x20000000 /* Compile */

Definition at line 136 of file pcre.h.

#define PCRE_UNGREEDY   0x00000200 /* Compile */

Definition at line 112 of file pcre.h.

#define PCRE_UTF8   0x00000800 /* Compile */

Definition at line 114 of file pcre.h.


Typedef Documentation

typedef struct pcre_extra pcre_extra
typedef struct real_pcre

Definition at line 213 of file pcre.h.


Function Documentation

PCRE_EXP_DECL pcre* pcre_compile ( const char *  ,
int  ,
const char **  ,
int ,
const unsigned char *   
)

Definition at line 6806 of file pcre_compile.c.

{
return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
}
PCRE_EXP_DECL pcre* pcre_compile2 ( const char *  ,
int  ,
int ,
const char **  ,
int ,
const unsigned char *   
)

Definition at line 6814 of file pcre_compile.c.

{
real_pcre *re;
int length = 1;  /* For final END opcode */
int firstbyte, reqbyte, newline;
int errorcode = 0;
int skipatstart = 0;
BOOL utf8;
size_t size;
uschar *code;
const uschar *codestart;
const uschar *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. */

uschar cworkspace[COMPILE_WORK_SIZE];

/* Set this early so that early errors get offset 0. */

ptr = (const uschar *)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 = _pcre_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;

  if (strncmp((char *)(ptr+skipatstart+2), STRING_UTF8_RIGHTPAR, 5) == 0)
    { skipatstart += 7; options |= PCRE_UTF8; continue; }
  else if (strncmp((char *)(ptr+skipatstart+2), STRING_UCP_RIGHTPAR, 4) == 0)
    { skipatstart += 6; options |= PCRE_UCP; continue; }
  else if (strncmp((char *)(ptr+skipatstart+2), STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
    { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }

  if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)
    { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
  else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3)  == 0)
    { skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
  else if (strncmp((char *)(ptr+skipatstart+2), STRING_CRLF_RIGHTPAR, 5)  == 0)
    { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
  else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANY_RIGHTPAR, 4) == 0)
    { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
  else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANYCRLF_RIGHTPAR, 8) == 0)
    { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }

  else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
    { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
  else if (strncmp((char *)(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;
  }

utf8 = (options & PCRE_UTF8) != 0;

/* Can't support UTF8 unless PCRE has been compiled to include the code. */

#ifdef SUPPORT_UTF8
if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&
     (*erroroffset = _pcre_valid_utf8((USPTR)pattern, -1)) >= 0)
  {
  errorcode = ERR44;
  goto PCRE_EARLY_ERROR_RETURN2;
  }
#else
if (utf8)
  {
  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. */

switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
  {
  case 0:
  case PCRE_BSR_ANYCRLF:
  case PCRE_BSR_UNICODE:
  break;
  default: 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"));
DPRINTF(("%s\n", pattern));

/* 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_workspace = cworkspace;
cd->start_code = cworkspace;
cd->hwm = cworkspace;
cd->start_pattern = (const uschar *)pattern;
cd->end_pattern = (const uschar *)(pattern + strlen(pattern));
cd->req_varyopt = 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, cd->external_options & PCRE_IMS,
  &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
  &length);
if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;

DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
  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 = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3);
re = (real_pcre *)(pcre_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->dummy1 = 0;
re->first_byte = 0;
re->req_byte = 0;
re->name_table_offset = sizeof(real_pcre);
re->name_entry_size = cd->name_entry_size;
re->name_count = cd->names_found;
re->ref_count = 0;
re->tables = (tables == _pcre_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->bracount = 0;
cd->names_found = 0;
cd->name_table = (uschar *)re + re->name_table_offset;
codestart = cd->name_table + re->name_entry_size * re->name_count;
cd->start_code = codestart;
cd->hwm = cworkspace;
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 uschar *)pattern + skipatstart;
code = (uschar *)codestart;
*code = OP_BRA;
(void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
  &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
re->top_bracket = cd->bracount;
re->top_backref = cd->top_backref;
re->flags = cd->external_flags;

if (cd->had_accept) reqbyte = -1;   /* 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. */

while (errorcode == 0 && cd->hwm > cworkspace)
  {
  int offset, recno;
  const uschar *groupptr;
  cd->hwm -= LINK_SIZE;
  offset = GET(cd->hwm, 0);
  recno = GET(codestart, offset);
  groupptr = _pcre_find_bracket(codestart, utf8, recno);
  if (groupptr == NULL) errorcode = ERR53;
    else PUT(((uschar *)codestart), offset, (int)(groupptr - codestart));
  }

/* 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)
  {
  uschar *cc = (uschar *)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 = (uschar *)_pcre_find_bracket(codestart, utf8, -1);
       cc != NULL;
       cc = (uschar *)_pcre_find_bracket(cc, utf8, -1))
    {
    if (GET(cc, 1) == 0)
      {
      int fixed_length;
      uschar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
      int end_op = *be;
      *be = OP_END;
      fixed_length = find_fixedlength(cc, re->options, TRUE, cd);
      *be = end_op;
      DPRINTF(("fixed length = %d\n", fixed_length));
      if (fixed_length < 0)
        {
        errorcode = (fixed_length == -2)? ERR36 : ERR25;
        break;
        }
      PUT(cc, 1, fixed_length);
      }
    cc += 1 + LINK_SIZE;
    }
  }

/* Failed to compile, or error while post-processing */

if (errorcode != 0)
  {
  (pcre_free)(re);
  PCRE_EARLY_ERROR_RETURN:
  *erroroffset = (int)(ptr - (const uschar *)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)
  {
  int temp_options = re->options;   /* May get changed during these scans */
  if (is_anchored(codestart, &temp_options, 0, cd->backref_map))
    re->options |= PCRE_ANCHORED;
  else
    {
    if (firstbyte < 0)
      firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE);
    if (firstbyte >= 0)   /* Remove caseless flag for non-caseable chars */
      {
      int ch = firstbyte & 255;
      re->first_byte = ((firstbyte & REQ_CASELESS) != 0 &&
         cd->fcc[ch] == ch)? ch : firstbyte;
      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 (reqbyte >= 0 &&
     ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0))
  {
  int ch = reqbyte & 255;
  re->req_byte = ((reqbyte & REQ_CASELESS) != 0 &&
    cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte;
  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)
  {
  int ch = re->first_byte & 255;
  const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)?
    "" : " (caseless)";
  if (isprint(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)
  {
  int ch = re->req_byte & 255;
  const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)?
    "" : " (caseless)";
  if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless);
    else printf("Req char = \\x%02x%s\n", ch, caseless);
  }

pcre_printint(re, stdout, TRUE);

/* This check is done here in the debugging case so that the code that
was compiled can be seen. */

if (code - codestart > length)
  {
  (pcre_free)(re);
  *errorptr = find_error_text(ERR23);
  *erroroffset = ptr - (uschar *)pattern;
  if (errorcodeptr != NULL) *errorcodeptr = ERR23;
  return NULL;
  }
#endif   /* PCRE_DEBUG */

return (pcre *)re;
}

Here is the call graph for this function:

PCRE_EXP_DECL int pcre_config ( int  ,
void *   
)

Definition at line 64 of file pcre_config.c.

{
switch (what)
  {
  case PCRE_CONFIG_UTF8:
#ifdef SUPPORT_UTF8
  *((int *)where) = 1;
#else
  *((int *)where) = 0;
#endif
  break;

  case PCRE_CONFIG_UNICODE_PROPERTIES:
#ifdef SUPPORT_UCP
  *((int *)where) = 1;
#else
  *((int *)where) = 0;
#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) = 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;
}
PCRE_EXP_DECL int pcre_copy_named_substring ( const pcre *  ,
const char *  ,
int ,
int  ,
const char *  ,
char *  ,
int   
)

Definition at line 278 of file pcre_get.c.

{
int n = get_first_set(code, stringname, ovector);
if (n <= 0) return n;
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
}

Here is the call graph for this function:

PCRE_EXP_DECL int pcre_copy_substring ( const char *  ,
int ,
int  ,
int  ,
char *  ,
int   
)

Definition at line 233 of file pcre_get.c.

{
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], yield);
buffer[yield] = 0;
return yield;
}
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 pcre_exec ( const pcre *  ,
const pcre_extra ,
PCRE_SPTR  ,
int  ,
int  ,
int  ,
int ,
int   
)

Definition at line 5596 of file pcre_exec.c.

{
int rc, resetcount, ocount;
int first_byte = -1;
int req_byte = -1;
int req_byte2 = -1;
int newline;
unsigned long int ims;
BOOL using_temporary_offsets = FALSE;
BOOL anchored;
BOOL startline;
BOOL firstline;
BOOL first_byte_caseless = FALSE;
BOOL req_byte_caseless = FALSE;
BOOL utf8;
match_data match_block;
match_data *md = &match_block;
const uschar *tables;
const uschar *start_bits = NULL;
USPTR start_match = (USPTR)subject + start_offset;
USPTR end_subject;
USPTR start_partial = NULL;
USPTR req_byte_ptr = start_match - 1;

pcre_study_data internal_study;
const pcre_study_data *study;

real_pcre internal_re;
const real_pcre *external_re = (const real_pcre *)argument_re;
const real_pcre *re = external_re;

/* 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;

/* This information is for finding all the numbers associated with a given
name, for condition testing. */

md->name_table = (uschar *)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 = external_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 = _pcre_default_tables;

/* Check that the first field in the block is the magic number. If it is not,
test for a regex that was compiled on a host of opposite endianness. If this is
the case, flipped values are put in internal_re and internal_study if there was
study data too. */

if (re->magic_number != MAGIC_NUMBER)
  {
  re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
  if (re == NULL) return PCRE_ERROR_BADMAGIC;
  if (study != NULL) study = &internal_study;
  }

/* 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 uschar *)external_re + re->name_table_offset +
  re->name_count * re->name_entry_size;

md->start_subject = (USPTR)subject;
md->start_offset = start_offset;
md->end_subject = md->start_subject + length;
end_subject = md->end_subject;

md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;
md->use_ucp = (re->options & PCRE_UCP) != 0;
md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;

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->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
              ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
md->hitend = FALSE;
md->mark = NULL;                        /* In case never set */

md->recursive = NULL;                   /* No recursion at top level */

md->lcc = tables + lcc_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;

/* Check a UTF-8 string if required. Unfortunately there's no way of passing
back the character offset. */

#ifdef SUPPORT_UTF8
if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
  {
  int tb;
  if ((tb = _pcre_valid_utf8((USPTR)subject, length)) >= 0)
    return (tb == length && md->partial > 1)?
      PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
  if (start_offset > 0 && start_offset < length)
    {
    tb = ((USPTR)subject)[start_offset] & 0xc0;
    if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET;
    }
  }
#endif

/* The ims options can vary during the matching as a result of the presence
of (?ims) items in the pattern. They are kept in a local variable so that
restoring at the exit of a group is easy. */

ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL);

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

if (re->top_backref > 0 && re->top_backref >= ocount/3)
  {
  ocount = re->top_backref * 3 + 3;
  md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
  if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
  using_temporary_offsets = TRUE;
  DPRINTF(("Got memory to hold back references\n"));
  }
else md->offset_vector = offsets;

md->offset_end = ocount;
md->offset_max = (2*ocount)/3;
md->offset_overflow = FALSE;
md->capture_last = -1;

/* Compute the minimum number of offsets that we need to reset each time. Doing
this makes a huge difference to execution time when there aren't many brackets
in the pattern. */

resetcount = 2 + re->top_bracket * 2;
if (resetcount > offsetcount) resetcount = ocount;

/* 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. */

if (md->offset_vector != NULL)
  {
  register int *iptr = md->offset_vector + ocount;
  register int *iend = iptr - resetcount/2 + 1;
  while (--iptr >= iend) *iptr = -1;
  }

/* 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)
    {
    first_byte = re->first_byte & 255;
    if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
      first_byte = md->lcc[first_byte];
    }
  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)
  {
  req_byte = re->req_byte & 255;
  req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
  req_byte2 = (tables + fcc_offset)[req_byte];  /* case flipped */
  }


/* ==========================================================================*/

/* Loop for handling unanchored repeated matching attempts; for anchored regexs
the loop runs just once. */

for(;;)
  {
  USPTR save_end_subject = end_subject;
  USPTR new_start_match;

  /* Reset the maximum number of extractions we might see. */

  if (md->offset_vector != NULL)
    {
    register int *iptr = md->offset_vector;
    register int *iend = iptr + resetcount;
    while (iptr < iend) *iptr++ = -1;
    }

  /* 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)
    {
    USPTR t = start_match;
#ifdef SUPPORT_UTF8
    if (utf8)
      {
      while (t < md->end_subject && !IS_NEWLINE(t))
        {
        t++;
        while (t < end_subject && (*t & 0xc0) == 0x80) 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 byte if there is one. */

    if (first_byte >= 0)
      {
      if (first_byte_caseless)
        while (start_match < end_subject && md->lcc[*start_match] != first_byte)
          start_match++;
      else
        while (start_match < end_subject && *start_match != first_byte)
          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_UTF8
        if (utf8)
          {
          while (start_match < end_subject && !WAS_NEWLINE(start_match))
            {
            start_match++;
            while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
              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;
        if ((start_bits[c/8] & (1 << (c&7))) == 0)
          {
          start_match++;
#ifdef SUPPORT_UTF8
          if (utf8)
            while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
              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 & 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_byte is set, we know that that character must appear in the
    subject for the match to succeed. If the first character is set, req_byte
    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 (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)
      {
      register USPTR p = start_match + ((first_byte >= 0)? 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_byte_ptr)
        {
        if (req_byte_caseless)
          {
          while (p < end_subject)
            {
            register int pp = *p++;
            if (pp == req_byte || pp == req_byte2) { p--; break; }
            }
          }
        else
          {
          while (p < end_subject)
            {
            if (*p++ == req_byte) { 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_byte_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;
  rc = match(start_match, md->start_code, start_match, NULL, 2, md, ims, NULL,
    0, 0);
  if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;

  switch(rc)
    {
    /* 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 */

    /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
    the SKIP's arg was not found. We also treat this as NOMATCH. */

    case MATCH_SKIP_ARG:
    /* Fall through */

    /* NOMATCH and PRUNE advance by one character. THEN at this level acts
    exactly like PRUNE. */

    case MATCH_NOMATCH:
    case MATCH_PRUNE:
    case MATCH_THEN:
    new_start_match = start_match + 1;
#ifdef SUPPORT_UTF8
    if (utf8)
      while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)
        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. */

  if (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 (offsetcount >= 4)
      {
      memcpy(offsets + 2, md->offset_vector + 2,
        (offsetcount - 2) * sizeof(int));
      DPRINTF(("Copied offsets from temporary memory\n"));
      }
    if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
    DPRINTF(("Freeing temporary memory\n"));
    (pcre_free)(md->offset_vector);
    }

  /* Set the return code to the number of captured strings, or 0 if there are
  too many to fit into the vector. */

  rc = md->offset_overflow? 0 : md->end_offset_top/2;

  /* 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);
    }

  DPRINTF((">>>> returning %d\n", rc));
  goto RETURN_MARK;
  }

/* 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"));
  (pcre_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));
  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 - (USPTR)subject);
    offsets[1] = (int)(end_subject - (USPTR)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. */

RETURN_MARK:

if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
  *(extra_data->mark) = (unsigned char *)(md->mark);
return rc;
}

Here is the call graph for this function:

PCRE_EXP_DECL void pcre_free_substring ( const char *  )

Definition at line 458 of file pcre_get.c.

{
(pcre_free)((void *)pointer);
}
PCRE_EXP_DECL void pcre_free_substring_list ( const char **  )

Definition at line 355 of file pcre_get.c.

{
(pcre_free)((void *)pointer);
}
PCRE_EXP_DECL int pcre_fullinfo ( const pcre *  ,
const pcre_extra ,
int  ,
void *   
)

Definition at line 67 of file pcre_fullinfo.c.

{
real_pcre internal_re;
pcre_study_data internal_study;
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;

if (re->magic_number != MAGIC_NUMBER)
  {
  re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
  if (re == NULL) return PCRE_ERROR_BADMAGIC;
  if (study != NULL) study = &internal_study;
  }

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_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_byte :
    ((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 uschar **)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)?
      study->minlength : -1;
  break;

  case PCRE_INFO_LASTLITERAL:
  *((int *)where) =
    ((re->flags & PCRE_REQCHSET) != 0)? re->req_byte : -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 uschar **)where) = (const uschar *)re + re->name_table_offset;
  break;

  case PCRE_INFO_DEFAULT_TABLES:
  *((const uschar **)where) = (const uschar *)(_pcre_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;

  default: return PCRE_ERROR_BADOPTION;
  }

return 0;
}
PCRE_EXP_DECL int pcre_get_named_substring ( const pcre *  ,
const char *  ,
int ,
int  ,
const char *  ,
const char **   
)

Definition at line 435 of file pcre_get.c.

{
int n = get_first_set(code, stringname, ovector);
if (n <= 0) return n;
return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
}

Here is the call graph for this function:

PCRE_EXP_DECL int pcre_get_stringnumber ( const pcre *  ,
const char *   
)

Definition at line 67 of file pcre_get.c.

{
int rc;
int entrysize;
int top, bot;
uschar *nametable;

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;

bot = 0;
while (top > bot)
  {
  int mid = (top + bot) / 2;
  uschar *entry = nametable + entrysize*mid;
  int c = strcmp(stringname, (char *)(entry + 2));
  if (c == 0) return (entry[0] << 8) + entry[1];
  if (c > 0) bot = mid + 1; else top = mid;
  }

return PCRE_ERROR_NOSUBSTRING;
}
PCRE_EXP_DECL int pcre_get_stringtable_entries ( const pcre *  ,
const char *  ,
char **  ,
char **   
)

Definition at line 116 of file pcre_get.c.

{
int rc;
int entrysize;
int top, bot;
uschar *nametable, *lastentry;

if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
  return rc;
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;

if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
  return rc;
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
  return rc;

lastentry = nametable + entrysize * (top - 1);
bot = 0;
while (top > bot)
  {
  int mid = (top + bot) / 2;
  uschar *entry = nametable + entrysize*mid;
  int c = strcmp(stringname, (char *)(entry + 2));
  if (c == 0)
    {
    uschar *first = entry;
    uschar *last = entry;
    while (first > nametable)
      {
      if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break;
      first -= entrysize;
      }
    while (last < lastentry)
      {
      if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break;
      last += entrysize;
      }
    *firstptr = (char *)first;
    *lastptr = (char *)last;
    return entrysize;
    }
  if (c > 0) bot = mid + 1; else top = mid;
  }

return PCRE_ERROR_NOSUBSTRING;
}
PCRE_EXP_DECL int pcre_get_substring ( const char *  ,
int ,
int  ,
int  ,
const char **   
)

Definition at line 388 of file pcre_get.c.

{
int yield;
char *substring;
if (stringnumber < 0 || stringnumber >= stringcount)
  return PCRE_ERROR_NOSUBSTRING;
stringnumber *= 2;
yield = ovector[stringnumber+1] - ovector[stringnumber];
substring = (char *)(pcre_malloc)(yield + 1);
if (substring == NULL) return PCRE_ERROR_NOMEMORY;
memcpy(substring, subject + ovector[stringnumber], yield);
substring[yield] = 0;
*stringptr = substring;
return yield;
}
PCRE_EXP_DECL int pcre_get_substring_list ( const char *  ,
int ,
int  ,
const char ***   
)

Definition at line 310 of file pcre_get.c.

{
int i;
int size = sizeof(char *);
int double_count = stringcount * 2;
char **stringlist;
char *p;

for (i = 0; i < double_count; i += 2)
  size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;

stringlist = (char **)(pcre_malloc)(size);
if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;

*listptr = (const char **)stringlist;
p = (char *)(stringlist + stringcount + 1);

for (i = 0; i < double_count; i += 2)
  {
  int len = ovector[i+1] - ovector[i];
  memcpy(p, subject + ovector[i], len);
  *stringlist++ = p;
  p += len;
  *p++ = 0;
  }

*stringlist = NULL;
return 0;
}
PCRE_EXP_DECL int pcre_info ( const pcre *  ,
int ,
int  
)

Definition at line 74 of file pcre_info.c.

{
real_pcre internal_re;
const real_pcre *re = (const real_pcre *)argument_re;
if (re == NULL) return PCRE_ERROR_NULL;
if (re->magic_number != MAGIC_NUMBER)
  {
  re = _pcre_try_flipped(re, &internal_re, NULL, NULL);
  if (re == NULL) return PCRE_ERROR_BADMAGIC;
  }
if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_COMPILE_OPTIONS);
if (first_byte != NULL)
  *first_byte = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
     ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
return re->top_bracket;
}
PCRE_EXP_DECL const unsigned char* pcre_maketables ( void  )

Definition at line 68 of file pcre_maketables.c.

{
unsigned char *yield, *p;
int i;

#ifndef DFTABLES
yield = (unsigned char*)(pcre_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;
}
PCRE_EXP_DECL int pcre_refcount ( pcre *  ,
int   
)

Definition at line 70 of file pcre_refcount.c.

{
real_pcre *re = (real_pcre *)argument_re;
if (re == NULL) return PCRE_ERROR_NULL;
re->ref_count = (-adjust > re->ref_count)? 0 :
                (adjust + re->ref_count > 65535)? 65535 :
                re->ref_count + adjust;
return re->ref_count;
}
PCRE_EXP_DECL pcre_extra* pcre_study ( const pcre *  ,
int  ,
const char **   
)

Definition at line 1025 of file pcre_study.c.

{
int min;
BOOL bits_set = FALSE;
uschar start_bits[32];
pcre_extra *extra;
pcre_study_data *study;
const uschar *tables;
uschar *code;
compile_data compile_block;
const real_pcre *re = (const real_pcre *)external_re;

*errorptr = NULL;

if (re == NULL || re->magic_number != MAGIC_NUMBER)
  {
  *errorptr = "argument is not a compiled regular expression";
  return NULL;
  }

if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
  {
  *errorptr = "unknown or incorrect option bit(s) set";
  return NULL;
  }

code = (uschar *)re + re->name_table_offset +
  (re->name_count * re->name_entry_size);

/* For an anchored pattern, or an unanchored pattern that has a first char, or
a multiline pattern that matches only at "line starts", there is no point in
seeking a list of starting bytes. */

if ((re->options & PCRE_ANCHORED) == 0 &&
    (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0)
  {
  /* Set the character tables in the block that is passed around */

  tables = re->tables;
  if (tables == NULL)
    (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
    (void *)(&tables));

  compile_block.lcc = tables + lcc_offset;
  compile_block.fcc = tables + fcc_offset;
  compile_block.cbits = tables + cbits_offset;
  compile_block.ctypes = tables + ctypes_offset;

  /* See if we can find a fixed set of initial characters for the pattern. */

  memset(start_bits, 0, 32 * sizeof(uschar));
  bits_set = set_start_bits(code, start_bits,
    (re->options & PCRE_CASELESS) != 0, (re->options & PCRE_UTF8) != 0,
    &compile_block) == SSB_DONE;
  }

/* Find the minimum length of subject string. */

min = find_minlength(code, code, re->options);

/* Return NULL if no optimization is possible. */

if (!bits_set && min < 0) return NULL;

/* Get a pcre_extra block and a pcre_study_data block. The study data is put in
the latter, which is pointed to by the former, which may also get additional
data set later by the calling program. At the moment, the size of
pcre_study_data is fixed. We nevertheless save it in a field for returning via
the pcre_fullinfo() function so that if it becomes variable in the future, we
don't have to change that code. */

extra = (pcre_extra *)(pcre_malloc)
  (sizeof(pcre_extra) + sizeof(pcre_study_data));

if (extra == NULL)
  {
  *errorptr = "failed to get memory";
  return NULL;
  }

study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra));
extra->flags = PCRE_EXTRA_STUDY_DATA;
extra->study_data = study;

study->size = sizeof(pcre_study_data);
study->flags = 0;

if (bits_set)
  {
  study->flags |= PCRE_STUDY_MAPPED;
  memcpy(study->start_bits, start_bits, sizeof(start_bits));
  }

if (min >= 0)
  {
  study->flags |= PCRE_STUDY_MINLEN;
  study->minlength = min;
  }

return extra;
}

Here is the call graph for this function:

PCRE_EXP_DECL const char* pcre_version ( void  )

Definition at line 81 of file pcre_version.c.

{
return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
  XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
  XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE);
}

Variable Documentation

Definition at line 271 of file pcre.h.

PCRE_EXP_DECL void(* pcre_free)(void *)

Definition at line 268 of file pcre.h.

Definition at line 267 of file pcre.h.

PCRE_EXP_DECL void(* pcre_stack_free)(void *)

Definition at line 270 of file pcre.h.

Definition at line 269 of file pcre.h.