EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

AppPkg/Applications/Python/PyMod-2.7.2/Modules/_sre.c

Go to the documentation of this file.
00001 /*
00002  * Secret Labs' Regular Expression Engine
00003  *
00004  * regular expression matching engine
00005 
00006     Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
00007     This program and the accompanying materials are licensed and made available under
00008     the terms and conditions of the BSD License that accompanies this distribution.
00009     The full text of the license may be found at
00010     http://opensource.org/licenses/bsd-license.
00011 
00012     THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
00013     WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
00014  *
00015  * partial history:
00016  * 1999-10-24 fl  created (based on existing template matcher code)
00017  * 2000-03-06 fl  first alpha, sort of
00018  * 2000-08-01 fl  fixes for 1.6b1
00019  * 2000-08-07 fl  use PyOS_CheckStack() if available
00020  * 2000-09-20 fl  added expand method
00021  * 2001-03-20 fl  lots of fixes for 2.1b2
00022  * 2001-04-15 fl  export copyright as Python attribute, not global
00023  * 2001-04-28 fl  added __copy__ methods (work in progress)
00024  * 2001-05-14 fl  fixes for 1.5.2 compatibility
00025  * 2001-07-01 fl  added BIGCHARSET support (from Martin von Loewis)
00026  * 2001-10-18 fl  fixed group reset issue (from Matthew Mueller)
00027  * 2001-10-20 fl  added split primitive; reenable unicode for 1.6/2.0/2.1
00028  * 2001-10-21 fl  added sub/subn primitive
00029  * 2001-10-24 fl  added finditer primitive (for 2.2 only)
00030  * 2001-12-07 fl  fixed memory leak in sub/subn (Guido van Rossum)
00031  * 2002-11-09 fl  fixed empty sub/subn return type
00032  * 2003-04-18 mvl fully support 4-byte codes
00033  * 2003-10-17 gn  implemented non recursive scheme
00034  *
00035  * Copyright (c) 1997-2001 by Secret Labs AB.  All rights reserved.
00036  *
00037  * This version of the SRE library can be redistributed under CNRI's
00038  * Python 1.6 license.  For any other use, please contact Secret Labs
00039  * AB (info@pythonware.com).
00040  *
00041  * Portions of this engine have been developed in cooperation with
00042  * CNRI.  Hewlett-Packard provided funding for 1.6 integration and
00043  * other compatibility work.
00044  */
00045 
00046 /* Get rid of these macros to prevent collisions between EFI and Python in this file. */
00047 #undef  RETURN_ERROR
00048 #undef  RETURN_SUCCESS
00049 
00050 #ifndef SRE_RECURSIVE
00051 
00052 static char copyright[] =
00053     " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB ";
00054 
00055 #define PY_SSIZE_T_CLEAN
00056 
00057 #include "Python.h"
00058 #include "structmember.h" /* offsetof */
00059 
00060 #include "sre.h"
00061 
00062 #include <ctype.h>
00063 
00064 /* name of this module, minus the leading underscore */
00065 #if !defined(SRE_MODULE)
00066 #define SRE_MODULE "sre"
00067 #endif
00068 
00069 #define SRE_PY_MODULE "re"
00070 
00071 /* defining this one enables tracing */
00072 #undef VERBOSE
00073 
00074 #if PY_VERSION_HEX >= 0x01060000
00075 #if PY_VERSION_HEX  < 0x02020000 || defined(Py_USING_UNICODE)
00076 /* defining this enables unicode support (default under 1.6a1 and later) */
00077 #define HAVE_UNICODE
00078 #endif
00079 #endif
00080 
00081 /* -------------------------------------------------------------------- */
00082 /* optional features */
00083 
00084 /* enables fast searching */
00085 #define USE_FAST_SEARCH
00086 
00087 /* enables aggressive inlining (always on for Visual C) */
00088 #undef USE_INLINE
00089 
00090 /* enables copy/deepcopy handling (work in progress) */
00091 #undef USE_BUILTIN_COPY
00092 
00093 #if PY_VERSION_HEX < 0x01060000
00094 #define PyObject_DEL(op) PyMem_DEL((op))
00095 #endif
00096 
00097 /* -------------------------------------------------------------------- */
00098 
00099 #if defined(_MSC_VER)
00100 #pragma optimize("gt", on) /* doesn't seem to make much difference... */
00101 #pragma warning(disable: 4710) /* who cares if functions are not inlined ;-) */
00102 /* fastest possible local call under MSVC */
00103 #define LOCAL(type) static __inline type __fastcall
00104 #elif defined(USE_INLINE)
00105 #define LOCAL(type) static inline type
00106 #else
00107 #define LOCAL(type) static type
00108 #endif
00109 
00110 /* error codes */
00111 #define SRE_ERROR_ILLEGAL -1 /* illegal opcode */
00112 #define SRE_ERROR_STATE -2 /* illegal state */
00113 #define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
00114 #define SRE_ERROR_MEMORY -9 /* out of memory */
00115 #define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */
00116 
00117 #if defined(VERBOSE)
00118 #define TRACE(v) printf v
00119 #else
00120 #define TRACE(v)
00121 #endif
00122 
00123 /* -------------------------------------------------------------------- */
00124 /* search engine state */
00125 
00126 /* default character predicates (run sre_chars.py to regenerate tables) */
00127 
00128 #define SRE_DIGIT_MASK 1
00129 #define SRE_SPACE_MASK 2
00130 #define SRE_LINEBREAK_MASK 4
00131 #define SRE_ALNUM_MASK 8
00132 #define SRE_WORD_MASK 16
00133 
00134 /* FIXME: this assumes ASCII.  create tables in init_sre() instead */
00135 
00136 static char sre_char_info[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2,
00137 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
00138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25,
00139 25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
00140 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0,
00141 0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
00142 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 };
00143 
00144 static char sre_char_lower[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
00145 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
00146 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
00147 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
00148 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
00149 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
00150 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
00151 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
00152 120, 121, 122, 123, 124, 125, 126, 127 };
00153 
00154 #define SRE_IS_DIGIT(ch)\
00155     ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)
00156 #define SRE_IS_SPACE(ch)\
00157     ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)
00158 #define SRE_IS_LINEBREAK(ch)\
00159     ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)
00160 #define SRE_IS_ALNUM(ch)\
00161     ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)
00162 #define SRE_IS_WORD(ch)\
00163     ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)
00164 
00165 static unsigned int sre_lower(unsigned int ch)
00166 {
00167     return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch);
00168 }
00169 
00170 /* locale-specific character predicates */
00171 /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
00172  * warnings when c's type supports only numbers < N+1 */
00173 #define SRE_LOC_IS_DIGIT(ch) (!((ch) & ~255) ? isdigit((ch)) : 0)
00174 #define SRE_LOC_IS_SPACE(ch) (!((ch) & ~255) ? isspace((ch)) : 0)
00175 #define SRE_LOC_IS_LINEBREAK(ch) ((ch) == '\n')
00176 #define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0)
00177 #define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')
00178 
00179 static unsigned int sre_lower_locale(unsigned int ch)
00180 {
00181     return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch);
00182 }
00183 
00184 /* unicode-specific character predicates */
00185 
00186 #if defined(HAVE_UNICODE)
00187 
00188 #define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDECIMAL((Py_UNICODE)(ch))
00189 #define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE((Py_UNICODE)(ch))
00190 #define SRE_UNI_IS_LINEBREAK(ch) Py_UNICODE_ISLINEBREAK((Py_UNICODE)(ch))
00191 #define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM((Py_UNICODE)(ch))
00192 #define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_')
00193 
00194 static unsigned int sre_lower_unicode(unsigned int ch)
00195 {
00196     return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch));
00197 }
00198 
00199 #endif
00200 
00201 LOCAL(int)
00202 sre_category(SRE_CODE category, unsigned int ch)
00203 {
00204     switch (category) {
00205 
00206     case SRE_CATEGORY_DIGIT:
00207         return SRE_IS_DIGIT(ch);
00208     case SRE_CATEGORY_NOT_DIGIT:
00209         return !SRE_IS_DIGIT(ch);
00210     case SRE_CATEGORY_SPACE:
00211         return SRE_IS_SPACE(ch);
00212     case SRE_CATEGORY_NOT_SPACE:
00213         return !SRE_IS_SPACE(ch);
00214     case SRE_CATEGORY_WORD:
00215         return SRE_IS_WORD(ch);
00216     case SRE_CATEGORY_NOT_WORD:
00217         return !SRE_IS_WORD(ch);
00218     case SRE_CATEGORY_LINEBREAK:
00219         return SRE_IS_LINEBREAK(ch);
00220     case SRE_CATEGORY_NOT_LINEBREAK:
00221         return !SRE_IS_LINEBREAK(ch);
00222 
00223     case SRE_CATEGORY_LOC_WORD:
00224         return SRE_LOC_IS_WORD(ch);
00225     case SRE_CATEGORY_LOC_NOT_WORD:
00226         return !SRE_LOC_IS_WORD(ch);
00227 
00228 #if defined(HAVE_UNICODE)
00229     case SRE_CATEGORY_UNI_DIGIT:
00230         return SRE_UNI_IS_DIGIT(ch);
00231     case SRE_CATEGORY_UNI_NOT_DIGIT:
00232         return !SRE_UNI_IS_DIGIT(ch);
00233     case SRE_CATEGORY_UNI_SPACE:
00234         return SRE_UNI_IS_SPACE(ch);
00235     case SRE_CATEGORY_UNI_NOT_SPACE:
00236         return !SRE_UNI_IS_SPACE(ch);
00237     case SRE_CATEGORY_UNI_WORD:
00238         return SRE_UNI_IS_WORD(ch);
00239     case SRE_CATEGORY_UNI_NOT_WORD:
00240         return !SRE_UNI_IS_WORD(ch);
00241     case SRE_CATEGORY_UNI_LINEBREAK:
00242         return SRE_UNI_IS_LINEBREAK(ch);
00243     case SRE_CATEGORY_UNI_NOT_LINEBREAK:
00244         return !SRE_UNI_IS_LINEBREAK(ch);
00245 #else
00246     case SRE_CATEGORY_UNI_DIGIT:
00247         return SRE_IS_DIGIT(ch);
00248     case SRE_CATEGORY_UNI_NOT_DIGIT:
00249         return !SRE_IS_DIGIT(ch);
00250     case SRE_CATEGORY_UNI_SPACE:
00251         return SRE_IS_SPACE(ch);
00252     case SRE_CATEGORY_UNI_NOT_SPACE:
00253         return !SRE_IS_SPACE(ch);
00254     case SRE_CATEGORY_UNI_WORD:
00255         return SRE_LOC_IS_WORD(ch);
00256     case SRE_CATEGORY_UNI_NOT_WORD:
00257         return !SRE_LOC_IS_WORD(ch);
00258     case SRE_CATEGORY_UNI_LINEBREAK:
00259         return SRE_IS_LINEBREAK(ch);
00260     case SRE_CATEGORY_UNI_NOT_LINEBREAK:
00261         return !SRE_IS_LINEBREAK(ch);
00262 #endif
00263     }
00264     return 0;
00265 }
00266 
00267 /* helpers */
00268 
00269 static void
00270 data_stack_dealloc(SRE_STATE* state)
00271 {
00272     if (state->data_stack) {
00273         PyMem_FREE(state->data_stack);
00274         state->data_stack = NULL;
00275     }
00276     state->data_stack_size = state->data_stack_base = 0;
00277 }
00278 
00279 static int
00280 data_stack_grow(SRE_STATE* state, Py_ssize_t size)
00281 {
00282     Py_ssize_t minsize, cursize;
00283     minsize = state->data_stack_base+size;
00284     cursize = state->data_stack_size;
00285     if (cursize < minsize) {
00286         void* stack;
00287         cursize = minsize+minsize/4+1024;
00288         TRACE(("allocate/grow stack %d\n", cursize));
00289         stack = PyMem_REALLOC(state->data_stack, cursize);
00290         if (!stack) {
00291             data_stack_dealloc(state);
00292             return SRE_ERROR_MEMORY;
00293         }
00294         state->data_stack = (char *)stack;
00295         state->data_stack_size = cursize;
00296     }
00297     return 0;
00298 }
00299 
00300 /* generate 8-bit version */
00301 
00302 #define SRE_CHAR unsigned char
00303 #define SRE_AT sre_at
00304 #define SRE_COUNT sre_count
00305 #define SRE_CHARSET sre_charset
00306 #define SRE_INFO sre_info
00307 #define SRE_MATCH sre_match
00308 #define SRE_MATCH_CONTEXT sre_match_context
00309 #define SRE_SEARCH sre_search
00310 #define SRE_LITERAL_TEMPLATE sre_literal_template
00311 
00312 #if defined(HAVE_UNICODE)
00313 
00314 #define SRE_RECURSIVE
00315 #include "_sre.c"
00316 #undef SRE_RECURSIVE
00317 
00318 #undef SRE_LITERAL_TEMPLATE
00319 #undef SRE_SEARCH
00320 #undef SRE_MATCH
00321 #undef SRE_MATCH_CONTEXT
00322 #undef SRE_INFO
00323 #undef SRE_CHARSET
00324 #undef SRE_COUNT
00325 #undef SRE_AT
00326 #undef SRE_CHAR
00327 
00328 /* generate 16-bit unicode version */
00329 
00330 #define SRE_CHAR Py_UNICODE
00331 #define SRE_AT sre_uat
00332 #define SRE_COUNT sre_ucount
00333 #define SRE_CHARSET sre_ucharset
00334 #define SRE_INFO sre_uinfo
00335 #define SRE_MATCH sre_umatch
00336 #define SRE_MATCH_CONTEXT sre_umatch_context
00337 #define SRE_SEARCH sre_usearch
00338 #define SRE_LITERAL_TEMPLATE sre_uliteral_template
00339 #endif
00340 
00341 #endif /* SRE_RECURSIVE */
00342 
00343 /* -------------------------------------------------------------------- */
00344 /* String matching engine */
00345 
00346 /* the following section is compiled twice, with different character
00347    settings */
00348 
00349 LOCAL(int)
00350 SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at)
00351 {
00352     /* check if pointer is at given position */
00353 
00354     Py_ssize_t thisp, thatp;
00355 
00356     switch (at) {
00357 
00358     case SRE_AT_BEGINNING:
00359     case SRE_AT_BEGINNING_STRING:
00360         return ((void*) ptr == state->beginning);
00361 
00362     case SRE_AT_BEGINNING_LINE:
00363         return ((void*) ptr == state->beginning ||
00364                 SRE_IS_LINEBREAK((int) ptr[-1]));
00365 
00366     case SRE_AT_END:
00367         return (((void*) (ptr+1) == state->end &&
00368                  SRE_IS_LINEBREAK((int) ptr[0])) ||
00369                 ((void*) ptr == state->end));
00370 
00371     case SRE_AT_END_LINE:
00372         return ((void*) ptr == state->end ||
00373                 SRE_IS_LINEBREAK((int) ptr[0]));
00374 
00375     case SRE_AT_END_STRING:
00376         return ((void*) ptr == state->end);
00377 
00378     case SRE_AT_BOUNDARY:
00379         if (state->beginning == state->end)
00380             return 0;
00381         thatp = ((void*) ptr > state->beginning) ?
00382             SRE_IS_WORD((int) ptr[-1]) : 0;
00383         thisp = ((void*) ptr < state->end) ?
00384             SRE_IS_WORD((int) ptr[0]) : 0;
00385         return thisp != thatp;
00386 
00387     case SRE_AT_NON_BOUNDARY:
00388         if (state->beginning == state->end)
00389             return 0;
00390         thatp = ((void*) ptr > state->beginning) ?
00391             SRE_IS_WORD((int) ptr[-1]) : 0;
00392         thisp = ((void*) ptr < state->end) ?
00393             SRE_IS_WORD((int) ptr[0]) : 0;
00394         return thisp == thatp;
00395 
00396     case SRE_AT_LOC_BOUNDARY:
00397         if (state->beginning == state->end)
00398             return 0;
00399         thatp = ((void*) ptr > state->beginning) ?
00400             SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
00401         thisp = ((void*) ptr < state->end) ?
00402             SRE_LOC_IS_WORD((int) ptr[0]) : 0;
00403         return thisp != thatp;
00404 
00405     case SRE_AT_LOC_NON_BOUNDARY:
00406         if (state->beginning == state->end)
00407             return 0;
00408         thatp = ((void*) ptr > state->beginning) ?
00409             SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
00410         thisp = ((void*) ptr < state->end) ?
00411             SRE_LOC_IS_WORD((int) ptr[0]) : 0;
00412         return thisp == thatp;
00413 
00414 #if defined(HAVE_UNICODE)
00415     case SRE_AT_UNI_BOUNDARY:
00416         if (state->beginning == state->end)
00417             return 0;
00418         thatp = ((void*) ptr > state->beginning) ?
00419             SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
00420         thisp = ((void*) ptr < state->end) ?
00421             SRE_UNI_IS_WORD((int) ptr[0]) : 0;
00422         return thisp != thatp;
00423 
00424     case SRE_AT_UNI_NON_BOUNDARY:
00425         if (state->beginning == state->end)
00426             return 0;
00427         thatp = ((void*) ptr > state->beginning) ?
00428             SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
00429         thisp = ((void*) ptr < state->end) ?
00430             SRE_UNI_IS_WORD((int) ptr[0]) : 0;
00431         return thisp == thatp;
00432 #endif
00433 
00434     }
00435 
00436     return 0;
00437 }
00438 
00439 LOCAL(int)
00440 SRE_CHARSET(SRE_CODE* set, SRE_CODE ch)
00441 {
00442     /* check if character is a member of the given set */
00443 
00444     int ok = 1;
00445 
00446     for (;;) {
00447         switch (*set++) {
00448 
00449         case SRE_OP_FAILURE:
00450             return !ok;
00451 
00452         case SRE_OP_LITERAL:
00453             /* <LITERAL> <code> */
00454             if (ch == set[0])
00455                 return ok;
00456             set++;
00457             break;
00458 
00459         case SRE_OP_CATEGORY:
00460             /* <CATEGORY> <code> */
00461             if (sre_category(set[0], (int) ch))
00462                 return ok;
00463             set += 1;
00464             break;
00465 
00466         case SRE_OP_CHARSET:
00467             if (sizeof(SRE_CODE) == 2) {
00468                 /* <CHARSET> <bitmap> (16 bits per code word) */
00469                 if (ch < 256 && (set[ch >> 4] & (1 << (ch & 15))))
00470                     return ok;
00471                 set += 16;
00472             }
00473             else {
00474                 /* <CHARSET> <bitmap> (32 bits per code word) */
00475                 if (ch < 256 && (set[ch >> 5] & (1 << (ch & 31))))
00476                     return ok;
00477                 set += 8;
00478             }
00479             break;
00480 
00481         case SRE_OP_RANGE:
00482             /* <RANGE> <lower> <upper> */
00483             if (set[0] <= ch && ch <= set[1])
00484                 return ok;
00485             set += 2;
00486             break;
00487 
00488         case SRE_OP_NEGATE:
00489             ok = !ok;
00490             break;
00491 
00492         case SRE_OP_BIGCHARSET:
00493             /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
00494         {
00495             Py_ssize_t count, block;
00496             count = *(set++);
00497 
00498             if (sizeof(SRE_CODE) == 2) {
00499                 block = ((unsigned char*)set)[ch >> 8];
00500                 set += 128;
00501                 if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15)))
00502                     return ok;
00503                 set += count*16;
00504             }
00505             else {
00506                 /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
00507                  * warnings when c's type supports only numbers < N+1 */
00508                 if (!(ch & ~65535))
00509                     block = ((unsigned char*)set)[ch >> 8];
00510                 else
00511                     block = -1;
00512                 set += 64;
00513                 if (block >=0 &&
00514                     (set[block*8 + ((ch & 255)>>5)] & (1 << (ch & 31))))
00515                     return ok;
00516                 set += count*8;
00517             }
00518             break;
00519         }
00520 
00521         default:
00522             /* internal error -- there's not much we can do about it
00523                here, so let's just pretend it didn't match... */
00524             return 0;
00525         }
00526     }
00527 }
00528 
00529 LOCAL(Py_ssize_t) SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern);
00530 
00531 LOCAL(Py_ssize_t)
00532 SRE_COUNT(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
00533 {
00534     SRE_CODE chr;
00535     SRE_CHAR* ptr = (SRE_CHAR *)state->ptr;
00536     SRE_CHAR* end = (SRE_CHAR *)state->end;
00537     Py_ssize_t i;
00538 
00539     /* adjust end */
00540     if (maxcount < end - ptr && maxcount != 65535)
00541         end = ptr + maxcount;
00542 
00543     switch (pattern[0]) {
00544 
00545     case SRE_OP_IN:
00546         /* repeated set */
00547         TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
00548         while (ptr < end && SRE_CHARSET(pattern + 2, *ptr))
00549             ptr++;
00550         break;
00551 
00552     case SRE_OP_ANY:
00553         /* repeated dot wildcard. */
00554         TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
00555         while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
00556             ptr++;
00557         break;
00558 
00559     case SRE_OP_ANY_ALL:
00560         /* repeated dot wildcard.  skip to the end of the target
00561            string, and backtrack from there */
00562         TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
00563         ptr = end;
00564         break;
00565 
00566     case SRE_OP_LITERAL:
00567         /* repeated literal */
00568         chr = pattern[1];
00569         TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
00570         while (ptr < end && (SRE_CODE) *ptr == chr)
00571             ptr++;
00572         break;
00573 
00574     case SRE_OP_LITERAL_IGNORE:
00575         /* repeated literal */
00576         chr = pattern[1];
00577         TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
00578         while (ptr < end && (SRE_CODE) state->lower(*ptr) == chr)
00579             ptr++;
00580         break;
00581 
00582     case SRE_OP_NOT_LITERAL:
00583         /* repeated non-literal */
00584         chr = pattern[1];
00585         TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
00586         while (ptr < end && (SRE_CODE) *ptr != chr)
00587             ptr++;
00588         break;
00589 
00590     case SRE_OP_NOT_LITERAL_IGNORE:
00591         /* repeated non-literal */
00592         chr = pattern[1];
00593         TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
00594         while (ptr < end && (SRE_CODE) state->lower(*ptr) != chr)
00595             ptr++;
00596         break;
00597 
00598     default:
00599         /* repeated single character pattern */
00600         TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
00601         while ((SRE_CHAR*) state->ptr < end) {
00602             i = SRE_MATCH(state, pattern);
00603             if (i < 0)
00604                 return i;
00605             if (!i)
00606                 break;
00607         }
00608         TRACE(("|%p|%p|COUNT %d\n", pattern, ptr,
00609                (SRE_CHAR*) state->ptr - ptr));
00610         return (SRE_CHAR*) state->ptr - ptr;
00611     }
00612 
00613     TRACE(("|%p|%p|COUNT %d\n", pattern, ptr, ptr - (SRE_CHAR*) state->ptr));
00614     return ptr - (SRE_CHAR*) state->ptr;
00615 }
00616 
00617 #if 0 /* not used in this release */
00618 LOCAL(int)
00619 SRE_INFO(SRE_STATE* state, SRE_CODE* pattern)
00620 {
00621     /* check if an SRE_OP_INFO block matches at the current position.
00622        returns the number of SRE_CODE objects to skip if successful, 0
00623        if no match */
00624 
00625     SRE_CHAR* end = state->end;
00626     SRE_CHAR* ptr = state->ptr;
00627     Py_ssize_t i;
00628 
00629     /* check minimal length */
00630     if (pattern[3] && (end - ptr) < pattern[3])
00631         return 0;
00632 
00633     /* check known prefix */
00634     if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) {
00635         /* <length> <skip> <prefix data> <overlap data> */
00636         for (i = 0; i < pattern[5]; i++)
00637             if ((SRE_CODE) ptr[i] != pattern[7 + i])
00638                 return 0;
00639         return pattern[0] + 2 * pattern[6];
00640     }
00641     return pattern[0];
00642 }
00643 #endif
00644 
00645 /* The macros below should be used to protect recursive SRE_MATCH()
00646  * calls that *failed* and do *not* return immediately (IOW, those
00647  * that will backtrack). Explaining:
00648  *
00649  * - Recursive SRE_MATCH() returned true: that's usually a success
00650  *   (besides atypical cases like ASSERT_NOT), therefore there's no
00651  *   reason to restore lastmark;
00652  *
00653  * - Recursive SRE_MATCH() returned false but the current SRE_MATCH()
00654  *   is returning to the caller: If the current SRE_MATCH() is the
00655  *   top function of the recursion, returning false will be a matching
00656  *   failure, and it doesn't matter where lastmark is pointing to.
00657  *   If it's *not* the top function, it will be a recursive SRE_MATCH()
00658  *   failure by itself, and the calling SRE_MATCH() will have to deal
00659  *   with the failure by the same rules explained here (it will restore
00660  *   lastmark by itself if necessary);
00661  *
00662  * - Recursive SRE_MATCH() returned false, and will continue the
00663  *   outside 'for' loop: must be protected when breaking, since the next
00664  *   OP could potentially depend on lastmark;
00665  *
00666  * - Recursive SRE_MATCH() returned false, and will be called again
00667  *   inside a local for/while loop: must be protected between each
00668  *   loop iteration, since the recursive SRE_MATCH() could do anything,
00669  *   and could potentially depend on lastmark.
00670  *
00671  * For more information, check the discussion at SF patch #712900.
00672  */
00673 #define LASTMARK_SAVE()     \
00674     do { \
00675         ctx->lastmark = state->lastmark; \
00676         ctx->lastindex = state->lastindex; \
00677     } while (0)
00678 #define LASTMARK_RESTORE()  \
00679     do { \
00680         state->lastmark = ctx->lastmark; \
00681         state->lastindex = ctx->lastindex; \
00682     } while (0)
00683 
00684 #define RETURN_ERROR(i) do { return i; } while(0)
00685 #define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
00686 #define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
00687 
00688 #define RETURN_ON_ERROR(i) \
00689     do { if (i < 0) RETURN_ERROR(i); } while (0)
00690 #define RETURN_ON_SUCCESS(i) \
00691     do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
00692 #define RETURN_ON_FAILURE(i) \
00693     do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
00694 
00695 #define SFY(x) #x
00696 
00697 #define DATA_STACK_ALLOC(state, type, ptr) \
00698 do { \
00699     alloc_pos = state->data_stack_base; \
00700     TRACE(("allocating %s in %d (%d)\n", \
00701            SFY(type), alloc_pos, sizeof(type))); \
00702     if (state->data_stack_size < alloc_pos+sizeof(type)) { \
00703         int j = data_stack_grow(state, sizeof(type)); \
00704         if (j < 0) return j; \
00705         if (ctx_pos != -1) \
00706             DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
00707     } \
00708     ptr = (type*)(state->data_stack+alloc_pos); \
00709     state->data_stack_base += sizeof(type); \
00710 } while (0)
00711 
00712 #define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
00713 do { \
00714     TRACE(("looking up %s at %d\n", SFY(type), pos)); \
00715     ptr = (type*)(state->data_stack+pos); \
00716 } while (0)
00717 
00718 #define DATA_STACK_PUSH(state, data, size) \
00719 do { \
00720     TRACE(("copy data in %p to %d (%d)\n", \
00721            data, state->data_stack_base, size)); \
00722     if (state->data_stack_size < state->data_stack_base+size) { \
00723         int j = data_stack_grow(state, size); \
00724         if (j < 0) return j; \
00725         if (ctx_pos != -1) \
00726             DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
00727     } \
00728     memcpy(state->data_stack+state->data_stack_base, data, size); \
00729     state->data_stack_base += size; \
00730 } while (0)
00731 
00732 #define DATA_STACK_POP(state, data, size, discard) \
00733 do { \
00734     TRACE(("copy data to %p from %d (%d)\n", \
00735            data, state->data_stack_base-size, size)); \
00736     memcpy(data, state->data_stack+state->data_stack_base-size, size); \
00737     if (discard) \
00738         state->data_stack_base -= size; \
00739 } while (0)
00740 
00741 #define DATA_STACK_POP_DISCARD(state, size) \
00742 do { \
00743     TRACE(("discard data from %d (%d)\n", \
00744            state->data_stack_base-size, size)); \
00745     state->data_stack_base -= size; \
00746 } while(0)
00747 
00748 #define DATA_PUSH(x) \
00749     DATA_STACK_PUSH(state, (x), sizeof(*(x)))
00750 #define DATA_POP(x) \
00751     DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
00752 #define DATA_POP_DISCARD(x) \
00753     DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
00754 #define DATA_ALLOC(t,p) \
00755     DATA_STACK_ALLOC(state, t, p)
00756 #define DATA_LOOKUP_AT(t,p,pos) \
00757     DATA_STACK_LOOKUP_AT(state,t,p,pos)
00758 
00759 #define MARK_PUSH(lastmark) \
00760     do if (lastmark > 0) { \
00761         i = lastmark; /* ctx->lastmark may change if reallocated */ \
00762         DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \
00763     } while (0)
00764 #define MARK_POP(lastmark) \
00765     do if (lastmark > 0) { \
00766         DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \
00767     } while (0)
00768 #define MARK_POP_KEEP(lastmark) \
00769     do if (lastmark > 0) { \
00770         DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \
00771     } while (0)
00772 #define MARK_POP_DISCARD(lastmark) \
00773     do if (lastmark > 0) { \
00774         DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \
00775     } while (0)
00776 
00777 #define JUMP_NONE            0
00778 #define JUMP_MAX_UNTIL_1     1
00779 #define JUMP_MAX_UNTIL_2     2
00780 #define JUMP_MAX_UNTIL_3     3
00781 #define JUMP_MIN_UNTIL_1     4
00782 #define JUMP_MIN_UNTIL_2     5
00783 #define JUMP_MIN_UNTIL_3     6
00784 #define JUMP_REPEAT          7
00785 #define JUMP_REPEAT_ONE_1    8
00786 #define JUMP_REPEAT_ONE_2    9
00787 #define JUMP_MIN_REPEAT_ONE  10
00788 #define JUMP_BRANCH          11
00789 #define JUMP_ASSERT          12
00790 #define JUMP_ASSERT_NOT      13
00791 
00792 #define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
00793     DATA_ALLOC(SRE_MATCH_CONTEXT, nextctx); \
00794     nextctx->last_ctx_pos = ctx_pos; \
00795     nextctx->jump = jumpvalue; \
00796     nextctx->pattern = nextpattern; \
00797     ctx_pos = alloc_pos; \
00798     ctx = nextctx; \
00799     goto entrance; \
00800     jumplabel: \
00801     while (0) /* gcc doesn't like labels at end of scopes */ \
00802 
00803 typedef struct {
00804     Py_ssize_t last_ctx_pos;
00805     Py_ssize_t jump;
00806     SRE_CHAR* ptr;
00807     SRE_CODE* pattern;
00808     Py_ssize_t count;
00809     Py_ssize_t lastmark;
00810     Py_ssize_t lastindex;
00811     union {
00812         SRE_CODE chr;
00813         SRE_REPEAT* rep;
00814     } u;
00815 } SRE_MATCH_CONTEXT;
00816 
00817 /* check if string matches the given pattern.  returns <0 for
00818    error, 0 for failure, and 1 for success */
00819 LOCAL(Py_ssize_t)
00820 SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
00821 {
00822     SRE_CHAR* end = (SRE_CHAR *)state->end;
00823     Py_ssize_t alloc_pos, ctx_pos = -1;
00824     Py_ssize_t i, ret = 0;
00825     Py_ssize_t jump;
00826     unsigned int sigcount=0;
00827 
00828     SRE_MATCH_CONTEXT* ctx;
00829     SRE_MATCH_CONTEXT* nextctx;
00830 
00831     TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
00832 
00833     DATA_ALLOC(SRE_MATCH_CONTEXT, ctx);
00834     ctx->last_ctx_pos = -1;
00835     ctx->jump = JUMP_NONE;
00836     ctx->pattern = pattern;
00837     ctx_pos = alloc_pos;
00838 
00839 entrance:
00840 
00841     ctx->ptr = (SRE_CHAR *)state->ptr;
00842 
00843     if (ctx->pattern[0] == SRE_OP_INFO) {
00844         /* optimization info block */
00845         /* <INFO> <1=skip> <2=flags> <3=min> ... */
00846         if (ctx->pattern[3] && (end - ctx->ptr) < ctx->pattern[3]) {
00847             TRACE(("reject (got %d chars, need %d)\n",
00848                    (end - ctx->ptr), ctx->pattern[3]));
00849             RETURN_FAILURE;
00850         }
00851         ctx->pattern += ctx->pattern[1] + 1;
00852     }
00853 
00854     for (;;) {
00855         ++sigcount;
00856         if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
00857             RETURN_ERROR(SRE_ERROR_INTERRUPTED);
00858 
00859         switch (*ctx->pattern++) {
00860 
00861         case SRE_OP_MARK:
00862             /* set mark */
00863             /* <MARK> <gid> */
00864             TRACE(("|%p|%p|MARK %d\n", ctx->pattern,
00865                    ctx->ptr, ctx->pattern[0]));
00866             i = ctx->pattern[0];
00867             if (i & 1)
00868                 state->lastindex = i/2 + 1;
00869             if (i > state->lastmark) {
00870                 /* state->lastmark is the highest valid index in the
00871                    state->mark array.  If it is increased by more than 1,
00872                    the intervening marks must be set to NULL to signal
00873                    that these marks have not been encountered. */
00874                 Py_ssize_t j = state->lastmark + 1;
00875                 while (j < i)
00876                     state->mark[j++] = NULL;
00877                 state->lastmark = i;
00878             }
00879             state->mark[i] = ctx->ptr;
00880             ctx->pattern++;
00881             break;
00882 
00883         case SRE_OP_LITERAL:
00884             /* match literal string */
00885             /* <LITERAL> <code> */
00886             TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern,
00887                    ctx->ptr, *ctx->pattern));
00888             if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0])
00889                 RETURN_FAILURE;
00890             ctx->pattern++;
00891             ctx->ptr++;
00892             break;
00893 
00894         case SRE_OP_NOT_LITERAL:
00895             /* match anything that is not literal character */
00896             /* <NOT_LITERAL> <code> */
00897             TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern,
00898                    ctx->ptr, *ctx->pattern));
00899             if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0])
00900                 RETURN_FAILURE;
00901             ctx->pattern++;
00902             ctx->ptr++;
00903             break;
00904 
00905         case SRE_OP_SUCCESS:
00906             /* end of pattern */
00907             TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));
00908             state->ptr = ctx->ptr;
00909             RETURN_SUCCESS;
00910 
00911         case SRE_OP_AT:
00912             /* match at given position */
00913             /* <AT> <code> */
00914             TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern));
00915             if (!SRE_AT(state, ctx->ptr, *ctx->pattern))
00916                 RETURN_FAILURE;
00917             ctx->pattern++;
00918             break;
00919 
00920         case SRE_OP_CATEGORY:
00921             /* match at given category */
00922             /* <CATEGORY> <code> */
00923             TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern,
00924                    ctx->ptr, *ctx->pattern));
00925             if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0]))
00926                 RETURN_FAILURE;
00927             ctx->pattern++;
00928             ctx->ptr++;
00929             break;
00930 
00931         case SRE_OP_ANY:
00932             /* match anything (except a newline) */
00933             /* <ANY> */
00934             TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr));
00935             if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0]))
00936                 RETURN_FAILURE;
00937             ctx->ptr++;
00938             break;
00939 
00940         case SRE_OP_ANY_ALL:
00941             /* match anything */
00942             /* <ANY_ALL> */
00943             TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr));
00944             if (ctx->ptr >= end)
00945                 RETURN_FAILURE;
00946             ctx->ptr++;
00947             break;
00948 
00949         case SRE_OP_IN:
00950             /* match set member (or non_member) */
00951             /* <IN> <skip> <set> */
00952             TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr));
00953             if (ctx->ptr >= end || !SRE_CHARSET(ctx->pattern + 1, *ctx->ptr))
00954                 RETURN_FAILURE;
00955             ctx->pattern += ctx->pattern[0];
00956             ctx->ptr++;
00957             break;
00958 
00959         case SRE_OP_LITERAL_IGNORE:
00960             TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
00961                    ctx->pattern, ctx->ptr, ctx->pattern[0]));
00962             if (ctx->ptr >= end ||
00963                 state->lower(*ctx->ptr) != state->lower(*ctx->pattern))
00964                 RETURN_FAILURE;
00965             ctx->pattern++;
00966             ctx->ptr++;
00967             break;
00968 
00969         case SRE_OP_NOT_LITERAL_IGNORE:
00970             TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
00971                    ctx->pattern, ctx->ptr, *ctx->pattern));
00972             if (ctx->ptr >= end ||
00973                 state->lower(*ctx->ptr) == state->lower(*ctx->pattern))
00974                 RETURN_FAILURE;
00975             ctx->pattern++;
00976             ctx->ptr++;
00977             break;
00978 
00979         case SRE_OP_IN_IGNORE:
00980             TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr));
00981             if (ctx->ptr >= end
00982                 || !SRE_CHARSET(ctx->pattern+1,
00983                                 (SRE_CODE)state->lower(*ctx->ptr)))
00984                 RETURN_FAILURE;
00985             ctx->pattern += ctx->pattern[0];
00986             ctx->ptr++;
00987             break;
00988 
00989         case SRE_OP_JUMP:
00990         case SRE_OP_INFO:
00991             /* jump forward */
00992             /* <JUMP> <offset> */
00993             TRACE(("|%p|%p|JUMP %d\n", ctx->pattern,
00994                    ctx->ptr, ctx->pattern[0]));
00995             ctx->pattern += ctx->pattern[0];
00996             break;
00997 
00998         case SRE_OP_BRANCH:
00999             /* alternation */
01000             /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
01001             TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr));
01002             LASTMARK_SAVE();
01003             ctx->u.rep = state->repeat;
01004             if (ctx->u.rep)
01005                 MARK_PUSH(ctx->lastmark);
01006             for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) {
01007                 if (ctx->pattern[1] == SRE_OP_LITERAL &&
01008                     (ctx->ptr >= end ||
01009                      (SRE_CODE) *ctx->ptr != ctx->pattern[2]))
01010                     continue;
01011                 if (ctx->pattern[1] == SRE_OP_IN &&
01012                     (ctx->ptr >= end ||
01013                      !SRE_CHARSET(ctx->pattern + 3, (SRE_CODE) *ctx->ptr)))
01014                     continue;
01015                 state->ptr = ctx->ptr;
01016                 DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1);
01017                 if (ret) {
01018                     if (ctx->u.rep)
01019                         MARK_POP_DISCARD(ctx->lastmark);
01020                     RETURN_ON_ERROR(ret);
01021                     RETURN_SUCCESS;
01022                 }
01023                 if (ctx->u.rep)
01024                     MARK_POP_KEEP(ctx->lastmark);
01025                 LASTMARK_RESTORE();
01026             }
01027             if (ctx->u.rep)
01028                 MARK_POP_DISCARD(ctx->lastmark);
01029             RETURN_FAILURE;
01030 
01031         case SRE_OP_REPEAT_ONE:
01032             /* match repeated sequence (maximizing regexp) */
01033 
01034             /* this operator only works if the repeated item is
01035                exactly one character wide, and we're not already
01036                collecting backtracking points.  for other cases,
01037                use the MAX_REPEAT operator */
01038 
01039             /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
01040 
01041             TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
01042                    ctx->pattern[1], ctx->pattern[2]));
01043 
01044             if (ctx->ptr + ctx->pattern[1] > end)
01045                 RETURN_FAILURE; /* cannot match */
01046 
01047             state->ptr = ctx->ptr;
01048 
01049             ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[2]);
01050             RETURN_ON_ERROR(ret);
01051             DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
01052             ctx->count = ret;
01053             ctx->ptr += ctx->count;
01054 
01055             /* when we arrive here, count contains the number of
01056                matches, and ctx->ptr points to the tail of the target
01057                string.  check if the rest of the pattern matches,
01058                and backtrack if not. */
01059 
01060             if (ctx->count < (Py_ssize_t) ctx->pattern[1])
01061                 RETURN_FAILURE;
01062 
01063             if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
01064                 /* tail is empty.  we're finished */
01065                 state->ptr = ctx->ptr;
01066                 RETURN_SUCCESS;
01067             }
01068 
01069             LASTMARK_SAVE();
01070 
01071             if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) {
01072                 /* tail starts with a literal. skip positions where
01073                    the rest of the pattern cannot possibly match */
01074                 ctx->u.chr = ctx->pattern[ctx->pattern[0]+1];
01075                 for (;;) {
01076                     while (ctx->count >= (Py_ssize_t) ctx->pattern[1] &&
01077                            (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) {
01078                         ctx->ptr--;
01079                         ctx->count--;
01080                     }
01081                     if (ctx->count < (Py_ssize_t) ctx->pattern[1])
01082                         break;
01083                     state->ptr = ctx->ptr;
01084                     DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
01085                             ctx->pattern+ctx->pattern[0]);
01086                     if (ret) {
01087                         RETURN_ON_ERROR(ret);
01088                         RETURN_SUCCESS;
01089                     }
01090 
01091                     LASTMARK_RESTORE();
01092 
01093                     ctx->ptr--;
01094                     ctx->count--;
01095                 }
01096 
01097             } else {
01098                 /* general case */
01099                 while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) {
01100                     state->ptr = ctx->ptr;
01101                     DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
01102                             ctx->pattern+ctx->pattern[0]);
01103                     if (ret) {
01104                         RETURN_ON_ERROR(ret);
01105                         RETURN_SUCCESS;
01106                     }
01107                     ctx->ptr--;
01108                     ctx->count--;
01109                     LASTMARK_RESTORE();
01110                 }
01111             }
01112             RETURN_FAILURE;
01113 
01114         case SRE_OP_MIN_REPEAT_ONE:
01115             /* match repeated sequence (minimizing regexp) */
01116 
01117             /* this operator only works if the repeated item is
01118                exactly one character wide, and we're not already
01119                collecting backtracking points.  for other cases,
01120                use the MIN_REPEAT operator */
01121 
01122             /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
01123 
01124             TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
01125                    ctx->pattern[1], ctx->pattern[2]));
01126 
01127             if (ctx->ptr + ctx->pattern[1] > end)
01128                 RETURN_FAILURE; /* cannot match */
01129 
01130             state->ptr = ctx->ptr;
01131 
01132             if (ctx->pattern[1] == 0)
01133                 ctx->count = 0;
01134             else {
01135                 /* count using pattern min as the maximum */
01136                 ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[1]);
01137                 RETURN_ON_ERROR(ret);
01138                 DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
01139                 if (ret < (Py_ssize_t) ctx->pattern[1])
01140                     /* didn't match minimum number of times */
01141                     RETURN_FAILURE;
01142                 /* advance past minimum matches of repeat */
01143                 ctx->count = ret;
01144                 ctx->ptr += ctx->count;
01145             }
01146 
01147             if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
01148                 /* tail is empty.  we're finished */
01149                 state->ptr = ctx->ptr;
01150                 RETURN_SUCCESS;
01151 
01152             } else {
01153                 /* general case */
01154                 LASTMARK_SAVE();
01155                 while ((Py_ssize_t)ctx->pattern[2] == 65535
01156                        || ctx->count <= (Py_ssize_t)ctx->pattern[2]) {
01157                     state->ptr = ctx->ptr;
01158                     DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
01159                             ctx->pattern+ctx->pattern[0]);
01160                     if (ret) {
01161                         RETURN_ON_ERROR(ret);
01162                         RETURN_SUCCESS;
01163                     }
01164                     state->ptr = ctx->ptr;
01165                     ret = SRE_COUNT(state, ctx->pattern+3, 1);
01166                     RETURN_ON_ERROR(ret);
01167                     DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
01168                     if (ret == 0)
01169                         break;
01170                     assert(ret == 1);
01171                     ctx->ptr++;
01172                     ctx->count++;
01173                     LASTMARK_RESTORE();
01174                 }
01175             }
01176             RETURN_FAILURE;
01177 
01178         case SRE_OP_REPEAT:
01179             /* create repeat context.  all the hard work is done
01180                by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
01181             /* <REPEAT> <skip> <1=min> <2=max> item <UNTIL> tail */
01182             TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr,
01183                    ctx->pattern[1], ctx->pattern[2]));
01184 
01185             /* install new repeat context */
01186             ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
01187             if (!ctx->u.rep) {
01188                 PyErr_NoMemory();
01189                 RETURN_FAILURE;
01190             }
01191             ctx->u.rep->count = -1;
01192             ctx->u.rep->pattern = ctx->pattern;
01193             ctx->u.rep->prev = state->repeat;
01194             ctx->u.rep->last_ptr = NULL;
01195             state->repeat = ctx->u.rep;
01196 
01197             state->ptr = ctx->ptr;
01198             DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
01199             state->repeat = ctx->u.rep->prev;
01200             PyObject_FREE(ctx->u.rep);
01201 
01202             if (ret) {
01203                 RETURN_ON_ERROR(ret);
01204                 RETURN_SUCCESS;
01205             }
01206             RETURN_FAILURE;
01207 
01208         case SRE_OP_MAX_UNTIL:
01209             /* maximizing repeat */
01210             /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
01211 
01212             /* FIXME: we probably need to deal with zero-width
01213                matches in here... */
01214 
01215             ctx->u.rep = state->repeat;
01216             if (!ctx->u.rep)
01217                 RETURN_ERROR(SRE_ERROR_STATE);
01218 
01219             state->ptr = ctx->ptr;
01220 
01221             ctx->count = ctx->u.rep->count+1;
01222 
01223             TRACE(("|%p|%p|MAX_UNTIL %d\n", ctx->pattern,
01224                    ctx->ptr, ctx->count));
01225 
01226             if (ctx->count < ctx->u.rep->pattern[1]) {
01227                 /* not enough matches */
01228                 ctx->u.rep->count = ctx->count;
01229                 DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
01230                         ctx->u.rep->pattern+3);
01231                 if (ret) {
01232                     RETURN_ON_ERROR(ret);
01233                     RETURN_SUCCESS;
01234                 }
01235                 ctx->u.rep->count = ctx->count-1;
01236                 state->ptr = ctx->ptr;
01237                 RETURN_FAILURE;
01238             }
01239 
01240             if ((ctx->count < ctx->u.rep->pattern[2] ||
01241                 ctx->u.rep->pattern[2] == 65535) &&
01242                 state->ptr != ctx->u.rep->last_ptr) {
01243                 /* we may have enough matches, but if we can
01244                    match another item, do so */
01245                 ctx->u.rep->count = ctx->count;
01246                 LASTMARK_SAVE();
01247                 MARK_PUSH(ctx->lastmark);
01248                 /* zero-width match protection */
01249                 DATA_PUSH(&ctx->u.rep->last_ptr);
01250                 ctx->u.rep->last_ptr = state->ptr;
01251                 DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
01252                         ctx->u.rep->pattern+3);
01253                 DATA_POP(&ctx->u.rep->last_ptr);
01254                 if (ret) {
01255                     MARK_POP_DISCARD(ctx->lastmark);
01256                     RETURN_ON_ERROR(ret);
01257                     RETURN_SUCCESS;
01258                 }
01259                 MARK_POP(ctx->lastmark);
01260                 LASTMARK_RESTORE();
01261                 ctx->u.rep->count = ctx->count-1;
01262                 state->ptr = ctx->ptr;
01263             }
01264 
01265             /* cannot match more repeated items here.  make sure the
01266                tail matches */
01267             state->repeat = ctx->u.rep->prev;
01268             DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern);
01269             RETURN_ON_SUCCESS(ret);
01270             state->repeat = ctx->u.rep;
01271             state->ptr = ctx->ptr;
01272             RETURN_FAILURE;
01273 
01274         case SRE_OP_MIN_UNTIL:
01275             /* minimizing repeat */
01276             /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
01277 
01278             ctx->u.rep = state->repeat;
01279             if (!ctx->u.rep)
01280                 RETURN_ERROR(SRE_ERROR_STATE);
01281 
01282             state->ptr = ctx->ptr;
01283 
01284             ctx->count = ctx->u.rep->count+1;
01285 
01286             TRACE(("|%p|%p|MIN_UNTIL %d %p\n", ctx->pattern,
01287                    ctx->ptr, ctx->count, ctx->u.rep->pattern));
01288 
01289             if (ctx->count < ctx->u.rep->pattern[1]) {
01290                 /* not enough matches */
01291                 ctx->u.rep->count = ctx->count;
01292                 DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
01293                         ctx->u.rep->pattern+3);
01294                 if (ret) {
01295                     RETURN_ON_ERROR(ret);
01296                     RETURN_SUCCESS;
01297                 }
01298                 ctx->u.rep->count = ctx->count-1;
01299                 state->ptr = ctx->ptr;
01300                 RETURN_FAILURE;
01301             }
01302 
01303             LASTMARK_SAVE();
01304 
01305             /* see if the tail matches */
01306             state->repeat = ctx->u.rep->prev;
01307             DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern);
01308             if (ret) {
01309                 RETURN_ON_ERROR(ret);
01310                 RETURN_SUCCESS;
01311             }
01312 
01313             state->repeat = ctx->u.rep;
01314             state->ptr = ctx->ptr;
01315 
01316             LASTMARK_RESTORE();
01317 
01318             if (ctx->count >= ctx->u.rep->pattern[2]
01319                 && ctx->u.rep->pattern[2] != 65535)
01320                 RETURN_FAILURE;
01321 
01322             ctx->u.rep->count = ctx->count;
01323             DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
01324                     ctx->u.rep->pattern+3);
01325             if (ret) {
01326                 RETURN_ON_ERROR(ret);
01327                 RETURN_SUCCESS;
01328             }
01329             ctx->u.rep->count = ctx->count-1;
01330             state->ptr = ctx->ptr;
01331             RETURN_FAILURE;
01332 
01333         case SRE_OP_GROUPREF:
01334             /* match backreference */
01335             TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern,
01336                    ctx->ptr, ctx->pattern[0]));
01337             i = ctx->pattern[0];
01338             {
01339                 Py_ssize_t groupref = i+i;
01340                 if (groupref >= state->lastmark) {
01341                     RETURN_FAILURE;
01342                 } else {
01343                     SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
01344                     SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
01345                     if (!p || !e || e < p)
01346                         RETURN_FAILURE;
01347                     while (p < e) {
01348                         if (ctx->ptr >= end || *ctx->ptr != *p)
01349                             RETURN_FAILURE;
01350                         p++; ctx->ptr++;
01351                     }
01352                 }
01353             }
01354             ctx->pattern++;
01355             break;
01356 
01357         case SRE_OP_GROUPREF_IGNORE:
01358             /* match backreference */
01359             TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern,
01360                    ctx->ptr, ctx->pattern[0]));
01361             i = ctx->pattern[0];
01362             {
01363                 Py_ssize_t groupref = i+i;
01364                 if (groupref >= state->lastmark) {
01365                     RETURN_FAILURE;
01366                 } else {
01367                     SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
01368                     SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
01369                     if (!p || !e || e < p)
01370                         RETURN_FAILURE;
01371                     while (p < e) {
01372                         if (ctx->ptr >= end ||
01373                             state->lower(*ctx->ptr) != state->lower(*p))
01374                             RETURN_FAILURE;
01375                         p++; ctx->ptr++;
01376                     }
01377                 }
01378             }
01379             ctx->pattern++;
01380             break;
01381 
01382         case SRE_OP_GROUPREF_EXISTS:
01383             TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern,
01384                    ctx->ptr, ctx->pattern[0]));
01385             /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
01386             i = ctx->pattern[0];
01387             {
01388                 Py_ssize_t groupref = i+i;
01389                 if (groupref >= state->lastmark) {
01390                     ctx->pattern += ctx->pattern[1];
01391                     break;
01392                 } else {
01393                     SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
01394                     SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
01395                     if (!p || !e || e < p) {
01396                         ctx->pattern += ctx->pattern[1];
01397                         break;
01398                     }
01399                 }
01400             }
01401             ctx->pattern += 2;
01402             break;
01403 
01404         case SRE_OP_ASSERT:
01405             /* assert subpattern */
01406             /* <ASSERT> <skip> <back> <pattern> */
01407             TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern,
01408                    ctx->ptr, ctx->pattern[1]));
01409             state->ptr = ctx->ptr - ctx->pattern[1];
01410             if (state->ptr < state->beginning)
01411                 RETURN_FAILURE;
01412             DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2);
01413             RETURN_ON_FAILURE(ret);
01414             ctx->pattern += ctx->pattern[0];
01415             break;
01416 
01417         case SRE_OP_ASSERT_NOT:
01418             /* assert not subpattern */
01419             /* <ASSERT_NOT> <skip> <back> <pattern> */
01420             TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern,
01421                    ctx->ptr, ctx->pattern[1]));
01422             state->ptr = ctx->ptr - ctx->pattern[1];
01423             if (state->ptr >= state->beginning) {
01424                 DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
01425                 if (ret) {
01426                     RETURN_ON_ERROR(ret);
01427                     RETURN_FAILURE;
01428                 }
01429             }
01430             ctx->pattern += ctx->pattern[0];
01431             break;
01432 
01433         case SRE_OP_FAILURE:
01434             /* immediate failure */
01435             TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr));
01436             RETURN_FAILURE;
01437 
01438         default:
01439             TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr,
01440                    ctx->pattern[-1]));
01441             RETURN_ERROR(SRE_ERROR_ILLEGAL);
01442         }
01443     }
01444 
01445 exit:
01446     ctx_pos = ctx->last_ctx_pos;
01447     jump = ctx->jump;
01448     DATA_POP_DISCARD(ctx);
01449     if (ctx_pos == -1)
01450         return ret;
01451     DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
01452 
01453     switch (jump) {
01454         case JUMP_MAX_UNTIL_2:
01455             TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr));
01456             goto jump_max_until_2;
01457         case JUMP_MAX_UNTIL_3:
01458             TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr));
01459             goto jump_max_until_3;
01460         case JUMP_MIN_UNTIL_2:
01461             TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr));
01462             goto jump_min_until_2;
01463         case JUMP_MIN_UNTIL_3:
01464             TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr));
01465             goto jump_min_until_3;
01466         case JUMP_BRANCH:
01467             TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr));
01468             goto jump_branch;
01469         case JUMP_MAX_UNTIL_1:
01470             TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr));
01471             goto jump_max_until_1;
01472         case JUMP_MIN_UNTIL_1:
01473             TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr));
01474             goto jump_min_until_1;
01475         case JUMP_REPEAT:
01476             TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr));
01477             goto jump_repeat;
01478         case JUMP_REPEAT_ONE_1:
01479             TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr));
01480             goto jump_repeat_one_1;
01481         case JUMP_REPEAT_ONE_2:
01482             TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr));
01483             goto jump_repeat_one_2;
01484         case JUMP_MIN_REPEAT_ONE:
01485             TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr));
01486             goto jump_min_repeat_one;
01487         case JUMP_ASSERT:
01488             TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr));
01489             goto jump_assert;
01490         case JUMP_ASSERT_NOT:
01491             TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr));
01492             goto jump_assert_not;
01493         case JUMP_NONE:
01494             TRACE(("|%p|%p|RETURN %d\n", ctx->pattern, ctx->ptr, ret));
01495             break;
01496     }
01497 
01498     return ret; /* should never get here */
01499 }
01500 
01501 LOCAL(Py_ssize_t)
01502 SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
01503 {
01504     SRE_CHAR* ptr = (SRE_CHAR *)state->start;
01505     SRE_CHAR* end = (SRE_CHAR *)state->end;
01506     Py_ssize_t status = 0;
01507     Py_ssize_t prefix_len = 0;
01508     Py_ssize_t prefix_skip = 0;
01509     SRE_CODE* prefix = NULL;
01510     SRE_CODE* charset = NULL;
01511     SRE_CODE* overlap = NULL;
01512     int flags = 0;
01513 
01514     if (pattern[0] == SRE_OP_INFO) {
01515         /* optimization info block */
01516         /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info>  */
01517 
01518         flags = pattern[2];
01519 
01520         if (pattern[3] > 1) {
01521             /* adjust end point (but make sure we leave at least one
01522                character in there, so literal search will work) */
01523             end -= pattern[3]-1;
01524             if (end <= ptr)
01525                 end = ptr+1;
01526         }
01527 
01528         if (flags & SRE_INFO_PREFIX) {
01529             /* pattern starts with a known prefix */
01530             /* <length> <skip> <prefix data> <overlap data> */
01531             prefix_len = pattern[5];
01532             prefix_skip = pattern[6];
01533             prefix = pattern + 7;
01534             overlap = prefix + prefix_len - 1;
01535         } else if (flags & SRE_INFO_CHARSET)
01536             /* pattern starts with a character from a known set */
01537             /* <charset> */
01538             charset = pattern + 5;
01539 
01540         pattern += 1 + pattern[1];
01541     }
01542 
01543     TRACE(("prefix = %p %d %d\n", prefix, prefix_len, prefix_skip));
01544     TRACE(("charset = %p\n", charset));
01545 
01546 #if defined(USE_FAST_SEARCH)
01547     if (prefix_len > 1) {
01548         /* pattern starts with a known prefix.  use the overlap
01549            table to skip forward as fast as we possibly can */
01550         Py_ssize_t i = 0;
01551         end = (SRE_CHAR *)state->end;
01552         while (ptr < end) {
01553             for (;;) {
01554                 if ((SRE_CODE) ptr[0] != prefix[i]) {
01555                     if (!i)
01556                         break;
01557                     else
01558                         i = overlap[i];
01559                 } else {
01560                     if (++i == prefix_len) {
01561                         /* found a potential match */
01562                         TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));
01563                         state->start = ptr + 1 - prefix_len;
01564                         state->ptr = ptr + 1 - prefix_len + prefix_skip;
01565                         if (flags & SRE_INFO_LITERAL)
01566                             return 1; /* we got all of it */
01567                         status = SRE_MATCH(state, pattern + 2*prefix_skip);
01568                         if (status != 0)
01569                             return status;
01570                         /* close but no cigar -- try again */
01571                         i = overlap[i];
01572                     }
01573                     break;
01574                 }
01575             }
01576             ptr++;
01577         }
01578         return 0;
01579     }
01580 #endif
01581 
01582     if (pattern[0] == SRE_OP_LITERAL) {
01583         /* pattern starts with a literal character.  this is used
01584            for short prefixes, and if fast search is disabled */
01585         SRE_CODE chr = pattern[1];
01586         end = (SRE_CHAR *)state->end;
01587         for (;;) {
01588             while (ptr < end && (SRE_CODE) ptr[0] != chr)
01589                 ptr++;
01590             if (ptr >= end)
01591                 return 0;
01592             TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
01593             state->start = ptr;
01594             state->ptr = ++ptr;
01595             if (flags & SRE_INFO_LITERAL)
01596                 return 1; /* we got all of it */
01597             status = SRE_MATCH(state, pattern + 2);
01598             if (status != 0)
01599                 break;
01600         }
01601     } else if (charset) {
01602         /* pattern starts with a character from a known set */
01603         end = (SRE_CHAR *)state->end;
01604         for (;;) {
01605             while (ptr < end && !SRE_CHARSET(charset, ptr[0]))
01606                 ptr++;
01607             if (ptr >= end)
01608                 return 0;
01609             TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
01610             state->start = ptr;
01611             state->ptr = ptr;
01612             status = SRE_MATCH(state, pattern);
01613             if (status != 0)
01614                 break;
01615             ptr++;
01616         }
01617     } else
01618         /* general case */
01619         while (ptr <= end) {
01620             TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
01621             state->start = state->ptr = ptr++;
01622             status = SRE_MATCH(state, pattern);
01623             if (status != 0)
01624                 break;
01625         }
01626 
01627     return status;
01628 }
01629 
01630 LOCAL(int)
01631 SRE_LITERAL_TEMPLATE(SRE_CHAR* ptr, Py_ssize_t len)
01632 {
01633     /* check if given string is a literal template (i.e. no escapes) */
01634     while (len-- > 0)
01635         if (*ptr++ == '\\')
01636             return 0;
01637     return 1;
01638 }
01639 
01640 #if !defined(SRE_RECURSIVE)
01641 
01642 /* -------------------------------------------------------------------- */
01643 /* factories and destructors */
01644 
01645 /* see sre.h for object declarations */
01646 static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, int);
01647 static PyObject*pattern_scanner(PatternObject*, PyObject*);
01648 
01649 static PyObject *
01650 sre_codesize(PyObject* self, PyObject *unused)
01651 {
01652     return Py_BuildValue("l", sizeof(SRE_CODE));
01653 }
01654 
01655 static PyObject *
01656 sre_getlower(PyObject* self, PyObject* args)
01657 {
01658     int character, flags;
01659     if (!PyArg_ParseTuple(args, "ii", &character, &flags))
01660         return NULL;
01661     if (flags & SRE_FLAG_LOCALE)
01662         return Py_BuildValue("i", sre_lower_locale(character));
01663     if (flags & SRE_FLAG_UNICODE)
01664 #if defined(HAVE_UNICODE)
01665         return Py_BuildValue("i", sre_lower_unicode(character));
01666 #else
01667         return Py_BuildValue("i", sre_lower_locale(character));
01668 #endif
01669     return Py_BuildValue("i", sre_lower(character));
01670 }
01671 
01672 LOCAL(void)
01673 state_reset(SRE_STATE* state)
01674 {
01675     /* FIXME: dynamic! */
01676     /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/
01677 
01678     state->lastmark = -1;
01679     state->lastindex = -1;
01680 
01681     state->repeat = NULL;
01682 
01683     data_stack_dealloc(state);
01684 }
01685 
01686 static void*
01687 getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
01688 {
01689     /* given a python object, return a data pointer, a length (in
01690        characters), and a character size.  return NULL if the object
01691        is not a string (or not compatible) */
01692 
01693     PyBufferProcs *buffer;
01694     Py_ssize_t size, bytes;
01695     int charsize;
01696     void* ptr;
01697 
01698 #if defined(HAVE_UNICODE)
01699     if (PyUnicode_Check(string)) {
01700         /* unicode strings doesn't always support the buffer interface */
01701         ptr = (void*) PyUnicode_AS_DATA(string);
01702         /* bytes = PyUnicode_GET_DATA_SIZE(string); */
01703         size = PyUnicode_GET_SIZE(string);
01704         charsize = sizeof(Py_UNICODE);
01705 
01706     } else {
01707 #endif
01708 
01709     /* get pointer to string buffer */
01710     buffer = Py_TYPE(string)->tp_as_buffer;
01711     if (!buffer || !buffer->bf_getreadbuffer || !buffer->bf_getsegcount ||
01712         buffer->bf_getsegcount(string, NULL) != 1) {
01713         PyErr_SetString(PyExc_TypeError, "expected string or buffer");
01714         return NULL;
01715     }
01716 
01717     /* determine buffer size */
01718     bytes = buffer->bf_getreadbuffer(string, 0, &ptr);
01719     if (bytes < 0) {
01720         PyErr_SetString(PyExc_TypeError, "buffer has negative size");
01721         return NULL;
01722     }
01723 
01724     /* determine character size */
01725 #if PY_VERSION_HEX >= 0x01060000
01726     size = PyObject_Size(string);
01727 #else
01728     size = PyObject_Length(string);
01729 #endif
01730 
01731     if (PyString_Check(string) || bytes == size)
01732         charsize = 1;
01733 #if defined(HAVE_UNICODE)
01734     else if (bytes == (Py_ssize_t) (size * sizeof(Py_UNICODE)))
01735         charsize = sizeof(Py_UNICODE);
01736 #endif
01737     else {
01738         PyErr_SetString(PyExc_TypeError, "buffer size mismatch");
01739         return NULL;
01740     }
01741 
01742 #if defined(HAVE_UNICODE)
01743     }
01744 #endif
01745 
01746     *p_length = size;
01747     *p_charsize = charsize;
01748 
01749     return ptr;
01750 }
01751 
01752 LOCAL(PyObject*)
01753 state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
01754            Py_ssize_t start, Py_ssize_t end)
01755 {
01756     /* prepare state object */
01757 
01758     Py_ssize_t length;
01759     int charsize;
01760     void* ptr;
01761 
01762     memset(state, 0, sizeof(SRE_STATE));
01763 
01764     state->lastmark = -1;
01765     state->lastindex = -1;
01766 
01767     ptr = getstring(string, &length, &charsize);
01768     if (!ptr)
01769         return NULL;
01770 
01771     /* adjust boundaries */
01772     if (start < 0)
01773         start = 0;
01774     else if (start > length)
01775         start = length;
01776 
01777     if (end < 0)
01778         end = 0;
01779     else if (end > length)
01780         end = length;
01781 
01782     state->charsize = charsize;
01783 
01784     state->beginning = ptr;
01785 
01786     state->start = (void*) ((char*) ptr + start * state->charsize);
01787     state->end = (void*) ((char*) ptr + end * state->charsize);
01788 
01789     Py_INCREF(string);
01790     state->string = string;
01791     state->pos = start;
01792     state->endpos = end;
01793 
01794     if (pattern->flags & SRE_FLAG_LOCALE)
01795         state->lower = sre_lower_locale;
01796     else if (pattern->flags & SRE_FLAG_UNICODE)
01797 #if defined(HAVE_UNICODE)
01798         state->lower = sre_lower_unicode;
01799 #else
01800         state->lower = sre_lower_locale;
01801 #endif
01802     else
01803         state->lower = sre_lower;
01804 
01805     return string;
01806 }
01807 
01808 LOCAL(void)
01809 state_fini(SRE_STATE* state)
01810 {
01811     Py_XDECREF(state->string);
01812     data_stack_dealloc(state);
01813 }
01814 
01815 /* calculate offset from start of string */
01816 #define STATE_OFFSET(state, member)\
01817     (((char*)(member) - (char*)(state)->beginning) / (state)->charsize)
01818 
01819 LOCAL(PyObject*)
01820 state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty)
01821 {
01822     Py_ssize_t i, j;
01823 
01824     index = (index - 1) * 2;
01825 
01826     if (string == Py_None || index >= state->lastmark || !state->mark[index] || !state->mark[index+1]) {
01827         if (empty)
01828             /* want empty string */
01829             i = j = 0;
01830         else {
01831             Py_INCREF(Py_None);
01832             return Py_None;
01833         }
01834     } else {
01835         i = STATE_OFFSET(state, state->mark[index]);
01836         j = STATE_OFFSET(state, state->mark[index+1]);
01837     }
01838 
01839     return PySequence_GetSlice(string, i, j);
01840 }
01841 
01842 static void
01843 pattern_error(int status)
01844 {
01845     switch (status) {
01846     case SRE_ERROR_RECURSION_LIMIT:
01847         PyErr_SetString(
01848             PyExc_RuntimeError,
01849             "maximum recursion limit exceeded"
01850             );
01851         break;
01852     case SRE_ERROR_MEMORY:
01853         PyErr_NoMemory();
01854         break;
01855     case SRE_ERROR_INTERRUPTED:
01856     /* An exception has already been raised, so let it fly */
01857         break;
01858     default:
01859         /* other error codes indicate compiler/engine bugs */
01860         PyErr_SetString(
01861             PyExc_RuntimeError,
01862             "internal error in regular expression engine"
01863             );
01864     }
01865 }
01866 
01867 static void
01868 pattern_dealloc(PatternObject* self)
01869 {
01870     if (self->weakreflist != NULL)
01871         PyObject_ClearWeakRefs((PyObject *) self);
01872     Py_XDECREF(self->pattern);
01873     Py_XDECREF(self->groupindex);
01874     Py_XDECREF(self->indexgroup);
01875     PyObject_DEL(self);
01876 }
01877 
01878 static PyObject*
01879 pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
01880 {
01881     SRE_STATE state;
01882     int status;
01883 
01884     PyObject* string;
01885     Py_ssize_t start = 0;
01886     Py_ssize_t end = PY_SSIZE_T_MAX;
01887     static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
01888     if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist,
01889                                      &string, &start, &end))
01890         return NULL;
01891 
01892     string = state_init(&state, self, string, start, end);
01893     if (!string)
01894         return NULL;
01895 
01896     state.ptr = state.start;
01897 
01898     TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
01899 
01900     if (state.charsize == 1) {
01901         status = sre_match(&state, PatternObject_GetCode(self));
01902     } else {
01903 #if defined(HAVE_UNICODE)
01904         status = sre_umatch(&state, PatternObject_GetCode(self));
01905 #endif
01906     }
01907 
01908     TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
01909     if (PyErr_Occurred())
01910         return NULL;
01911 
01912     state_fini(&state);
01913 
01914     return pattern_new_match(self, &state, status);
01915 }
01916 
01917 static PyObject*
01918 pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
01919 {
01920     SRE_STATE state;
01921     int status;
01922 
01923     PyObject* string;
01924     Py_ssize_t start = 0;
01925     Py_ssize_t end = PY_SSIZE_T_MAX;
01926     static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
01927     if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist,
01928                                      &string, &start, &end))
01929         return NULL;
01930 
01931     string = state_init(&state, self, string, start, end);
01932     if (!string)
01933         return NULL;
01934 
01935     TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr));
01936 
01937     if (state.charsize == 1) {
01938         status = sre_search(&state, PatternObject_GetCode(self));
01939     } else {
01940 #if defined(HAVE_UNICODE)
01941         status = sre_usearch(&state, PatternObject_GetCode(self));
01942 #endif
01943     }
01944 
01945     TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
01946 
01947     state_fini(&state);
01948 
01949     if (PyErr_Occurred())
01950         return NULL;
01951 
01952     return pattern_new_match(self, &state, status);
01953 }
01954 
01955 static PyObject*
01956 call(char* module, char* function, PyObject* args)
01957 {
01958     PyObject* name;
01959     PyObject* mod;
01960     PyObject* func;
01961     PyObject* result;
01962 
01963     if (!args)
01964         return NULL;
01965     name = PyString_FromString(module);
01966     if (!name)
01967         return NULL;
01968     mod = PyImport_Import(name);
01969     Py_DECREF(name);
01970     if (!mod)
01971         return NULL;
01972     func = PyObject_GetAttrString(mod, function);
01973     Py_DECREF(mod);
01974     if (!func)
01975         return NULL;
01976     result = PyObject_CallObject(func, args);
01977     Py_DECREF(func);
01978     Py_DECREF(args);
01979     return result;
01980 }
01981 
01982 #ifdef USE_BUILTIN_COPY
01983 static int
01984 deepcopy(PyObject** object, PyObject* memo)
01985 {
01986     PyObject* copy;
01987 
01988     copy = call(
01989         "copy", "deepcopy",
01990         PyTuple_Pack(2, *object, memo)
01991         );
01992     if (!copy)
01993         return 0;
01994 
01995     Py_DECREF(*object);
01996     *object = copy;
01997 
01998     return 1; /* success */
01999 }
02000 #endif
02001 
02002 static PyObject*
02003 join_list(PyObject* list, PyObject* string)
02004 {
02005     /* join list elements */
02006 
02007     PyObject* joiner;
02008 #if PY_VERSION_HEX >= 0x01060000
02009     PyObject* function;
02010     PyObject* args;
02011 #endif
02012     PyObject* result;
02013 
02014     joiner = PySequence_GetSlice(string, 0, 0);
02015     if (!joiner)
02016         return NULL;
02017 
02018     if (PyList_GET_SIZE(list) == 0) {
02019         Py_DECREF(list);
02020         return joiner;
02021     }
02022 
02023 #if PY_VERSION_HEX >= 0x01060000
02024     function = PyObject_GetAttrString(joiner, "join");
02025     if (!function) {
02026         Py_DECREF(joiner);
02027         return NULL;
02028     }
02029     args = PyTuple_New(1);
02030     if (!args) {
02031         Py_DECREF(function);
02032         Py_DECREF(joiner);
02033         return NULL;
02034     }
02035     PyTuple_SET_ITEM(args, 0, list);
02036     result = PyObject_CallObject(function, args);
02037     Py_DECREF(args); /* also removes list */
02038     Py_DECREF(function);
02039 #else
02040     result = call(
02041         "string", "join",
02042         PyTuple_Pack(2, list, joiner)
02043         );
02044 #endif
02045     Py_DECREF(joiner);
02046 
02047     return result;
02048 }
02049 
02050 static PyObject*
02051 pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
02052 {
02053     SRE_STATE state;
02054     PyObject* list;
02055     int status;
02056     Py_ssize_t i, b, e;
02057 
02058     PyObject* string;
02059     Py_ssize_t start = 0;
02060     Py_ssize_t end = PY_SSIZE_T_MAX;
02061     static char* kwlist[] = { "source", "pos", "endpos", NULL };
02062     if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist,
02063                                      &string, &start, &end))
02064         return NULL;
02065 
02066     string = state_init(&state, self, string, start, end);
02067     if (!string)
02068         return NULL;
02069 
02070     list = PyList_New(0);
02071     if (!list) {
02072         state_fini(&state);
02073         return NULL;
02074     }
02075 
02076     while (state.start <= state.end) {
02077 
02078         PyObject* item;
02079 
02080         state_reset(&state);
02081 
02082         state.ptr = state.start;
02083 
02084         if (state.charsize == 1) {
02085             status = sre_search(&state, PatternObject_GetCode(self));
02086         } else {
02087 #if defined(HAVE_UNICODE)
02088             status = sre_usearch(&state, PatternObject_GetCode(self));
02089 #endif
02090         }
02091 
02092         if (PyErr_Occurred())
02093             goto error;
02094 
02095         if (status <= 0) {
02096             if (status == 0)
02097                 break;
02098             pattern_error(status);
02099             goto error;
02100         }
02101 
02102         /* don't bother to build a match object */
02103         switch (self->groups) {
02104         case 0:
02105             b = STATE_OFFSET(&state, state.start);
02106             e = STATE_OFFSET(&state, state.ptr);
02107             item = PySequence_GetSlice(string, b, e);
02108             if (!item)
02109                 goto error;
02110             break;
02111         case 1:
02112             item = state_getslice(&state, 1, string, 1);
02113             if (!item)
02114                 goto error;
02115             break;
02116         default:
02117             item = PyTuple_New(self->groups);
02118             if (!item)
02119                 goto error;
02120             for (i = 0; i < self->groups; i++) {
02121                 PyObject* o = state_getslice(&state, i+1, string, 1);
02122                 if (!o) {
02123                     Py_DECREF(item);
02124                     goto error;
02125                 }
02126                 PyTuple_SET_ITEM(item, i, o);
02127             }
02128             break;
02129         }
02130 
02131         status = PyList_Append(list, item);
02132         Py_DECREF(item);
02133         if (status < 0)
02134             goto error;
02135 
02136         if (state.ptr == state.start)
02137             state.start = (void*) ((char*) state.ptr + state.charsize);
02138         else
02139             state.start = state.ptr;
02140 
02141     }
02142 
02143     state_fini(&state);
02144     return list;
02145 
02146 error:
02147     Py_DECREF(list);
02148     state_fini(&state);
02149     return NULL;
02150 
02151 }
02152 
02153 #if PY_VERSION_HEX >= 0x02020000
02154 static PyObject*
02155 pattern_finditer(PatternObject* pattern, PyObject* args)
02156 {
02157     PyObject* scanner;
02158     PyObject* search;
02159     PyObject* iterator;
02160 
02161     scanner = pattern_scanner(pattern, args);
02162     if (!scanner)
02163         return NULL;
02164 
02165     search = PyObject_GetAttrString(scanner, "search");
02166     Py_DECREF(scanner);
02167     if (!search)
02168         return NULL;
02169 
02170     iterator = PyCallIter_New(search, Py_None);
02171     Py_DECREF(search);
02172 
02173     return iterator;
02174 }
02175 #endif
02176 
02177 static PyObject*
02178 pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
02179 {
02180     SRE_STATE state;
02181     PyObject* list;
02182     PyObject* item;
02183     int status;
02184     Py_ssize_t n;
02185     Py_ssize_t i;
02186     void* last;
02187 
02188     PyObject* string;
02189     Py_ssize_t maxsplit = 0;
02190     static char* kwlist[] = { "source", "maxsplit", NULL };
02191     if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist,
02192                                      &string, &maxsplit))
02193         return NULL;
02194 
02195     string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
02196     if (!string)
02197         return NULL;
02198 
02199     list = PyList_New(0);
02200     if (!list) {
02201         state_fini(&state);
02202         return NULL;
02203     }
02204 
02205     n = 0;
02206     last = state.start;
02207 
02208     while (!maxsplit || n < maxsplit) {
02209 
02210         state_reset(&state);
02211 
02212         state.ptr = state.start;
02213 
02214         if (state.charsize == 1) {
02215             status = sre_search(&state, PatternObject_GetCode(self));
02216         } else {
02217 #if defined(HAVE_UNICODE)
02218             status = sre_usearch(&state, PatternObject_GetCode(self));
02219 #endif
02220         }
02221 
02222         if (PyErr_Occurred())
02223             goto error;
02224 
02225         if (status <= 0) {
02226             if (status == 0)
02227                 break;
02228             pattern_error(status);
02229             goto error;
02230         }
02231 
02232         if (state.start == state.ptr) {
02233             if (last == state.end)
02234                 break;
02235             /* skip one character */
02236             state.start = (void*) ((char*) state.ptr + state.charsize);
02237             continue;
02238         }
02239 
02240         /* get segment before this match */
02241         item = PySequence_GetSlice(
02242             string, STATE_OFFSET(&state, last),
02243             STATE_OFFSET(&state, state.start)
02244             );
02245         if (!item)
02246             goto error;
02247         status = PyList_Append(list, item);
02248         Py_DECREF(item);
02249         if (status < 0)
02250             goto error;
02251 
02252         /* add groups (if any) */
02253         for (i = 0; i < self->groups; i++) {
02254             item = state_getslice(&state, i+1, string, 0);
02255             if (!item)
02256                 goto error;
02257             status = PyList_Append(list, item);
02258             Py_DECREF(item);
02259             if (status < 0)
02260                 goto error;
02261         }
02262 
02263         n = n + 1;
02264 
02265         last = state.start = state.ptr;
02266 
02267     }
02268 
02269     /* get segment following last match (even if empty) */
02270     item = PySequence_GetSlice(
02271         string, STATE_OFFSET(&state, last), state.endpos
02272         );
02273     if (!item)
02274         goto error;
02275     status = PyList_Append(list, item);
02276     Py_DECREF(item);
02277     if (status < 0)
02278         goto error;
02279 
02280     state_fini(&state);
02281     return list;
02282 
02283 error:
02284     Py_DECREF(list);
02285     state_fini(&state);
02286     return NULL;
02287 
02288 }
02289 
02290 static PyObject*
02291 pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
02292              Py_ssize_t count, Py_ssize_t subn)
02293 {
02294     SRE_STATE state;
02295     PyObject* list;
02296     PyObject* item;
02297     PyObject* filter;
02298     PyObject* args;
02299     PyObject* match;
02300     void* ptr;
02301     int status;
02302     Py_ssize_t n;
02303     Py_ssize_t i, b, e;
02304     int bint;
02305     int filter_is_callable;
02306 
02307     if (PyCallable_Check(ptemplate)) {
02308         /* sub/subn takes either a function or a template */
02309         filter = ptemplate;
02310         Py_INCREF(filter);
02311         filter_is_callable = 1;
02312     } else {
02313         /* if not callable, check if it's a literal string */
02314         int literal;
02315         ptr = getstring(ptemplate, &n, &bint);
02316         b = bint;
02317         if (ptr) {
02318             if (b == 1) {
02319                 literal = sre_literal_template((unsigned char *)ptr, n);
02320             } else {
02321 #if defined(HAVE_UNICODE)
02322                 literal = sre_uliteral_template((Py_UNICODE *)ptr, n);
02323 #endif
02324             }
02325         } else {
02326             PyErr_Clear();
02327             literal = 0;
02328         }
02329         if (literal) {
02330             filter = ptemplate;
02331             Py_INCREF(filter);
02332             filter_is_callable = 0;
02333         } else {
02334             /* not a literal; hand it over to the template compiler */
02335             filter = call(
02336                 SRE_PY_MODULE, "_subx",
02337                 PyTuple_Pack(2, self, ptemplate)
02338                 );
02339             if (!filter)
02340                 return NULL;
02341             filter_is_callable = PyCallable_Check(filter);
02342         }
02343     }
02344 
02345     string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
02346     if (!string) {
02347         Py_DECREF(filter);
02348         return NULL;
02349     }
02350 
02351     list = PyList_New(0);
02352     if (!list) {
02353         Py_DECREF(filter);
02354         state_fini(&state);
02355         return NULL;
02356     }
02357 
02358     n = i = 0;
02359 
02360     while (!count || n < count) {
02361 
02362         state_reset(&state);
02363 
02364         state.ptr = state.start;
02365 
02366         if (state.charsize == 1) {
02367             status = sre_search(&state, PatternObject_GetCode(self));
02368         } else {
02369 #if defined(HAVE_UNICODE)
02370             status = sre_usearch(&state, PatternObject_GetCode(self));
02371 #endif
02372         }
02373 
02374         if (PyErr_Occurred())
02375             goto error;
02376 
02377         if (status <= 0) {
02378             if (status == 0)
02379                 break;
02380             pattern_error(status);
02381             goto error;
02382         }
02383 
02384         b = STATE_OFFSET(&state, state.start);
02385         e = STATE_OFFSET(&state, state.ptr);
02386 
02387         if (i < b) {
02388             /* get segment before this match */
02389             item = PySequence_GetSlice(string, i, b);
02390             if (!item)
02391                 goto error;
02392             status = PyList_Append(list, item);
02393             Py_DECREF(item);
02394             if (status < 0)
02395                 goto error;
02396 
02397         } else if (i == b && i == e && n > 0)
02398             /* ignore empty match on latest position */
02399             goto next;
02400 
02401         if (filter_is_callable) {
02402             /* pass match object through filter */
02403             match = pattern_new_match(self, &state, 1);
02404             if (!match)
02405                 goto error;
02406             args = PyTuple_Pack(1, match);
02407             if (!args) {
02408                 Py_DECREF(match);
02409                 goto error;
02410             }
02411             item = PyObject_CallObject(filter, args);
02412             Py_DECREF(args);
02413             Py_DECREF(match);
02414             if (!item)
02415                 goto error;
02416         } else {
02417             /* filter is literal string */
02418             item = filter;
02419             Py_INCREF(item);
02420         }
02421 
02422         /* add to list */
02423         if (item != Py_None) {
02424             status = PyList_Append(list, item);
02425             Py_DECREF(item);
02426             if (status < 0)
02427                 goto error;
02428         }
02429 
02430         i = e;
02431         n = n + 1;
02432 
02433 next:
02434         /* move on */
02435         if (state.ptr == state.start)
02436             state.start = (void*) ((char*) state.ptr + state.charsize);
02437         else
02438             state.start = state.ptr;
02439 
02440     }
02441 
02442     /* get segment following last match */
02443     if (i < state.endpos) {
02444         item = PySequence_GetSlice(string, i, state.endpos);
02445         if (!item)
02446             goto error;
02447         status = PyList_Append(list, item);
02448         Py_DECREF(item);
02449         if (status < 0)
02450             goto error;
02451     }
02452 
02453     state_fini(&state);
02454 
02455     Py_DECREF(filter);
02456 
02457     /* convert list to single string (also removes list) */
02458     item = join_list(list, string);
02459 
02460     if (!item)
02461         return NULL;
02462 
02463     if (subn)
02464         return Py_BuildValue("Ni", item, n);
02465 
02466     return item;
02467 
02468 error:
02469     Py_DECREF(list);
02470     state_fini(&state);
02471     Py_DECREF(filter);
02472     return NULL;
02473 
02474 }
02475 
02476 static PyObject*
02477 pattern_sub(PatternObject* self, PyObject* args, PyObject* kw)
02478 {
02479     PyObject* ptemplate;
02480     PyObject* string;
02481     Py_ssize_t count = 0;
02482     static char* kwlist[] = { "repl", "string", "count", NULL };
02483     if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:sub", kwlist,
02484                                      &ptemplate, &string, &count))
02485         return NULL;
02486 
02487     return pattern_subx(self, ptemplate, string, count, 0);
02488 }
02489 
02490 static PyObject*
02491 pattern_subn(PatternObject* self, PyObject* args, PyObject* kw)
02492 {
02493     PyObject* ptemplate;
02494     PyObject* string;
02495     Py_ssize_t count = 0;
02496     static char* kwlist[] = { "repl", "string", "count", NULL };
02497     if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:subn", kwlist,
02498                                      &ptemplate, &string, &count))
02499         return NULL;
02500 
02501     return pattern_subx(self, ptemplate, string, count, 1);
02502 }
02503 
02504 static PyObject*
02505 pattern_copy(PatternObject* self, PyObject *unused)
02506 {
02507 #ifdef USE_BUILTIN_COPY
02508     PatternObject* copy;
02509     int offset;
02510 
02511     copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize);
02512     if (!copy)
02513         return NULL;
02514 
02515     offset = offsetof(PatternObject, groups);
02516 
02517     Py_XINCREF(self->groupindex);
02518     Py_XINCREF(self->indexgroup);
02519     Py_XINCREF(self->pattern);
02520 
02521     memcpy((char*) copy + offset, (char*) self + offset,
02522            sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);
02523     copy->weakreflist = NULL;
02524 
02525     return (PyObject*) copy;
02526 #else
02527     PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object");
02528     return NULL;
02529 #endif
02530 }
02531 
02532 static PyObject*
02533 pattern_deepcopy(PatternObject* self, PyObject* memo)
02534 {
02535 #ifdef USE_BUILTIN_COPY
02536     PatternObject* copy;
02537 
02538     copy = (PatternObject*) pattern_copy(self);
02539     if (!copy)
02540         return NULL;
02541 
02542     if (!deepcopy(&copy->groupindex, memo) ||
02543         !deepcopy(&copy->indexgroup, memo) ||
02544         !deepcopy(&copy->pattern, memo)) {
02545         Py_DECREF(copy);
02546         return NULL;
02547     }
02548 
02549 #else
02550     PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object");
02551     return NULL;
02552 #endif
02553 }
02554 
02555 PyDoc_STRVAR(pattern_match_doc,
02556 "match(string[, pos[, endpos]]) --> match object or None.\n\
02557     Matches zero or more characters at the beginning of the string");
02558 
02559 PyDoc_STRVAR(pattern_search_doc,
02560 "search(string[, pos[, endpos]]) --> match object or None.\n\
02561     Scan through string looking for a match, and return a corresponding\n\
02562     MatchObject instance. Return None if no position in the string matches.");
02563 
02564 PyDoc_STRVAR(pattern_split_doc,
02565 "split(string[, maxsplit = 0])  --> list.\n\
02566     Split string by the occurrences of pattern.");
02567 
02568 PyDoc_STRVAR(pattern_findall_doc,
02569 "findall(string[, pos[, endpos]]) --> list.\n\
02570    Return a list of all non-overlapping matches of pattern in string.");
02571 
02572 PyDoc_STRVAR(pattern_finditer_doc,
02573 "finditer(string[, pos[, endpos]]) --> iterator.\n\
02574     Return an iterator over all non-overlapping matches for the \n\
02575     RE pattern in string. For each match, the iterator returns a\n\
02576     match object.");
02577 
02578 PyDoc_STRVAR(pattern_sub_doc,
02579 "sub(repl, string[, count = 0]) --> newstring\n\
02580     Return the string obtained by replacing the leftmost non-overlapping\n\
02581     occurrences of pattern in string by the replacement repl.");
02582 
02583 PyDoc_STRVAR(pattern_subn_doc,
02584 "subn(repl, string[, count = 0]) --> (newstring, number of subs)\n\
02585     Return the tuple (new_string, number_of_subs_made) found by replacing\n\
02586     the leftmost non-overlapping occurrences of pattern with the\n\
02587     replacement repl.");
02588 
02589 PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects");
02590 
02591 static PyMethodDef pattern_methods[] = {
02592     {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS,
02593         pattern_match_doc},
02594     {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS,
02595         pattern_search_doc},
02596     {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS,
02597         pattern_sub_doc},
02598     {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS,
02599         pattern_subn_doc},
02600     {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS,
02601         pattern_split_doc},
02602     {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS,
02603         pattern_findall_doc},
02604 #if PY_VERSION_HEX >= 0x02020000
02605     {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS,
02606         pattern_finditer_doc},
02607 #endif
02608     {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS},
02609     {"__copy__", (PyCFunction) pattern_copy, METH_NOARGS},
02610     {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_O},
02611     {NULL, NULL}
02612 };
02613 
02614 #define PAT_OFF(x) offsetof(PatternObject, x)
02615 static PyMemberDef pattern_members[] = {
02616     {"pattern",    T_OBJECT,    PAT_OFF(pattern),       READONLY},
02617     {"flags",      T_INT,       PAT_OFF(flags),         READONLY},
02618     {"groups",     T_PYSSIZET,  PAT_OFF(groups),        READONLY},
02619     {"groupindex", T_OBJECT,    PAT_OFF(groupindex),    READONLY},
02620     {NULL}  /* Sentinel */
02621 };
02622 
02623 statichere PyTypeObject Pattern_Type = {
02624     PyObject_HEAD_INIT(NULL)
02625     0, "_" SRE_MODULE ".SRE_Pattern",
02626     sizeof(PatternObject), sizeof(SRE_CODE),
02627     (destructor)pattern_dealloc, /*tp_dealloc*/
02628     0,                                  /* tp_print */
02629     0,                                  /* tp_getattrn */
02630     0,          /* tp_setattr */
02631     0,          /* tp_compare */
02632     0,          /* tp_repr */
02633     0,          /* tp_as_number */
02634     0,          /* tp_as_sequence */
02635     0,          /* tp_as_mapping */
02636     0,          /* tp_hash */
02637     0,          /* tp_call */
02638     0,          /* tp_str */
02639     0,          /* tp_getattro */
02640     0,          /* tp_setattro */
02641     0,          /* tp_as_buffer */
02642     Py_TPFLAGS_DEFAULT,           /* tp_flags */
02643     pattern_doc,      /* tp_doc */
02644     0,          /* tp_traverse */
02645     0,          /* tp_clear */
02646     0,          /* tp_richcompare */
02647     offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */
02648     0,          /* tp_iter */
02649     0,          /* tp_iternext */
02650     pattern_methods,      /* tp_methods */
02651     pattern_members,      /* tp_members */
02652 };
02653 
02654 static int _validate(PatternObject *self); /* Forward */
02655 
02656 static PyObject *
02657 _compile(PyObject* self_, PyObject* args)
02658 {
02659     /* "compile" pattern descriptor to pattern object */
02660 
02661     PatternObject* self;
02662     Py_ssize_t i, n;
02663 
02664     PyObject* pattern;
02665     int flags = 0;
02666     PyObject* code;
02667     Py_ssize_t groups = 0;
02668     PyObject* groupindex = NULL;
02669     PyObject* indexgroup = NULL;
02670     if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags,
02671                           &PyList_Type, &code, &groups,
02672                           &groupindex, &indexgroup))
02673         return NULL;
02674 
02675     n = PyList_GET_SIZE(code);
02676     /* coverity[ampersand_in_size] */
02677     self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
02678     if (!self)
02679         return NULL;
02680     self->weakreflist = NULL;
02681     self->pattern = NULL;
02682     self->groupindex = NULL;
02683     self->indexgroup = NULL;
02684 
02685     self->codesize = n;
02686 
02687     for (i = 0; i < n; i++) {
02688         PyObject *o = PyList_GET_ITEM(code, i);
02689         unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)
02690                                               : PyLong_AsUnsignedLong(o);
02691         self->code[i] = (SRE_CODE) value;
02692         if ((unsigned long) self->code[i] != value) {
02693             PyErr_SetString(PyExc_OverflowError,
02694                             "regular expression code size limit exceeded");
02695             break;
02696         }
02697     }
02698 
02699     if (PyErr_Occurred()) {
02700         Py_DECREF(self);
02701         return NULL;
02702     }
02703 
02704     Py_INCREF(pattern);
02705     self->pattern = pattern;
02706 
02707     self->flags = flags;
02708 
02709     self->groups = groups;
02710 
02711     Py_XINCREF(groupindex);
02712     self->groupindex = groupindex;
02713 
02714     Py_XINCREF(indexgroup);
02715     self->indexgroup = indexgroup;
02716 
02717     self->weakreflist = NULL;
02718 
02719     if (!_validate(self)) {
02720         Py_DECREF(self);
02721         return NULL;
02722     }
02723 
02724     return (PyObject*) self;
02725 }
02726 
02727 /* -------------------------------------------------------------------- */
02728 /* Code validation */
02729 
02730 /* To learn more about this code, have a look at the _compile() function in
02731    Lib/sre_compile.py.  The validation functions below checks the code array
02732    for conformance with the code patterns generated there.
02733 
02734    The nice thing about the generated code is that it is position-independent:
02735    all jumps are relative jumps forward.  Also, jumps don't cross each other:
02736    the target of a later jump is always earlier than the target of an earlier
02737    jump.  IOW, this is okay:
02738 
02739    J---------J-------T--------T
02740     \         \_____/        /
02741      \______________________/
02742 
02743    but this is not:
02744 
02745    J---------J-------T--------T
02746     \_________\_____/        /
02747                \____________/
02748 
02749    It also helps that SRE_CODE is always an unsigned type, either 2 bytes or 4
02750    bytes wide (the latter if Python is compiled for "wide" unicode support).
02751 */
02752 
02753 /* Defining this one enables tracing of the validator */
02754 #undef VVERBOSE
02755 
02756 /* Trace macro for the validator */
02757 #if defined(VVERBOSE)
02758 #define VTRACE(v) printf v
02759 #else
02760 #define VTRACE(v)
02761 #endif
02762 
02763 /* Report failure */
02764 #define FAIL do { VTRACE(("FAIL: %d\n", __LINE__)); return 0; } while (0)
02765 
02766 /* Extract opcode, argument, or skip count from code array */
02767 #define GET_OP                                          \
02768     do {                                                \
02769         VTRACE(("%p: ", code));                         \
02770         if (code >= end) FAIL;                          \
02771         op = *code++;                                   \
02772         VTRACE(("%lu (op)\n", (unsigned long)op));      \
02773     } while (0)
02774 #define GET_ARG                                         \
02775     do {                                                \
02776         VTRACE(("%p= ", code));                         \
02777         if (code >= end) FAIL;                          \
02778         arg = *code++;                                  \
02779         VTRACE(("%lu (arg)\n", (unsigned long)arg));    \
02780     } while (0)
02781 #define GET_SKIP_ADJ(adj)                               \
02782     do {                                                \
02783         VTRACE(("%p= ", code));                         \
02784         if (code >= end) FAIL;                          \
02785         skip = *code;                                   \
02786         VTRACE(("%lu (skip to %p)\n",                   \
02787                (unsigned long)skip, code+skip));        \
02788         if (code+skip-adj < code || code+skip-adj > end)\
02789             FAIL;                                       \
02790         code++;                                         \
02791     } while (0)
02792 #define GET_SKIP GET_SKIP_ADJ(0)
02793 
02794 static int
02795 _validate_charset(SRE_CODE *code, SRE_CODE *end)
02796 {
02797     /* Some variables are manipulated by the macros above */
02798     SRE_CODE op;
02799     SRE_CODE arg;
02800     SRE_CODE offset;
02801     int i;
02802 
02803     while (code < end) {
02804         GET_OP;
02805         switch (op) {
02806 
02807         case SRE_OP_NEGATE:
02808             break;
02809 
02810         case SRE_OP_LITERAL:
02811             GET_ARG;
02812             break;
02813 
02814         case SRE_OP_RANGE:
02815             GET_ARG;
02816             GET_ARG;
02817             break;
02818 
02819         case SRE_OP_CHARSET:
02820             offset = 32/sizeof(SRE_CODE); /* 32-byte bitmap */
02821             if (code+offset < code || code+offset > end)
02822                 FAIL;
02823             code += offset;
02824             break;
02825 
02826         case SRE_OP_BIGCHARSET:
02827             GET_ARG; /* Number of blocks */
02828             offset = 256/sizeof(SRE_CODE); /* 256-byte table */
02829             if (code+offset < code || code+offset > end)
02830                 FAIL;
02831             /* Make sure that each byte points to a valid block */
02832             for (i = 0; i < 256; i++) {
02833                 if (((unsigned char *)code)[i] >= arg)
02834                     FAIL;
02835             }
02836             code += offset;
02837             offset = arg * 32/sizeof(SRE_CODE); /* 32-byte bitmap times arg */
02838             if (code+offset < code || code+offset > end)
02839                 FAIL;
02840             code += offset;
02841             break;
02842 
02843         case SRE_OP_CATEGORY:
02844             GET_ARG;
02845             switch (arg) {
02846             case SRE_CATEGORY_DIGIT:
02847             case SRE_CATEGORY_NOT_DIGIT:
02848             case SRE_CATEGORY_SPACE:
02849             case SRE_CATEGORY_NOT_SPACE:
02850             case SRE_CATEGORY_WORD:
02851             case SRE_CATEGORY_NOT_WORD:
02852             case SRE_CATEGORY_LINEBREAK:
02853             case SRE_CATEGORY_NOT_LINEBREAK:
02854             case SRE_CATEGORY_LOC_WORD:
02855             case SRE_CATEGORY_LOC_NOT_WORD:
02856             case SRE_CATEGORY_UNI_DIGIT:
02857             case SRE_CATEGORY_UNI_NOT_DIGIT:
02858             case SRE_CATEGORY_UNI_SPACE:
02859             case SRE_CATEGORY_UNI_NOT_SPACE:
02860             case SRE_CATEGORY_UNI_WORD:
02861             case SRE_CATEGORY_UNI_NOT_WORD:
02862             case SRE_CATEGORY_UNI_LINEBREAK:
02863             case SRE_CATEGORY_UNI_NOT_LINEBREAK:
02864                 break;
02865             default:
02866                 FAIL;
02867             }
02868             break;
02869 
02870         default:
02871             FAIL;
02872 
02873         }
02874     }
02875 
02876     return 1;
02877 }
02878 
02879 static int
02880 _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
02881 {
02882     /* Some variables are manipulated by the macros above */
02883     SRE_CODE op;
02884     SRE_CODE arg;
02885     SRE_CODE skip;
02886 
02887     VTRACE(("code=%p, end=%p\n", code, end));
02888 
02889     if (code > end)
02890         FAIL;
02891 
02892     while (code < end) {
02893         GET_OP;
02894         switch (op) {
02895 
02896         case SRE_OP_MARK:
02897             /* We don't check whether marks are properly nested; the
02898                sre_match() code is robust even if they don't, and the worst
02899                you can get is nonsensical match results. */
02900             GET_ARG;
02901             if (arg > 2*groups+1) {
02902                 VTRACE(("arg=%d, groups=%d\n", (int)arg, (int)groups));
02903                 FAIL;
02904             }
02905             break;
02906 
02907         case SRE_OP_LITERAL:
02908         case SRE_OP_NOT_LITERAL:
02909         case SRE_OP_LITERAL_IGNORE:
02910         case SRE_OP_NOT_LITERAL_IGNORE:
02911             GET_ARG;
02912             /* The arg is just a character, nothing to check */
02913             break;
02914 
02915         case SRE_OP_SUCCESS:
02916         case SRE_OP_FAILURE:
02917             /* Nothing to check; these normally end the matching process */
02918             break;
02919 
02920         case SRE_OP_AT:
02921             GET_ARG;
02922             switch (arg) {
02923             case SRE_AT_BEGINNING:
02924             case SRE_AT_BEGINNING_STRING:
02925             case SRE_AT_BEGINNING_LINE:
02926             case SRE_AT_END:
02927             case SRE_AT_END_LINE:
02928             case SRE_AT_END_STRING:
02929             case SRE_AT_BOUNDARY:
02930             case SRE_AT_NON_BOUNDARY:
02931             case SRE_AT_LOC_BOUNDARY:
02932             case SRE_AT_LOC_NON_BOUNDARY:
02933             case SRE_AT_UNI_BOUNDARY:
02934             case SRE_AT_UNI_NON_BOUNDARY:
02935                 break;
02936             default:
02937                 FAIL;
02938             }
02939             break;
02940 
02941         case SRE_OP_ANY:
02942         case SRE_OP_ANY_ALL:
02943             /* These have no operands */
02944             break;
02945 
02946         case SRE_OP_IN:
02947         case SRE_OP_IN_IGNORE:
02948             GET_SKIP;
02949             /* Stop 1 before the end; we check the FAILURE below */
02950             if (!_validate_charset(code, code+skip-2))
02951                 FAIL;
02952             if (code[skip-2] != SRE_OP_FAILURE)
02953                 FAIL;
02954             code += skip-1;
02955             break;
02956 
02957         case SRE_OP_INFO:
02958             {
02959                 /* A minimal info field is
02960                    <INFO> <1=skip> <2=flags> <3=min> <4=max>;
02961                    If SRE_INFO_PREFIX or SRE_INFO_CHARSET is in the flags,
02962                    more follows. */
02963                 SRE_CODE flags, i;
02964                 SRE_CODE *newcode;
02965                 GET_SKIP;
02966                 newcode = code+skip-1;
02967                 GET_ARG; flags = arg;
02968                 GET_ARG; /* min */
02969                 GET_ARG; /* max */
02970                 /* Check that only valid flags are present */
02971                 if ((flags & ~(SRE_INFO_PREFIX |
02972                                SRE_INFO_LITERAL |
02973                                SRE_INFO_CHARSET)) != 0)
02974                     FAIL;
02975                 /* PREFIX and CHARSET are mutually exclusive */
02976                 if ((flags & SRE_INFO_PREFIX) &&
02977                     (flags & SRE_INFO_CHARSET))
02978                     FAIL;
02979                 /* LITERAL implies PREFIX */
02980                 if ((flags & SRE_INFO_LITERAL) &&
02981                     !(flags & SRE_INFO_PREFIX))
02982                     FAIL;
02983                 /* Validate the prefix */
02984                 if (flags & SRE_INFO_PREFIX) {
02985                     SRE_CODE prefix_len;
02986                     GET_ARG; prefix_len = arg;
02987                     GET_ARG; /* prefix skip */
02988                     /* Here comes the prefix string */
02989                     if (code+prefix_len < code || code+prefix_len > newcode)
02990                         FAIL;
02991                     code += prefix_len;
02992                     /* And here comes the overlap table */
02993                     if (code+prefix_len < code || code+prefix_len > newcode)
02994                         FAIL;
02995                     /* Each overlap value should be < prefix_len */
02996                     for (i = 0; i < prefix_len; i++) {
02997                         if (code[i] >= prefix_len)
02998                             FAIL;
02999                     }
03000                     code += prefix_len;
03001                 }
03002                 /* Validate the charset */
03003                 if (flags & SRE_INFO_CHARSET) {
03004                     if (!_validate_charset(code, newcode-1))
03005                         FAIL;
03006                     if (newcode[-1] != SRE_OP_FAILURE)
03007                         FAIL;
03008                     code = newcode;
03009                 }
03010                 else if (code != newcode) {
03011                   VTRACE(("code=%p, newcode=%p\n", code, newcode));
03012                     FAIL;
03013                 }
03014             }
03015             break;
03016 
03017         case SRE_OP_BRANCH:
03018             {
03019                 SRE_CODE *target = NULL;
03020                 for (;;) {
03021                     GET_SKIP;
03022                     if (skip == 0)
03023                         break;
03024                     /* Stop 2 before the end; we check the JUMP below */
03025                     if (!_validate_inner(code, code+skip-3, groups))
03026                         FAIL;
03027                     code += skip-3;
03028                     /* Check that it ends with a JUMP, and that each JUMP
03029                        has the same target */
03030                     GET_OP;
03031                     if (op != SRE_OP_JUMP)
03032                         FAIL;
03033                     GET_SKIP;
03034                     if (target == NULL)
03035                         target = code+skip-1;
03036                     else if (code+skip-1 != target)
03037                         FAIL;
03038                 }
03039             }
03040             break;
03041 
03042         case SRE_OP_REPEAT_ONE:
03043         case SRE_OP_MIN_REPEAT_ONE:
03044             {
03045                 SRE_CODE min, max;
03046                 GET_SKIP;
03047                 GET_ARG; min = arg;
03048                 GET_ARG; max = arg;
03049                 if (min > max)
03050                     FAIL;
03051 #ifdef Py_UNICODE_WIDE
03052                 if (max > 65535)
03053                     FAIL;
03054 #endif
03055                 if (!_validate_inner(code, code+skip-4, groups))
03056                     FAIL;
03057                 code += skip-4;
03058                 GET_OP;
03059                 if (op != SRE_OP_SUCCESS)
03060                     FAIL;
03061             }
03062             break;
03063 
03064         case SRE_OP_REPEAT:
03065             {
03066                 SRE_CODE min, max;
03067                 GET_SKIP;
03068                 GET_ARG; min = arg;
03069                 GET_ARG; max = arg;
03070                 if (min > max)
03071                     FAIL;
03072 #ifdef Py_UNICODE_WIDE
03073                 if (max > 65535)
03074                     FAIL;
03075 #endif
03076                 if (!_validate_inner(code, code+skip-3, groups))
03077                     FAIL;
03078                 code += skip-3;
03079                 GET_OP;
03080                 if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL)
03081                     FAIL;
03082             }
03083             break;
03084 
03085         case SRE_OP_GROUPREF:
03086         case SRE_OP_GROUPREF_IGNORE:
03087             GET_ARG;
03088             if (arg >= groups)
03089                 FAIL;
03090             break;
03091 
03092         case SRE_OP_GROUPREF_EXISTS:
03093             /* The regex syntax for this is: '(?(group)then|else)', where
03094                'group' is either an integer group number or a group name,
03095                'then' and 'else' are sub-regexes, and 'else' is optional. */
03096             GET_ARG;
03097             if (arg >= groups)
03098                 FAIL;
03099             GET_SKIP_ADJ(1);
03100             code--; /* The skip is relative to the first arg! */
03101             /* There are two possibilities here: if there is both a 'then'
03102                part and an 'else' part, the generated code looks like:
03103 
03104                GROUPREF_EXISTS
03105                <group>
03106                <skipyes>
03107                ...then part...
03108                JUMP
03109                <skipno>
03110                (<skipyes> jumps here)
03111                ...else part...
03112                (<skipno> jumps here)
03113 
03114                If there is only a 'then' part, it looks like:
03115 
03116                GROUPREF_EXISTS
03117                <group>
03118                <skip>
03119                ...then part...
03120                (<skip> jumps here)
03121 
03122                There is no direct way to decide which it is, and we don't want
03123                to allow arbitrary jumps anywhere in the code; so we just look
03124                for a JUMP opcode preceding our skip target.
03125             */
03126             if (skip >= 3 && code+skip-3 >= code &&
03127                 code[skip-3] == SRE_OP_JUMP)
03128             {
03129                 VTRACE(("both then and else parts present\n"));
03130                 if (!_validate_inner(code+1, code+skip-3, groups))
03131                     FAIL;
03132                 code += skip-2; /* Position after JUMP, at <skipno> */
03133                 GET_SKIP;
03134                 if (!_validate_inner(code, code+skip-1, groups))
03135                     FAIL;
03136                 code += skip-1;
03137             }
03138             else {
03139                 VTRACE(("only a then part present\n"));
03140                 if (!_validate_inner(code+1, code+skip-1, groups))
03141                     FAIL;
03142                 code += skip-1;
03143             }
03144             break;
03145 
03146         case SRE_OP_ASSERT:
03147         case SRE_OP_ASSERT_NOT:
03148             GET_SKIP;
03149             GET_ARG; /* 0 for lookahead, width for lookbehind */
03150             code--; /* Back up over arg to simplify math below */
03151             if (arg & 0x80000000)
03152                 FAIL; /* Width too large */
03153             /* Stop 1 before the end; we check the SUCCESS below */
03154             if (!_validate_inner(code+1, code+skip-2, groups))
03155                 FAIL;
03156             code += skip-2;
03157             GET_OP;
03158             if (op != SRE_OP_SUCCESS)
03159                 FAIL;
03160             break;
03161 
03162         default:
03163             FAIL;
03164 
03165         }
03166     }
03167 
03168     VTRACE(("okay\n"));
03169     return 1;
03170 }
03171 
03172 static int
03173 _validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
03174 {
03175     if (groups < 0 || groups > 100 || code >= end || end[-1] != SRE_OP_SUCCESS)
03176         FAIL;
03177     if (groups == 0)  /* fix for simplejson */
03178         groups = 100; /* 100 groups should always be safe */
03179     return _validate_inner(code, end-1, groups);
03180 }
03181 
03182 static int
03183 _validate(PatternObject *self)
03184 {
03185     if (!_validate_outer(self->code, self->code+self->codesize, self->groups))
03186     {
03187         PyErr_SetString(PyExc_RuntimeError, "invalid SRE code");
03188         return 0;
03189     }
03190     else
03191         VTRACE(("Success!\n"));
03192     return 1;
03193 }
03194 
03195 /* -------------------------------------------------------------------- */
03196 /* match methods */
03197 
03198 static void
03199 match_dealloc(MatchObject* self)
03200 {
03201     Py_XDECREF(self->regs);
03202     Py_XDECREF(self->string);
03203     Py_DECREF(self->pattern);
03204     PyObject_DEL(self);
03205 }
03206 
03207 static PyObject*
03208 match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def)
03209 {
03210     if (index < 0 || index >= self->groups) {
03211         /* raise IndexError if we were given a bad group number */
03212         PyErr_SetString(
03213             PyExc_IndexError,
03214             "no such group"
03215             );
03216         return NULL;
03217     }
03218 
03219     index *= 2;
03220 
03221     if (self->string == Py_None || self->mark[index] < 0) {
03222         /* return default value if the string or group is undefined */
03223         Py_INCREF(def);
03224         return def;
03225     }
03226 
03227     return PySequence_GetSlice(
03228         self->string, self->mark[index], self->mark[index+1]
03229         );
03230 }
03231 
03232 static Py_ssize_t
03233 match_getindex(MatchObject* self, PyObject* index)
03234 {
03235     Py_ssize_t i;
03236 
03237     if (PyInt_Check(index))
03238         return PyInt_AsSsize_t(index);
03239 
03240     i = -1;
03241 
03242     if (self->pattern->groupindex) {
03243         index = PyObject_GetItem(self->pattern->groupindex, index);
03244         if (index) {
03245             if (PyInt_Check(index) || PyLong_Check(index))
03246                 i = PyInt_AsSsize_t(index);
03247             Py_DECREF(index);
03248         } else
03249             PyErr_Clear();
03250     }
03251 
03252     return i;
03253 }
03254 
03255 static PyObject*
03256 match_getslice(MatchObject* self, PyObject* index, PyObject* def)
03257 {
03258     return match_getslice_by_index(self, match_getindex(self, index), def);
03259 }
03260 
03261 static PyObject*
03262 match_expand(MatchObject* self, PyObject* ptemplate)
03263 {
03264     /* delegate to Python code */
03265     return call(
03266         SRE_PY_MODULE, "_expand",
03267         PyTuple_Pack(3, self->pattern, self, ptemplate)
03268         );
03269 }
03270 
03271 static PyObject*
03272 match_group(MatchObject* self, PyObject* args)
03273 {
03274     PyObject* result;
03275     Py_ssize_t i, size;
03276 
03277     size = PyTuple_GET_SIZE(args);
03278 
03279     switch (size) {
03280     case 0:
03281         result = match_getslice(self, Py_False, Py_None);
03282         break;
03283     case 1:
03284         result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None);
03285         break;
03286     default:
03287         /* fetch multiple items */
03288         result = PyTuple_New(size);
03289         if (!result)
03290             return NULL;
03291         for (i = 0; i < size; i++) {
03292             PyObject* item = match_getslice(
03293                 self, PyTuple_GET_ITEM(args, i), Py_None
03294                 );
03295             if (!item) {
03296                 Py_DECREF(result);
03297                 return NULL;
03298             }
03299             PyTuple_SET_ITEM(result, i, item);
03300         }
03301         break;
03302     }
03303     return result;
03304 }
03305 
03306 static PyObject*
03307 match_groups(MatchObject* self, PyObject* args, PyObject* kw)
03308 {
03309     PyObject* result;
03310     Py_ssize_t index;
03311 
03312     PyObject* def = Py_None;
03313     static char* kwlist[] = { "default", NULL };
03314     if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def))
03315         return NULL;
03316 
03317     result = PyTuple_New(self->groups-1);
03318     if (!result)
03319         return NULL;
03320 
03321     for (index = 1; index < self->groups; index++) {
03322         PyObject* item;
03323         item = match_getslice_by_index(self, index, def);
03324         if (!item) {
03325             Py_DECREF(result);
03326             return NULL;
03327         }
03328         PyTuple_SET_ITEM(result, index-1, item);
03329     }
03330 
03331     return result;
03332 }
03333 
03334 static PyObject*
03335 match_groupdict(MatchObject* self, PyObject* args, PyObject* kw)
03336 {
03337     PyObject* result;
03338     PyObject* keys;
03339     Py_ssize_t index;
03340 
03341     PyObject* def = Py_None;
03342     static char* kwlist[] = { "default", NULL };
03343     if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def))
03344         return NULL;
03345 
03346     result = PyDict_New();
03347     if (!result || !self->pattern->groupindex)
03348         return result;
03349 
03350     keys = PyMapping_Keys(self->pattern->groupindex);
03351     if (!keys)
03352         goto failed;
03353 
03354     for (index = 0; index < PyList_GET_SIZE(keys); index++) {
03355         int status;
03356         PyObject* key;
03357         PyObject* value;
03358         key = PyList_GET_ITEM(keys, index);
03359         if (!key)
03360             goto failed;
03361         value = match_getslice(self, key, def);
03362         if (!value) {
03363             Py_DECREF(key);
03364             goto failed;
03365         }
03366         status = PyDict_SetItem(result, key, value);
03367         Py_DECREF(value);
03368         if (status < 0)
03369             goto failed;
03370     }
03371 
03372     Py_DECREF(keys);
03373 
03374     return result;
03375 
03376 failed:
03377     Py_XDECREF(keys);
03378     Py_DECREF(result);
03379     return NULL;
03380 }
03381 
03382 static PyObject*
03383 match_start(MatchObject* self, PyObject* args)
03384 {
03385     Py_ssize_t index;
03386 
03387     PyObject* index_ = Py_False; /* zero */
03388     if (!PyArg_UnpackTuple(args, "start", 0, 1, &index_))
03389         return NULL;
03390 
03391     index = match_getindex(self, index_);
03392 
03393     if (index < 0 || index >= self->groups) {
03394         PyErr_SetString(
03395             PyExc_IndexError,
03396             "no such group"
03397             );
03398         return NULL;
03399     }
03400 
03401     /* mark is -1 if group is undefined */
03402     return Py_BuildValue("i", self->mark[index*2]);
03403 }
03404 
03405 static PyObject*
03406 match_end(MatchObject* self, PyObject* args)
03407 {
03408     Py_ssize_t index;
03409 
03410     PyObject* index_ = Py_False; /* zero */
03411     if (!PyArg_UnpackTuple(args, "end", 0, 1, &index_))
03412         return NULL;
03413 
03414     index = match_getindex(self, index_);
03415 
03416     if (index < 0 || index >= self->groups) {
03417         PyErr_SetString(
03418             PyExc_IndexError,
03419             "no such group"
03420             );
03421         return NULL;
03422     }
03423 
03424     /* mark is -1 if group is undefined */
03425     return Py_BuildValue("i", self->mark[index*2+1]);
03426 }
03427 
03428 LOCAL(PyObject*)
03429 _pair(Py_ssize_t i1, Py_ssize_t i2)
03430 {
03431     PyObject* pair;
03432     PyObject* item;
03433 
03434     pair = PyTuple_New(2);
03435     if (!pair)
03436         return NULL;
03437 
03438     item = PyInt_FromSsize_t(i1);
03439     if (!item)
03440         goto error;
03441     PyTuple_SET_ITEM(pair, 0, item);
03442 
03443     item = PyInt_FromSsize_t(i2);
03444     if (!item)
03445         goto error;
03446     PyTuple_SET_ITEM(pair, 1, item);
03447 
03448     return pair;
03449 
03450   error:
03451     Py_DECREF(pair);
03452     return NULL;
03453 }
03454 
03455 static PyObject*
03456 match_span(MatchObject* self, PyObject* args)
03457 {
03458     Py_ssize_t index;
03459 
03460     PyObject* index_ = Py_False; /* zero */
03461     if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_))
03462         return NULL;
03463 
03464     index = match_getindex(self, index_);
03465 
03466     if (index < 0 || index >= self->groups) {
03467         PyErr_SetString(
03468             PyExc_IndexError,
03469             "no such group"
03470             );
03471         return NULL;
03472     }
03473 
03474     /* marks are -1 if group is undefined */
03475     return _pair(self->mark[index*2], self->mark[index*2+1]);
03476 }
03477 
03478 static PyObject*
03479 match_regs(MatchObject* self)
03480 {
03481     PyObject* regs;
03482     PyObject* item;
03483     Py_ssize_t index;
03484 
03485     regs = PyTuple_New(self->groups);
03486     if (!regs)
03487         return NULL;
03488 
03489     for (index = 0; index < self->groups; index++) {
03490         item = _pair(self->mark[index*2], self->mark[index*2+1]);
03491         if (!item) {
03492             Py_DECREF(regs);
03493             return NULL;
03494         }
03495         PyTuple_SET_ITEM(regs, index, item);
03496     }
03497 
03498     Py_INCREF(regs);
03499     self->regs = regs;
03500 
03501     return regs;
03502 }
03503 
03504 static PyObject*
03505 match_copy(MatchObject* self, PyObject *unused)
03506 {
03507 #ifdef USE_BUILTIN_COPY
03508     MatchObject* copy;
03509     Py_ssize_t slots, offset;
03510 
03511     slots = 2 * (self->pattern->groups+1);
03512 
03513     copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots);
03514     if (!copy)
03515         return NULL;
03516 
03517     /* this value a constant, but any compiler should be able to
03518        figure that out all by itself */
03519     offset = offsetof(MatchObject, string);
03520 
03521     Py_XINCREF(self->pattern);
03522     Py_XINCREF(self->string);
03523     Py_XINCREF(self->regs);
03524 
03525     memcpy((char*) copy + offset, (char*) self + offset,
03526            sizeof(MatchObject) + slots * sizeof(Py_ssize_t) - offset);
03527 
03528     return (PyObject*) copy;
03529 #else
03530     PyErr_SetString(PyExc_TypeError, "cannot copy this match object");
03531     return NULL;
03532 #endif
03533 }
03534 
03535 static PyObject*
03536 match_deepcopy(MatchObject* self, PyObject* memo)
03537 {
03538 #ifdef USE_BUILTIN_COPY
03539     MatchObject* copy;
03540 
03541     copy = (MatchObject*) match_copy(self);
03542     if (!copy)
03543         return NULL;
03544 
03545     if (!deepcopy((PyObject**) &copy->pattern, memo) ||
03546         !deepcopy(&copy->string, memo) ||
03547         !deepcopy(&copy->regs, memo)) {
03548         Py_DECREF(copy);
03549         return NULL;
03550     }
03551 
03552 #else
03553     PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object");
03554     return NULL;
03555 #endif
03556 }
03557 
03558 static struct PyMethodDef match_methods[] = {
03559     {"group", (PyCFunction) match_group, METH_VARARGS},
03560     {"start", (PyCFunction) match_start, METH_VARARGS},
03561     {"end", (PyCFunction) match_end, METH_VARARGS},
03562     {"span", (PyCFunction) match_span, METH_VARARGS},
03563     {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS},
03564     {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS},
03565     {"expand", (PyCFunction) match_expand, METH_O},
03566     {"__copy__", (PyCFunction) match_copy, METH_NOARGS},
03567     {"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},
03568     {NULL, NULL}
03569 };
03570 
03571 static PyObject *
03572 match_lastindex_get(MatchObject *self)
03573 {
03574     if (self->lastindex >= 0)
03575   return Py_BuildValue("i", self->lastindex);
03576     Py_INCREF(Py_None);
03577     return Py_None;
03578 }
03579 
03580 static PyObject *
03581 match_lastgroup_get(MatchObject *self)
03582 {
03583     if (self->pattern->indexgroup && self->lastindex >= 0) {
03584         PyObject* result = PySequence_GetItem(
03585             self->pattern->indexgroup, self->lastindex
03586             );
03587         if (result)
03588             return result;
03589         PyErr_Clear();
03590     }
03591     Py_INCREF(Py_None);
03592     return Py_None;
03593 }
03594 
03595 static PyObject *
03596 match_regs_get(MatchObject *self)
03597 {
03598     if (self->regs) {
03599         Py_INCREF(self->regs);
03600         return self->regs;
03601     } else
03602         return match_regs(self);
03603 }
03604 
03605 static PyGetSetDef match_getset[] = {
03606     {"lastindex", (getter)match_lastindex_get, (setter)NULL},
03607     {"lastgroup", (getter)match_lastgroup_get, (setter)NULL},
03608     {"regs",      (getter)match_regs_get,      (setter)NULL},
03609     {NULL}
03610 };
03611 
03612 #define MATCH_OFF(x) offsetof(MatchObject, x)
03613 static PyMemberDef match_members[] = {
03614     {"string",  T_OBJECT,   MATCH_OFF(string),  READONLY},
03615     {"re",      T_OBJECT,   MATCH_OFF(pattern), READONLY},
03616     {"pos",     T_PYSSIZET, MATCH_OFF(pos),     READONLY},
03617     {"endpos",  T_PYSSIZET, MATCH_OFF(endpos),  READONLY},
03618     {NULL}
03619 };
03620 
03621 
03622 /* FIXME: implement setattr("string", None) as a special case (to
03623    detach the associated string, if any */
03624 
03625 static PyTypeObject Match_Type = {
03626     PyVarObject_HEAD_INIT(NULL, 0)
03627     "_" SRE_MODULE ".SRE_Match",
03628     sizeof(MatchObject), sizeof(Py_ssize_t),
03629     (destructor)match_dealloc,  /* tp_dealloc */
03630     0,                          /* tp_print */
03631     0,                          /* tp_getattr */
03632     0,                          /* tp_setattr */
03633     0,                          /* tp_compare */
03634     0,                          /* tp_repr */
03635     0,                          /* tp_as_number */
03636     0,                          /* tp_as_sequence */
03637     0,                          /* tp_as_mapping */
03638     0,                          /* tp_hash */
03639     0,                          /* tp_call */
03640     0,                          /* tp_str */
03641     0,                          /* tp_getattro */
03642     0,                          /* tp_setattro */
03643     0,                          /* tp_as_buffer */
03644     Py_TPFLAGS_DEFAULT,
03645     0,                          /* tp_doc */
03646     0,                          /* tp_traverse */
03647     0,                          /* tp_clear */
03648     0,                          /* tp_richcompare */
03649     0,                          /* tp_weaklistoffset */
03650     0,                          /* tp_iter */
03651     0,                          /* tp_iternext */
03652     match_methods,    /* tp_methods */
03653     match_members,    /* tp_members */
03654     match_getset,           /* tp_getset */
03655 };
03656 
03657 static PyObject*
03658 pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status)
03659 {
03660     /* create match object (from state object) */
03661 
03662     MatchObject* match;
03663     Py_ssize_t i, j;
03664     char* base;
03665     int n;
03666 
03667     if (status > 0) {
03668 
03669         /* create match object (with room for extra group marks) */
03670         /* coverity[ampersand_in_size] */
03671         match = PyObject_NEW_VAR(MatchObject, &Match_Type,
03672                                  2*(pattern->groups+1));
03673         if (!match)
03674             return NULL;
03675 
03676         Py_INCREF(pattern);
03677         match->pattern = pattern;
03678 
03679         Py_INCREF(state->string);
03680         match->string = state->string;
03681 
03682         match->regs = NULL;
03683         match->groups = pattern->groups+1;
03684 
03685         /* fill in group slices */
03686 
03687         base = (char*) state->beginning;
03688         n = state->charsize;
03689 
03690         match->mark[0] = ((char*) state->start - base) / n;
03691         match->mark[1] = ((char*) state->ptr - base) / n;
03692 
03693         for (i = j = 0; i < pattern->groups; i++, j+=2)
03694             if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) {
03695                 match->mark[j+2] = ((char*) state->mark[j] - base) / n;
03696                 match->mark[j+3] = ((char*) state->mark[j+1] - base) / n;
03697             } else
03698                 match->mark[j+2] = match->mark[j+3] = -1; /* undefined */
03699 
03700         match->pos = state->pos;
03701         match->endpos = state->endpos;
03702 
03703         match->lastindex = state->lastindex;
03704 
03705         return (PyObject*) match;
03706 
03707     } else if (status == 0) {
03708 
03709         /* no match */
03710         Py_INCREF(Py_None);
03711         return Py_None;
03712 
03713     }
03714 
03715     /* internal error */
03716     pattern_error(status);
03717     return NULL;
03718 }
03719 
03720 
03721 /* -------------------------------------------------------------------- */
03722 /* scanner methods (experimental) */
03723 
03724 static void
03725 scanner_dealloc(ScannerObject* self)
03726 {
03727     state_fini(&self->state);
03728     Py_XDECREF(self->pattern);
03729     PyObject_DEL(self);
03730 }
03731 
03732 static PyObject*
03733 scanner_match(ScannerObject* self, PyObject *unused)
03734 {
03735     SRE_STATE* state = &self->state;
03736     PyObject* match;
03737     int status;
03738 
03739     state_reset(state);
03740 
03741     state->ptr = state->start;
03742 
03743     if (state->charsize == 1) {
03744         status = sre_match(state, PatternObject_GetCode(self->pattern));
03745     } else {
03746 #if defined(HAVE_UNICODE)
03747         status = sre_umatch(state, PatternObject_GetCode(self->pattern));
03748 #endif
03749     }
03750     if (PyErr_Occurred())
03751         return NULL;
03752 
03753     match = pattern_new_match((PatternObject*) self->pattern,
03754                                state, status);
03755 
03756     if (status == 0 || state->ptr == state->start)
03757         state->start = (void*) ((char*) state->ptr + state->charsize);
03758     else
03759         state->start = state->ptr;
03760 
03761     return match;
03762 }
03763 
03764 
03765 static PyObject*
03766 scanner_search(ScannerObject* self, PyObject *unused)
03767 {
03768     SRE_STATE* state = &self->state;
03769     PyObject* match;
03770     int status;
03771 
03772     state_reset(state);
03773 
03774     state->ptr = state->start;
03775 
03776     if (state->charsize == 1) {
03777         status = sre_search(state, PatternObject_GetCode(self->pattern));
03778     } else {
03779 #if defined(HAVE_UNICODE)
03780         status = sre_usearch(state, PatternObject_GetCode(self->pattern));
03781 #endif
03782     }
03783     if (PyErr_Occurred())
03784         return NULL;
03785 
03786     match = pattern_new_match((PatternObject*) self->pattern,
03787                                state, status);
03788 
03789     if (status == 0 || state->ptr == state->start)
03790         state->start = (void*) ((char*) state->ptr + state->charsize);
03791     else
03792         state->start = state->ptr;
03793 
03794     return match;
03795 }
03796 
03797 static PyMethodDef scanner_methods[] = {
03798     {"match", (PyCFunction) scanner_match, METH_NOARGS},
03799     {"search", (PyCFunction) scanner_search, METH_NOARGS},
03800     {NULL, NULL}
03801 };
03802 
03803 #define SCAN_OFF(x) offsetof(ScannerObject, x)
03804 static PyMemberDef scanner_members[] = {
03805     {"pattern", T_OBJECT, SCAN_OFF(pattern),  READONLY},
03806     {NULL}  /* Sentinel */
03807 };
03808 
03809 statichere PyTypeObject Scanner_Type = {
03810     PyObject_HEAD_INIT(NULL)
03811     0, "_" SRE_MODULE ".SRE_Scanner",
03812     sizeof(ScannerObject), 0,
03813     (destructor)scanner_dealloc, /*tp_dealloc*/
03814     0,        /* tp_print */
03815     0,        /* tp_getattr */
03816     0,        /* tp_setattr */
03817     0,        /* tp_reserved */
03818     0,        /* tp_repr */
03819     0,        /* tp_as_number */
03820     0,        /* tp_as_sequence */
03821     0,        /* tp_as_mapping */
03822     0,        /* tp_hash */
03823     0,        /* tp_call */
03824     0,        /* tp_str */
03825     0,        /* tp_getattro */
03826     0,        /* tp_setattro */
03827     0,        /* tp_as_buffer */
03828     Py_TPFLAGS_DEFAULT,   /* tp_flags */
03829     0,        /* tp_doc */
03830     0,        /* tp_traverse */
03831     0,        /* tp_clear */
03832     0,        /* tp_richcompare */
03833     0,        /* tp_weaklistoffset */
03834     0,        /* tp_iter */
03835     0,        /* tp_iternext */
03836     scanner_methods,    /* tp_methods */
03837     scanner_members,    /* tp_members */
03838     0,        /* tp_getset */
03839 };
03840 
03841 static PyObject*
03842 pattern_scanner(PatternObject* pattern, PyObject* args)
03843 {
03844     /* create search state object */
03845 
03846     ScannerObject* self;
03847 
03848     PyObject* string;
03849     Py_ssize_t start = 0;
03850     Py_ssize_t end = PY_SSIZE_T_MAX;
03851     if (!PyArg_ParseTuple(args, "O|nn:scanner", &string, &start, &end))
03852         return NULL;
03853 
03854     /* create scanner object */
03855     self = PyObject_NEW(ScannerObject, &Scanner_Type);
03856     if (!self)
03857         return NULL;
03858     self->pattern = NULL;
03859 
03860     string = state_init(&self->state, pattern, string, start, end);
03861     if (!string) {
03862         Py_DECREF(self);
03863         return NULL;
03864     }
03865 
03866     Py_INCREF(pattern);
03867     self->pattern = (PyObject*) pattern;
03868 
03869     return (PyObject*) self;
03870 }
03871 
03872 static PyMethodDef _functions[] = {
03873     {"compile", _compile, METH_VARARGS},
03874     {"getcodesize", sre_codesize, METH_NOARGS},
03875     {"getlower", sre_getlower, METH_VARARGS},
03876     {NULL, NULL}
03877 };
03878 
03879 #if PY_VERSION_HEX < 0x02030000
03880 DL_EXPORT(void) init_sre(void)
03881 #else
03882 PyMODINIT_FUNC init_sre(void)
03883 #endif
03884 {
03885     PyObject* m;
03886     PyObject* d;
03887     PyObject* x;
03888 
03889     /* Patch object types */
03890     if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) ||
03891         PyType_Ready(&Scanner_Type))
03892         return;
03893 
03894     m = Py_InitModule("_" SRE_MODULE, _functions);
03895     if (m == NULL)
03896         return;
03897     d = PyModule_GetDict(m);
03898 
03899     x = PyInt_FromLong(SRE_MAGIC);
03900     if (x) {
03901         PyDict_SetItemString(d, "MAGIC", x);
03902         Py_DECREF(x);
03903     }
03904 
03905     x = PyInt_FromLong(sizeof(SRE_CODE));
03906     if (x) {
03907         PyDict_SetItemString(d, "CODESIZE", x);
03908         Py_DECREF(x);
03909     }
03910 
03911     x = PyString_FromString(copyright);
03912     if (x) {
03913         PyDict_SetItemString(d, "copyright", x);
03914         Py_DECREF(x);
03915     }
03916 }
03917 
03918 #endif /* !defined(SRE_RECURSIVE) */
03919 
03920 /* vim:ts=4:sw=4:et
03921 */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines