Back to index

python3.2  3.2.2
Classes | Defines | Functions | Variables
_sre.c File Reference
#include "Python.h"
#include "structmember.h"
#include "sre.h"
#include <ctype.h>
#include "_sre.c"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  SRE_MATCH_CONTEXT
union  SRE_MATCH_CONTEXT.u

Defines

#define PY_SSIZE_T_CLEAN
#define SRE_MODULE   "sre"
#define SRE_PY_MODULE   "re"
#define HAVE_UNICODE
#define USE_FAST_SEARCH
#define PyObject_DEL(op)   PyMem_DEL((op))
#define LOCAL(type)   static type
#define SRE_ERROR_ILLEGAL   -1 /* illegal opcode */
#define SRE_ERROR_STATE   -2 /* illegal state */
#define SRE_ERROR_RECURSION_LIMIT   -3 /* runaway recursion */
#define SRE_ERROR_MEMORY   -9 /* out of memory */
#define SRE_ERROR_INTERRUPTED   -10 /* signal handler raised exception */
#define TRACE(v)
#define SRE_DIGIT_MASK   1
#define SRE_SPACE_MASK   2
#define SRE_LINEBREAK_MASK   4
#define SRE_ALNUM_MASK   8
#define SRE_WORD_MASK   16
#define SRE_IS_DIGIT(ch)   ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)
#define SRE_IS_SPACE(ch)   ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)
#define SRE_IS_LINEBREAK(ch)   ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)
#define SRE_IS_ALNUM(ch)   ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)
#define SRE_IS_WORD(ch)   ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)
#define SRE_LOC_IS_DIGIT(ch)   (!((ch) & ~255) ? isdigit((ch)) : 0)
#define SRE_LOC_IS_SPACE(ch)   (!((ch) & ~255) ? isspace((ch)) : 0)
#define SRE_LOC_IS_LINEBREAK(ch)   ((ch) == '\n')
#define SRE_LOC_IS_ALNUM(ch)   (!((ch) & ~255) ? isalnum((ch)) : 0)
#define SRE_LOC_IS_WORD(ch)   (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')
#define SRE_UNI_IS_DIGIT(ch)   Py_UNICODE_ISDECIMAL((Py_UNICODE)(ch))
#define SRE_UNI_IS_SPACE(ch)   Py_UNICODE_ISSPACE((Py_UNICODE)(ch))
#define SRE_UNI_IS_LINEBREAK(ch)   Py_UNICODE_ISLINEBREAK((Py_UNICODE)(ch))
#define SRE_UNI_IS_ALNUM(ch)   Py_UNICODE_ISALNUM((Py_UNICODE)(ch))
#define SRE_UNI_IS_WORD(ch)   (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_')
#define SRE_CHAR   unsigned char
#define SRE_AT   sre_at
#define SRE_COUNT   sre_count
#define SRE_CHARSET   sre_charset
#define SRE_INFO   sre_info
#define SRE_MATCH   sre_match
#define SRE_MATCH_CONTEXT   sre_match_context
#define SRE_SEARCH   sre_search
#define SRE_LITERAL_TEMPLATE   sre_literal_template
#define SRE_RECURSIVE
#define SRE_CHAR   Py_UNICODE
#define SRE_AT   sre_uat
#define SRE_COUNT   sre_ucount
#define SRE_CHARSET   sre_ucharset
#define SRE_INFO   sre_uinfo
#define SRE_MATCH   sre_umatch
#define SRE_MATCH_CONTEXT   sre_umatch_context
#define SRE_SEARCH   sre_usearch
#define SRE_LITERAL_TEMPLATE   sre_uliteral_template
#define LASTMARK_SAVE()
#define LASTMARK_RESTORE()
#define RETURN_ERROR(i)   do { return i; } while(0)
#define RETURN_FAILURE   do { ret = 0; goto exit; } while(0)
#define RETURN_SUCCESS   do { ret = 1; goto exit; } while(0)
#define RETURN_ON_ERROR(i)   do { if (i < 0) RETURN_ERROR(i); } while (0)
#define RETURN_ON_SUCCESS(i)   do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
#define RETURN_ON_FAILURE(i)   do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
#define SFY(x)   #x
#define DATA_STACK_ALLOC(state, type, ptr)
#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos)
#define DATA_STACK_PUSH(state, data, size)
#define DATA_STACK_POP(state, data, size, discard)
#define DATA_STACK_POP_DISCARD(state, size)
#define DATA_PUSH(x)   DATA_STACK_PUSH(state, (x), sizeof(*(x)))
#define DATA_POP(x)   DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
#define DATA_POP_DISCARD(x)   DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
#define DATA_ALLOC(t, p)   DATA_STACK_ALLOC(state, t, p)
#define DATA_LOOKUP_AT(t, p, pos)   DATA_STACK_LOOKUP_AT(state,t,p,pos)
#define MARK_PUSH(lastmark)
#define MARK_POP(lastmark)
#define MARK_POP_KEEP(lastmark)
#define MARK_POP_DISCARD(lastmark)
#define JUMP_NONE   0
#define JUMP_MAX_UNTIL_1   1
#define JUMP_MAX_UNTIL_2   2
#define JUMP_MAX_UNTIL_3   3
#define JUMP_MIN_UNTIL_1   4
#define JUMP_MIN_UNTIL_2   5
#define JUMP_MIN_UNTIL_3   6
#define JUMP_REPEAT   7
#define JUMP_REPEAT_ONE_1   8
#define JUMP_REPEAT_ONE_2   9
#define JUMP_MIN_REPEAT_ONE   10
#define JUMP_BRANCH   11
#define JUMP_ASSERT   12
#define JUMP_ASSERT_NOT   13
#define DO_JUMP(jumpvalue, jumplabel, nextpattern)

Functions

static unsigned int sre_lower (unsigned int ch)
static unsigned int sre_lower_locale (unsigned int ch)
static unsigned int sre_lower_unicode (unsigned int ch)
 sre_category (SRE_CODE category, unsigned int ch)
static void data_stack_dealloc (SRE_STATE *state)
static int data_stack_grow (SRE_STATE *state, Py_ssize_t size)
 SRE_AT (SRE_STATE *state, SRE_CHAR *ptr, SRE_CODE at)
 SRE_CHARSET (SRE_CODE *set, SRE_CODE ch)
 LOCAL (Py_ssize_t)
 SRE_MATCH (SRE_STATE *state, SRE_CODE *pattern)
 SRE_SEARCH (SRE_STATE *state, SRE_CODE *pattern)
 SRE_LITERAL_TEMPLATE (SRE_CHAR *ptr, Py_ssize_t len)

Variables

static char copyright [] = " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB "
static char sre_char_info [128]
static char sre_char_lower [128]

Class Documentation

struct SRE_MATCH_CONTEXT

Definition at line 783 of file _sre.c.

Class Members
Py_ssize_t count
Py_ssize_t jump
Py_ssize_t last_ctx_pos
Py_ssize_t lastindex
Py_ssize_t lastmark
SRE_CODE * pattern
SRE_CHAR * ptr
union SRE_MATCH_CONTEXT u
union SRE_MATCH_CONTEXT.u

Definition at line 791 of file _sre.c.

Class Members
SRE_CODE chr
SRE_REPEAT * rep

Define Documentation

#define DATA_ALLOC (   t,
  p 
)    DATA_STACK_ALLOC(state, t, p)

Definition at line 734 of file _sre.c.

#define DATA_LOOKUP_AT (   t,
  p,
  pos 
)    DATA_STACK_LOOKUP_AT(state,t,p,pos)

Definition at line 736 of file _sre.c.

#define DATA_POP (   x)    DATA_STACK_POP(state, (x), sizeof(*(x)), 1)

Definition at line 730 of file _sre.c.

#define DATA_POP_DISCARD (   x)    DATA_STACK_POP_DISCARD(state, sizeof(*(x)))

Definition at line 732 of file _sre.c.

#define DATA_PUSH (   x)    DATA_STACK_PUSH(state, (x), sizeof(*(x)))

Definition at line 728 of file _sre.c.

#define DATA_STACK_ALLOC (   state,
  type,
  ptr 
)
Value:
do { \
    alloc_pos = state->data_stack_base; \
    TRACE(("allocating %s in %d (%d)\n", \
           SFY(type), alloc_pos, sizeof(type))); \
    if (state->data_stack_size < alloc_pos+sizeof(type)) { \
        int j = data_stack_grow(state, sizeof(type)); \
        if (j < 0) return j; \
        if (ctx_pos != -1) \
            DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
    } \
    ptr = (type*)(state->data_stack+alloc_pos); \
    state->data_stack_base += sizeof(type); \
} while (0)

Definition at line 677 of file _sre.c.

#define DATA_STACK_LOOKUP_AT (   state,
  type,
  ptr,
  pos 
)
Value:
do { \
    TRACE(("looking up %s at %d\n", SFY(type), pos)); \
    ptr = (type*)(state->data_stack+pos); \
} while (0)

Definition at line 692 of file _sre.c.

#define DATA_STACK_POP (   state,
  data,
  size,
  discard 
)
Value:
do { \
    TRACE(("copy data to %p from %d (%d)\n", \
           data, state->data_stack_base-size, size)); \
    memcpy(data, state->data_stack+state->data_stack_base-size, size); \
    if (discard) \
        state->data_stack_base -= size; \
} while (0)

Definition at line 712 of file _sre.c.

#define DATA_STACK_POP_DISCARD (   state,
  size 
)
Value:
do { \
    TRACE(("discard data from %d (%d)\n", \
           state->data_stack_base-size, size)); \
    state->data_stack_base -= size; \
} while(0)

Definition at line 721 of file _sre.c.

#define DATA_STACK_PUSH (   state,
  data,
  size 
)
Value:
do { \
    TRACE(("copy data in %p to %d (%d)\n", \
           data, state->data_stack_base, size)); \
    if (state->data_stack_size < state->data_stack_base+size) { \
        int j = data_stack_grow(state, size); \
        if (j < 0) return j; \
        if (ctx_pos != -1) \
            DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
    } \
    memcpy(state->data_stack+state->data_stack_base, data, size); \
    state->data_stack_base += size; \
} while (0)

Definition at line 698 of file _sre.c.

#define DO_JUMP (   jumpvalue,
  jumplabel,
  nextpattern 
)
Value:
DATA_ALLOC(SRE_MATCH_CONTEXT, nextctx); \
    nextctx->last_ctx_pos = ctx_pos; \
    nextctx->jump = jumpvalue; \
    nextctx->pattern = nextpattern; \
    ctx_pos = alloc_pos; \
    ctx = nextctx; \
    goto entrance; \
    jumplabel: \
    while (0) /* gcc doesn't like labels at end of scopes */ \

Definition at line 772 of file _sre.c.

#define HAVE_UNICODE

Definition at line 62 of file _sre.c.

#define JUMP_ASSERT   12

Definition at line 769 of file _sre.c.

#define JUMP_ASSERT_NOT   13

Definition at line 770 of file _sre.c.

#define JUMP_BRANCH   11

Definition at line 768 of file _sre.c.

#define JUMP_MAX_UNTIL_1   1

Definition at line 758 of file _sre.c.

#define JUMP_MAX_UNTIL_2   2

Definition at line 759 of file _sre.c.

#define JUMP_MAX_UNTIL_3   3

Definition at line 760 of file _sre.c.

#define JUMP_MIN_REPEAT_ONE   10

Definition at line 767 of file _sre.c.

#define JUMP_MIN_UNTIL_1   4

Definition at line 761 of file _sre.c.

#define JUMP_MIN_UNTIL_2   5

Definition at line 762 of file _sre.c.

#define JUMP_MIN_UNTIL_3   6

Definition at line 763 of file _sre.c.

#define JUMP_NONE   0

Definition at line 757 of file _sre.c.

#define JUMP_REPEAT   7

Definition at line 764 of file _sre.c.

#define JUMP_REPEAT_ONE_1   8

Definition at line 765 of file _sre.c.

#define JUMP_REPEAT_ONE_2   9

Definition at line 766 of file _sre.c.

#define LASTMARK_RESTORE ( )
Value:
do { \
        state->lastmark = ctx->lastmark; \
        state->lastindex = ctx->lastindex; \
    } while (0)

Definition at line 658 of file _sre.c.

#define LASTMARK_SAVE ( )
Value:
do { \
        ctx->lastmark = state->lastmark; \
        ctx->lastindex = state->lastindex; \
    } while (0)

Definition at line 653 of file _sre.c.

#define LOCAL (   type)    static type

Definition at line 87 of file _sre.c.

#define MARK_POP (   lastmark)
Value:
do if (lastmark > 0) { \
        DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \
    } while (0)

Definition at line 744 of file _sre.c.

#define MARK_POP_DISCARD (   lastmark)
Value:
do if (lastmark > 0) { \
        DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \
    } while (0)

Definition at line 752 of file _sre.c.

#define MARK_POP_KEEP (   lastmark)
Value:
do if (lastmark > 0) { \
        DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \
    } while (0)

Definition at line 748 of file _sre.c.

#define MARK_PUSH (   lastmark)
Value:
do if (lastmark > 0) { \
        i = lastmark; /* ctx->lastmark may change if reallocated */ \
        DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \
    } while (0)

Definition at line 739 of file _sre.c.

Definition at line 42 of file _sre.c.

#define PyObject_DEL (   op)    PyMem_DEL((op))

Definition at line 74 of file _sre.c.

#define RETURN_ERROR (   i)    do { return i; } while(0)

Definition at line 664 of file _sre.c.

#define RETURN_FAILURE   do { ret = 0; goto exit; } while(0)

Definition at line 665 of file _sre.c.

#define RETURN_ON_ERROR (   i)    do { if (i < 0) RETURN_ERROR(i); } while (0)

Definition at line 668 of file _sre.c.

#define RETURN_ON_FAILURE (   i)    do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)

Definition at line 672 of file _sre.c.

#define RETURN_ON_SUCCESS (   i)    do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)

Definition at line 670 of file _sre.c.

#define RETURN_SUCCESS   do { ret = 1; goto exit; } while(0)

Definition at line 666 of file _sre.c.

#define SFY (   x)    #x

Definition at line 675 of file _sre.c.

#define SRE_ALNUM_MASK   8

Definition at line 111 of file _sre.c.

#define SRE_AT   sre_at

Definition at line 311 of file _sre.c.

#define SRE_AT   sre_uat

Definition at line 311 of file _sre.c.

#define SRE_CHAR   unsigned char

Definition at line 310 of file _sre.c.

#define SRE_CHAR   Py_UNICODE

Definition at line 310 of file _sre.c.

#define SRE_CHARSET   sre_charset

Definition at line 313 of file _sre.c.

#define SRE_CHARSET   sre_ucharset

Definition at line 313 of file _sre.c.

#define SRE_COUNT   sre_count

Definition at line 312 of file _sre.c.

#define SRE_COUNT   sre_ucount

Definition at line 312 of file _sre.c.

#define SRE_DIGIT_MASK   1

Definition at line 108 of file _sre.c.

#define SRE_ERROR_ILLEGAL   -1 /* illegal opcode */

Definition at line 91 of file _sre.c.

#define SRE_ERROR_INTERRUPTED   -10 /* signal handler raised exception */

Definition at line 95 of file _sre.c.

#define SRE_ERROR_MEMORY   -9 /* out of memory */

Definition at line 94 of file _sre.c.

#define SRE_ERROR_RECURSION_LIMIT   -3 /* runaway recursion */

Definition at line 93 of file _sre.c.

#define SRE_ERROR_STATE   -2 /* illegal state */

Definition at line 92 of file _sre.c.

#define SRE_INFO   sre_info

Definition at line 314 of file _sre.c.

#define SRE_INFO   sre_uinfo

Definition at line 314 of file _sre.c.

#define SRE_IS_ALNUM (   ch)    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)

Definition at line 140 of file _sre.c.

#define SRE_IS_DIGIT (   ch)    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)

Definition at line 134 of file _sre.c.

#define SRE_IS_LINEBREAK (   ch)    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)

Definition at line 138 of file _sre.c.

#define SRE_IS_SPACE (   ch)    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)

Definition at line 136 of file _sre.c.

#define SRE_IS_WORD (   ch)    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)

Definition at line 142 of file _sre.c.

#define SRE_LINEBREAK_MASK   4

Definition at line 110 of file _sre.c.

#define SRE_LITERAL_TEMPLATE   sre_literal_template

Definition at line 318 of file _sre.c.

#define SRE_LITERAL_TEMPLATE   sre_uliteral_template

Definition at line 318 of file _sre.c.

#define SRE_LOC_IS_ALNUM (   ch)    (!((ch) & ~255) ? isalnum((ch)) : 0)

Definition at line 156 of file _sre.c.

#define SRE_LOC_IS_DIGIT (   ch)    (!((ch) & ~255) ? isdigit((ch)) : 0)

Definition at line 153 of file _sre.c.

#define SRE_LOC_IS_LINEBREAK (   ch)    ((ch) == '\n')

Definition at line 155 of file _sre.c.

#define SRE_LOC_IS_SPACE (   ch)    (!((ch) & ~255) ? isspace((ch)) : 0)

Definition at line 154 of file _sre.c.

#define SRE_LOC_IS_WORD (   ch)    (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')

Definition at line 157 of file _sre.c.

#define SRE_MATCH   sre_match

Definition at line 315 of file _sre.c.

#define SRE_MATCH   sre_umatch

Definition at line 315 of file _sre.c.

#define SRE_MATCH_CONTEXT   sre_match_context

Definition at line 316 of file _sre.c.

#define SRE_MATCH_CONTEXT   sre_umatch_context

Definition at line 316 of file _sre.c.

#define SRE_MODULE   "sre"

Definition at line 53 of file _sre.c.

#define SRE_PY_MODULE   "re"

Definition at line 56 of file _sre.c.

#define SRE_RECURSIVE

Definition at line 294 of file _sre.c.

#define SRE_SEARCH   sre_search

Definition at line 317 of file _sre.c.

#define SRE_SEARCH   sre_usearch

Definition at line 317 of file _sre.c.

#define SRE_SPACE_MASK   2

Definition at line 109 of file _sre.c.

#define SRE_UNI_IS_ALNUM (   ch)    Py_UNICODE_ISALNUM((Py_UNICODE)(ch))

Definition at line 171 of file _sre.c.

#define SRE_UNI_IS_DIGIT (   ch)    Py_UNICODE_ISDECIMAL((Py_UNICODE)(ch))

Definition at line 168 of file _sre.c.

Definition at line 170 of file _sre.c.

#define SRE_UNI_IS_SPACE (   ch)    Py_UNICODE_ISSPACE((Py_UNICODE)(ch))

Definition at line 169 of file _sre.c.

#define SRE_UNI_IS_WORD (   ch)    (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_')

Definition at line 172 of file _sre.c.

#define SRE_WORD_MASK   16

Definition at line 112 of file _sre.c.

#define TRACE (   v)

Definition at line 100 of file _sre.c.

#define USE_FAST_SEARCH

Definition at line 68 of file _sre.c.


Function Documentation

static void data_stack_dealloc ( SRE_STATE state) [static]

Definition at line 250 of file _sre.c.

{
    if (state->data_stack) {
        PyMem_FREE(state->data_stack);
        state->data_stack = NULL;
    }
    state->data_stack_size = state->data_stack_base = 0;
}

Here is the caller graph for this function:

static int data_stack_grow ( SRE_STATE state,
Py_ssize_t  size 
) [static]

Definition at line 260 of file _sre.c.

{
    Py_ssize_t minsize, cursize;
    minsize = state->data_stack_base+size;
    cursize = state->data_stack_size;
    if (cursize < minsize) {
        void* stack;
        cursize = minsize+minsize/4+1024;
        TRACE(("allocate/grow stack %d\n", cursize));
        stack = PyMem_REALLOC(state->data_stack, cursize);
        if (!stack) {
            data_stack_dealloc(state);
            return SRE_ERROR_MEMORY;
        }
        state->data_stack = (char *)stack;
        state->data_stack_size = cursize;
    }
    return 0;
}

Here is the call graph for this function:

Definition at line 509 of file _sre.c.

{
    SRE_CODE chr;
    SRE_CHAR* ptr = (SRE_CHAR *)state->ptr;
    SRE_CHAR* end = (SRE_CHAR *)state->end;
    Py_ssize_t i;

    /* adjust end */
    if (maxcount < end - ptr && maxcount != 65535)
        end = ptr + maxcount;

    switch (pattern[0]) {

    case SRE_OP_IN:
        /* repeated set */
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
        while (ptr < end && SRE_CHARSET(pattern + 2, *ptr))
            ptr++;
        break;

    case SRE_OP_ANY:
        /* repeated dot wildcard. */
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
            ptr++;
        break;

    case SRE_OP_ANY_ALL:
        /* repeated dot wildcard.  skip to the end of the target
           string, and backtrack from there */
        TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
        ptr = end;
        break;

    case SRE_OP_LITERAL:
        /* repeated literal */
        chr = pattern[1];
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
        while (ptr < end && (SRE_CODE) *ptr == chr)
            ptr++;
        break;

    case SRE_OP_LITERAL_IGNORE:
        /* repeated literal */
        chr = pattern[1];
        TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
        while (ptr < end && (SRE_CODE) state->lower(*ptr) == chr)
            ptr++;
        break;

    case SRE_OP_NOT_LITERAL:
        /* repeated non-literal */
        chr = pattern[1];
        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
        while (ptr < end && (SRE_CODE) *ptr != chr)
            ptr++;
        break;

    case SRE_OP_NOT_LITERAL_IGNORE:
        /* repeated non-literal */
        chr = pattern[1];
        TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
        while (ptr < end && (SRE_CODE) state->lower(*ptr) != chr)
            ptr++;
        break;

    default:
        /* repeated single character pattern */
        TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
        while ((SRE_CHAR*) state->ptr < end) {
            i = SRE_MATCH(state, pattern);
            if (i < 0)
                return i;
            if (!i)
                break;
        }
        TRACE(("|%p|%p|COUNT %d\n", pattern, ptr,
               (SRE_CHAR*) state->ptr - ptr));
        return (SRE_CHAR*) state->ptr - ptr;
    }

    TRACE(("|%p|%p|COUNT %d\n", pattern, ptr, ptr - (SRE_CHAR*) state->ptr));
    return ptr - (SRE_CHAR*) state->ptr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SRE_AT ( SRE_STATE state,
SRE_CHAR ptr,
SRE_CODE  at 
)

Definition at line 330 of file _sre.c.

{
    /* check if pointer is at given position */

    Py_ssize_t thisp, thatp;

    switch (at) {

    case SRE_AT_BEGINNING:
    case SRE_AT_BEGINNING_STRING:
        return ((void*) ptr == state->beginning);

    case SRE_AT_BEGINNING_LINE:
        return ((void*) ptr == state->beginning ||
                SRE_IS_LINEBREAK((int) ptr[-1]));

    case SRE_AT_END:
        return (((void*) (ptr+1) == state->end &&
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
                ((void*) ptr == state->end));

    case SRE_AT_END_LINE:
        return ((void*) ptr == state->end ||
                SRE_IS_LINEBREAK((int) ptr[0]));

    case SRE_AT_END_STRING:
        return ((void*) ptr == state->end);

    case SRE_AT_BOUNDARY:
        if (state->beginning == state->end)
            return 0;
        thatp = ((void*) ptr > state->beginning) ?
            SRE_IS_WORD((int) ptr[-1]) : 0;
        thisp = ((void*) ptr < state->end) ?
            SRE_IS_WORD((int) ptr[0]) : 0;
        return thisp != thatp;

    case SRE_AT_NON_BOUNDARY:
        if (state->beginning == state->end)
            return 0;
        thatp = ((void*) ptr > state->beginning) ?
            SRE_IS_WORD((int) ptr[-1]) : 0;
        thisp = ((void*) ptr < state->end) ?
            SRE_IS_WORD((int) ptr[0]) : 0;
        return thisp == thatp;

    case SRE_AT_LOC_BOUNDARY:
        if (state->beginning == state->end)
            return 0;
        thatp = ((void*) ptr > state->beginning) ?
            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
        thisp = ((void*) ptr < state->end) ?
            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
        return thisp != thatp;

    case SRE_AT_LOC_NON_BOUNDARY:
        if (state->beginning == state->end)
            return 0;
        thatp = ((void*) ptr > state->beginning) ?
            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
        thisp = ((void*) ptr < state->end) ?
            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
        return thisp == thatp;

#if defined(HAVE_UNICODE)
    case SRE_AT_UNI_BOUNDARY:
        if (state->beginning == state->end)
            return 0;
        thatp = ((void*) ptr > state->beginning) ?
            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
        thisp = ((void*) ptr < state->end) ?
            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
        return thisp != thatp;

    case SRE_AT_UNI_NON_BOUNDARY:
        if (state->beginning == state->end)
            return 0;
        thatp = ((void*) ptr > state->beginning) ?
            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
        thisp = ((void*) ptr < state->end) ?
            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
        return thisp == thatp;
#endif

    }

    return 0;
}
sre_category ( SRE_CODE  category,
unsigned int  ch 
)

Definition at line 182 of file _sre.c.

{
    switch (category) {

    case SRE_CATEGORY_DIGIT:
        return SRE_IS_DIGIT(ch);
    case SRE_CATEGORY_NOT_DIGIT:
        return !SRE_IS_DIGIT(ch);
    case SRE_CATEGORY_SPACE:
        return SRE_IS_SPACE(ch);
    case SRE_CATEGORY_NOT_SPACE:
        return !SRE_IS_SPACE(ch);
    case SRE_CATEGORY_WORD:
        return SRE_IS_WORD(ch);
    case SRE_CATEGORY_NOT_WORD:
        return !SRE_IS_WORD(ch);
    case SRE_CATEGORY_LINEBREAK:
        return SRE_IS_LINEBREAK(ch);
    case SRE_CATEGORY_NOT_LINEBREAK:
        return !SRE_IS_LINEBREAK(ch);

    case SRE_CATEGORY_LOC_WORD:
        return SRE_LOC_IS_WORD(ch);
    case SRE_CATEGORY_LOC_NOT_WORD:
        return !SRE_LOC_IS_WORD(ch);

#if defined(HAVE_UNICODE)
    case SRE_CATEGORY_UNI_DIGIT:
        return SRE_UNI_IS_DIGIT(ch);
    case SRE_CATEGORY_UNI_NOT_DIGIT:
        return !SRE_UNI_IS_DIGIT(ch);
    case SRE_CATEGORY_UNI_SPACE:
        return SRE_UNI_IS_SPACE(ch);
    case SRE_CATEGORY_UNI_NOT_SPACE:
        return !SRE_UNI_IS_SPACE(ch);
    case SRE_CATEGORY_UNI_WORD:
        return SRE_UNI_IS_WORD(ch);
    case SRE_CATEGORY_UNI_NOT_WORD:
        return !SRE_UNI_IS_WORD(ch);
    case SRE_CATEGORY_UNI_LINEBREAK:
        return SRE_UNI_IS_LINEBREAK(ch);
    case SRE_CATEGORY_UNI_NOT_LINEBREAK:
        return !SRE_UNI_IS_LINEBREAK(ch);
#else
    case SRE_CATEGORY_UNI_DIGIT:
        return SRE_IS_DIGIT(ch);
    case SRE_CATEGORY_UNI_NOT_DIGIT:
        return !SRE_IS_DIGIT(ch);
    case SRE_CATEGORY_UNI_SPACE:
        return SRE_IS_SPACE(ch);
    case SRE_CATEGORY_UNI_NOT_SPACE:
        return !SRE_IS_SPACE(ch);
    case SRE_CATEGORY_UNI_WORD:
        return SRE_LOC_IS_WORD(ch);
    case SRE_CATEGORY_UNI_NOT_WORD:
        return !SRE_LOC_IS_WORD(ch);
    case SRE_CATEGORY_UNI_LINEBREAK:
        return SRE_IS_LINEBREAK(ch);
    case SRE_CATEGORY_UNI_NOT_LINEBREAK:
        return !SRE_IS_LINEBREAK(ch);
#endif
    }
    return 0;
}

Here is the caller graph for this function:

SRE_CHARSET ( SRE_CODE set,
SRE_CODE  ch 
)

Definition at line 420 of file _sre.c.

{
    /* check if character is a member of the given set */

    int ok = 1;

    for (;;) {
        switch (*set++) {

        case SRE_OP_FAILURE:
            return !ok;

        case SRE_OP_LITERAL:
            /* <LITERAL> <code> */
            if (ch == set[0])
                return ok;
            set++;
            break;

        case SRE_OP_CATEGORY:
            /* <CATEGORY> <code> */
            if (sre_category(set[0], (int) ch))
                return ok;
            set += 1;
            break;

        case SRE_OP_CHARSET:
            if (sizeof(SRE_CODE) == 2) {
                /* <CHARSET> <bitmap> (16 bits per code word) */
                if (ch < 256 && (set[ch >> 4] & (1 << (ch & 15))))
                    return ok;
                set += 16;
            }
            else {
                /* <CHARSET> <bitmap> (32 bits per code word) */
                if (ch < 256 && (set[ch >> 5] & (1 << (ch & 31))))
                    return ok;
                set += 8;
            }
            break;

        case SRE_OP_RANGE:
            /* <RANGE> <lower> <upper> */
            if (set[0] <= ch && ch <= set[1])
                return ok;
            set += 2;
            break;

        case SRE_OP_NEGATE:
            ok = !ok;
            break;

        case SRE_OP_BIGCHARSET:
            /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
        {
            Py_ssize_t count, block;
            count = *(set++);

            if (sizeof(SRE_CODE) == 2) {
                block = ((unsigned char*)set)[ch >> 8];
                set += 128;
                if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15)))
                    return ok;
                set += count*16;
            }
            else {
                /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
                 * warnings when c's type supports only numbers < N+1 */
                if (!(ch & ~65535))
                    block = ((unsigned char*)set)[ch >> 8];
                else
                    block = -1;
                set += 64;
                if (block >=0 &&
                    (set[block*8 + ((ch & 255)>>5)] & (1 << (ch & 31))))
                    return ok;
                set += count*8;
            }
            break;
        }

        default:
            /* internal error -- there's not much we can do about it
               here, so let's just pretend it didn't match... */
            return 0;
        }
    }
}

Here is the call graph for this function:

Definition at line 1611 of file _sre.c.

{
    /* check if given string is a literal template (i.e. no escapes) */
    while (len-- > 0)
        if (*ptr++ == '\\')
            return 0;
    return 1;
}
static unsigned int sre_lower ( unsigned int  ch) [static]

Definition at line 145 of file _sre.c.

{
    return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch);
}
static unsigned int sre_lower_locale ( unsigned int  ch) [static]

Definition at line 159 of file _sre.c.

{
    return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch);
}
static unsigned int sre_lower_unicode ( unsigned int  ch) [static]

Definition at line 174 of file _sre.c.

{
    return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch));
}
SRE_MATCH ( SRE_STATE state,
SRE_CODE pattern 
)

Definition at line 800 of file _sre.c.

{
    SRE_CHAR* end = (SRE_CHAR *)state->end;
    Py_ssize_t alloc_pos, ctx_pos = -1;
    Py_ssize_t i, ret = 0;
    Py_ssize_t jump;
    unsigned int sigcount=0;

    SRE_MATCH_CONTEXT* ctx;
    SRE_MATCH_CONTEXT* nextctx;

    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));

    DATA_ALLOC(SRE_MATCH_CONTEXT, ctx);
    ctx->last_ctx_pos = -1;
    ctx->jump = JUMP_NONE;
    ctx->pattern = pattern;
    ctx_pos = alloc_pos;

entrance:

    ctx->ptr = (SRE_CHAR *)state->ptr;

    if (ctx->pattern[0] == SRE_OP_INFO) {
        /* optimization info block */
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
        if (ctx->pattern[3] && (end - ctx->ptr) < ctx->pattern[3]) {
            TRACE(("reject (got %d chars, need %d)\n",
                   (end - ctx->ptr), ctx->pattern[3]));
            RETURN_FAILURE;
        }
        ctx->pattern += ctx->pattern[1] + 1;
    }

    for (;;) {
        ++sigcount;
        if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
            RETURN_ERROR(SRE_ERROR_INTERRUPTED);

        switch (*ctx->pattern++) {

        case SRE_OP_MARK:
            /* set mark */
            /* <MARK> <gid> */
            TRACE(("|%p|%p|MARK %d\n", ctx->pattern,
                   ctx->ptr, ctx->pattern[0]));
            i = ctx->pattern[0];
            if (i & 1)
                state->lastindex = i/2 + 1;
            if (i > state->lastmark) {
                /* state->lastmark is the highest valid index in the
                   state->mark array.  If it is increased by more than 1,
                   the intervening marks must be set to NULL to signal
                   that these marks have not been encountered. */
                Py_ssize_t j = state->lastmark + 1;
                while (j < i)
                    state->mark[j++] = NULL;
                state->lastmark = i;
            }
            state->mark[i] = ctx->ptr;
            ctx->pattern++;
            break;

        case SRE_OP_LITERAL:
            /* match literal string */
            /* <LITERAL> <code> */
            TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern,
                   ctx->ptr, *ctx->pattern));
            if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0])
                RETURN_FAILURE;
            ctx->pattern++;
            ctx->ptr++;
            break;

        case SRE_OP_NOT_LITERAL:
            /* match anything that is not literal character */
            /* <NOT_LITERAL> <code> */
            TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern,
                   ctx->ptr, *ctx->pattern));
            if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0])
                RETURN_FAILURE;
            ctx->pattern++;
            ctx->ptr++;
            break;

        case SRE_OP_SUCCESS:
            /* end of pattern */
            TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));
            state->ptr = ctx->ptr;
            RETURN_SUCCESS;

        case SRE_OP_AT:
            /* match at given position */
            /* <AT> <code> */
            TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern));
            if (!SRE_AT(state, ctx->ptr, *ctx->pattern))
                RETURN_FAILURE;
            ctx->pattern++;
            break;

        case SRE_OP_CATEGORY:
            /* match at given category */
            /* <CATEGORY> <code> */
            TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern,
                   ctx->ptr, *ctx->pattern));
            if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0]))
                RETURN_FAILURE;
            ctx->pattern++;
            ctx->ptr++;
            break;

        case SRE_OP_ANY:
            /* match anything (except a newline) */
            /* <ANY> */
            TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr));
            if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0]))
                RETURN_FAILURE;
            ctx->ptr++;
            break;

        case SRE_OP_ANY_ALL:
            /* match anything */
            /* <ANY_ALL> */
            TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr));
            if (ctx->ptr >= end)
                RETURN_FAILURE;
            ctx->ptr++;
            break;

        case SRE_OP_IN:
            /* match set member (or non_member) */
            /* <IN> <skip> <set> */
            TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr));
            if (ctx->ptr >= end || !SRE_CHARSET(ctx->pattern + 1, *ctx->ptr))
                RETURN_FAILURE;
            ctx->pattern += ctx->pattern[0];
            ctx->ptr++;
            break;

        case SRE_OP_LITERAL_IGNORE:
            TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
                   ctx->pattern, ctx->ptr, ctx->pattern[0]));
            if (ctx->ptr >= end ||
                state->lower(*ctx->ptr) != state->lower(*ctx->pattern))
                RETURN_FAILURE;
            ctx->pattern++;
            ctx->ptr++;
            break;

        case SRE_OP_NOT_LITERAL_IGNORE:
            TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
                   ctx->pattern, ctx->ptr, *ctx->pattern));
            if (ctx->ptr >= end ||
                state->lower(*ctx->ptr) == state->lower(*ctx->pattern))
                RETURN_FAILURE;
            ctx->pattern++;
            ctx->ptr++;
            break;

        case SRE_OP_IN_IGNORE:
            TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr));
            if (ctx->ptr >= end
                || !SRE_CHARSET(ctx->pattern+1,
                                (SRE_CODE)state->lower(*ctx->ptr)))
                RETURN_FAILURE;
            ctx->pattern += ctx->pattern[0];
            ctx->ptr++;
            break;

        case SRE_OP_JUMP:
        case SRE_OP_INFO:
            /* jump forward */
            /* <JUMP> <offset> */
            TRACE(("|%p|%p|JUMP %d\n", ctx->pattern,
                   ctx->ptr, ctx->pattern[0]));
            ctx->pattern += ctx->pattern[0];
            break;

        case SRE_OP_BRANCH:
            /* alternation */
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
            TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr));
            LASTMARK_SAVE();
            ctx->u.rep = state->repeat;
            if (ctx->u.rep)
                MARK_PUSH(ctx->lastmark);
            for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) {
                if (ctx->pattern[1] == SRE_OP_LITERAL &&
                    (ctx->ptr >= end ||
                     (SRE_CODE) *ctx->ptr != ctx->pattern[2]))
                    continue;
                if (ctx->pattern[1] == SRE_OP_IN &&
                    (ctx->ptr >= end ||
                     !SRE_CHARSET(ctx->pattern + 3, (SRE_CODE) *ctx->ptr)))
                    continue;
                state->ptr = ctx->ptr;
                DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1);
                if (ret) {
                    if (ctx->u.rep)
                        MARK_POP_DISCARD(ctx->lastmark);
                    RETURN_ON_ERROR(ret);
                    RETURN_SUCCESS;
                }
                if (ctx->u.rep)
                    MARK_POP_KEEP(ctx->lastmark);
                LASTMARK_RESTORE();
            }
            if (ctx->u.rep)
                MARK_POP_DISCARD(ctx->lastmark);
            RETURN_FAILURE;

        case SRE_OP_REPEAT_ONE:
            /* match repeated sequence (maximizing regexp) */

            /* this operator only works if the repeated item is
               exactly one character wide, and we're not already
               collecting backtracking points.  for other cases,
               use the MAX_REPEAT operator */

            /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */

            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
                   ctx->pattern[1], ctx->pattern[2]));

            if (ctx->ptr + ctx->pattern[1] > end)
                RETURN_FAILURE; /* cannot match */

            state->ptr = ctx->ptr;

            ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[2]);
            RETURN_ON_ERROR(ret);
            DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
            ctx->count = ret;
            ctx->ptr += ctx->count;

            /* when we arrive here, count contains the number of
               matches, and ctx->ptr points to the tail of the target
               string.  check if the rest of the pattern matches,
               and backtrack if not. */

            if (ctx->count < (Py_ssize_t) ctx->pattern[1])
                RETURN_FAILURE;

            if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
                /* tail is empty.  we're finished */
                state->ptr = ctx->ptr;
                RETURN_SUCCESS;
            }

            LASTMARK_SAVE();

            if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) {
                /* tail starts with a literal. skip positions where
                   the rest of the pattern cannot possibly match */
                ctx->u.chr = ctx->pattern[ctx->pattern[0]+1];
                for (;;) {
                    while (ctx->count >= (Py_ssize_t) ctx->pattern[1] &&
                           (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) {
                        ctx->ptr--;
                        ctx->count--;
                    }
                    if (ctx->count < (Py_ssize_t) ctx->pattern[1])
                        break;
                    state->ptr = ctx->ptr;
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
                            ctx->pattern+ctx->pattern[0]);
                    if (ret) {
                        RETURN_ON_ERROR(ret);
                        RETURN_SUCCESS;
                    }

                    LASTMARK_RESTORE();

                    ctx->ptr--;
                    ctx->count--;
                }

            } else {
                /* general case */
                while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) {
                    state->ptr = ctx->ptr;
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
                            ctx->pattern+ctx->pattern[0]);
                    if (ret) {
                        RETURN_ON_ERROR(ret);
                        RETURN_SUCCESS;
                    }
                    ctx->ptr--;
                    ctx->count--;
                    LASTMARK_RESTORE();
                }
            }
            RETURN_FAILURE;

        case SRE_OP_MIN_REPEAT_ONE:
            /* match repeated sequence (minimizing regexp) */

            /* this operator only works if the repeated item is
               exactly one character wide, and we're not already
               collecting backtracking points.  for other cases,
               use the MIN_REPEAT operator */

            /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */

            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
                   ctx->pattern[1], ctx->pattern[2]));

            if (ctx->ptr + ctx->pattern[1] > end)
                RETURN_FAILURE; /* cannot match */

            state->ptr = ctx->ptr;

            if (ctx->pattern[1] == 0)
                ctx->count = 0;
            else {
                /* count using pattern min as the maximum */
                ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[1]);
                RETURN_ON_ERROR(ret);
                DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
                if (ret < (Py_ssize_t) ctx->pattern[1])
                    /* didn't match minimum number of times */
                    RETURN_FAILURE;
                /* advance past minimum matches of repeat */
                ctx->count = ret;
                ctx->ptr += ctx->count;
            }

            if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
                /* tail is empty.  we're finished */
                state->ptr = ctx->ptr;
                RETURN_SUCCESS;

            } else {
                /* general case */
                LASTMARK_SAVE();
                while ((Py_ssize_t)ctx->pattern[2] == 65535
                       || ctx->count <= (Py_ssize_t)ctx->pattern[2]) {
                    state->ptr = ctx->ptr;
                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
                            ctx->pattern+ctx->pattern[0]);
                    if (ret) {
                        RETURN_ON_ERROR(ret);
                        RETURN_SUCCESS;
                    }
                    state->ptr = ctx->ptr;
                    ret = SRE_COUNT(state, ctx->pattern+3, 1);
                    RETURN_ON_ERROR(ret);
                    DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
                    if (ret == 0)
                        break;
                    assert(ret == 1);
                    ctx->ptr++;
                    ctx->count++;
                    LASTMARK_RESTORE();
                }
            }
            RETURN_FAILURE;

        case SRE_OP_REPEAT:
            /* create repeat context.  all the hard work is done
               by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
            /* <REPEAT> <skip> <1=min> <2=max> item <UNTIL> tail */
            TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr,
                   ctx->pattern[1], ctx->pattern[2]));

            /* install new repeat context */
            ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
            if (!ctx->u.rep) {
                PyErr_NoMemory();
                RETURN_FAILURE;
            }
            ctx->u.rep->count = -1;
            ctx->u.rep->pattern = ctx->pattern;
            ctx->u.rep->prev = state->repeat;
            ctx->u.rep->last_ptr = NULL;
            state->repeat = ctx->u.rep;

            state->ptr = ctx->ptr;
            DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
            state->repeat = ctx->u.rep->prev;
            PyObject_FREE(ctx->u.rep);

            if (ret) {
                RETURN_ON_ERROR(ret);
                RETURN_SUCCESS;
            }
            RETURN_FAILURE;

        case SRE_OP_MAX_UNTIL:
            /* maximizing repeat */
            /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */

            /* FIXME: we probably need to deal with zero-width
               matches in here... */

            ctx->u.rep = state->repeat;
            if (!ctx->u.rep)
                RETURN_ERROR(SRE_ERROR_STATE);

            state->ptr = ctx->ptr;

            ctx->count = ctx->u.rep->count+1;

            TRACE(("|%p|%p|MAX_UNTIL %d\n", ctx->pattern,
                   ctx->ptr, ctx->count));

            if (ctx->count < ctx->u.rep->pattern[1]) {
                /* not enough matches */
                ctx->u.rep->count = ctx->count;
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
                        ctx->u.rep->pattern+3);
                if (ret) {
                    RETURN_ON_ERROR(ret);
                    RETURN_SUCCESS;
                }
                ctx->u.rep->count = ctx->count-1;
                state->ptr = ctx->ptr;
                RETURN_FAILURE;
            }

            if ((ctx->count < ctx->u.rep->pattern[2] ||
                ctx->u.rep->pattern[2] == 65535) &&
                state->ptr != ctx->u.rep->last_ptr) {
                /* we may have enough matches, but if we can
                   match another item, do so */
                ctx->u.rep->count = ctx->count;
                LASTMARK_SAVE();
                MARK_PUSH(ctx->lastmark);
                /* zero-width match protection */
                DATA_PUSH(&ctx->u.rep->last_ptr);
                ctx->u.rep->last_ptr = state->ptr;
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
                        ctx->u.rep->pattern+3);
                DATA_POP(&ctx->u.rep->last_ptr);
                if (ret) {
                    MARK_POP_DISCARD(ctx->lastmark);
                    RETURN_ON_ERROR(ret);
                    RETURN_SUCCESS;
                }
                MARK_POP(ctx->lastmark);
                LASTMARK_RESTORE();
                ctx->u.rep->count = ctx->count-1;
                state->ptr = ctx->ptr;
            }

            /* cannot match more repeated items here.  make sure the
               tail matches */
            state->repeat = ctx->u.rep->prev;
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern);
            RETURN_ON_SUCCESS(ret);
            state->repeat = ctx->u.rep;
            state->ptr = ctx->ptr;
            RETURN_FAILURE;

        case SRE_OP_MIN_UNTIL:
            /* minimizing repeat */
            /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */

            ctx->u.rep = state->repeat;
            if (!ctx->u.rep)
                RETURN_ERROR(SRE_ERROR_STATE);

            state->ptr = ctx->ptr;

            ctx->count = ctx->u.rep->count+1;

            TRACE(("|%p|%p|MIN_UNTIL %d %p\n", ctx->pattern,
                   ctx->ptr, ctx->count, ctx->u.rep->pattern));

            if (ctx->count < ctx->u.rep->pattern[1]) {
                /* not enough matches */
                ctx->u.rep->count = ctx->count;
                DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
                        ctx->u.rep->pattern+3);
                if (ret) {
                    RETURN_ON_ERROR(ret);
                    RETURN_SUCCESS;
                }
                ctx->u.rep->count = ctx->count-1;
                state->ptr = ctx->ptr;
                RETURN_FAILURE;
            }

            LASTMARK_SAVE();

            /* see if the tail matches */
            state->repeat = ctx->u.rep->prev;
            DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern);
            if (ret) {
                RETURN_ON_ERROR(ret);
                RETURN_SUCCESS;
            }

            state->repeat = ctx->u.rep;
            state->ptr = ctx->ptr;

            LASTMARK_RESTORE();

            if (ctx->count >= ctx->u.rep->pattern[2]
                && ctx->u.rep->pattern[2] != 65535)
                RETURN_FAILURE;

            ctx->u.rep->count = ctx->count;
            DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
                    ctx->u.rep->pattern+3);
            if (ret) {
                RETURN_ON_ERROR(ret);
                RETURN_SUCCESS;
            }
            ctx->u.rep->count = ctx->count-1;
            state->ptr = ctx->ptr;
            RETURN_FAILURE;

        case SRE_OP_GROUPREF:
            /* match backreference */
            TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern,
                   ctx->ptr, ctx->pattern[0]));
            i = ctx->pattern[0];
            {
                Py_ssize_t groupref = i+i;
                if (groupref >= state->lastmark) {
                    RETURN_FAILURE;
                } else {
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
                    if (!p || !e || e < p)
                        RETURN_FAILURE;
                    while (p < e) {
                        if (ctx->ptr >= end || *ctx->ptr != *p)
                            RETURN_FAILURE;
                        p++; ctx->ptr++;
                    }
                }
            }
            ctx->pattern++;
            break;

        case SRE_OP_GROUPREF_IGNORE:
            /* match backreference */
            TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern,
                   ctx->ptr, ctx->pattern[0]));
            i = ctx->pattern[0];
            {
                Py_ssize_t groupref = i+i;
                if (groupref >= state->lastmark) {
                    RETURN_FAILURE;
                } else {
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
                    if (!p || !e || e < p)
                        RETURN_FAILURE;
                    while (p < e) {
                        if (ctx->ptr >= end ||
                            state->lower(*ctx->ptr) != state->lower(*p))
                            RETURN_FAILURE;
                        p++; ctx->ptr++;
                    }
                }
            }
            ctx->pattern++;
            break;

        case SRE_OP_GROUPREF_EXISTS:
            TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern,
                   ctx->ptr, ctx->pattern[0]));
            /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
            i = ctx->pattern[0];
            {
                Py_ssize_t groupref = i+i;
                if (groupref >= state->lastmark) {
                    ctx->pattern += ctx->pattern[1];
                    break;
                } else {
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
                    if (!p || !e || e < p) {
                        ctx->pattern += ctx->pattern[1];
                        break;
                    }
                }
            }
            ctx->pattern += 2;
            break;

        case SRE_OP_ASSERT:
            /* assert subpattern */
            /* <ASSERT> <skip> <back> <pattern> */
            TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern,
                   ctx->ptr, ctx->pattern[1]));
            state->ptr = ctx->ptr - ctx->pattern[1];
            if (state->ptr < state->beginning)
                RETURN_FAILURE;
            DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2);
            RETURN_ON_FAILURE(ret);
            ctx->pattern += ctx->pattern[0];
            break;

        case SRE_OP_ASSERT_NOT:
            /* assert not subpattern */
            /* <ASSERT_NOT> <skip> <back> <pattern> */
            TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern,
                   ctx->ptr, ctx->pattern[1]));
            state->ptr = ctx->ptr - ctx->pattern[1];
            if (state->ptr >= state->beginning) {
                DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
                if (ret) {
                    RETURN_ON_ERROR(ret);
                    RETURN_FAILURE;
                }
            }
            ctx->pattern += ctx->pattern[0];
            break;

        case SRE_OP_FAILURE:
            /* immediate failure */
            TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr));
            RETURN_FAILURE;

        default:
            TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr,
                   ctx->pattern[-1]));
            RETURN_ERROR(SRE_ERROR_ILLEGAL);
        }
    }

exit:
    ctx_pos = ctx->last_ctx_pos;
    jump = ctx->jump;
    DATA_POP_DISCARD(ctx);
    if (ctx_pos == -1)
        return ret;
    DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);

    switch (jump) {
        case JUMP_MAX_UNTIL_2:
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr));
            goto jump_max_until_2;
        case JUMP_MAX_UNTIL_3:
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr));
            goto jump_max_until_3;
        case JUMP_MIN_UNTIL_2:
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr));
            goto jump_min_until_2;
        case JUMP_MIN_UNTIL_3:
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr));
            goto jump_min_until_3;
        case JUMP_BRANCH:
            TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr));
            goto jump_branch;
        case JUMP_MAX_UNTIL_1:
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr));
            goto jump_max_until_1;
        case JUMP_MIN_UNTIL_1:
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr));
            goto jump_min_until_1;
        case JUMP_REPEAT:
            TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr));
            goto jump_repeat;
        case JUMP_REPEAT_ONE_1:
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr));
            goto jump_repeat_one_1;
        case JUMP_REPEAT_ONE_2:
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr));
            goto jump_repeat_one_2;
        case JUMP_MIN_REPEAT_ONE:
            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr));
            goto jump_min_repeat_one;
        case JUMP_ASSERT:
            TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr));
            goto jump_assert;
        case JUMP_ASSERT_NOT:
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr));
            goto jump_assert_not;
        case JUMP_NONE:
            TRACE(("|%p|%p|RETURN %d\n", ctx->pattern, ctx->ptr, ret));
            break;
    }

    return ret; /* should never get here */
}

Here is the call graph for this function:

SRE_SEARCH ( SRE_STATE state,
SRE_CODE pattern 
)

Definition at line 1482 of file _sre.c.

{
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
    SRE_CHAR* end = (SRE_CHAR *)state->end;
    Py_ssize_t status = 0;
    Py_ssize_t prefix_len = 0;
    Py_ssize_t prefix_skip = 0;
    SRE_CODE* prefix = NULL;
    SRE_CODE* charset = NULL;
    SRE_CODE* overlap = NULL;
    int flags = 0;

    if (pattern[0] == SRE_OP_INFO) {
        /* optimization info block */
        /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info>  */

        flags = pattern[2];

        if (pattern[3] > 1) {
            /* adjust end point (but make sure we leave at least one
               character in there, so literal search will work) */
            end -= pattern[3]-1;
            if (end <= ptr)
                end = ptr+1;
        }

        if (flags & SRE_INFO_PREFIX) {
            /* pattern starts with a known prefix */
            /* <length> <skip> <prefix data> <overlap data> */
            prefix_len = pattern[5];
            prefix_skip = pattern[6];
            prefix = pattern + 7;
            overlap = prefix + prefix_len - 1;
        } else if (flags & SRE_INFO_CHARSET)
            /* pattern starts with a character from a known set */
            /* <charset> */
            charset = pattern + 5;

        pattern += 1 + pattern[1];
    }

    TRACE(("prefix = %p %d %d\n", prefix, prefix_len, prefix_skip));
    TRACE(("charset = %p\n", charset));

#if defined(USE_FAST_SEARCH)
    if (prefix_len > 1) {
        /* pattern starts with a known prefix.  use the overlap
           table to skip forward as fast as we possibly can */
        Py_ssize_t i = 0;
        end = (SRE_CHAR *)state->end;
        while (ptr < end) {
            for (;;) {
                if ((SRE_CODE) ptr[0] != prefix[i]) {
                    if (!i)
                        break;
                    else
                        i = overlap[i];
                } else {
                    if (++i == prefix_len) {
                        /* found a potential match */
                        TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));
                        state->start = ptr + 1 - prefix_len;
                        state->ptr = ptr + 1 - prefix_len + prefix_skip;
                        if (flags & SRE_INFO_LITERAL)
                            return 1; /* we got all of it */
                        status = SRE_MATCH(state, pattern + 2*prefix_skip);
                        if (status != 0)
                            return status;
                        /* close but no cigar -- try again */
                        i = overlap[i];
                    }
                    break;
                }
            }
            ptr++;
        }
        return 0;
    }
#endif

    if (pattern[0] == SRE_OP_LITERAL) {
        /* pattern starts with a literal character.  this is used
           for short prefixes, and if fast search is disabled */
        SRE_CODE chr = pattern[1];
        end = (SRE_CHAR *)state->end;
        for (;;) {
            while (ptr < end && (SRE_CODE) ptr[0] != chr)
                ptr++;
            if (ptr >= end)
                return 0;
            TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
            state->start = ptr;
            state->ptr = ++ptr;
            if (flags & SRE_INFO_LITERAL)
                return 1; /* we got all of it */
            status = SRE_MATCH(state, pattern + 2);
            if (status != 0)
                break;
        }
    } else if (charset) {
        /* pattern starts with a character from a known set */
        end = (SRE_CHAR *)state->end;
        for (;;) {
            while (ptr < end && !SRE_CHARSET(charset, ptr[0]))
                ptr++;
            if (ptr >= end)
                return 0;
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
            state->start = ptr;
            state->ptr = ptr;
            status = SRE_MATCH(state, pattern);
            if (status != 0)
                break;
            ptr++;
        }
    } else
        /* general case */
        while (ptr <= end) {
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
            state->start = state->ptr = ptr++;
            status = SRE_MATCH(state, pattern);
            if (status != 0)
                break;
        }

    return status;
}

Here is the call graph for this function:


Variable Documentation

char copyright[] = " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB " [static]

Definition at line 39 of file _sre.c.

char sre_char_info[128] [static]
Initial value:
 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2,
2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0,
0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 }

Definition at line 116 of file _sre.c.

char sre_char_lower[128] [static]
Initial value:
 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127 }

Definition at line 124 of file _sre.c.