⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regexec.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 5 页
字号:
/**********************************************************************  regexec.c -  Oniguruma (regular expression library)**********************************************************************//*- * Copyright (c) 2002-2005  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "regint.h"#ifdef USE_CAPTURE_HISTORYstatic void history_tree_free(OnigCaptureTreeNode* node);static voidhistory_tree_clear(OnigCaptureTreeNode* node){  int i;  if (IS_NOT_NULL(node)) {    for (i = 0; i < node->num_childs; i++) {      if (IS_NOT_NULL(node->childs[i])) {        history_tree_free(node->childs[i]);      }    }    for (i = 0; i < node->allocated; i++) {      node->childs[i] = (OnigCaptureTreeNode* )0;    }    node->num_childs = 0;    node->beg = ONIG_REGION_NOTPOS;    node->end = ONIG_REGION_NOTPOS;    node->group = -1;  }}static voidhistory_tree_free(OnigCaptureTreeNode* node){  history_tree_clear(node);  xfree(node);}static voidhistory_root_free(OnigRegion* r){  if (IS_NOT_NULL(r->history_root)) {    history_tree_free(r->history_root);    r->history_root = (OnigCaptureTreeNode* )0;  }}static OnigCaptureTreeNode*history_node_new(){  OnigCaptureTreeNode* node;  node = (OnigCaptureTreeNode* )xmalloc(sizeof(OnigCaptureTreeNode));  CHECK_NULL_RETURN(node);  node->childs     = (OnigCaptureTreeNode** )0;  node->allocated  = 0;  node->num_childs = 0;  node->group      = -1;  node->beg        = ONIG_REGION_NOTPOS;  node->end        = ONIG_REGION_NOTPOS;  return node;}static inthistory_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child){#define HISTORY_TREE_INIT_ALLOC_SIZE  8  if (parent->num_childs >= parent->allocated) {    int n, i;    if (IS_NULL(parent->childs)) {      n = HISTORY_TREE_INIT_ALLOC_SIZE;      parent->childs =        (OnigCaptureTreeNode** )xmalloc(sizeof(OnigCaptureTreeNode*) * n);    }    else {      n = parent->allocated * 2;      parent->childs =        (OnigCaptureTreeNode** )xrealloc(parent->childs,                                         sizeof(OnigCaptureTreeNode*) * n);    }    CHECK_NULL_RETURN_VAL(parent->childs, ONIGERR_MEMORY);    for (i = parent->allocated; i < n; i++) {      parent->childs[i] = (OnigCaptureTreeNode* )0;    }    parent->allocated = n;  }  parent->childs[parent->num_childs] = child;  parent->num_childs++;  return 0;}static OnigCaptureTreeNode*history_tree_clone(OnigCaptureTreeNode* node){  int i;  OnigCaptureTreeNode *clone, *child;  clone = history_node_new();  CHECK_NULL_RETURN(clone);  clone->beg = node->beg;  clone->end = node->end;  for (i = 0; i < node->num_childs; i++) {    child = history_tree_clone(node->childs[i]);    if (IS_NULL(child)) {      history_tree_free(clone);      return (OnigCaptureTreeNode* )0;    }    history_tree_add_child(clone, child);  }  return clone;}extern  OnigCaptureTreeNode*onig_get_capture_tree(OnigRegion* region){  return region->history_root;}#endif /* USE_CAPTURE_HISTORY */extern voidonig_region_clear(OnigRegion* region){  int i;  for (i = 0; i < region->num_regs; i++) {    region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;  }#ifdef USE_CAPTURE_HISTORY  history_root_free(region);#endif}extern intonig_region_resize(OnigRegion* region, int n){  region->num_regs = n;  if (n < ONIG_NREGION)    n = ONIG_NREGION;  if (region->allocated == 0) {    region->beg = (int* )xmalloc(n * sizeof(int));    region->end = (int* )xmalloc(n * sizeof(int));    if (region->beg == 0 || region->end == 0)      return ONIGERR_MEMORY;    region->allocated = n;  }  else if (region->allocated < n) {    region->beg = (int* )xrealloc(region->beg, n * sizeof(int));    region->end = (int* )xrealloc(region->end, n * sizeof(int));    if (region->beg == 0 || region->end == 0)      return ONIGERR_MEMORY;    region->allocated = n;  }  return 0;}extern intonig_region_resize_clear(OnigRegion* region, int n){  int r;    r = onig_region_resize(region, n);  if (r != 0) return r;  onig_region_clear(region);  return 0;}    extern intonig_region_set(OnigRegion* region, int at, int beg, int end){  if (at < 0) return ONIGERR_INVALID_ARGUMENT;  if (at >= region->allocated) {    int r = onig_region_resize(region, at + 1);    if (r < 0) return r;  }    region->beg[at] = beg;  region->end[at] = end;  return 0;}extern voidonig_region_init(OnigRegion* region){  region->num_regs     = 0;  region->allocated    = 0;  region->beg          = (int* )0;  region->end          = (int* )0;  region->history_root = (OnigCaptureTreeNode* )0;}extern OnigRegion*onig_region_new(){  OnigRegion* r;  r = (OnigRegion* )xmalloc(sizeof(OnigRegion));  onig_region_init(r);  return r;}extern voidonig_region_free(OnigRegion* r, int free_self){  if (r) {    if (r->allocated > 0) {      if (r->beg) xfree(r->beg);      if (r->end) xfree(r->end);      r->allocated = 0;    }#ifdef USE_CAPTURE_HISTORY    history_root_free(r);#endif    if (free_self) xfree(r);  }}extern voidonig_region_copy(OnigRegion* to, OnigRegion* from){#define RREGC_SIZE   (sizeof(int) * from->num_regs)  int i;  if (to == from) return;  if (to->allocated == 0) {    if (from->num_regs > 0) {      to->beg = (int* )xmalloc(RREGC_SIZE);      to->end = (int* )xmalloc(RREGC_SIZE);      to->allocated = from->num_regs;    }  }  else if (to->allocated < from->num_regs) {    to->beg = (int* )xrealloc(to->beg, RREGC_SIZE);    to->end = (int* )xrealloc(to->end, RREGC_SIZE);    to->allocated = from->num_regs;  }  for (i = 0; i < from->num_regs; i++) {    to->beg[i] = from->beg[i];    to->end[i] = from->end[i];  }  to->num_regs = from->num_regs;#ifdef USE_CAPTURE_HISTORY  history_root_free(to);  if (IS_NOT_NULL(from->history_root)) {    to->history_root = history_tree_clone(from->history_root);  }#endif}/** stack **/#define INVALID_STACK_INDEX   -1typedef long StackIndex;typedef struct _StackType {  unsigned int type;  union {    struct {      UChar *pcode;      /* byte code position */      UChar *pstr;       /* string position */      UChar *pstr_prev;  /* previous char position of pstr */    } state;    struct {      int   count;       /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */      UChar *pcode;      /* byte code position (head of repeated target) */      int   num;         /* repeat id */    } repeat;    struct {      StackIndex si;     /* index of stack */    } repeat_inc;    struct {      int num;           /* memory num */      UChar *pstr;       /* start/end position */      /* Following information is setted, if this stack type is MEM-START */      StackIndex start;  /* prev. info (for backtrack  "(...)*" ) */      StackIndex end;    /* prev. info (for backtrack  "(...)*" ) */    } mem;    struct {      int num;           /* null check id */      UChar *pstr;       /* start position */    } null_check;#ifdef USE_SUBEXP_CALL    struct {      UChar *ret_addr;   /* byte code position */      int    num;        /* null check id */      UChar *pstr;       /* string position */    } call_frame;#endif  } u;} StackType;/* stack type *//* used by normal-POP */#define STK_ALT                    0x0001#define STK_LOOK_BEHIND_NOT        0x0003#define STK_POS_NOT                0x0005/* avoided by normal-POP, but value should be small */#define STK_NULL_CHECK_START       0x0100/* handled by normal-POP */#define STK_MEM_START              0x0200#define STK_MEM_END                0x0300#define STK_REPEAT_INC             0x0400/* avoided by normal-POP */#define STK_POS                    0x0500  /* used when POP-POS */#define STK_STOP_BT                0x0600  /* mark for "(?>...)" */#define STK_REPEAT                 0x0700#define STK_CALL_FRAME             0x0800#define STK_RETURN                 0x0900#define STK_MEM_END_MARK           0x0a00#define STK_VOID                   0x0b00  /* for fill a blank */#define STK_NULL_CHECK_END         0x0c00  /* for recursive call *//* stack type check mask */#define STK_MASK_POP_USED     0x00ff#define IS_TO_VOID_TARGET(stk) \     (((stk)->type & STK_MASK_POP_USED) || (stk)->type == STK_NULL_CHECK_START)typedef struct {  void* stack_p;  int   stack_n;  OnigOptionType options;  OnigRegion*    region;  const UChar* start;   /* search start position (for \G: BEGIN_POSITION) */} MatchArg;#define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start) do {\  (msa).stack_p = (void* )0;\  (msa).options = (arg_option);\  (msa).region  = (arg_region);\  (msa).start   = (arg_start);\} while (0)#define MATCH_ARG_FREE(msa)   if ((msa).stack_p) xfree((msa).stack_p)#define STACK_INIT(alloc_addr, ptr_num, stack_num)  do {\  if (msa->stack_p) {\    alloc_addr = (char* )xalloca(sizeof(char*) * (ptr_num));\    stk_alloc  = (StackType* )(msa->stack_p);\    stk_base   = stk_alloc;\    stk        = stk_base;\    stk_end    = stk_base + msa->stack_n;\  }\  else {\    alloc_addr = (char* )xalloca(sizeof(char*) * (ptr_num)\		       + sizeof(StackType) * (stack_num));\    stk_alloc  = (StackType* )(alloc_addr + sizeof(char*) * (ptr_num));\    stk_base   = stk_alloc;\    stk        = stk_base;\    stk_end    = stk_base + (stack_num);\  }\} while(0)#define STACK_SAVE do{\  if (stk_base != stk_alloc) {\    msa->stack_p = stk_base;\    msa->stack_n = stk_end - stk_base;\  };\} while(0)static unsigned int MatchStackLimitSize = DEFAULT_MATCH_STACK_LIMIT_SIZE;extern unsigned intonig_get_match_stack_limit_size(void){  return MatchStackLimitSize;}extern intonig_set_match_stack_limit_size(unsigned int size){  MatchStackLimitSize = size;  return 0;}static intstack_double(StackType** arg_stk_base, StackType** arg_stk_end,	     StackType** arg_stk, StackType* stk_alloc, MatchArg* msa){  unsigned int n;  StackType *x, *stk_base, *stk_end, *stk;  stk_base = *arg_stk_base;  stk_end  = *arg_stk_end;  stk      = *arg_stk;  n = stk_end - stk_base;  if (stk_base == stk_alloc && IS_NULL(msa->stack_p)) {    x = (StackType* )xmalloc(sizeof(StackType) * n * 2);    if (IS_NULL(x)) {      STACK_SAVE;      return ONIGERR_MEMORY;    }    xmemcpy(x, stk_base, n * sizeof(StackType));    n *= 2;  }  else {    n *= 2;    if (MatchStackLimitSize != 0 && n > MatchStackLimitSize) {      if ((unsigned int )(stk_end - stk_base) == MatchStackLimitSize)        return ONIGERR_MATCH_STACK_LIMIT_OVER;      else        n = MatchStackLimitSize;    }    x = (StackType* )xrealloc(stk_base, sizeof(StackType) * n);    if (IS_NULL(x)) {      STACK_SAVE;      return ONIGERR_MEMORY;    }  }  *arg_stk      = x + (stk - stk_base);  *arg_stk_base = x;  *arg_stk_end  = x + n;  return 0;}#define STACK_ENSURE(n)	do {\  if (stk_end - stk < (n)) {\    int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\    if (r != 0) { STACK_SAVE; return r; } \  }\} while(0)#define STACK_AT(index)        (stk_base + (index))#define GET_STACK_INDEX(stk)   ((stk) - stk_base)#define STACK_PUSH(stack_type,pat,s,sprev) do {\  STACK_ENSURE(1);\  stk->type = (stack_type);\  stk->u.state.pcode     = (pat);\  stk->u.state.pstr      = (s);\  stk->u.state.pstr_prev = (sprev);\  STACK_INC;\} while(0)#define STACK_PUSH_ENSURED(stack_type,pat) do {\  stk->type = (stack_type);\  stk->u.state.pcode = (pat);\  STACK_INC;\} while(0)#define STACK_PUSH_TYPE(stack_type) do {\  STACK_ENSURE(1);\  stk->type = (stack_type);\  STACK_INC;\} while(0)#define STACK_PUSH_ALT(pat,s,sprev)     STACK_PUSH(STK_ALT,pat,s,sprev)#define STACK_PUSH_POS(s,sprev)         STACK_PUSH(STK_POS,NULL_UCHARP,s,sprev)#define STACK_PUSH_POS_NOT(pat,s,sprev) STACK_PUSH(STK_POS_NOT,pat,s,sprev)#define STACK_PUSH_STOP_BT              STACK_PUSH_TYPE(STK_STOP_BT)#define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev) \        STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev)#define STACK_PUSH_REPEAT(id, pat) do {\  STACK_ENSURE(1);\  stk->type = STK_REPEAT;\  stk->u.repeat.num    = (id);\  stk->u.repeat.pcode  = (pat);\  stk->u.repeat.count  = 0;\  STACK_INC;\} while(0)#define STACK_PUSH_REPEAT_INC(sindex) do {\  STACK_ENSURE(1);\  stk->type = STK_REPEAT_INC;\  stk->u.repeat_inc.si  = (sindex);\  STACK_INC;\} while(0)#define STACK_PUSH_MEM_START(mnum, s) do {\  STACK_ENSURE(1);\  stk->type = STK_MEM_START;\  stk->u.mem.num      = (mnum);\  stk->u.mem.pstr     = (s);\  stk->u.mem.start    = mem_start_stk[mnum];\  stk->u.mem.end      = mem_end_stk[mnum];\  mem_start_stk[mnum] = GET_STACK_INDEX(stk);\  mem_end_stk[mnum]   = INVALID_STACK_INDEX;\  STACK_INC;\} while(0)#define STACK_PUSH_MEM_END(mnum, s) do {\  STACK_ENSURE(1);\  stk->type = STK_MEM_END;\  stk->u.mem.num    = (mnum);\  stk->u.mem.pstr   = (s);\  stk->u.mem.start  = mem_start_stk[mnum];\  stk->u.mem.end    = mem_end_stk[mnum];\  mem_end_stk[mnum] = GET_STACK_INDEX(stk);\  STACK_INC;\} while(0)#define STACK_PUSH_MEM_END_MARK(mnum) do {\  STACK_ENSURE(1);\  stk->type = STK_MEM_END_MARK;\  stk->u.mem.num = (mnum);\  STACK_INC;\} while(0)#define STACK_GET_MEM_START(mnum, k) do {\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -