Back to index

php5  5.3.10
Classes | Defines | Functions | Variables
regcomp.c File Reference
#include "regparse.h"

Go to the source code of this file.

Classes

struct  MinMaxLen
struct  OptEnv
struct  OptAncInfo
struct  OptExactInfo
struct  OptMapInfo
struct  NodeOptInfo

Defines

#define IS_NEED_STR_LEN_OP_EXACT(op)
#define REPEAT_RANGE_ALLOC   4
#define QUANTIFIER_EXPAND_LIMIT_SIZE   50
#define CKN_ON   (ckn > 0)
#define GET_CHAR_LEN_VARLEN   -1
#define GET_CHAR_LEN_TOP_ALT_VARLEN   -2
#define RECURSION_EXIST   1
#define RECURSION_INFINITE   2
#define FOUND_CALLED_NODE   1
#define CEC_THRES_NUM_BIG_REPEAT   512
#define CEC_INFINITE_NUM   0x7fffffff
#define CEC_IN_INFINITE_REPEAT   (1<<0)
#define CEC_IN_FINITE_REPEAT   (1<<1)
#define CEC_CONT_BIG_REPEAT   (1<<2)
#define IN_ALT   (1<<0)
#define IN_NOT   (1<<1)
#define IN_REPEAT   (1<<2)
#define IN_VAR_REPEAT   (1<<3)
#define EXPAND_STRING_MAX_LENGTH   100
#define ALLOWED_TYPE_IN_LB
#define ALLOWED_EFFECT_IN_LB   ( EFFECT_MEMORY )
#define ALLOWED_EFFECT_IN_LB_NOT   0
#define ALLOWED_ANCHOR_IN_LB   ( ANCHOR_LOOK_BEHIND | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION )
#define ALLOWED_ANCHOR_IN_LB_NOT   ( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION )
#define OPT_EXACT_MAXLEN   24
#define COMP_EM_BASE   20
#define MAX_NODE_OPT_INFO_REF_COUNT   5
#define REGEX_TRANSFER(to, from)
#define REGEX_CHAIN_HEAD(reg)
#define COMPILE_INIT_SIZE   20

Functions

OnigAmbigType onig_get_default_ambig_flag (void)
int onig_set_default_ambig_flag (OnigAmbigType ambig_flag)
static UChark_strdup (UChar *s, UChar *end)
static void swap_node (Node *a, Node *b)
static OnigDistance distance_add (OnigDistance d1, OnigDistance d2)
static OnigDistance distance_multiply (OnigDistance d, int m)
static int bitset_is_empty (BitSetRef bs)
int onig_bbuf_init (BBuf *buf, int size)
static int unset_addr_list_init (UnsetAddrList *uslist, int size)
static void unset_addr_list_end (UnsetAddrList *uslist)
static int unset_addr_list_add (UnsetAddrList *uslist, int offset, struct _Node *node)
static int add_opcode (regex_t *reg, int opcode)
static int add_state_check_num (regex_t *reg, int num)
static int add_rel_addr (regex_t *reg, int addr)
static int add_abs_addr (regex_t *reg, int addr)
static int add_length (regex_t *reg, int len)
static int add_mem_num (regex_t *reg, int num)
static int add_pointer (regex_t *reg, void *addr)
static int add_option (regex_t *reg, OnigOptionType option)
static int add_opcode_rel_addr (regex_t *reg, int opcode, int addr)
static int add_bytes (regex_t *reg, UChar *bytes, int len)
static int add_bitset (regex_t *reg, BitSetRef bs)
static int add_opcode_option (regex_t *reg, int opcode, OnigOptionType option)
static int compile_length_tree (Node *node, regex_t *reg)
static int compile_tree (Node *node, regex_t *reg)
static int select_str_opcode (int mb_len, int str_len, int ignore_case)
static int compile_tree_empty_check (Node *node, regex_t *reg, int empty_info)
static int compile_call (CallNode *node, regex_t *reg)
static int compile_tree_n_times (Node *node, int n, regex_t *reg)
static int add_compile_string_length (UChar *s, int mb_len, int str_len, regex_t *reg, int ignore_case)
static int add_compile_string (UChar *s, int mb_len, int str_len, regex_t *reg, int ignore_case)
static int compile_length_string_node (Node *node, regex_t *reg)
static int compile_length_string_raw_node (StrNode *sn, regex_t *reg)
static int compile_string_node (Node *node, regex_t *reg)
static int compile_string_raw_node (StrNode *sn, regex_t *reg)
static int add_multi_byte_cclass (BBuf *mbuf, regex_t *reg)
static int compile_length_cclass_node (CClassNode *cc, regex_t *reg)
static int compile_cclass_node (CClassNode *cc, regex_t *reg)
static int entry_repeat_range (regex_t *reg, int id, int lower, int upper)
static int compile_range_repeat_node (QuantifierNode *qn, int target_len, int empty_info, regex_t *reg)
static int is_anychar_star_quantifier (QuantifierNode *qn)
static int compile_length_quantifier_node (QuantifierNode *qn, regex_t *reg)
static int compile_quantifier_node (QuantifierNode *qn, regex_t *reg)
static int compile_length_option_node (EffectNode *node, regex_t *reg)
static int compile_option_node (EffectNode *node, regex_t *reg)
static int compile_length_effect_node (EffectNode *node, regex_t *reg)
static int get_char_length_tree (Node *node, regex_t *reg, int *len)
static int compile_effect_node (EffectNode *node, regex_t *reg)
static int compile_length_anchor_node (AnchorNode *node, regex_t *reg)
static int compile_anchor_node (AnchorNode *node, regex_t *reg)
static int noname_disable_map (Node **plink, GroupNumRemap *map, int *counter)
static int renumber_node_backref (Node *node, GroupNumRemap *map)
static int renumber_by_map (Node *node, GroupNumRemap *map)
static int numbered_ref_check (Node *node)
static int disable_noname_group_capture (Node **root, regex_t *reg, ScanEnv *env)
static int unset_addr_list_fix (UnsetAddrList *uslist, regex_t *reg)
static int quantifiers_memory_node_info (Node *node)
static int get_min_match_length (Node *node, OnigDistance *min, ScanEnv *env)
static int get_max_match_length (Node *node, OnigDistance *max, ScanEnv *env)
static int get_char_length_tree1 (Node *node, regex_t *reg, int *len, int level)
static int is_not_included (Node *x, Node *y, regex_t *reg)
static Nodeget_head_value_node (Node *node, int exact, regex_t *reg)
static int check_type_tree (Node *node, int type_mask, int effect_mask, int anchor_mask)
static int subexp_inf_recursive_check (Node *node, ScanEnv *env, int head)
static int subexp_inf_recursive_check_trav (Node *node, ScanEnv *env)
static int subexp_recursive_check (Node *node)
static int subexp_recursive_check_trav (Node *node, ScanEnv *env)
static int setup_subexp_call (Node *node, ScanEnv *env)
static int divide_look_behind_alternatives (Node *node)
static int setup_look_behind (Node *node, regex_t *reg, ScanEnv *env)
static int next_setup (Node *node, Node *next_node, regex_t *reg)
static int divide_ambig_string_node_sub (regex_t *reg, int prev_ambig, UChar *prev_start, UChar *prev, UChar *end, Node ***tailp, Node **root)
static int divide_ambig_string_node (Node *node, regex_t *reg)
static int setup_comb_exp_check (Node *node, int state, ScanEnv *env)
static int setup_tree (Node *node, regex_t *reg, int state, ScanEnv *env)
static int set_bm_skip (UChar *s, UChar *end, OnigEncoding enc, UChar skip[], int **int_skip)
static int map_position_value (OnigEncoding enc, int i)
static int distance_value (MinMaxLen *mm)
static int comp_distance_value (MinMaxLen *d1, MinMaxLen *d2, int v1, int v2)
static int is_equal_mml (MinMaxLen *a, MinMaxLen *b)
static void set_mml (MinMaxLen *mml, OnigDistance min, OnigDistance max)
static void clear_mml (MinMaxLen *mml)
static void copy_mml (MinMaxLen *to, MinMaxLen *from)
static void add_mml (MinMaxLen *to, MinMaxLen *from)
static void alt_merge_mml (MinMaxLen *to, MinMaxLen *from)
static void copy_opt_env (OptEnv *to, OptEnv *from)
static void clear_opt_anc_info (OptAncInfo *anc)
static void copy_opt_anc_info (OptAncInfo *to, OptAncInfo *from)
static void concat_opt_anc_info (OptAncInfo *to, OptAncInfo *left, OptAncInfo *right, OnigDistance left_len, OnigDistance right_len)
static int is_left_anchor (int anc)
static int is_set_opt_anc_info (OptAncInfo *to, int anc)
static void add_opt_anc_info (OptAncInfo *to, int anc)
static void remove_opt_anc_info (OptAncInfo *to, int anc)
static void alt_merge_opt_anc_info (OptAncInfo *to, OptAncInfo *add)
static int is_full_opt_exact_info (OptExactInfo *ex)
static void clear_opt_exact_info (OptExactInfo *ex)
static void copy_opt_exact_info (OptExactInfo *to, OptExactInfo *from)
static void concat_opt_exact_info (OptExactInfo *to, OptExactInfo *add, OnigEncoding enc)
static void concat_opt_exact_info_str (OptExactInfo *to, UChar *s, UChar *end, int raw, OnigEncoding enc)
static void alt_merge_opt_exact_info (OptExactInfo *to, OptExactInfo *add, OptEnv *env)
static void select_opt_exact_info (OnigEncoding enc, OptExactInfo *now, OptExactInfo *alt)
static void clear_opt_map_info (OptMapInfo *map)
static void copy_opt_map_info (OptMapInfo *to, OptMapInfo *from)
static void add_char_opt_map_info (OptMapInfo *map, UChar c, OnigEncoding enc)
static int add_char_amb_opt_map_info (OptMapInfo *map, UChar *p, UChar *end, OnigEncoding enc, OnigAmbigType ambig_flag)
static void select_opt_map_info (OptMapInfo *now, OptMapInfo *alt)
static int comp_opt_exact_or_map_info (OptExactInfo *e, OptMapInfo *m)
static void alt_merge_opt_map_info (OnigEncoding enc, OptMapInfo *to, OptMapInfo *add)
static void set_bound_node_opt_info (NodeOptInfo *opt, MinMaxLen *mmd)
static void clear_node_opt_info (NodeOptInfo *opt)
static void copy_node_opt_info (NodeOptInfo *to, NodeOptInfo *from)
static void concat_left_node_opt_info (OnigEncoding enc, NodeOptInfo *to, NodeOptInfo *add)
static void alt_merge_node_opt_info (NodeOptInfo *to, NodeOptInfo *add, OptEnv *env)
static int optimize_node_left (Node *node, NodeOptInfo *opt, OptEnv *env)
static int set_optimize_exact_info (regex_t *reg, OptExactInfo *e)
static void set_optimize_map_info (regex_t *reg, OptMapInfo *m)
static void set_sub_anchor (regex_t *reg, OptAncInfo *anc)
static int set_optimize_info_from_tree (Node *node, regex_t *reg, ScanEnv *scan_env)
static void clear_optimize_info (regex_t *reg)
static void onig_free_body (regex_t *reg)
void onig_free (regex_t *reg)
void onig_transfer (regex_t *to, regex_t *from)
void onig_chain_link_add (regex_t *to, regex_t *add)
void onig_chain_reduce (regex_t *reg)
int onig_compile (regex_t *reg, const UChar *pattern, const UChar *pattern_end, OnigErrorInfo *einfo)
int onig_alloc_init (regex_t **reg, OnigOptionType option, OnigAmbigType ambig_flag, OnigEncoding enc, OnigSyntaxType *syntax)
int onig_new (regex_t **reg, const UChar *pattern, const UChar *pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType *syntax, OnigErrorInfo *einfo)
int onig_init (void)
int onig_end (void)

Variables

OnigAmbigType OnigDefaultAmbigFlag
static int onig_inited = 0

Class Documentation

struct MinMaxLen

Definition at line 3719 of file regcomp.c.

Class Members
OnigDistance max
OnigDistance min
struct OptEnv

Definition at line 3724 of file regcomp.c.

Collaboration diagram for OptEnv:
Class Members
OnigAmbigType ambig_flag
OnigEncoding enc
MinMaxLen mmd
OnigOptionType options
ScanEnv * scan_env
struct OptAncInfo

Definition at line 3732 of file regcomp.c.

Class Members
int left_anchor
int right_anchor
struct OptExactInfo

Definition at line 3737 of file regcomp.c.

Collaboration diagram for OptExactInfo:
Class Members
OptAncInfo anc
int ignore_case
int len
MinMaxLen mmd
int reach_end
UChar s
struct OptMapInfo

Definition at line 3747 of file regcomp.c.

Collaboration diagram for OptMapInfo:
Class Members
OptAncInfo anc
UChar map
MinMaxLen mmd
int value
struct NodeOptInfo

Definition at line 3755 of file regcomp.c.

Collaboration diagram for NodeOptInfo:
Class Members
OptAncInfo anc
OptExactInfo exb
OptExactInfo exm
OptExactInfo expr
MinMaxLen len
OptMapInfo map

Define Documentation

#define ALLOWED_EFFECT_IN_LB_NOT   0
Value:
#define CEC_CONT_BIG_REPEAT   (1<<2)

Definition at line 3298 of file regcomp.c.

#define CEC_IN_FINITE_REPEAT   (1<<1)

Definition at line 3297 of file regcomp.c.

#define CEC_IN_INFINITE_REPEAT   (1<<0)

Definition at line 3296 of file regcomp.c.

#define CEC_INFINITE_NUM   0x7fffffff

Definition at line 3294 of file regcomp.c.

#define CEC_THRES_NUM_BIG_REPEAT   512

Definition at line 3293 of file regcomp.c.

#define CKN_ON   (ckn > 0)

Definition at line 707 of file regcomp.c.

#define COMP_EM_BASE   20
#define COMPILE_INIT_SIZE   20
#define EXPAND_STRING_MAX_LENGTH   100
#define FOUND_CALLED_NODE   1
#define GET_CHAR_LEN_TOP_ALT_VARLEN   -2

Definition at line 2255 of file regcomp.c.

#define GET_CHAR_LEN_VARLEN   -1

Definition at line 2254 of file regcomp.c.

#define IN_ALT   (1<<0)

Definition at line 3431 of file regcomp.c.

#define IN_NOT   (1<<1)

Definition at line 3432 of file regcomp.c.

#define IN_REPEAT   (1<<2)

Definition at line 3433 of file regcomp.c.

#define IN_VAR_REPEAT   (1<<3)

Definition at line 3434 of file regcomp.c.

#define IS_NEED_STR_LEN_OP_EXACT (   op)
Value:
((op) == OP_EXACTN    || (op) == OP_EXACTMB2N ||\
    (op) == OP_EXACTMB3N || (op) == OP_EXACTMBN  || (op) == OP_EXACTN_IC)

Definition at line 288 of file regcomp.c.

Definition at line 4331 of file regcomp.c.

#define OPT_EXACT_MAXLEN   24

Definition at line 3717 of file regcomp.c.

Definition at line 706 of file regcomp.c.

#define RECURSION_EXIST   1

Definition at line 2720 of file regcomp.c.

#define RECURSION_INFINITE   2

Definition at line 2721 of file regcomp.c.

#define REGEX_CHAIN_HEAD (   reg)
Value:
do {\
  while (IS_NOT_NULL((reg)->chain)) {\
    (reg) = (reg)->chain;\
  }\
} while (0)

Definition at line 5013 of file regcomp.c.

#define REGEX_TRANSFER (   to,
  from 
)
Value:
do {\
  (to)->state = ONIG_STATE_MODIFY;\
  onig_free_body(to);\
  xmemcpy(to, from, sizeof(regex_t));\
  xfree(from);\
} while (0)

Definition at line 4998 of file regcomp.c.

#define REPEAT_RANGE_ALLOC   4

Function Documentation

static int add_abs_addr ( regex_t reg,
int  addr 
) [static]

Definition at line 206 of file regcomp.c.

{
  AbsAddrType ra = (AbsAddrType )addr;

  BBUF_ADD(reg, &ra, SIZE_ABSADDR);
  return 0;
}

Here is the caller graph for this function:

static int add_bitset ( regex_t reg,
BitSetRef  bs 
) [static]

Definition at line 267 of file regcomp.c.

{
  BBUF_ADD(reg, bs, SIZE_BITSET);
  return 0;
}

Here is the caller graph for this function:

static int add_bytes ( regex_t reg,
UChar bytes,
int  len 
) [static]

Definition at line 260 of file regcomp.c.

{
  BBUF_ADD(reg, bytes, len);
  return 0;
}

Here is the caller graph for this function:

static int add_char_amb_opt_map_info ( OptMapInfo map,
UChar p,
UChar end,
OnigEncoding  enc,
OnigAmbigType  ambig_flag 
) [static]

Definition at line 4148 of file regcomp.c.

{
  int i, n, len;
  UChar buf[ONIGENC_MBC_NORMALIZE_MAXLEN];
  OnigCodePoint code;
  const OnigPairAmbigCodes* pccs;
  OnigAmbigType amb;

  add_char_opt_map_info(map, p[0], enc);
  code = ONIGENC_MBC_TO_CODE(enc, p, end);

  for (amb = 0x01; amb <= ONIGENC_AMBIGUOUS_MATCH_LIMIT; amb <<= 1) {
    if ((amb & ambig_flag) == 0)  continue;

    n = ONIGENC_GET_ALL_PAIR_AMBIG_CODES(enc, amb, &pccs);
    for (i = 0; i < n; i++) {
      if (pccs[i].from == code) {
        len = ONIGENC_CODE_TO_MBC(enc, pccs[i].to, buf);
        if (len < 0) return len;
        add_char_opt_map_info(map, buf[0], enc);
      }
    }
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void add_char_opt_map_info ( OptMapInfo map,
UChar  c,
OnigEncoding  enc 
) [static]

Definition at line 4139 of file regcomp.c.

{
  if (map->map[c] == 0) {
    map->map[c] = 1;
    map->value += map_position_value(enc, c);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int add_compile_string ( UChar s,
int  mb_len,
int  str_len,
regex_t reg,
int  ignore_case 
) [static]

Definition at line 414 of file regcomp.c.

{
  int op = select_str_opcode(mb_len, str_len, ignore_case);
  add_opcode(reg, op);

  if (op == OP_EXACTMBN)
    add_length(reg, mb_len);

  if (IS_NEED_STR_LEN_OP_EXACT(op)) {
    if (op == OP_EXACTN_IC)
      add_length(reg, mb_len * str_len);
    else
      add_length(reg, str_len);
  }

  add_bytes(reg, s, mb_len * str_len);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int add_compile_string_length ( UChar s,
int  mb_len,
int  str_len,
regex_t reg,
int  ignore_case 
) [static]

Definition at line 397 of file regcomp.c.

{
  int len;
  int op = select_str_opcode(mb_len, str_len, ignore_case);

  len = SIZE_OPCODE;

  if (op == OP_EXACTMBN)  len += SIZE_LENGTH;
  if (IS_NEED_STR_LEN_OP_EXACT(op))
    len += SIZE_LENGTH;

  len += mb_len * str_len;
  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int add_length ( regex_t reg,
int  len 
) [static]

Definition at line 215 of file regcomp.c.

{
  LengthType l = (LengthType )len;

  BBUF_ADD(reg, &l, SIZE_LENGTH);
  return 0;
}

Here is the caller graph for this function:

static int add_mem_num ( regex_t reg,
int  num 
) [static]

Definition at line 224 of file regcomp.c.

{
  MemNumType n = (MemNumType )num;

  BBUF_ADD(reg, &n, SIZE_MEMNUM);
  return 0;
}

Here is the caller graph for this function:

static void add_mml ( MinMaxLen to,
MinMaxLen from 
) [static]

Definition at line 3865 of file regcomp.c.

{
  to->min = distance_add(to->min, from->min);
  to->max = distance_add(to->max, from->max);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int add_multi_byte_cclass ( BBuf mbuf,
regex_t reg 
) [static]

Definition at line 532 of file regcomp.c.

{
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
  add_length(reg, mbuf->used);
  return add_bytes(reg, mbuf->p, mbuf->used);
#else
  static unsigned char PadBuf[WORD_ALIGNMENT_SIZE];

  int r, pad_size;
  UChar* p = BBUF_GET_ADD_ADDRESS(reg) + SIZE_LENGTH;

  GET_ALIGNMENT_PAD_SIZE(p, pad_size);
  add_length(reg, mbuf->used + (WORD_ALIGNMENT_SIZE - 1));
  if (pad_size != 0) add_bytes(reg, PadBuf, pad_size);

  r = add_bytes(reg, mbuf->p, mbuf->used);

  /* padding for return value from compile_length_cclass_node() to be fix. */
  pad_size = (WORD_ALIGNMENT_SIZE - 1) - pad_size;
  if (pad_size != 0) add_bytes(reg, PadBuf, pad_size);
  return r;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int add_opcode ( regex_t reg,
int  opcode 
) [static]

Definition at line 179 of file regcomp.c.

{
  BBUF_ADD1(reg, opcode);
  return 0;
}

Here is the caller graph for this function:

static int add_opcode_option ( regex_t reg,
int  opcode,
OnigOptionType  option 
) [static]

Definition at line 274 of file regcomp.c.

{
  int r;

  r = add_opcode(reg, opcode);
  if (r) return r;
  r = add_option(reg, option);
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int add_opcode_rel_addr ( regex_t reg,
int  opcode,
int  addr 
) [static]

Definition at line 249 of file regcomp.c.

{
  int r;

  r = add_opcode(reg, opcode);
  if (r) return r;
  r = add_rel_addr(reg, addr);
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void add_opt_anc_info ( OptAncInfo to,
int  anc 
) [static]

Definition at line 3943 of file regcomp.c.

{
  if (is_left_anchor(anc))
    to->left_anchor |= anc;
  else
    to->right_anchor |= anc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int add_option ( regex_t reg,
OnigOptionType  option 
) [static]

Definition at line 242 of file regcomp.c.

{
  BBUF_ADD(reg, &option, SIZE_OPTION);
  return 0;
}

Here is the caller graph for this function:

static int add_pointer ( regex_t reg,
void *  addr 
) [static]

Definition at line 233 of file regcomp.c.

{
  PointerType ptr = (PointerType )addr;

  BBUF_ADD(reg, &ptr, SIZE_POINTER);
  return 0;
}

Here is the caller graph for this function:

static int add_rel_addr ( regex_t reg,
int  addr 
) [static]

Definition at line 197 of file regcomp.c.

{
  RelAddrType ra = (RelAddrType )addr;

  BBUF_ADD(reg, &ra, SIZE_RELADDR);
  return 0;
}

Here is the caller graph for this function:

static int add_state_check_num ( regex_t reg,
int  num 
) [static]

Definition at line 187 of file regcomp.c.

Here is the caller graph for this function:

static void alt_merge_mml ( MinMaxLen to,
MinMaxLen from 
) [static]

Definition at line 3881 of file regcomp.c.

{
  if (to->min > from->min) to->min = from->min;
  if (to->max < from->max) to->max = from->max;
}

Here is the caller graph for this function:

static void alt_merge_node_opt_info ( NodeOptInfo to,
NodeOptInfo add,
OptEnv env 
) [static]

Definition at line 4319 of file regcomp.c.

{
  alt_merge_opt_anc_info  (&to->anc,  &add->anc);
  alt_merge_opt_exact_info(&to->exb,  &add->exb, env);
  alt_merge_opt_exact_info(&to->exm,  &add->exm, env);
  alt_merge_opt_exact_info(&to->expr, &add->expr, env);
  alt_merge_opt_map_info(env->enc, &to->map,  &add->map);

  alt_merge_mml(&to->len, &add->len);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void alt_merge_opt_anc_info ( OptAncInfo to,
OptAncInfo add 
) [static]

Definition at line 3961 of file regcomp.c.

{
  to->left_anchor  &= add->left_anchor;
  to->right_anchor &= add->right_anchor;
}

Here is the caller graph for this function:

static void alt_merge_opt_exact_info ( OptExactInfo to,
OptExactInfo add,
OptEnv env 
) [static]

Definition at line 4038 of file regcomp.c.

{
  int i, j, len;

  if (add->len == 0 || to->len == 0) {
    clear_opt_exact_info(to);
    return ;
  }

  if (! is_equal_mml(&to->mmd, &add->mmd)) {
    clear_opt_exact_info(to);
    return ;
  }

  for (i = 0; i < to->len && i < add->len; ) {
    if (to->s[i] != add->s[i]) break;
    len = enc_len(env->enc, to->s + i);

    for (j = 1; j < len; j++) {
      if (to->s[i+j] != add->s[i+j]) break;
    }
    if (j < len) break;
    i += len;
  }

  if (! add->reach_end || i < add->len || i < to->len) {
    to->reach_end = 0;
  }
  to->len = i;
  to->ignore_case |= add->ignore_case;

  alt_merge_opt_anc_info(&to->anc, &add->anc);
  if (! to->reach_end) to->anc.right_anchor = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void alt_merge_opt_map_info ( OnigEncoding  enc,
OptMapInfo to,
OptMapInfo add 
) [static]

Definition at line 4208 of file regcomp.c.

{
  int i, val;

  /* if (! is_equal_mml(&to->mmd, &add->mmd)) return ; */
  if (to->value == 0) return ;
  if (add->value == 0 || to->mmd.max < add->mmd.min) {
    clear_opt_map_info(to);
    return ;
  }

  alt_merge_mml(&to->mmd, &add->mmd);

  val = 0;
  for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
    if (add->map[i])
      to->map[i] = 1;

    if (to->map[i])
      val += map_position_value(enc, i);
  }
  to->value = val;

  alt_merge_opt_anc_info(&to->anc, &add->anc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int bitset_is_empty ( BitSetRef  bs) [static]

Definition at line 99 of file regcomp.c.

{
  int i;
  for (i = 0; i < BITSET_SIZE; i++) {
    if (bs[i] != 0) return 0;
  }
  return 1;
}

Here is the caller graph for this function:

static int check_type_tree ( Node node,
int  type_mask,
int  effect_mask,
int  anchor_mask 
) [static]

Definition at line 2671 of file regcomp.c.

{
  int type, r = 0;

  type = NTYPE(node);
  if ((type & type_mask) == 0)
    return 1;

  switch (type) {
  case N_LIST:
  case N_ALT:
    do {
      r = check_type_tree(NCONS(node).left, type_mask, effect_mask, anchor_mask);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_QUANTIFIER:
    r = check_type_tree(NQUANTIFIER(node).target, type_mask, effect_mask,
                     anchor_mask);
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));
      if ((en->type & effect_mask) == 0)
       return 1;

      r = check_type_tree(en->target, type_mask, effect_mask, anchor_mask);
    }
    break;

  case N_ANCHOR:
    type = NANCHOR(node).type;
    if ((type & anchor_mask) == 0)
      return 1;

    if (NANCHOR(node).target)
      r = check_type_tree(NANCHOR(node).target,
                       type_mask, effect_mask, anchor_mask);
    break;

  default:
    break;
  }
  return r;
}

Here is the caller graph for this function:

static void clear_mml ( MinMaxLen mml) [static]

Definition at line 3852 of file regcomp.c.

{
  mml->min = mml->max = 0;
}

Here is the caller graph for this function:

static void clear_node_opt_info ( NodeOptInfo opt) [static]

Definition at line 4243 of file regcomp.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void clear_opt_anc_info ( OptAncInfo anc) [static]

Definition at line 3894 of file regcomp.c.

{
  anc->left_anchor  = 0;
  anc->right_anchor = 0;
}

Here is the caller graph for this function:

static void clear_opt_exact_info ( OptExactInfo ex) [static]

Definition at line 3974 of file regcomp.c.

{
  clear_mml(&ex->mmd);
  clear_opt_anc_info(&ex->anc);
  ex->reach_end   = 0;
  ex->ignore_case = 0;
  ex->len         = 0;
  ex->s[0]        = '\0';
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void clear_opt_map_info ( OptMapInfo map) [static]

Definition at line 4105 of file regcomp.c.

{
  static const OptMapInfo clean_info = {
    {0, 0}, {0, 0}, 0,
    {
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    }
  };

  xmemcpy(map, &clean_info, sizeof(OptMapInfo));
}

Here is the caller graph for this function:

static void clear_optimize_info ( regex_t reg) [static]

Definition at line 4806 of file regcomp.c.

{
  reg->optimize      = ONIG_OPTIMIZE_NONE;
  reg->anchor        = 0;
  reg->anchor_dmin   = 0;
  reg->anchor_dmax   = 0;
  reg->sub_anchor    = 0;
  reg->exact_end     = (UChar* )NULL;
  reg->threshold_len = 0;
  if (IS_NOT_NULL(reg->exact)) {
    xfree(reg->exact);
    reg->exact = (UChar* )NULL;
  }
}

Here is the caller graph for this function:

static int comp_distance_value ( MinMaxLen d1,
MinMaxLen d2,
int  v1,
int  v2 
) [static]

Definition at line 3821 of file regcomp.c.

{
  if (v2 <= 0) return -1;
  if (v1 <= 0) return  1;

  v1 *= distance_value(d1);
  v2 *= distance_value(d2);

  if (v2 > v1) return  1;
  if (v2 < v1) return -1;

  if (d2->min < d1->min) return  1;
  if (d2->min > d1->min) return -1;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int comp_opt_exact_or_map_info ( OptExactInfo e,
OptMapInfo m 
) [static]

Definition at line 4195 of file regcomp.c.

{
#define COMP_EM_BASE  20
  int ve, vm;

  if (m->value <= 0) return -1;

  ve = COMP_EM_BASE * e->len * (e->ignore_case ? 1 : 2);
  vm = COMP_EM_BASE * 5 * 2 / m->value;
  return comp_distance_value(&e->mmd, &m->mmd, ve, vm);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_anchor_node ( AnchorNode node,
regex_t reg 
) [static]

Definition at line 1385 of file regcomp.c.

{
  int r, len;

  switch (node->type) {
  case ANCHOR_BEGIN_BUF:      r = add_opcode(reg, OP_BEGIN_BUF);      break;
  case ANCHOR_END_BUF:        r = add_opcode(reg, OP_END_BUF);        break;
  case ANCHOR_BEGIN_LINE:     r = add_opcode(reg, OP_BEGIN_LINE);     break;
  case ANCHOR_END_LINE:       r = add_opcode(reg, OP_END_LINE);       break;
  case ANCHOR_SEMI_END_BUF:   r = add_opcode(reg, OP_SEMI_END_BUF);   break;
  case ANCHOR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION); break;

  case ANCHOR_WORD_BOUND:     r = add_opcode(reg, OP_WORD_BOUND);     break;
  case ANCHOR_NOT_WORD_BOUND: r = add_opcode(reg, OP_NOT_WORD_BOUND); break;
#ifdef USE_WORD_BEGIN_END
  case ANCHOR_WORD_BEGIN:     r = add_opcode(reg, OP_WORD_BEGIN);     break;
  case ANCHOR_WORD_END:       r = add_opcode(reg, OP_WORD_END);       break;
#endif

  case ANCHOR_PREC_READ:
    r = add_opcode(reg, OP_PUSH_POS);
    if (r) return r;
    r = compile_tree(node->target, reg);
    if (r) return r;
    r = add_opcode(reg, OP_POP_POS);
    break;

  case ANCHOR_PREC_READ_NOT:
    len = compile_length_tree(node->target, reg);
    if (len < 0) return len;
    r = add_opcode_rel_addr(reg, OP_PUSH_POS_NOT, len + SIZE_OP_FAIL_POS);
    if (r) return r;
    r = compile_tree(node->target, reg);
    if (r) return r;
    r = add_opcode(reg, OP_FAIL_POS);
    break;

  case ANCHOR_LOOK_BEHIND:
    {
      int n;
      r = add_opcode(reg, OP_LOOK_BEHIND);
      if (r) return r;
      if (node->char_len < 0) {
       r = get_char_length_tree(node->target, reg, &n);
       if (r) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
      }
      else
       n = node->char_len;
      r = add_length(reg, n);
      if (r) return r;
      r = compile_tree(node->target, reg);
    }
    break;

  case ANCHOR_LOOK_BEHIND_NOT:
    {
      int n;
      len = compile_length_tree(node->target, reg);
      r = add_opcode_rel_addr(reg, OP_PUSH_LOOK_BEHIND_NOT,
                        len + SIZE_OP_FAIL_LOOK_BEHIND_NOT);
      if (r) return r;
      if (node->char_len < 0) {
       r = get_char_length_tree(node->target, reg, &n);
       if (r) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
      }
      else
       n = node->char_len;
      r = add_length(reg, n);
      if (r) return r;
      r = compile_tree(node->target, reg);
      if (r) return r;
      r = add_opcode(reg, OP_FAIL_LOOK_BEHIND_NOT);
    }
    break;

  default:
    return ONIGERR_TYPE_BUG;
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_call ( CallNode node,
regex_t reg 
) [static]

Definition at line 370 of file regcomp.c.

{
  int r;

  r = add_opcode(reg, OP_CALL);
  if (r) return r;
  r = unset_addr_list_add(node->unset_addr_list, BBUF_GET_OFFSET_POS(reg),
                          node->target);
  if (r) return r;
  r = add_abs_addr(reg, 0 /*dummy addr.*/);
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_cclass_node ( CClassNode cc,
regex_t reg 
) [static]

Definition at line 587 of file regcomp.c.

{
  int r;

  if (IS_CCLASS_SHARE(cc)) {
    add_opcode(reg, OP_CCLASS_NODE);
    r = add_pointer(reg, cc);
    return r;
  }

  if (IS_NULL(cc->mbuf)) {
    if (IS_CCLASS_NOT(cc))
      add_opcode(reg, OP_CCLASS_NOT);
    else
      add_opcode(reg, OP_CCLASS);

    r = add_bitset(reg, cc->bs);
  }
  else {
    if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
      if (IS_CCLASS_NOT(cc))
        add_opcode(reg, OP_CCLASS_MB_NOT);
      else
        add_opcode(reg, OP_CCLASS_MB);

      r = add_multi_byte_cclass(cc->mbuf, reg);
    }
    else {
      if (IS_CCLASS_NOT(cc))
        add_opcode(reg, OP_CCLASS_MIX_NOT);
      else
        add_opcode(reg, OP_CCLASS_MIX);

      r = add_bitset(reg, cc->bs);
      if (r) return r;
      r = add_multi_byte_cclass(cc->mbuf, reg);
    }
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_effect_node ( EffectNode node,
regex_t reg 
) [static]

Definition at line 1251 of file regcomp.c.

{
  int r, len;

  if (node->type == EFFECT_OPTION)
    return compile_option_node(node, reg);

  switch (node->type) {
  case EFFECT_MEMORY:
#ifdef USE_SUBEXP_CALL
    if (IS_EFFECT_CALLED(node)) {
      r = add_opcode(reg, OP_CALL);
      if (r) return r;
      node->call_addr = BBUF_GET_OFFSET_POS(reg) + SIZE_ABSADDR + SIZE_OP_JUMP;
      node->state |= NST_ADDR_FIXED;
      r = add_abs_addr(reg, (int )node->call_addr);
      if (r) return r;
      len = compile_length_tree(node->target, reg);
      len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
       len += (IS_EFFECT_RECURSION(node)
              ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
      else
       len += (IS_EFFECT_RECURSION(node)
              ? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);

      r = add_opcode_rel_addr(reg, OP_JUMP, len);
      if (r) return r;
    }
#endif
    if (BIT_STATUS_AT(reg->bt_mem_start, node->regnum))
      r = add_opcode(reg, OP_MEMORY_START_PUSH);
    else
      r = add_opcode(reg, OP_MEMORY_START);
    if (r) return r;
    r = add_mem_num(reg, node->regnum);
    if (r) return r;
    r = compile_tree(node->target, reg);
    if (r) return r;
#ifdef USE_SUBEXP_CALL
    if (IS_EFFECT_CALLED(node)) {
      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
       r = add_opcode(reg, (IS_EFFECT_RECURSION(node)
                          ? OP_MEMORY_END_PUSH_REC : OP_MEMORY_END_PUSH));
      else
       r = add_opcode(reg, (IS_EFFECT_RECURSION(node)
                          ? OP_MEMORY_END_REC : OP_MEMORY_END));

      if (r) return r;
      r = add_mem_num(reg, node->regnum);
      if (r) return r;
      r = add_opcode(reg, OP_RETURN);
    }
    else
#endif
    {
      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
       r = add_opcode(reg, OP_MEMORY_END_PUSH);
      else
       r = add_opcode(reg, OP_MEMORY_END);
      if (r) return r;
      r = add_mem_num(reg, node->regnum);
    }
    break;

  case EFFECT_STOP_BACKTRACK:
    if (IS_EFFECT_STOP_BT_SIMPLE_REPEAT(node)) {
      QuantifierNode* qn = &NQUANTIFIER(node->target);
      r = compile_tree_n_times(qn->target, qn->lower, reg);
      if (r) return r;

      len = compile_length_tree(qn->target, reg);
      if (len < 0) return len;

      r = add_opcode_rel_addr(reg, OP_PUSH, len + SIZE_OP_POP + SIZE_OP_JUMP);
      if (r) return r;
      r = compile_tree(qn->target, reg);
      if (r) return r;
      r = add_opcode(reg, OP_POP);
      if (r) return r;
      r = add_opcode_rel_addr(reg, OP_JUMP,
        -((int )SIZE_OP_PUSH + len + (int )SIZE_OP_POP + (int )SIZE_OP_JUMP));
    }
    else {
      r = add_opcode(reg, OP_PUSH_STOP_BT);
      if (r) return r;
      r = compile_tree(node->target, reg);
      if (r) return r;
      r = add_opcode(reg, OP_POP_STOP_BT);
    }
    break;

  default:
    return ONIGERR_TYPE_BUG;
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_anchor_node ( AnchorNode node,
regex_t reg 
) [static]

Definition at line 1352 of file regcomp.c.

{
  int len;
  int tlen = 0;

  if (node->target) {
    tlen = compile_length_tree(node->target, reg);
    if (tlen < 0) return tlen;
  }

  switch (node->type) {
  case ANCHOR_PREC_READ:
    len = SIZE_OP_PUSH_POS + tlen + SIZE_OP_POP_POS;
    break;
  case ANCHOR_PREC_READ_NOT:
    len = SIZE_OP_PUSH_POS_NOT + tlen + SIZE_OP_FAIL_POS;
    break;
  case ANCHOR_LOOK_BEHIND:
    len = SIZE_OP_LOOK_BEHIND + tlen;
    break;
  case ANCHOR_LOOK_BEHIND_NOT:
    len = SIZE_OP_PUSH_LOOK_BEHIND_NOT + tlen + SIZE_OP_FAIL_LOOK_BEHIND_NOT;
    break;

  default:
    len = SIZE_OPCODE;
    break;
  }

  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_cclass_node ( CClassNode cc,
regex_t reg 
) [static]

Definition at line 557 of file regcomp.c.

{
  int len;

  if (IS_CCLASS_SHARE(cc)) {
    len = SIZE_OPCODE + SIZE_POINTER;
    return len;
  }

  if (IS_NULL(cc->mbuf)) {
    len = SIZE_OPCODE + SIZE_BITSET;
  }
  else {
    if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
      len = SIZE_OPCODE;
    }
    else {
      len = SIZE_OPCODE + SIZE_BITSET;
    }
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
    len += SIZE_LENGTH + cc->mbuf->used;
#else
    len += SIZE_LENGTH + cc->mbuf->used + (WORD_ALIGNMENT_SIZE - 1);
#endif
  }

  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_effect_node ( EffectNode node,
regex_t reg 
) [static]

Definition at line 1185 of file regcomp.c.

{
  int len;
  int tlen;

  if (node->type == EFFECT_OPTION)
    return compile_length_option_node(node, reg);

  if (node->target) {
    tlen = compile_length_tree(node->target, reg);
    if (tlen < 0) return tlen;
  }
  else
    tlen = 0;

  switch (node->type) {
  case EFFECT_MEMORY:
#ifdef USE_SUBEXP_CALL
    if (IS_EFFECT_CALLED(node)) {
      len = SIZE_OP_MEMORY_START_PUSH + tlen
         + SIZE_OP_CALL + SIZE_OP_JUMP + SIZE_OP_RETURN;
      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
       len += (IS_EFFECT_RECURSION(node)
              ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
      else
       len += (IS_EFFECT_RECURSION(node)
              ? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
    }
    else
#endif
    {
      if (BIT_STATUS_AT(reg->bt_mem_start, node->regnum))
       len = SIZE_OP_MEMORY_START_PUSH;
      else
       len = SIZE_OP_MEMORY_START;

      len += tlen + (BIT_STATUS_AT(reg->bt_mem_end, node->regnum)
                   ? SIZE_OP_MEMORY_END_PUSH : SIZE_OP_MEMORY_END);
    }
    break;

  case EFFECT_STOP_BACKTRACK:
    if (IS_EFFECT_STOP_BT_SIMPLE_REPEAT(node)) {
      QuantifierNode* qn = &NQUANTIFIER(node->target);
      tlen = compile_length_tree(qn->target, reg);
      if (tlen < 0) return tlen;

      len = tlen * qn->lower
         + SIZE_OP_PUSH + tlen + SIZE_OP_POP + SIZE_OP_JUMP;
    }
    else {
      len = SIZE_OP_PUSH_STOP_BT + tlen + SIZE_OP_POP_STOP_BT;
    }
    break;

  default:
    return ONIGERR_TYPE_BUG;
    break;
  }

  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_option_node ( EffectNode node,
regex_t reg 
) [static]

Definition at line 1139 of file regcomp.c.

{
  int tlen;
  OnigOptionType prev = reg->options;

  reg->options = node->option;
  tlen = compile_length_tree(node->target, reg);
  reg->options = prev;

  if (tlen < 0) return tlen;

  if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
    return SIZE_OP_SET_OPTION_PUSH + SIZE_OP_SET_OPTION + SIZE_OP_FAIL
           + tlen + SIZE_OP_SET_OPTION;
  }
  else
    return tlen;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_quantifier_node ( QuantifierNode qn,
regex_t reg 
) [static]

Definition at line 712 of file regcomp.c.

{
  int len, mod_tlen, cklen;
  int ckn;
  int infinite = IS_REPEAT_INFINITE(qn->upper);
  int empty_info = qn->target_empty_info;
  int tlen = compile_length_tree(qn->target, reg);

  if (tlen < 0) return tlen;

  ckn = ((reg->num_comb_exp_check > 0) ? qn->comb_exp_check_num : 0);

  cklen = (CKN_ON ? SIZE_STATE_CHECK_NUM: 0);

  /* anychar repeat */
  if (NTYPE(qn->target) == N_ANYCHAR) {
    if (qn->greedy && infinite) {
      if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON)
        return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower + cklen;
      else
        return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower + cklen;
    }
  }

  if (empty_info != 0)
    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
  else
    mod_tlen = tlen;

  if (infinite && qn->lower <= 1) {
    if (qn->greedy) {
      if (qn->lower == 1)
       len = SIZE_OP_JUMP;
      else
       len = 0;

      len += SIZE_OP_PUSH + cklen + mod_tlen + SIZE_OP_JUMP;
    }
    else {
      if (qn->lower == 0)
       len = SIZE_OP_JUMP;
      else
       len = 0;

      len += mod_tlen + SIZE_OP_PUSH + cklen;
    }
  }
  else if (qn->upper == 0) {
    if (qn->is_refered != 0) /* /(?<n>..){0}/ */
      len = SIZE_OP_JUMP + tlen;
    else
      len = 0;
  }
  else if (qn->upper == 1 && qn->greedy) {
    if (qn->lower == 0) {
      if (CKN_ON) {
       len = SIZE_OP_STATE_CHECK_PUSH + tlen;
      }
      else {
       len = SIZE_OP_PUSH + tlen;
      }
    }
    else {
      len = tlen;
    }
  }
  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
    len = SIZE_OP_PUSH + cklen + SIZE_OP_JUMP + tlen;
  }
  else {
    len = SIZE_OP_REPEAT_INC
        + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
    if (CKN_ON)
      len += SIZE_OP_STATE_CHECK;
  }

  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_string_node ( Node node,
regex_t reg 
) [static]

Definition at line 436 of file regcomp.c.

{
  int rlen, r, len, prev_len, slen, ambig;
  OnigEncoding enc = reg->enc;
  UChar *p, *prev;
  StrNode* sn;

  sn = &(NSTRING(node));
  if (sn->end <= sn->s)
    return 0;

  ambig = NSTRING_IS_AMBIG(node);

  p = prev = sn->s;
  prev_len = enc_len(enc, p);
  p += prev_len;
  slen = 1;
  rlen = 0;

  for (; p < sn->end; ) {
    len = enc_len(enc, p);
    if (len == prev_len) {
      slen++;
    }
    else {
      r = add_compile_string_length(prev, prev_len, slen, reg, ambig);
      rlen += r;
      prev = p;
      slen = 1;
      prev_len = len;
    }
    p += len;
  }
  r = add_compile_string_length(prev, prev_len, slen, reg, ambig);
  rlen += r;
  return rlen;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_string_raw_node ( StrNode sn,
regex_t reg 
) [static]

Definition at line 475 of file regcomp.c.

{
  if (sn->end <= sn->s)
    return 0;

  return add_compile_string_length(sn->s, 1 /* sb */, sn->end - sn->s, reg, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_length_tree ( Node node,
regex_t reg 
) [static]

Definition at line 1469 of file regcomp.c.

{
  int len, type, r;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
    len = 0;
    do {
      r = compile_length_tree(NCONS(node).left, reg);
      if (r < 0) return r;
      len += r;
    } while (IS_NOT_NULL(node = NCONS(node).right));
    r = len;
    break;

  case N_ALT:
    {
      int n;

      n = r = 0;
      do {
       r += compile_length_tree(NCONS(node).left, reg);
       n++;
      } while (IS_NOT_NULL(node = NCONS(node).right));
      r += (SIZE_OP_PUSH + SIZE_OP_JUMP) * (n - 1);
    }
    break;

  case N_STRING:
    if (NSTRING_IS_RAW(node))
      r = compile_length_string_raw_node(&(NSTRING(node)), reg);
    else
      r = compile_length_string_node(node, reg);
    break;

  case N_CCLASS:
    r = compile_length_cclass_node(&(NCCLASS(node)), reg);
    break;

  case N_CTYPE:
  case N_ANYCHAR:
    r = SIZE_OPCODE;
    break;

  case N_BACKREF:
    {
      BackrefNode* br = &(NBACKREF(node));

#ifdef USE_BACKREF_AT_LEVEL
      if (IS_BACKREF_NEST_LEVEL(br)) {
        r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
            SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
      }
      else
#endif
      if (br->back_num == 1) {
       r = ((!IS_IGNORECASE(reg->options) && br->back_static[0] <= 2)
            ? SIZE_OPCODE : (SIZE_OPCODE + SIZE_MEMNUM));
      }
      else {
       r = SIZE_OPCODE + SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
      }
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    r = SIZE_OP_CALL;
    break;
#endif

  case N_QUANTIFIER:
    r = compile_length_quantifier_node(&(NQUANTIFIER(node)), reg);
    break;

  case N_EFFECT:
    r = compile_length_effect_node(&NEFFECT(node), reg);
    break;

  case N_ANCHOR:
    r = compile_length_anchor_node(&(NANCHOR(node)), reg);
    break;

  default:
    return ONIGERR_TYPE_BUG;
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_option_node ( EffectNode node,
regex_t reg 
) [static]

Definition at line 1159 of file regcomp.c.

{
  int r;
  OnigOptionType prev = reg->options;

  if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
    r = add_opcode_option(reg, OP_SET_OPTION_PUSH, node->option);
    if (r) return r;
    r = add_opcode_option(reg, OP_SET_OPTION, prev);
    if (r) return r;
    r = add_opcode(reg, OP_FAIL);
    if (r) return r;
  }

  reg->options = node->option;
  r = compile_tree(node->target, reg);
  reg->options = prev;

  if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
    if (r) return r;
    r = add_opcode_option(reg, OP_SET_OPTION, prev);
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_quantifier_node ( QuantifierNode qn,
regex_t reg 
) [static]

Definition at line 792 of file regcomp.c.

{
  int r, mod_tlen;
  int ckn;
  int infinite = IS_REPEAT_INFINITE(qn->upper);
  int empty_info = qn->target_empty_info;
  int tlen = compile_length_tree(qn->target, reg);

  if (tlen < 0) return tlen;

  ckn = ((reg->num_comb_exp_check > 0) ? qn->comb_exp_check_num : 0);

  if (is_anychar_star_quantifier(qn)) {
    r = compile_tree_n_times(qn->target, qn->lower, reg);
    if (r) return r;
    if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON) {
      if (IS_MULTILINE(reg->options))
       r = add_opcode(reg, OP_ANYCHAR_ML_STAR_PEEK_NEXT);
      else
       r = add_opcode(reg, OP_ANYCHAR_STAR_PEEK_NEXT);
      if (r) return r;
      if (CKN_ON) {
       r = add_state_check_num(reg, ckn);
       if (r) return r;
      }

      return add_bytes(reg, NSTRING(qn->next_head_exact).s, 1);
    }
    else {
      if (IS_MULTILINE(reg->options)) {
       r = add_opcode(reg, (CKN_ON ?
                            OP_STATE_CHECK_ANYCHAR_ML_STAR
                          : OP_ANYCHAR_ML_STAR));
      }
      else {
       r = add_opcode(reg, (CKN_ON ?
                            OP_STATE_CHECK_ANYCHAR_STAR
                          : OP_ANYCHAR_STAR));
      }
      if (r) return r;
      if (CKN_ON)
       r = add_state_check_num(reg, ckn);

      return r;
    }
  }

  if (empty_info != 0)
    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
  else
    mod_tlen = tlen;

  if (infinite && qn->lower <= 1) {
    if (qn->greedy) {
      if (qn->lower == 1) {
       r = add_opcode_rel_addr(reg, OP_JUMP,
                     (CKN_ON ? SIZE_OP_STATE_CHECK_PUSH : SIZE_OP_PUSH));
       if (r) return r;
      }

      if (CKN_ON) {
       r = add_opcode(reg, OP_STATE_CHECK_PUSH);
       if (r) return r;
       r = add_state_check_num(reg, ckn);
       if (r) return r;
       r = add_rel_addr(reg, mod_tlen + SIZE_OP_JUMP);
      }
      else {
       r = add_opcode_rel_addr(reg, OP_PUSH, mod_tlen + SIZE_OP_JUMP);
      }
      if (r) return r;
      r = compile_tree_empty_check(qn->target, reg, empty_info);
      if (r) return r;
      r = add_opcode_rel_addr(reg, OP_JUMP,
             -(mod_tlen + (int )SIZE_OP_JUMP
              + (int )(CKN_ON ? SIZE_OP_STATE_CHECK_PUSH : SIZE_OP_PUSH)));
    }
    else {
      if (qn->lower == 0) {
       r = add_opcode_rel_addr(reg, OP_JUMP, mod_tlen);
       if (r) return r;
      }
      r = compile_tree_empty_check(qn->target, reg, empty_info);
      if (r) return r;
      if (CKN_ON) {
       r = add_opcode(reg, OP_STATE_CHECK_PUSH_OR_JUMP);
       if (r) return r;
       r = add_state_check_num(reg, ckn);
       if (r) return r;
       r = add_rel_addr(reg,
               -(mod_tlen + (int )SIZE_OP_STATE_CHECK_PUSH_OR_JUMP));
      }
      else
       r = add_opcode_rel_addr(reg, OP_PUSH, -(mod_tlen + (int )SIZE_OP_PUSH));
    }
  }
  else if (qn->upper == 0) {
    if (qn->is_refered != 0) { /* /(?<n>..){0}/ */
      r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
      if (r) return r;
      r = compile_tree(qn->target, reg);
    }
    else
      r = 0;
  }
  else if (qn->upper == 1 && qn->greedy) {
    if (qn->lower == 0) {
      if (CKN_ON) {
       r = add_opcode(reg, OP_STATE_CHECK_PUSH);
       if (r) return r;
       r = add_state_check_num(reg, ckn);
       if (r) return r;
       r = add_rel_addr(reg, tlen);
      }
      else {
       r = add_opcode_rel_addr(reg, OP_PUSH, tlen);
      }
      if (r) return r;
    }

    r = compile_tree(qn->target, reg);
  }
  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
    if (CKN_ON) {
      r = add_opcode(reg, OP_STATE_CHECK_PUSH);
      if (r) return r;
      r = add_state_check_num(reg, ckn);
      if (r) return r;
      r = add_rel_addr(reg, SIZE_OP_JUMP);
    }
    else {
      r = add_opcode_rel_addr(reg, OP_PUSH, SIZE_OP_JUMP);
    }

    if (r) return r;
    r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
    if (r) return r;
    r = compile_tree(qn->target, reg);
  }
  else {
    r = compile_range_repeat_node(qn, mod_tlen, empty_info, reg);
    if (CKN_ON) {
      if (r) return r;
      r = add_opcode(reg, OP_STATE_CHECK);
      if (r) return r;
      r = add_state_check_num(reg, ckn);
    }
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_range_repeat_node ( QuantifierNode qn,
int  target_len,
int  empty_info,
regex_t reg 
) [static]

Definition at line 661 of file regcomp.c.

{
  int r;
  int num_repeat = reg->num_repeat;

  r = add_opcode(reg, qn->greedy ? OP_REPEAT : OP_REPEAT_NG);
  if (r) return r;
  r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */
  reg->num_repeat++;
  if (r) return r;
  r = add_rel_addr(reg, target_len + SIZE_OP_REPEAT_INC);
  if (r) return r;

  r = entry_repeat_range(reg, num_repeat, qn->lower, qn->upper);
  if (r) return r;

  r = compile_tree_empty_check(qn->target, reg, empty_info);
  if (r) return r;

  if (
#ifdef USE_SUBEXP_CALL
      reg->num_call > 0 ||
#endif
      IS_QUANTIFIER_IN_REPEAT(qn)) {
    r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC_SG : OP_REPEAT_INC_NG_SG);
  }
  else {
    r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC : OP_REPEAT_INC_NG);
  }
  if (r) return r;
  r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_string_node ( Node node,
regex_t reg 
) [static]

Definition at line 484 of file regcomp.c.

{
  int r, len, prev_len, slen, ambig;
  OnigEncoding enc = reg->enc;
  UChar *p, *prev, *end;
  StrNode* sn;

  sn = &(NSTRING(node));
  if (sn->end <= sn->s)
    return 0;

  end = sn->end;
  ambig = NSTRING_IS_AMBIG(node);

  p = prev = sn->s;
  prev_len = enc_len(enc, p);
  p += prev_len;
  slen = 1;

  for (; p < end; ) {
    len = enc_len(enc, p);
    if (len == prev_len) {
      slen++;
    }
    else {
      r = add_compile_string(prev, prev_len, slen, reg, ambig);
      if (r) return r;

      prev  = p;
      slen  = 1;
      prev_len = len;
    }

    p += len;
  }
  return add_compile_string(prev, prev_len, slen, reg, ambig);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_string_raw_node ( StrNode sn,
regex_t reg 
) [static]

Definition at line 523 of file regcomp.c.

{
  if (sn->end <= sn->s)
    return 0;

  return add_compile_string(sn->s, 1 /* sb */, sn->end - sn->s, reg, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_tree ( Node node,
regex_t reg 
) [static]

Definition at line 1562 of file regcomp.c.

{
  int n, type, len, pos, r = 0;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
    do {
      r = compile_tree(NCONS(node).left, reg);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_ALT:
    {
      Node* x = node;
      len = 0;
      do {
       len += compile_length_tree(NCONS(x).left, reg);
       if (NCONS(x).right != NULL) {
         len += SIZE_OP_PUSH + SIZE_OP_JUMP;
       }
      } while (IS_NOT_NULL(x = NCONS(x).right));
      pos = reg->used + len;  /* goal position */

      do {
       len = compile_length_tree(NCONS(node).left, reg);
       if (IS_NOT_NULL(NCONS(node).right)) {
         r = add_opcode_rel_addr(reg, OP_PUSH, len + SIZE_OP_JUMP);
         if (r) break;
       }
       r = compile_tree(NCONS(node).left, reg);
       if (r) break;
       if (IS_NOT_NULL(NCONS(node).right)) {
         len = pos - (reg->used + SIZE_OP_JUMP);
         r = add_opcode_rel_addr(reg, OP_JUMP, len);
         if (r) break;
       }
      } while (IS_NOT_NULL(node = NCONS(node).right));
    }
    break;

  case N_STRING:
    if (NSTRING_IS_RAW(node))
      r = compile_string_raw_node(&(NSTRING(node)), reg);
    else
      r = compile_string_node(node, reg);
    break;

  case N_CCLASS:
    r = compile_cclass_node(&(NCCLASS(node)), reg);
    break;

  case N_CTYPE:
    {
      int op;

      switch (NCTYPE(node).type) {
      case CTYPE_WORD:            op = OP_WORD;           break;
      case CTYPE_NOT_WORD:        op = OP_NOT_WORD;       break;
      default:
       return ONIGERR_TYPE_BUG;
       break;
      }
      r = add_opcode(reg, op);
    }
    break;

  case N_ANYCHAR:
    if (IS_MULTILINE(reg->options))
      r = add_opcode(reg, OP_ANYCHAR_ML);
    else
      r = add_opcode(reg, OP_ANYCHAR);
    break;

  case N_BACKREF:
    {
      BackrefNode* br = &(NBACKREF(node));

#ifdef USE_BACKREF_AT_LEVEL
      if (IS_BACKREF_NEST_LEVEL(br)) {
       r = add_opcode(reg, OP_BACKREF_AT_LEVEL);
       if (r) return r;
       r = add_option(reg, (reg->options & ONIG_OPTION_IGNORECASE));
       if (r) return r;
       r = add_length(reg, br->nest_level);
       if (r) return r;

       goto add_bacref_mems;
      }
      else
#endif
      if (br->back_num == 1) {
       n = br->back_static[0];
       if (IS_IGNORECASE(reg->options)) {
         r = add_opcode(reg, OP_BACKREFN_IC);
         if (r) return r;
         r = add_mem_num(reg, n);
       }
       else {
         switch (n) {
         case 1:  r = add_opcode(reg, OP_BACKREF1); break;
         case 2:  r = add_opcode(reg, OP_BACKREF2); break;
         default:
           r = add_opcode(reg, OP_BACKREFN);
           if (r) return r;
           r = add_mem_num(reg, n);
           break;
         }
       }
      }
      else {
       int i;
       int* p;

        if (IS_IGNORECASE(reg->options)) {
          r = add_opcode(reg, OP_BACKREF_MULTI_IC);
        }
        else {
          r = add_opcode(reg, OP_BACKREF_MULTI);
        }
       if (r) return r;

#ifdef USE_BACKREF_AT_LEVEL
      add_bacref_mems:
#endif
       r = add_length(reg, br->back_num);
       if (r) return r;
       p = BACKREFS_P(br);
       for (i = br->back_num - 1; i >= 0; i--) {
         r = add_mem_num(reg, p[i]);
         if (r) return r;
       }
      }
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    r = compile_call(&(NCALL(node)), reg);
    break;
#endif

  case N_QUANTIFIER:
    r = compile_quantifier_node(&(NQUANTIFIER(node)), reg);
    break;

  case N_EFFECT:
    r = compile_effect_node(&NEFFECT(node), reg);
    break;

  case N_ANCHOR:
    r = compile_anchor_node(&(NANCHOR(node)), reg);
    break;

  default:
#ifdef ONIG_DEBUG
    fprintf(stderr, "compile_tree: undefined node type %d\n", NTYPE(node));
#endif
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_tree_empty_check ( Node node,
regex_t reg,
int  empty_info 
) [static]

Definition at line 338 of file regcomp.c.

{
  int r;
  int saved_num_null_check = reg->num_null_check;

  if (empty_info != 0) {
    r = add_opcode(reg, OP_NULL_CHECK_START);
    if (r) return r;
    r = add_mem_num(reg, reg->num_null_check); /* NULL CHECK ID */
    if (r) return r;
    reg->num_null_check++;
  }

  r = compile_tree(node, reg);
  if (r) return r;

  if (empty_info != 0) {
    if (empty_info == NQ_TARGET_IS_EMPTY)
      r = add_opcode(reg, OP_NULL_CHECK_END);
    else if (empty_info == NQ_TARGET_IS_EMPTY_MEM)
      r = add_opcode(reg, OP_NULL_CHECK_END_MEMST);
    else if (empty_info == NQ_TARGET_IS_EMPTY_REC)
      r = add_opcode(reg, OP_NULL_CHECK_END_MEMST_PUSH);

    if (r) return r;
    r = add_mem_num(reg, saved_num_null_check); /* NULL CHECK ID */
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compile_tree_n_times ( Node node,
int  n,
regex_t reg 
) [static]

Definition at line 385 of file regcomp.c.

{
  int i, r;

  for (i = 0; i < n; i++) {
    r = compile_tree(node, reg);
    if (r) return r;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void concat_left_node_opt_info ( OnigEncoding  enc,
NodeOptInfo to,
NodeOptInfo add 
) [static]

Definition at line 4260 of file regcomp.c.

{
  int exb_reach, exm_reach;
  OptAncInfo tanc;

  concat_opt_anc_info(&tanc, &to->anc, &add->anc, to->len.max, add->len.max);
  copy_opt_anc_info(&to->anc, &tanc);

  if (add->exb.len > 0 && to->len.max == 0) {
    concat_opt_anc_info(&tanc, &to->anc, &add->exb.anc,
                     to->len.max, add->len.max);
    copy_opt_anc_info(&add->exb.anc, &tanc);
  }

  if (add->map.value > 0 && to->len.max == 0) {
    if (add->map.mmd.max == 0)
      add->map.anc.left_anchor |= to->anc.left_anchor;
  }

  exb_reach = to->exb.reach_end;
  exm_reach = to->exm.reach_end;

  if (add->len.max != 0)
    to->exb.reach_end = to->exm.reach_end = 0;

  if (add->exb.len > 0) {
    if (exb_reach) {
      concat_opt_exact_info(&to->exb, &add->exb, enc);
      clear_opt_exact_info(&add->exb);
    }
    else if (exm_reach) {
      concat_opt_exact_info(&to->exm, &add->exb, enc);
      clear_opt_exact_info(&add->exb);
    }
  }
  select_opt_exact_info(enc, &to->exm, &add->exb);
  select_opt_exact_info(enc, &to->exm, &add->exm);

  if (to->expr.len > 0) {
    if (add->len.max > 0) {
      if (to->expr.len > (int )add->len.max)
       to->expr.len = add->len.max;

      if (to->expr.mmd.max == 0)
       select_opt_exact_info(enc, &to->exb, &to->expr);
      else
       select_opt_exact_info(enc, &to->exm, &to->expr);
    }
  }
  else if (add->expr.len > 0) {
    copy_opt_exact_info(&to->expr, &add->expr);
  }

  select_opt_map_info(&to->map, &add->map);

  add_mml(&to->len, &add->len);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void concat_opt_anc_info ( OptAncInfo to,
OptAncInfo left,
OptAncInfo right,
OnigDistance  left_len,
OnigDistance  right_len 
) [static]

Definition at line 3907 of file regcomp.c.

{
  clear_opt_anc_info(to);

  to->left_anchor = left->left_anchor;
  if (left_len == 0) {
    to->left_anchor |= right->left_anchor;
  }

  to->right_anchor = right->right_anchor;
  if (right_len == 0) {
    to->right_anchor |= left->right_anchor;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void concat_opt_exact_info ( OptExactInfo to,
OptExactInfo add,
OnigEncoding  enc 
) [static]

Definition at line 3991 of file regcomp.c.

{
  int i, j, len;
  UChar *p, *end;
  OptAncInfo tanc;

  if (! to->ignore_case && add->ignore_case) {
    if (to->len >= add->len) return ;  /* avoid */

    to->ignore_case = 1;
  }

  p = add->s;
  end = p + add->len;
  for (i = to->len; p < end; ) {
    len = enc_len(enc, p);
    if (i + len > OPT_EXACT_MAXLEN) break;
    for (j = 0; j < len && p < end; j++)
      to->s[i++] = *p++;
  }

  to->len = i;
  to->reach_end = (p == end ? add->reach_end : 0);

  concat_opt_anc_info(&tanc, &to->anc, &add->anc, 1, 1);
  if (! to->reach_end) tanc.right_anchor = 0;
  copy_opt_anc_info(&to->anc, &tanc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void concat_opt_exact_info_str ( OptExactInfo to,
UChar s,
UChar end,
int  raw,
OnigEncoding  enc 
) [static]

Definition at line 4021 of file regcomp.c.

{
  int i, j, len;
  UChar *p;

  for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
    len = enc_len(enc, p);
    if (i + len > OPT_EXACT_MAXLEN) break;
    for (j = 0; j < len && p < end; j++)
      to->s[i++] = *p++;
  }

  to->len = i;
}

Here is the caller graph for this function:

static void copy_mml ( MinMaxLen to,
MinMaxLen from 
) [static]

Definition at line 3858 of file regcomp.c.

{
  to->min = from->min;
  to->max = from->max;
}

Here is the caller graph for this function:

static void copy_node_opt_info ( NodeOptInfo to,
NodeOptInfo from 
) [static]

Definition at line 4254 of file regcomp.c.

{
  *to = *from;
}

Here is the caller graph for this function:

static void copy_opt_anc_info ( OptAncInfo to,
OptAncInfo from 
) [static]

Definition at line 3901 of file regcomp.c.

{
  *to = *from;
}

Here is the caller graph for this function:

static void copy_opt_env ( OptEnv to,
OptEnv from 
) [static]

Definition at line 3888 of file regcomp.c.

{
  *to = *from;
}

Here is the caller graph for this function:

static void copy_opt_exact_info ( OptExactInfo to,
OptExactInfo from 
) [static]

Definition at line 3985 of file regcomp.c.

{
  *to = *from;
}

Here is the caller graph for this function:

static void copy_opt_map_info ( OptMapInfo to,
OptMapInfo from 
) [static]

Definition at line 4133 of file regcomp.c.

{
  *to = *from;
}

Here is the caller graph for this function:

static int disable_noname_group_capture ( Node **  root,
regex_t reg,
ScanEnv env 
) [static]

Definition at line 1872 of file regcomp.c.

{
  int r, i, pos, counter;
  BitStatusType loc;
  GroupNumRemap* map;

  map = (GroupNumRemap* )xalloca(sizeof(GroupNumRemap) * (env->num_mem + 1));
  CHECK_NULL_RETURN_VAL(map, ONIGERR_MEMORY);
  for (i = 1; i <= env->num_mem; i++) {
    map[i].new_val = 0;
  }
  counter = 0;
  r = noname_disable_map(root, map, &counter);
  if (r != 0) return r;

  r = renumber_by_map(*root, map);
  if (r != 0) return r;

  for (i = 1, pos = 1; i <= env->num_mem; i++) {
    if (map[i].new_val > 0) {
      SCANENV_MEM_NODES(env)[pos] = SCANENV_MEM_NODES(env)[i];
      pos++;
    }
  }

  loc = env->capture_history;
  BIT_STATUS_CLEAR(env->capture_history);
  for (i = 1; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
    if (BIT_STATUS_AT(loc, i)) {
      BIT_STATUS_ON_AT_SIMPLE(env->capture_history, map[i].new_val);
    }
  }

  env->num_mem = env->num_named;
  reg->num_mem = env->num_named;

  return onig_renumber_name_table(reg, map);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static OnigDistance distance_add ( OnigDistance  d1,
OnigDistance  d2 
) [static]

Definition at line 77 of file regcomp.c.

{
  if (d1 == ONIG_INFINITE_DISTANCE || d2 == ONIG_INFINITE_DISTANCE)
    return ONIG_INFINITE_DISTANCE;
  else {
    if (d1 <= ONIG_INFINITE_DISTANCE - d2) return d1 + d2;
    else return ONIG_INFINITE_DISTANCE;
  }
}

Here is the caller graph for this function:

static OnigDistance distance_multiply ( OnigDistance  d,
int  m 
) [static]

Definition at line 88 of file regcomp.c.

{
  if (m == 0) return 0;

  if (d < ONIG_INFINITE_DISTANCE / m)
    return d * m;
  else
    return ONIG_INFINITE_DISTANCE;
}

Here is the caller graph for this function:

static int distance_value ( MinMaxLen mm) [static]

Definition at line 3792 of file regcomp.c.

{
  /* 1000 / (min-max-dist + 1) */
  static const short int dist_vals[] = {
    1000,  500,  333,  250,  200,  167,  143,  125,  111,  100, 
      91,   83,   77,   71,   67,   63,   59,   56,   53,   50, 
      48,   45,   43,   42,   40,   38,   37,   36,   34,   33, 
      32,   31,   30,   29,   29,   28,   27,   26,   26,   25, 
      24,   24,   23,   23,   22,   22,   21,   21,   20,   20, 
      20,   19,   19,   19,   18,   18,   18,   17,   17,   17, 
      16,   16,   16,   16,   15,   15,   15,   15,   14,   14, 
      14,   14,   14,   14,   13,   13,   13,   13,   13,   13, 
      12,   12,   12,   12,   12,   12,   11,   11,   11,   11, 
      11,   11,   11,   11,   11,   10,   10,   10,   10,   10
  };

  int d;

  if (mm->max == ONIG_INFINITE_DISTANCE) return 0;

  d = mm->max - mm->min;
  if (d < sizeof(dist_vals)/sizeof(dist_vals[0]))
    /* return dist_vals[d] * 16 / (mm->min + 12); */
    return (int )dist_vals[d];
  else
    return 1;
}

Here is the caller graph for this function:

static int divide_ambig_string_node ( Node node,
regex_t reg 
) [static]

Definition at line 3236 of file regcomp.c.

{
  StrNode* sn = &NSTRING(node);
  int ambig, prev_ambig;
  UChar *prev, *p, *end, *prev_start, *start, *tmp, *wp;
  Node *root = NULL_NODE;
  Node **tailp = (Node** )0;
  int r;

  start = prev_start = p = sn->s;
  end  = sn->end;
  if (p >= end) return 0;

  prev_ambig = ONIGENC_IS_MBC_AMBIGUOUS(reg->enc, reg->ambig_flag, &p, end);

  while (p < end) {
    prev = p;
    if (prev_ambig != (ambig = ONIGENC_IS_MBC_AMBIGUOUS(reg->enc,
                                              reg->ambig_flag, &p, end))) {

      r = divide_ambig_string_node_sub(reg, prev_ambig, prev_start, prev,
                                       end, &tailp, &root);
      if (r != 0) return r;

      prev_ambig = ambig;
      prev_start = prev;
    }
  }

  if (prev_start == start) {
    if (prev_ambig != 0) {
      NSTRING_SET_AMBIG(node);
      tmp = start;
      wp  = start;
      while (tmp < end) {
        wp += ONIGENC_MBC_TO_NORMALIZE(reg->enc, reg->ambig_flag,
                                       &tmp, end, wp);
      }
      if (wp != sn->end) NSTRING_SET_AMBIG_REDUCE(node);
      sn->end = wp;
    }
  }
  else {
    r = divide_ambig_string_node_sub(reg, prev_ambig, prev_start, end,
                                     end, &tailp, &root);
    if (r != 0) return r;

    swap_node(node, root);
    onig_node_str_clear(root); /* should be after swap! */
    onig_node_free(root);      /* free original string node */
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int divide_ambig_string_node_sub ( regex_t reg,
int  prev_ambig,
UChar prev_start,
UChar prev,
UChar end,
Node ***  tailp,
Node **  root 
) [static]

Definition at line 3197 of file regcomp.c.

{
  UChar *tmp, *wp;
  Node* snode;

  if (prev_ambig != 0) {
    tmp = prev_start;
    wp  = prev_start;
    while (tmp < prev) {
      wp += ONIGENC_MBC_TO_NORMALIZE(reg->enc, reg->ambig_flag,
                                     &tmp, end, wp);
    }
    snode = onig_node_new_str(prev_start, wp);
    CHECK_NULL_RETURN_VAL(snode, ONIGERR_MEMORY);
    NSTRING_SET_AMBIG(snode);
    if (wp != prev) NSTRING_SET_AMBIG_REDUCE(snode);
  }
  else {
    snode = onig_node_new_str(prev_start, prev);
    CHECK_NULL_RETURN_VAL(snode, ONIGERR_MEMORY);
  }

  if (*tailp == (Node** )0) {
    *root = onig_node_new_list(snode, NULL);
    CHECK_NULL_RETURN_VAL(*root, ONIGERR_MEMORY);
    *tailp = &(NCONS(*root).right);
  }
  else {
    **tailp = onig_node_new_list(snode, NULL);
    CHECK_NULL_RETURN_VAL(**tailp, ONIGERR_MEMORY);
    *tailp = &(NCONS(**tailp).right);
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int divide_look_behind_alternatives ( Node node) [static]

Definition at line 3101 of file regcomp.c.

{
  Node tmp_node;
  Node *head, *np, *insert_node;
  AnchorNode* an = &(NANCHOR(node));
  int anc_type = an->type;

  head = an->target;
  np = NCONS(head).left;
  tmp_node = *node; *node = *head; *head = tmp_node;
  NCONS(node).left = head;
  NANCHOR(head).target = np;

  np = node;
  while ((np = NCONS(np).right) != NULL_NODE) {
    insert_node = onig_node_new_anchor(anc_type);
    CHECK_NULL_RETURN_VAL(insert_node, ONIGERR_MEMORY);
    NANCHOR(insert_node).target = NCONS(np).left;
    NCONS(np).left = insert_node;
  }

  if (anc_type == ANCHOR_LOOK_BEHIND_NOT) {
    np = node;
    do {
      np->type = N_LIST;  /* alt -> list */
    } while ((np = NCONS(np).right) != NULL_NODE);
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int entry_repeat_range ( regex_t reg,
int  id,
int  lower,
int  upper 
) [static]

Definition at line 630 of file regcomp.c.

{
#define REPEAT_RANGE_ALLOC  4

  OnigRepeatRange* p;

  if (reg->repeat_range_alloc == 0) {
    p = (OnigRepeatRange* )xmalloc(sizeof(OnigRepeatRange) * REPEAT_RANGE_ALLOC);
    CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
    reg->repeat_range = p;
    reg->repeat_range_alloc = REPEAT_RANGE_ALLOC;
  }
  else if (reg->repeat_range_alloc <= id) {
    int n;
    n = reg->repeat_range_alloc + REPEAT_RANGE_ALLOC;
    p = (OnigRepeatRange* )xrealloc(reg->repeat_range,
                                    sizeof(OnigRepeatRange) * n);
    CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
    reg->repeat_range = p;
    reg->repeat_range_alloc = n;
  }
  else {
    p = reg->repeat_range;
  }

  p[id].lower = lower;
  p[id].upper = (IS_REPEAT_INFINITE(upper) ? 0x7fffffff : upper);
  return 0;
}

Here is the caller graph for this function:

static int get_char_length_tree ( Node node,
regex_t reg,
int len 
) [static]

Definition at line 2387 of file regcomp.c.

{
  return get_char_length_tree1(node, reg, len, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_char_length_tree1 ( Node node,
regex_t reg,
int len,
int  level 
) [static]

Definition at line 2259 of file regcomp.c.

{
  int tlen;
  int r = 0;

  level++;
  *len = 0;
  switch (NTYPE(node)) {
  case N_LIST:
    do {
      r = get_char_length_tree1(NCONS(node).left, reg, &tlen, level);
      if (r == 0)
       *len = distance_add(*len, tlen);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_ALT:
    {
      int tlen2;
      int varlen = 0;

      r = get_char_length_tree1(NCONS(node).left, reg, &tlen, level);
      while (r == 0 && IS_NOT_NULL(node = NCONS(node).right)) {
       r = get_char_length_tree1(NCONS(node).left, reg, &tlen2, level);
       if (r == 0) {
         if (tlen != tlen2)
           varlen = 1;
       }
      }
      if (r == 0) {
       if (varlen != 0) {
         if (level == 1)
           r = GET_CHAR_LEN_TOP_ALT_VARLEN;
         else
           r = GET_CHAR_LEN_VARLEN;
       }
       else
         *len = tlen;
      }
    }
    break;

  case N_STRING:
    {
      StrNode* sn = &(NSTRING(node));
      UChar *s = sn->s;
      while (s < sn->end) {
       s += enc_len(reg->enc, s);
       (*len)++;
      }
    }
    break;

  case N_QUANTIFIER:
    {
      QuantifierNode* qn = &(NQUANTIFIER(node));
      if (qn->lower == qn->upper) {
       r = get_char_length_tree1(qn->target, reg, &tlen, level);
       if (r == 0)
         *len = distance_multiply(tlen, qn->lower);
      }
      else
       r = GET_CHAR_LEN_VARLEN;
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    if (! IS_CALL_RECURSION(&(NCALL(node))))
      r = get_char_length_tree1(NCALL(node).target, reg, len, level);
    else
      r = GET_CHAR_LEN_VARLEN;
    break;
#endif

  case N_CTYPE:
    switch (NCTYPE(node).type) {
    case CTYPE_WORD:
    case CTYPE_NOT_WORD:
      *len = 1;
      break;
    }
    break;

  case N_CCLASS:
  case N_ANYCHAR:
    *len = 1;
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));
      switch (en->type) {
      case EFFECT_MEMORY:
#ifdef USE_SUBEXP_CALL
       if (IS_EFFECT_CLEN_FIXED(en))
         *len = en->char_len;
       else {
         r = get_char_length_tree1(en->target, reg, len, level);
         if (r == 0) {
           en->char_len = *len;
           SET_EFFECT_STATUS(node, NST_CLEN_FIXED);
         }
       }
       break;
#endif
      case EFFECT_OPTION:
      case EFFECT_STOP_BACKTRACK:
       r = get_char_length_tree1(en->target, reg, len, level);
       break;
      default:
       break;
      }
    }
    break;

  case N_ANCHOR:
    break;

  default:
    r = GET_CHAR_LEN_VARLEN;
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Node* get_head_value_node ( Node node,
int  exact,
regex_t reg 
) [static]

Definition at line 2578 of file regcomp.c.

{
  Node* n = NULL_NODE;

  switch (NTYPE(node)) {
  case N_BACKREF:
  case N_ALT:
  case N_ANYCHAR:
#ifdef USE_SUBEXP_CALL
  case N_CALL:
#endif
    break;

  case N_CTYPE:
  case N_CCLASS:
    if (exact == 0) {
      n = node;
    }
    break;

  case N_LIST:
    n = get_head_value_node(NCONS(node).left, exact, reg);
    break;

  case N_STRING:
    {
      StrNode* sn = &(NSTRING(node));

      if (sn->end <= sn->s)
       break;

      if (exact != 0 &&
         !NSTRING_IS_RAW(node) && IS_IGNORECASE(reg->options)) {
#if 0
        UChar* tmp = sn->s;
       if (! ONIGENC_IS_MBC_AMBIGUOUS(reg->enc, reg->ambig_flag,
                                       &tmp, sn->end))
         n = node;
#endif
      }
      else {
       n = node;
      }
    }
    break;

  case N_QUANTIFIER:
    {
      QuantifierNode* qn = &(NQUANTIFIER(node));
      if (qn->lower > 0) {
       if (IS_NOT_NULL(qn->head_exact))
         n = qn->head_exact;
       else
         n = get_head_value_node(qn->target, exact, reg);
      }
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));
      switch (en->type) {
      case EFFECT_OPTION:
       {
         OnigOptionType options = reg->options;

         reg->options = NEFFECT(node).option;
         n = get_head_value_node(NEFFECT(node).target, exact, reg);
         reg->options = options;
       }
       break;

      case EFFECT_MEMORY:
      case EFFECT_STOP_BACKTRACK:
       n = get_head_value_node(en->target, exact, reg);
       break;
      }
    }
    break;

  case N_ANCHOR:
    if (NANCHOR(node).type == ANCHOR_PREC_READ)
      n = get_head_value_node(NANCHOR(node).target, exact, reg);
    break;

  default:
    break;
  }

  return n;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_max_match_length ( Node node,
OnigDistance max,
ScanEnv env 
) [static]

Definition at line 2130 of file regcomp.c.

{
  OnigDistance tmax;
  int r = 0;

  *max = 0;
  switch (NTYPE(node)) {
  case N_LIST:
    do {
      r = get_max_match_length(NCONS(node).left, &tmax, env);
      if (r == 0)
       *max = distance_add(*max, tmax);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_ALT:
    do {
      r = get_max_match_length(NCONS(node).left, &tmax, env);
      if (r == 0 && *max < tmax) *max = tmax;
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_STRING:
    {
      StrNode* sn = &(NSTRING(node));
      *max = sn->end - sn->s;
    }
    break;

  case N_CTYPE:
    switch (NCTYPE(node).type) {
    case CTYPE_WORD:
    case CTYPE_NOT_WORD:
      *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
      break;

    default:
      break;
    }
    break;

  case N_CCLASS:
  case N_ANYCHAR:
    *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
    break;

  case N_BACKREF:
    {
      int i;
      int* backs;
      Node** nodes = SCANENV_MEM_NODES(env);
      BackrefNode* br = &(NBACKREF(node));
      if (br->state & NST_RECURSION) {
       *max = ONIG_INFINITE_DISTANCE;
       break;
      }
      backs = BACKREFS_P(br);
      for (i = 0; i < br->back_num; i++) {
       if (backs[i] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
       r = get_max_match_length(nodes[backs[i]], &tmax, env);
       if (r != 0) break;
       if (*max < tmax) *max = tmax;
      }
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    if (! IS_CALL_RECURSION(&(NCALL(node))))
      r = get_max_match_length(NCALL(node).target, max, env);
    else
      *max = ONIG_INFINITE_DISTANCE;
    break;
#endif

  case N_QUANTIFIER:
    {
      QuantifierNode* qn = &(NQUANTIFIER(node));

      if (qn->upper != 0) {
       r = get_max_match_length(qn->target, max, env);
       if (r == 0 && *max != 0) {
         if (! IS_REPEAT_INFINITE(qn->upper))
           *max = distance_multiply(*max, qn->upper);
         else
           *max = ONIG_INFINITE_DISTANCE;
       }
      }
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));
      switch (en->type) {
      case EFFECT_MEMORY:
#ifdef USE_SUBEXP_CALL
       if (IS_EFFECT_MAX_FIXED(en))
         *max = en->max_len;
       else {
         r = get_max_match_length(en->target, max, env);
         if (r == 0) {
           en->max_len = *max;
           SET_EFFECT_STATUS(node, NST_MAX_FIXED);
         }
       }
       break;
#endif
      case EFFECT_OPTION:
      case EFFECT_STOP_BACKTRACK:
       r = get_max_match_length(en->target, max, env);
       break;
      }
    }
    break;

  case N_ANCHOR:
  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_min_match_length ( Node node,
OnigDistance min,
ScanEnv env 
) [static]

Definition at line 2002 of file regcomp.c.

{
  OnigDistance tmin;
  int r = 0;

  *min = 0;
  switch (NTYPE(node)) {
  case N_BACKREF:
    {
      int i;
      int* backs;
      Node** nodes = SCANENV_MEM_NODES(env);
      BackrefNode* br = &(NBACKREF(node));
      if (br->state & NST_RECURSION) break;

      backs = BACKREFS_P(br);
      if (backs[0] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
      r = get_min_match_length(nodes[backs[0]], min, env);
      if (r != 0) break;
      for (i = 1; i < br->back_num; i++) {
       if (backs[i] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
       r = get_min_match_length(nodes[backs[i]], &tmin, env);
       if (r != 0) break;
       if (*min > tmin) *min = tmin;
      }
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    if (IS_CALL_RECURSION(&NCALL(node))) {
      EffectNode* en = &(NEFFECT(NCALL(node).target));
      if (IS_EFFECT_MIN_FIXED(en))
       *min = en->min_len;
    }
    else
      r = get_min_match_length(NCALL(node).target, min, env);
    break;
#endif

  case N_LIST:
    do {
      r = get_min_match_length(NCONS(node).left, &tmin, env);
      if (r == 0) *min += tmin;
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_ALT:
    {
      Node *x, *y;
      y = node;
      do {
       x = NCONS(y).left;
       r = get_min_match_length(x, &tmin, env);
       if (r != 0) break;
       if (y == node) *min = tmin;
       else if (*min > tmin) *min = tmin;
      } while (r == 0 && IS_NOT_NULL(y = NCONS(y).right));
    }
    break;

  case N_STRING:
    {
      StrNode* sn = &(NSTRING(node));
      *min = sn->end - sn->s;
    }
    break;

  case N_CTYPE:
    switch (NCTYPE(node).type) {
    case CTYPE_WORD:     *min = 1; break;
    case CTYPE_NOT_WORD: *min = 1; break;
    default:
      break;
    }
    break;

  case N_CCLASS:
  case N_ANYCHAR:
    *min = 1;
    break;

  case N_QUANTIFIER:
    {
      QuantifierNode* qn = &(NQUANTIFIER(node));

      if (qn->lower > 0) {
       r = get_min_match_length(qn->target, min, env);
       if (r == 0)
         *min = distance_multiply(*min, qn->lower);
      }
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));
      switch (en->type) {
      case EFFECT_MEMORY:
#ifdef USE_SUBEXP_CALL
       if (IS_EFFECT_MIN_FIXED(en))
         *min = en->min_len;
       else {
         r = get_min_match_length(en->target, min, env);
         if (r == 0) {
           en->min_len = *min;
           SET_EFFECT_STATUS(node, NST_MIN_FIXED);
         }
       }
       break;
#endif
      case EFFECT_OPTION:
      case EFFECT_STOP_BACKTRACK:
       r = get_min_match_length(en->target, min, env);
       break;
      }
    }
    break;

  case N_ANCHOR:
  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int is_anychar_star_quantifier ( QuantifierNode qn) [static]

Definition at line 697 of file regcomp.c.

{
  if (qn->greedy && IS_REPEAT_INFINITE(qn->upper) &&
      NTYPE(qn->target) == N_ANYCHAR)
    return 1;
  else
    return 0;
}

Here is the caller graph for this function:

static int is_equal_mml ( MinMaxLen a,
MinMaxLen b 
) [static]

Definition at line 3838 of file regcomp.c.

{
  return (a->min == b->min && a->max == b->max) ? 1 : 0;
}

Here is the caller graph for this function:

static int is_full_opt_exact_info ( OptExactInfo ex) [static]

Definition at line 3968 of file regcomp.c.

{
  return (ex->len >= OPT_EXACT_MAXLEN ? 1 : 0);
}

Here is the caller graph for this function:

static int is_left_anchor ( int  anc) [static]

Definition at line 3924 of file regcomp.c.

{
  if (anc == ANCHOR_END_BUF || anc == ANCHOR_SEMI_END_BUF ||
      anc == ANCHOR_END_LINE || anc == ANCHOR_PREC_READ ||
      anc == ANCHOR_PREC_READ_NOT)
    return 0;

  return 1;
}

Here is the caller graph for this function:

static int is_not_included ( Node x,
Node y,
regex_t reg 
) [static]

Definition at line 2394 of file regcomp.c.

{
  int i, len;
  OnigCodePoint code;
  UChar *p, c;
  int ytype;

 retry:
  ytype = NTYPE(y);
  switch (NTYPE(x)) {
  case N_CTYPE:
    {
      switch (ytype) {
      case N_CTYPE:
       switch (NCTYPE(x).type) {
       case CTYPE_WORD:
         if (NCTYPE(y).type == CTYPE_NOT_WORD)
           return 1;
         else
           return 0;
         break;
       case CTYPE_NOT_WORD:
         if (NCTYPE(y).type == CTYPE_WORD)
           return 1;
         else
           return 0;
         break;
       default:
         break;
       }
       break;

      case N_CCLASS:
      swap:
       {
         Node* tmp;
         tmp = x; x = y; y = tmp;
         goto retry;
       }
       break;

      case N_STRING:
       goto swap;
       break;

      default:
       break;
      }
    }
    break;

  case N_CCLASS:
    {
      CClassNode* xc = &(NCCLASS(x));
      switch (ytype) {
      case N_CTYPE:
       switch (NCTYPE(y).type) {
       case CTYPE_WORD:
         if (IS_NULL(xc->mbuf) && !IS_CCLASS_NOT(xc)) {
           for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
             if (BITSET_AT(xc->bs, i)) {
              if (ONIGENC_IS_CODE_SB_WORD(reg->enc, i)) return 0;
             }
           }
           return 1;
         }
         return 0;
         break;
       case CTYPE_NOT_WORD:
         for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
           if (! ONIGENC_IS_CODE_SB_WORD(reg->enc, i)) {
             if (!IS_CCLASS_NOT(xc)) {
              if (BITSET_AT(xc->bs, i))
                return 0;
             }
             else {
              if (! BITSET_AT(xc->bs, i))
                return 0;
             }
           }
         }
         return 1;
         break;

       default:
         break;
       }
       break;

      case N_CCLASS:
       {
         int v;
         CClassNode* yc = &(NCCLASS(y));

         for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
           v = BITSET_AT(xc->bs, i);
           if ((v != 0 && !IS_CCLASS_NOT(xc)) ||
                (v == 0 && IS_CCLASS_NOT(xc))) {
             v = BITSET_AT(yc->bs, i);
             if ((v != 0 && !IS_CCLASS_NOT(yc)) ||
                  (v == 0 && IS_CCLASS_NOT(yc)))
              return 0;
           }
         }
         if ((IS_NULL(xc->mbuf) && !IS_CCLASS_NOT(xc)) ||
             (IS_NULL(yc->mbuf) && !IS_CCLASS_NOT(yc)))
           return 1;
         return 0;
       }
       break;

      case N_STRING:
       goto swap;
       break;

      default:
       break;
      }
    }
    break;

  case N_STRING:
    {
      StrNode* xs = &(NSTRING(x));
      if (NSTRING_LEN(x) == 0)
       break;

      c = *(xs->s);
      switch (ytype) {
      case N_CTYPE:
       switch (NCTYPE(y).type) {
       case CTYPE_WORD:
         return (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end) ? 0 : 1);
         break;
       case CTYPE_NOT_WORD:
         return (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end) ? 1 : 0);
         break;
       default:
         break;
       }
       break;

      case N_CCLASS:
       {
         CClassNode* cc = &(NCCLASS(y));

         code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
                                 xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
         return (onig_is_code_in_cc(reg->enc, code, cc) != 0 ? 0 : 1);
       }
       break;

      case N_STRING:
       {
         UChar *q;
         StrNode* ys = &(NSTRING(y));
         len = NSTRING_LEN(x);
         if (len > NSTRING_LEN(y)) len = NSTRING_LEN(y);
         if (NSTRING_IS_AMBIG(x) || NSTRING_IS_AMBIG(y)) {
            /* tiny version */
            return 0;
         }
         else {
           for (i = 0, p = ys->s, q = xs->s; i < len; i++, p++, q++) {
             if (*p != *q) return 1;
           }
         }
       }
       break;
       
      default:
       break;
      }
    }
    break;

  default:
    break;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int is_set_opt_anc_info ( OptAncInfo to,
int  anc 
) [static]

Definition at line 3935 of file regcomp.c.

{
  if ((to->left_anchor & anc) != 0) return 1;

  return ((to->right_anchor & anc) != 0 ? 1 : 0);
}

Here is the caller graph for this function:

static UChar* k_strdup ( UChar s,
UChar end 
) [static]

Definition at line 51 of file regcomp.c.

{
  int len = end - s;

  if (len > 0) {
    UChar* r = (UChar* )xmalloc(len + 1);
    CHECK_NULL_RETURN(r);
    xmemcpy(r, s, len);
    r[len] = (UChar )0;
    return r;
  }
  else return NULL;
}

Here is the caller graph for this function:

static int map_position_value ( OnigEncoding  enc,
int  i 
) [static]

Definition at line 3768 of file regcomp.c.

{
  static const short int ByteValTable[] = {
     5,  1,  1,  1,  1,  1,  1,  1,  1, 10, 10,  1,  1, 10,  1,  1,
     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    12,  4,  7,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5,  5,  5,
     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  5,  5,
     5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  6,  5,  5,  5,
     5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  1
  };

  if (i < sizeof(ByteValTable)/sizeof(ByteValTable[0])) {
    if (i == 0 && ONIGENC_MBC_MINLEN(enc) > 1)
      return 20;
    else
      return (int )ByteValTable[i];
  }
  else
    return 4;   /* Take it easy. */
}

Here is the caller graph for this function:

static int next_setup ( Node node,
Node next_node,
regex_t reg 
) [static]

Definition at line 3153 of file regcomp.c.

{
  int type;

 retry:
  type = NTYPE(node);
  if (type == N_QUANTIFIER) {
    QuantifierNode* qn = &(NQUANTIFIER(node));
    if (qn->greedy && IS_REPEAT_INFINITE(qn->upper)) {
#ifdef USE_QUANTIFIER_PEEK_NEXT
      qn->next_head_exact = get_head_value_node(next_node, 1, reg);
#endif
      /* automatic posseivation a*b ==> (?>a*)b */
      if (qn->lower <= 1) {
       int ttype = NTYPE(qn->target);
       if (IS_NODE_TYPE_SIMPLE(ttype)) {
         Node *x, *y;
         x = get_head_value_node(qn->target, 0, reg);
         if (IS_NOT_NULL(x)) {
           y = get_head_value_node(next_node,  0, reg);
           if (IS_NOT_NULL(y) && is_not_included(x, y, reg)) {
             Node* en = onig_node_new_effect(EFFECT_STOP_BACKTRACK);
             CHECK_NULL_RETURN_VAL(en, ONIGERR_MEMORY);
             SET_EFFECT_STATUS(en, NST_STOP_BT_SIMPLE_REPEAT);
             swap_node(node, en);
             NEFFECT(node).target = en;
           }
         }
       }
      }
    }
  }
  else if (type == N_EFFECT) {
    EffectNode* en = &(NEFFECT(node));
    if (en->type == EFFECT_MEMORY) {
      node = en->target;
      goto retry;
    }
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int noname_disable_map ( Node **  plink,
GroupNumRemap map,
int counter 
) [static]

Definition at line 1729 of file regcomp.c.

{
  int r = 0;
  Node* node = *plink;

  switch (NTYPE(node)) {
  case N_LIST:
  case N_ALT:
    do {
      r = noname_disable_map(&(NCONS(node).left), map, counter);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_QUANTIFIER:
    {
      Node** ptarget = &(NQUANTIFIER(node).target);
      Node*  old = *ptarget;
      r = noname_disable_map(ptarget, map, counter);
      if (*ptarget != old && NTYPE(*ptarget) == N_QUANTIFIER) {
       onig_reduce_nested_quantifier(node, *ptarget);
      }
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));
      if (en->type == EFFECT_MEMORY) {
       if (IS_EFFECT_NAMED_GROUP(en)) {
         (*counter)++;
         map[en->regnum].new_val = *counter;
         en->regnum = *counter;
         r = noname_disable_map(&(en->target), map, counter);
       }
       else {
         *plink = en->target;
         en->target = NULL_NODE;
         onig_node_free(node);
         r = noname_disable_map(plink, map, counter);
       }
      }
      else
       r = noname_disable_map(&(en->target), map, counter);
    }
    break;

  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int numbered_ref_check ( Node node) [static]

Definition at line 1841 of file regcomp.c.

{
  int r = 0;

  switch (NTYPE(node)) {
  case N_LIST:
  case N_ALT:
    do {
      r = numbered_ref_check(NCONS(node).left);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;
  case N_QUANTIFIER:
    r = numbered_ref_check(NQUANTIFIER(node).target);
    break;
  case N_EFFECT:
    r = numbered_ref_check(NEFFECT(node).target);
    break;

  case N_BACKREF:
    if (! IS_BACKREF_NAME_REF(&(NBACKREF(node))))
      return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
    break;

  default:
    break;
  }

  return r;
}

Here is the caller graph for this function:

int onig_alloc_init ( regex_t **  reg,
OnigOptionType  option,
OnigAmbigType  ambig_flag,
OnigEncoding  enc,
OnigSyntaxType syntax 
)

Definition at line 5341 of file regcomp.c.

{
  if (! onig_inited)
    onig_init();

  if (ONIGENC_IS_UNDEF(enc))
    return ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED;

  if ((option & (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP))
      == (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP)) {
    return ONIGERR_INVALID_COMBINATION_OF_OPTIONS;
  }

  *reg = (regex_t* )xmalloc(sizeof(regex_t));
  if (IS_NULL(*reg)) return ONIGERR_MEMORY;
  (*reg)->state = ONIG_STATE_MODIFY;

  if ((option & ONIG_OPTION_NEGATE_SINGLELINE) != 0) {
    option |= syntax->options;
    option &= ~ONIG_OPTION_SINGLELINE;
  }
  else
    option |= syntax->options;

  (*reg)->enc              = enc;
  (*reg)->options          = option;
  (*reg)->syntax           = syntax;
  (*reg)->optimize         = 0;
  (*reg)->exact            = (UChar* )NULL;
  (*reg)->int_map          = (int* )NULL;
  (*reg)->int_map_backward = (int* )NULL;
  (*reg)->chain            = (regex_t* )NULL;

  (*reg)->p                = (UChar* )NULL;
  (*reg)->alloc            = 0;
  (*reg)->used             = 0;
  (*reg)->name_table       = (void* )NULL;

  (*reg)->ambig_flag       = ambig_flag;
  (*reg)->ambig_flag      &= ONIGENC_SUPPORT_AMBIG_FLAG(enc);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int onig_bbuf_init ( BBuf buf,
int  size 
)

Definition at line 123 of file regcomp.c.

{
  buf->p = (UChar* )xmalloc(size);
  if (IS_NULL(buf->p)) return(ONIGERR_MEMORY);

  buf->alloc = size;
  buf->used  = 0;
  return 0;
}
void onig_chain_link_add ( regex_t to,
regex_t add 
)

Definition at line 5020 of file regcomp.c.

void onig_chain_reduce ( regex_t reg)

Definition at line 5029 of file regcomp.c.

{
  regex_t *head, *prev;

  prev = reg;
  head = prev->chain;
  if (IS_NOT_NULL(head)) {
    reg->state = ONIG_STATE_MODIFY;
    while (IS_NOT_NULL(head->chain)) {
      prev = head;
      head = head->chain;
    }
    prev->chain = (regex_t* )NULL;
    REGEX_TRANSFER(reg, head);
  }
}

Here is the caller graph for this function:

int onig_compile ( regex_t reg,
const UChar pattern,
const UChar pattern_end,
OnigErrorInfo einfo 
)

Definition at line 5132 of file regcomp.c.

{
#define COMPILE_INIT_SIZE  20

  int r, init_size;
  Node*  root;
  ScanEnv  scan_env;
#ifdef USE_SUBEXP_CALL
  UnsetAddrList  uslist;
#endif

  reg->state = ONIG_STATE_COMPILING;

#ifdef ONIG_DEBUG
  print_enc_string(stderr, reg->enc, pattern, pattern_end);
#endif

  if (reg->alloc == 0) {
    init_size = (pattern_end - pattern) * 2;
    if (init_size <= 0) init_size = COMPILE_INIT_SIZE;
    r = BBUF_INIT(reg, init_size);
    if (r != 0) goto end;
  }
  else
    reg->used = 0;

  reg->num_mem            = 0;
  reg->num_repeat         = 0;
  reg->num_null_check     = 0;
  reg->repeat_range_alloc = 0;
  reg->repeat_range       = (OnigRepeatRange* )NULL;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
  reg->num_comb_exp_check = 0;
#endif

  r = onig_parse_make_tree(&root, pattern, pattern_end, reg, &scan_env);
  if (r != 0) goto err;

#ifdef USE_NAMED_GROUP
  /* mixed use named group and no-named group */
  if (scan_env.num_named > 0 &&
      IS_SYNTAX_BV(scan_env.syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
      !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
    if (scan_env.num_named != scan_env.num_mem)
      r = disable_noname_group_capture(&root, reg, &scan_env);
    else
      r = numbered_ref_check(root);

    if (r != 0) goto err;
  }
#endif

#ifdef ONIG_DEBUG_PARSE_TREE
  print_tree(stderr, root);
#endif

#ifdef USE_SUBEXP_CALL
  if (scan_env.num_call > 0) {
    r = unset_addr_list_init(&uslist, scan_env.num_call);
    if (r != 0) goto err;
    scan_env.unset_addr_list = &uslist;
    r = setup_subexp_call(root, &scan_env);
    if (r != 0) goto err_unset;
    r = subexp_recursive_check_trav(root, &scan_env);
    if (r  < 0) goto err_unset;
    r = subexp_inf_recursive_check_trav(root, &scan_env);
    if (r != 0) goto err_unset;

    reg->num_call = scan_env.num_call;
  }
  else
    reg->num_call = 0;
#endif

  r = setup_tree(root, reg, 0, &scan_env);
  if (r != 0) goto err_unset;

  reg->capture_history  = scan_env.capture_history;
  reg->bt_mem_start     = scan_env.bt_mem_start;
  reg->bt_mem_start    |= reg->capture_history;
  if (IS_FIND_CONDITION(reg->options))
    BIT_STATUS_ON_ALL(reg->bt_mem_end);
  else {
    reg->bt_mem_end  = scan_env.bt_mem_end;
    reg->bt_mem_end |= reg->capture_history;
  }

#ifdef USE_COMBINATION_EXPLOSION_CHECK
  if (scan_env.backrefed_mem == 0
#ifdef USE_SUBEXP_CALL
      || scan_env.num_call == 0
#endif
      ) {
    setup_comb_exp_check(root, 0, &scan_env);
#ifdef USE_SUBEXP_CALL
    if (scan_env.has_recursion != 0) {
      scan_env.num_comb_exp_check = 0;
    }
    else
#endif
    if (scan_env.comb_exp_max_regnum > 0) {
      int i;
      for (i = 1; i <= scan_env.comb_exp_max_regnum; i++) {
       if (BIT_STATUS_AT(scan_env.backrefed_mem, i) != 0) {
         scan_env.num_comb_exp_check = 0;
         break;
       }
      }
    }
  }

  reg->num_comb_exp_check = scan_env.num_comb_exp_check;
#endif

  clear_optimize_info(reg);
#ifndef ONIG_DONT_OPTIMIZE
  r = set_optimize_info_from_tree(root, reg, &scan_env);
  if (r != 0) goto err_unset;
#endif

  if (IS_NOT_NULL(scan_env.mem_nodes_dynamic)) {
    xfree(scan_env.mem_nodes_dynamic);
    scan_env.mem_nodes_dynamic = (Node** )NULL;
  }

  r = compile_tree(root, reg);
  if (r == 0) {
    r = add_opcode(reg, OP_END);
#ifdef USE_SUBEXP_CALL
    if (scan_env.num_call > 0) {
      r = unset_addr_list_fix(&uslist, reg);
      unset_addr_list_end(&uslist);
      if (r) goto err;
    }
#endif

    if ((reg->num_repeat != 0) || (reg->bt_mem_end != 0))
      reg->stack_pop_level = STACK_POP_LEVEL_ALL;
    else {
      if (reg->bt_mem_start != 0)
       reg->stack_pop_level = STACK_POP_LEVEL_MEM_START;
      else
       reg->stack_pop_level = STACK_POP_LEVEL_FREE;
    }
  }
#ifdef USE_SUBEXP_CALL
  else if (scan_env.num_call > 0) {
    unset_addr_list_end(&uslist);
  }
#endif
  onig_node_free(root);

#ifdef ONIG_DEBUG_COMPILE
#ifdef USE_NAMED_GROUP
  onig_print_names(stderr, reg);
#endif
  print_compiled_byte_code_list(stderr, reg);
#endif

 end:
  reg->state = ONIG_STATE_NORMAL;
  return r;

 err_unset:
#ifdef USE_SUBEXP_CALL
  if (scan_env.num_call > 0) {
    unset_addr_list_end(&uslist);
  }
#endif
 err:
  if (IS_NOT_NULL(scan_env.error)) {
    if (IS_NOT_NULL(einfo)) {
      einfo->enc     = scan_env.enc;
      einfo->par     = scan_env.error;
      einfo->par_end = scan_env.error_end;
    }
  }

  if (IS_NOT_NULL(root)) onig_node_free(root);
  if (IS_NOT_NULL(scan_env.mem_nodes_dynamic))
      xfree(scan_env.mem_nodes_dynamic);
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int onig_end ( void  )

Definition at line 5431 of file regcomp.c.

{
  extern int onig_free_shared_cclass_table(void);

  THREAD_ATOMIC_START;

#ifdef ONIG_DEBUG_STATISTICS
  onig_print_statistics(stderr);
#endif

#ifdef USE_SHARED_CCLASS_TABLE
  onig_free_shared_cclass_table();
#endif

#ifdef USE_RECYCLE_NODE
  onig_free_node_list();
#endif

  onig_inited = 0;

  THREAD_ATOMIC_END;
  THREAD_SYSTEM_END;
  return 0;
}

Here is the call graph for this function:

void onig_free ( regex_t reg)

Definition at line 4990 of file regcomp.c.

{
  if (IS_NOT_NULL(reg)) {
    onig_free_body(reg);
    xfree(reg);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void onig_free_body ( regex_t reg) [static]

Definition at line 4975 of file regcomp.c.

{
  if (IS_NOT_NULL(reg->p))                xfree(reg->p);
  if (IS_NOT_NULL(reg->exact))            xfree(reg->exact);
  if (IS_NOT_NULL(reg->int_map))          xfree(reg->int_map);
  if (IS_NOT_NULL(reg->int_map_backward)) xfree(reg->int_map_backward);
  if (IS_NOT_NULL(reg->repeat_range))     xfree(reg->repeat_range);
  if (IS_NOT_NULL(reg->chain))            onig_free(reg->chain);

#ifdef USE_NAMED_GROUP
  onig_names_free(reg);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 37 of file regcomp.c.

int onig_init ( void  )

Definition at line 5408 of file regcomp.c.

{
  if (onig_inited != 0)
    return 0;

  onig_inited = 1;

  THREAD_SYSTEM_INIT;
  THREAD_ATOMIC_START;

  onigenc_init();
  onigenc_set_default_caseconv_table((UChar* )0);

#ifdef ONIG_DEBUG_STATISTICS
  onig_statistics_init();
#endif

  THREAD_ATOMIC_END;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int onig_new ( regex_t **  reg,
const UChar pattern,
const UChar pattern_end,
OnigOptionType  option,
OnigEncoding  enc,
OnigSyntaxType syntax,
OnigErrorInfo einfo 
)

Definition at line 5387 of file regcomp.c.

{
  int r;

  if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;

  r = onig_alloc_init(reg, option, ONIGENC_AMBIGUOUS_MATCH_DEFAULT,
                      enc, syntax);
  if (r) return r;

  r = onig_compile(*reg, pattern, pattern_end, einfo);
  if (r) {
    onig_free(*reg);
    *reg = NULL;
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 43 of file regcomp.c.

{
  OnigDefaultAmbigFlag = ambig_flag;
  return 0;
}
void onig_transfer ( regex_t to,
regex_t from 
)

Definition at line 5006 of file regcomp.c.

static int optimize_node_left ( Node node,
NodeOptInfo opt,
OptEnv env 
) [static]

Definition at line 4334 of file regcomp.c.

{
  int type;
  int r = 0;

  clear_node_opt_info(opt);
  set_bound_node_opt_info(opt, &env->mmd);

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
    {
      OptEnv nenv;
      NodeOptInfo nopt;
      Node* nd = node;

      copy_opt_env(&nenv, env);
      do {
       r = optimize_node_left(NCONS(nd).left, &nopt, &nenv);
       if (r == 0) {
         add_mml(&nenv.mmd, &nopt.len);
         concat_left_node_opt_info(env->enc, opt, &nopt);
       }
      } while (r == 0 && IS_NOT_NULL(nd = NCONS(nd).right));
    }
    break;

  case N_ALT:
    {
      NodeOptInfo nopt;
      Node* nd = node;

      do {
       r = optimize_node_left(NCONS(nd).left, &nopt, env);
       if (r == 0) {
         if (nd == node) copy_node_opt_info(opt, &nopt);
         else            alt_merge_node_opt_info(opt, &nopt, env);
       }
      } while ((r == 0) && IS_NOT_NULL(nd = NCONS(nd).right));
    }
    break;

  case N_STRING:
    {
      StrNode* sn = &(NSTRING(node));
      int slen = sn->end - sn->s;
      int is_raw = NSTRING_IS_RAW(node);

      if (! NSTRING_IS_AMBIG(node)) {
       concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
                              NSTRING_IS_RAW(node), env->enc);
       if (slen > 0) {
         add_char_opt_map_info(&opt->map, *(sn->s), env->enc);
       }
        set_mml(&opt->len, slen, slen);
      }
      else {
        int n, max;

        concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
                                  is_raw, env->enc);
        opt->exb.ignore_case = 1;

       if (slen > 0) {
          r = add_char_amb_opt_map_info(&opt->map, sn->s, sn->end,
                                        env->enc, env->ambig_flag);
          if (r != 0) break;
       }

        if (NSTRING_IS_AMBIG_REDUCE(node)) {
          n = onigenc_strlen(env->enc, sn->s, sn->end);
          max = ONIGENC_MBC_MAXLEN_DIST(env->enc) * n;
        }
        else {
          max = slen;
        }
        set_mml(&opt->len, slen, max);
      }

      if (opt->exb.len == slen)
       opt->exb.reach_end = 1;
    }
    break;

  case N_CCLASS:
    {
      int i, z;
      CClassNode* cc = &(NCCLASS(node));

      /* no need to check ignore case. (setted in setup_tree()) */

      if (IS_NOT_NULL(cc->mbuf) || IS_CCLASS_NOT(cc)) {
        OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
       OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);

       set_mml(&opt->len, min, max);
      }
      else {
        for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
          z = BITSET_AT(cc->bs, i);
          if ((z && !IS_CCLASS_NOT(cc)) || (!z && IS_CCLASS_NOT(cc))) {
            add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
          }
        }
       set_mml(&opt->len, 1, 1);
      }
    }
    break;

  case N_CTYPE:
    {
      int i, min, max;

      max = ONIGENC_MBC_MAXLEN_DIST(env->enc);

      if (max == 1) {
        min = 1;

       switch (NCTYPE(node).type) {
       case CTYPE_NOT_WORD:
          for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
            if (! ONIGENC_IS_CODE_WORD(env->enc, i)) {
              add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
            }
          }
          break;

       case CTYPE_WORD:
          for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
            if (ONIGENC_IS_CODE_WORD(env->enc, i)) {
              add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
            }
          }
         break;
       }
      }
      else {
        min = ONIGENC_MBC_MINLEN(env->enc);
      }
      set_mml(&opt->len, min, max);
    }
    break;

  case N_ANYCHAR:
    {
      OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
      OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
      set_mml(&opt->len, min, max);
    }
    break;

  case N_ANCHOR:
    switch (NANCHOR(node).type) {
    case ANCHOR_BEGIN_BUF:
    case ANCHOR_BEGIN_POSITION:
    case ANCHOR_BEGIN_LINE:
    case ANCHOR_END_BUF:
    case ANCHOR_SEMI_END_BUF:
    case ANCHOR_END_LINE:
      add_opt_anc_info(&opt->anc, NANCHOR(node).type);
      break;

    case ANCHOR_PREC_READ:
      {
       NodeOptInfo nopt;

       r = optimize_node_left(NANCHOR(node).target, &nopt, env);
       if (r == 0) {
         if (nopt.exb.len > 0)
           copy_opt_exact_info(&opt->expr, &nopt.exb);
         else if (nopt.exm.len > 0)
           copy_opt_exact_info(&opt->expr, &nopt.exm);

         opt->expr.reach_end = 0;

         if (nopt.map.value > 0)
           copy_opt_map_info(&opt->map, &nopt.map);
       }
      }
      break;

    case ANCHOR_PREC_READ_NOT:
    case ANCHOR_LOOK_BEHIND: /* Sorry, I can't make use of it. */
    case ANCHOR_LOOK_BEHIND_NOT:
      break;
    }
    break;

  case N_BACKREF:
    {
      int i;
      int* backs;
      OnigDistance min, max, tmin, tmax;
      Node** nodes = SCANENV_MEM_NODES(env->scan_env);
      BackrefNode* br = &(NBACKREF(node));

      if (br->state & NST_RECURSION) {
       set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
       break;
      }
      backs = BACKREFS_P(br);
      r = get_min_match_length(nodes[backs[0]], &min, env->scan_env);
      if (r != 0) break;
      r = get_max_match_length(nodes[backs[0]], &max, env->scan_env);
      if (r != 0) break;
      for (i = 1; i < br->back_num; i++) {
       r = get_min_match_length(nodes[backs[i]], &tmin, env->scan_env);
       if (r != 0) break;
       r = get_max_match_length(nodes[backs[i]], &tmax, env->scan_env);
       if (r != 0) break;
       if (min > tmin) min = tmin;
       if (max < tmax) max = tmax;
      }
      if (r == 0) set_mml(&opt->len, min, max);
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    if (IS_CALL_RECURSION(&(NCALL(node))))
      set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
    else {
      OnigOptionType save = env->options;
      env->options = NEFFECT(NCALL(node).target).option;
      r = optimize_node_left(NCALL(node).target, opt, env);
      env->options = save;
    }
    break;
#endif

  case N_QUANTIFIER:
    {
      int i;
      OnigDistance min, max;
      NodeOptInfo nopt;
      QuantifierNode* qn = &(NQUANTIFIER(node));

      r = optimize_node_left(qn->target, &nopt, env);
      if (r) break;

      if (qn->lower == 0 && IS_REPEAT_INFINITE(qn->upper)) {
       if (env->mmd.max == 0 &&
           NTYPE(qn->target) == N_ANYCHAR && qn->greedy) {
         if (IS_MULTILINE(env->options))
           add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_ML);
         else
           add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR);
       }
      }
      else {
       if (qn->lower > 0) {
         copy_node_opt_info(opt, &nopt);
         if (nopt.exb.len > 0) {
           if (nopt.exb.reach_end) {
             for (i = 2; i < qn->lower &&
                        ! is_full_opt_exact_info(&opt->exb); i++) {
              concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
             }
             if (i < qn->lower) {
              opt->exb.reach_end = 0;
             }
           }
         }

         if (qn->lower != qn->upper) {
           opt->exb.reach_end = 0;
           opt->exm.reach_end = 0;
         }
         if (qn->lower > 1)
           opt->exm.reach_end = 0;
       }
      }

      min = distance_multiply(nopt.len.min, qn->lower);
      if (IS_REPEAT_INFINITE(qn->upper))
       max = (nopt.len.max > 0 ? ONIG_INFINITE_DISTANCE : 0);
      else
       max = distance_multiply(nopt.len.max, qn->upper);

      set_mml(&opt->len, min, max);
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));

      switch (en->type) {
      case EFFECT_OPTION:
       {
         OnigOptionType save = env->options;

         env->options = en->option;
         r = optimize_node_left(en->target, opt, env);
         env->options = save;
       }
       break;

      case EFFECT_MEMORY:
#ifdef USE_SUBEXP_CALL
       en->opt_count++;
       if (en->opt_count > MAX_NODE_OPT_INFO_REF_COUNT) {
         OnigDistance min, max;

         min = 0;
         max = ONIG_INFINITE_DISTANCE;
         if (IS_EFFECT_MIN_FIXED(en)) min = en->min_len;
         if (IS_EFFECT_MAX_FIXED(en)) max = en->max_len;
         set_mml(&opt->len, min, max);
       }
       else
#endif
       {
         r = optimize_node_left(en->target, opt, env);

         if (is_set_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK)) {
           if (BIT_STATUS_AT(env->scan_env->backrefed_mem, en->regnum))
             remove_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK);
         }
       }
       break;

      case EFFECT_STOP_BACKTRACK:
       r = optimize_node_left(en->target, opt, env);
       break;
      }
    }
    break;

  default:
#ifdef ONIG_DEBUG
    fprintf(stderr, "optimize_node_left: undefined node type %d\n",
           NTYPE(node));
#endif
    r = ONIGERR_TYPE_BUG;
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int quantifiers_memory_node_info ( Node node) [static]

Definition at line 1934 of file regcomp.c.

{
  int r = 0;

  switch (NTYPE(node)) {
  case N_LIST:
  case N_ALT:
    {
      int v;
      do {
       v = quantifiers_memory_node_info(NCONS(node).left);
       if (v > r) r = v;
      } while (v >= 0 && IS_NOT_NULL(node = NCONS(node).right));
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    if (IS_CALL_RECURSION(&NCALL(node))) {
      return NQ_TARGET_IS_EMPTY_REC; /* tiny version */
    }
    else
      r = quantifiers_memory_node_info(NCALL(node).target);
    break;
#endif

  case N_QUANTIFIER:
    {
      QuantifierNode* qn = &(NQUANTIFIER(node));
      if (qn->upper != 0) {
       r = quantifiers_memory_node_info(qn->target);
      }
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));
      switch (en->type) {
      case EFFECT_MEMORY:
       return NQ_TARGET_IS_EMPTY_MEM;
       break;

      case EFFECT_OPTION:
      case EFFECT_STOP_BACKTRACK:
       r = quantifiers_memory_node_info(en->target);
       break;
      default:
       break;
      }
    }
    break;

  case N_BACKREF:
  case N_STRING:
  case N_CTYPE:
  case N_CCLASS:
  case N_ANYCHAR:
  case N_ANCHOR:
  default:
    break;
  }

  return r;
}

Here is the caller graph for this function:

static void remove_opt_anc_info ( OptAncInfo to,
int  anc 
) [static]

Definition at line 3952 of file regcomp.c.

{
  if (is_left_anchor(anc))
    to->left_anchor &= ~anc;
  else
    to->right_anchor &= ~anc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int renumber_by_map ( Node node,
GroupNumRemap map 
) [static]

Definition at line 1811 of file regcomp.c.

{
  int r = 0;

  switch (NTYPE(node)) {
  case N_LIST:
  case N_ALT:
    do {
      r = renumber_by_map(NCONS(node).left, map);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;
  case N_QUANTIFIER:
    r = renumber_by_map(NQUANTIFIER(node).target, map);
    break;
  case N_EFFECT:
    r = renumber_by_map(NEFFECT(node).target, map);
    break;

  case N_BACKREF:
    r = renumber_node_backref(node, map);
    break;

  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int renumber_node_backref ( Node node,
GroupNumRemap map 
) [static]

Definition at line 1783 of file regcomp.c.

{
  int i, pos, n, old_num;
  int *backs;
  BackrefNode* bn = &(NBACKREF(node));

  if (! IS_BACKREF_NAME_REF(bn))
    return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;

  old_num = bn->back_num;
  if (IS_NULL(bn->back_dynamic))
    backs = bn->back_static;
  else
    backs = bn->back_dynamic;

  for (i = 0, pos = 0; i < old_num; i++) {
    n = map[backs[i]].new_val;
    if (n > 0) {
      backs[pos] = n;
      pos++;
    }
  }

  bn->back_num = pos;
  return 0;
}

Here is the caller graph for this function:

static void select_opt_exact_info ( OnigEncoding  enc,
OptExactInfo now,
OptExactInfo alt 
) [static]

Definition at line 4074 of file regcomp.c.

{
  int v1, v2;

  v1 = now->len;
  v2 = alt->len;

  if (v2 == 0) {
    return ;
  }
  else if (v1 == 0) {
    copy_opt_exact_info(now, alt);
    return ;
  }
  else if (v1 <= 2 && v2 <= 2) {
    /* ByteValTable[x] is big value --> low price */
    v2 = map_position_value(enc, now->s[0]);
    v1 = map_position_value(enc, alt->s[0]);

    if (now->len > 1) v1 += 5;
    if (alt->len > 1) v2 += 5;
  }

  if (now->ignore_case == 0) v1 *= 2;
  if (alt->ignore_case == 0) v2 *= 2;

  if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
    copy_opt_exact_info(now, alt);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void select_opt_map_info ( OptMapInfo now,
OptMapInfo alt 
) [static]

Definition at line 4176 of file regcomp.c.

{
  static int z = 1<<15; /* 32768: something big value */

  int v1, v2;

  if (alt->value == 0) return ;
  if (now->value == 0) {
    copy_opt_map_info(now, alt);
    return ;
  }

  v1 = z / now->value;
  v2 = z / alt->value;
  if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
    copy_opt_map_info(now, alt);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int select_str_opcode ( int  mb_len,
int  str_len,
int  ignore_case 
) [static]

Definition at line 293 of file regcomp.c.

{
  int op;

  if (ignore_case) {
    switch (str_len) {
    case 1:  op = OP_EXACT1_IC; break;
    default: op = OP_EXACTN_IC; break;
    }
  }
  else {
    switch (mb_len) {
    case 1:
      switch (str_len) {
      case 1:  op = OP_EXACT1; break;
      case 2:  op = OP_EXACT2; break;
      case 3:  op = OP_EXACT3; break;
      case 4:  op = OP_EXACT4; break;
      case 5:  op = OP_EXACT5; break;
      default: op = OP_EXACTN; break;
      }
      break;

    case 2:
      switch (str_len) {
      case 1:  op = OP_EXACTMB2N1; break;
      case 2:  op = OP_EXACTMB2N2; break;
      case 3:  op = OP_EXACTMB2N3; break;
      default: op = OP_EXACTMB2N;  break;
      }
      break;

    case 3:
      op = OP_EXACTMB3N;
      break;

    default:
      op = OP_EXACTMBN;
      break;
    }
  }
  return op;
}

Here is the caller graph for this function:

static int set_bm_skip ( UChar s,
UChar end,
OnigEncoding  enc,
UChar  skip[],
int **  int_skip 
) [static]

Definition at line 3692 of file regcomp.c.

{
  int i, len;

  len = end - s;
  if (len < ONIG_CHAR_TABLE_SIZE) {
    for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) skip[i] = len;

    for (i = 0; i < len - 1; i++)
      skip[s[i]] = len - 1 - i;
  }
  else {
    if (IS_NULL(*int_skip)) {
      *int_skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
      if (IS_NULL(*int_skip)) return ONIGERR_MEMORY;
    }
    for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) (*int_skip)[i] = len;

    for (i = 0; i < len - 1; i++)
      (*int_skip)[s[i]] = len - 1 - i;
  }
  return 0;
}

Here is the caller graph for this function:

static void set_bound_node_opt_info ( NodeOptInfo opt,
MinMaxLen mmd 
) [static]

Definition at line 4235 of file regcomp.c.

{
  copy_mml(&(opt->exb.mmd),  mmd);
  copy_mml(&(opt->expr.mmd), mmd);
  copy_mml(&(opt->map.mmd),  mmd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void set_mml ( MinMaxLen mml,
OnigDistance  min,
OnigDistance  max 
) [static]

Definition at line 3845 of file regcomp.c.

{
  mml->min = min;
  mml->max = max;
}

Here is the caller graph for this function:

static int set_optimize_exact_info ( regex_t reg,
OptExactInfo e 
) [static]

Definition at line 4676 of file regcomp.c.

{
  int r;

  if (e->len == 0) return 0;

  if (e->ignore_case) {
    reg->exact = (UChar* )xmalloc(e->len);
    CHECK_NULL_RETURN_VAL(reg->exact, ONIGERR_MEMORY);
    xmemcpy(reg->exact, e->s, e->len);
    reg->exact_end = reg->exact + e->len;
    reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
  }
  else {
    int allow_reverse;

    reg->exact = k_strdup(e->s, e->s + e->len);
    CHECK_NULL_RETURN_VAL(reg->exact, ONIGERR_MEMORY);
    reg->exact_end = reg->exact + e->len;
 
    allow_reverse =
       ONIGENC_IS_ALLOWED_REVERSE_MATCH(reg->enc, reg->exact, reg->exact_end);

    if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
      r = set_bm_skip(reg->exact, reg->exact_end, reg->enc,
                     reg->map, &(reg->int_map));
      if (r) return r;

      reg->optimize = (allow_reverse != 0
                     ? ONIG_OPTIMIZE_EXACT_BM : ONIG_OPTIMIZE_EXACT_BM_NOT_REV);
    }
    else {
      reg->optimize = ONIG_OPTIMIZE_EXACT;
    }
  }

  reg->dmin = e->mmd.min;
  reg->dmax = e->mmd.max;

  if (reg->dmin != ONIG_INFINITE_DISTANCE) {
    reg->threshold_len = reg->dmin + (reg->exact_end - reg->exact);
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int set_optimize_info_from_tree ( Node node,
regex_t reg,
ScanEnv scan_env 
) [static]

Definition at line 4751 of file regcomp.c.

{

  int r;
  NodeOptInfo opt;
  OptEnv env;

  env.enc        = reg->enc;
  env.options    = reg->options;
  env.ambig_flag = reg->ambig_flag;
  env.scan_env   = scan_env;
  clear_mml(&env.mmd);

  r = optimize_node_left(node, &opt, &env);
  if (r) return r;

  reg->anchor = opt.anc.left_anchor & (ANCHOR_BEGIN_BUF |
        ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML);

  reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF);

  if (reg->anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)) {
    reg->anchor_dmin = opt.len.min;
    reg->anchor_dmax = opt.len.max;
  }

  if (opt.exb.len > 0 || opt.exm.len > 0) {
    select_opt_exact_info(reg->enc, &opt.exb, &opt.exm);
    if (opt.map.value > 0 &&
       comp_opt_exact_or_map_info(&opt.exb, &opt.map) > 0) {
      goto set_map;
    }
    else {
      r = set_optimize_exact_info(reg, &opt.exb);
      set_sub_anchor(reg, &opt.exb.anc);
    }
  }
  else if (opt.map.value > 0) {
  set_map:
    set_optimize_map_info(reg, &opt.map);
    set_sub_anchor(reg, &opt.map.anc);
  }
  else {
    reg->sub_anchor |= opt.anc.left_anchor & ANCHOR_BEGIN_LINE;
    if (opt.len.max == 0)
      reg->sub_anchor |= opt.anc.right_anchor & ANCHOR_END_LINE;
  }

#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
  print_optimize_info(stderr, reg);
#endif
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void set_optimize_map_info ( regex_t reg,
OptMapInfo m 
) [static]

Definition at line 4723 of file regcomp.c.

{
  int i;

  for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
    reg->map[i] = m->map[i];

  reg->optimize   = ONIG_OPTIMIZE_MAP;
  reg->dmin       = m->mmd.min;
  reg->dmax       = m->mmd.max;

  if (reg->dmin != ONIG_INFINITE_DISTANCE) {
    reg->threshold_len = reg->dmin + 1;
  }
}

Here is the caller graph for this function:

static void set_sub_anchor ( regex_t reg,
OptAncInfo anc 
) [static]

Definition at line 4740 of file regcomp.c.

{
  reg->sub_anchor |= anc->left_anchor  & ANCHOR_BEGIN_LINE;
  reg->sub_anchor |= anc->right_anchor & ANCHOR_END_LINE;
}

Here is the caller graph for this function:

static int setup_comb_exp_check ( Node node,
int  state,
ScanEnv env 
) [static]

Definition at line 3301 of file regcomp.c.

{
  int type;
  int r = state;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
    {
      Node* prev = NULL_NODE;
      do {
       r = setup_comb_exp_check(NCONS(node).left, r, env);
       prev = NCONS(node).left;
      } while (r >= 0 && IS_NOT_NULL(node = NCONS(node).right));
    }
    break;

  case N_ALT:
    {
      int ret;
      do {
       ret = setup_comb_exp_check(NCONS(node).left, state, env);
       r |= ret;
      } while (ret >= 0 && IS_NOT_NULL(node = NCONS(node).right));
    }
    break;

  case N_QUANTIFIER:
    {
      int child_state = state;
      int add_state = 0;
      QuantifierNode* qn = &(NQUANTIFIER(node));
      Node* target = qn->target;
      int var_num;

      if (! IS_REPEAT_INFINITE(qn->upper)) {
       if (qn->upper > 1) {
         /* {0,1}, {1,1} are allowed */
         child_state |= CEC_IN_FINITE_REPEAT;

         /* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
         if (env->backrefed_mem == 0) {
           if (NTYPE(qn->target) == N_EFFECT) {
             EffectNode* en = &(NEFFECT(qn->target));
             if (en->type == EFFECT_MEMORY) {
              if (NTYPE(en->target) == N_QUANTIFIER) {
                QuantifierNode* q = &(NQUANTIFIER(en->target));
                if (IS_REPEAT_INFINITE(q->upper)
                    && q->greedy == qn->greedy) {
                  qn->upper = (qn->lower == 0 ? 1 : qn->lower);
                  if (qn->upper == 1)
                    child_state = state;
                }
              }
             }
           }
         }
       }
      }

      if (state & CEC_IN_FINITE_REPEAT) {
       qn->comb_exp_check_num = -1;
      }
      else {
       if (IS_REPEAT_INFINITE(qn->upper)) {
         var_num = CEC_INFINITE_NUM;
         child_state |= CEC_IN_INFINITE_REPEAT;
       }
       else {
         var_num = qn->upper - qn->lower;
       }

       if (var_num >= CEC_THRES_NUM_BIG_REPEAT)
         add_state |= CEC_CONT_BIG_REPEAT;

       if (((state & CEC_IN_INFINITE_REPEAT) != 0 && var_num != 0) ||
           ((state & CEC_CONT_BIG_REPEAT) != 0 &&
            var_num >= CEC_THRES_NUM_BIG_REPEAT)) {
         if (qn->comb_exp_check_num == 0) {
           env->num_comb_exp_check++;
           qn->comb_exp_check_num = env->num_comb_exp_check;
           if (env->curr_max_regnum > env->comb_exp_max_regnum)
             env->comb_exp_max_regnum = env->curr_max_regnum;
         }
       }
      }

      r = setup_comb_exp_check(target, child_state, env);
      r |= add_state;
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));

      switch (en->type) {
      case EFFECT_MEMORY:
       {
         if (env->curr_max_regnum < en->regnum)
           env->curr_max_regnum = en->regnum;

         r = setup_comb_exp_check(en->target, state, env);
       }
       break;

      default:
       r = setup_comb_exp_check(en->target, state, env);
       break;
      }
    }
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    if (IS_CALL_RECURSION(&(NCALL(node))))
      env->has_recursion = 1;
    else
      r = setup_comb_exp_check(NCALL(node).target, state, env);
    break;
#endif

  default:
    break;
  }

  return r;
}

Here is the caller graph for this function:

static int setup_look_behind ( Node node,
regex_t reg,
ScanEnv env 
) [static]

Definition at line 3132 of file regcomp.c.

{
  int r, len;
  AnchorNode* an = &(NANCHOR(node));

  r = get_char_length_tree(an->target, reg, &len);
  if (r == 0)
    an->char_len = len;
  else if (r == GET_CHAR_LEN_VARLEN)
    r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
  else if (r == GET_CHAR_LEN_TOP_ALT_VARLEN) {
    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND))
      r = divide_look_behind_alternatives(node);
    else
      r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int setup_subexp_call ( Node node,
ScanEnv env 
) [static]

Definition at line 2990 of file regcomp.c.

{
  int type;
  int r = 0;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
    do {
      r = setup_subexp_call(NCONS(node).left, env);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_ALT:
    do {
      r = setup_subexp_call(NCONS(node).left, env);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_QUANTIFIER:
    r = setup_subexp_call(NQUANTIFIER(node).target, env);
    break;
  case N_EFFECT:
    r = setup_subexp_call(NEFFECT(node).target, env);
    break;

  case N_CALL:
    {
      int n, num, *refs;
      UChar *p;
      CallNode* cn = &(NCALL(node));
      Node** nodes = SCANENV_MEM_NODES(env);

#ifdef USE_NAMED_GROUP
      n = onig_name_to_group_numbers(env->reg, cn->name, cn->name_end, &refs);
#else
      n = -1;
#endif
      if (n <= 0) {
       /* name not found, check group number. (?*ddd) */
       p = cn->name;
       num = onig_scan_unsigned_number(&p, cn->name_end, env->enc);
       if (num <= 0 || p != cn->name_end) {
         onig_scan_env_set_error_string(env,
                ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
         return ONIGERR_UNDEFINED_NAME_REFERENCE;
       }
#ifdef USE_NAMED_GROUP
       if (env->num_named > 0 &&
           IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
           !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
         return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
       }
#endif
       if (num > env->num_mem) {
         onig_scan_env_set_error_string(env,
               ONIGERR_UNDEFINED_GROUP_REFERENCE, cn->name, cn->name_end);
         return ONIGERR_UNDEFINED_GROUP_REFERENCE;
       }
       cn->ref_num = num;
       goto set_call_attr;
      }
      else if (n > 1) {
       onig_scan_env_set_error_string(env,
              ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL, cn->name, cn->name_end);
       return ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL;
      }
      else {
       cn->ref_num = refs[0];
      set_call_attr:
       cn->target = nodes[cn->ref_num];
       if (IS_NULL(cn->target)) {
         onig_scan_env_set_error_string(env,
                ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
         return ONIGERR_UNDEFINED_NAME_REFERENCE;
       }
       SET_EFFECT_STATUS(cn->target, NST_CALLED);
       BIT_STATUS_ON_AT(env->bt_mem_start, cn->ref_num);
       cn->unset_addr_list = env->unset_addr_list;
      }
    }
    break;

  case N_ANCHOR:
    {
      AnchorNode* an = &(NANCHOR(node));

      switch (an->type) {
      case ANCHOR_PREC_READ:
      case ANCHOR_PREC_READ_NOT:
      case ANCHOR_LOOK_BEHIND:
      case ANCHOR_LOOK_BEHIND_NOT:
       r = setup_subexp_call(an->target, env);
       break;
      }
    }
    break;

  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int setup_tree ( Node node,
regex_t reg,
int  state,
ScanEnv env 
) [static]

Definition at line 3445 of file regcomp.c.

{
  int type;
  int r = 0;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
    {
      Node* prev = NULL_NODE;
      do {
       r = setup_tree(NCONS(node).left, reg, state, env);
       if (IS_NOT_NULL(prev) && r == 0) {
         r = next_setup(prev, NCONS(node).left, reg);
       }
       prev = NCONS(node).left;
      } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    }
    break;

  case N_ALT:
    do {
      r = setup_tree(NCONS(node).left, reg, (state | IN_ALT), env);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_CCLASS:
    break;

  case N_STRING:
    if (IS_IGNORECASE(reg->options) && !NSTRING_IS_RAW(node)) {
      r = divide_ambig_string_node(node, reg);
    }
    break;

  case N_CTYPE:
  case N_ANYCHAR:
    break;

#ifdef USE_SUBEXP_CALL
  case N_CALL:
    break;
#endif

  case N_BACKREF:
    {
      int i;
      int* p;
      Node** nodes = SCANENV_MEM_NODES(env);
      BackrefNode* br = &(NBACKREF(node));
      p = BACKREFS_P(br);
      for (i = 0; i < br->back_num; i++) {
       if (p[i] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
       BIT_STATUS_ON_AT(env->backrefed_mem, p[i]);
       BIT_STATUS_ON_AT(env->bt_mem_start, p[i]);
#ifdef USE_BACKREF_AT_LEVEL
       if (IS_BACKREF_NEST_LEVEL(br)) {
         BIT_STATUS_ON_AT(env->bt_mem_end, p[i]);
       }
#endif
       SET_EFFECT_STATUS(nodes[p[i]], NST_MEM_BACKREFED);
      }
    }
    break;

  case N_QUANTIFIER:
    {
      OnigDistance d;
      QuantifierNode* qn = &(NQUANTIFIER(node));
      Node* target = qn->target;

      if ((state & IN_REPEAT) != 0) {
        qn->state |= NST_IN_REPEAT;
      }

      if (IS_REPEAT_INFINITE(qn->upper) || qn->upper >= 1) {
       r = get_min_match_length(target, &d, env);
       if (r) break;
       if (d == 0) {
         qn->target_empty_info = NQ_TARGET_IS_EMPTY;
#ifdef USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
         r = quantifiers_memory_node_info(target);
         if (r < 0) break;
         if (r > 0) {
           qn->target_empty_info = r;
         }
#endif
#if 0
         r = get_max_match_length(target, &d, env);
         if (r == 0 && d == 0) {
           /*  ()* ==> ()?, ()+ ==> ()  */
           qn->upper = 1;
           if (qn->lower > 1) qn->lower = 1;
           if (NTYPE(target) == N_STRING) {
             qn->upper = qn->lower = 0;  /* /(?:)+/ ==> // */
           }
         }
#endif
       }
      }

      state |= IN_REPEAT;
      if (qn->lower != qn->upper)
       state |= IN_VAR_REPEAT;
      r = setup_tree(target, reg, state, env);
      if (r) break;

      /* expand string */
#define EXPAND_STRING_MAX_LENGTH  100
      if (NTYPE(target) == N_STRING) {
       if (!IS_REPEAT_INFINITE(qn->lower) && qn->lower == qn->upper &&
           qn->lower > 1 && qn->lower <= EXPAND_STRING_MAX_LENGTH) {
         int len = NSTRING_LEN(target);
         StrNode* sn = &(NSTRING(target));

         if (len * qn->lower <= EXPAND_STRING_MAX_LENGTH) {
           int i, n = qn->lower;
           onig_node_conv_to_str_node(node, NSTRING(target).flag);
           for (i = 0; i < n; i++) {
             r = onig_node_str_cat(node, sn->s, sn->end);
             if (r) break;
           }
           onig_node_free(target);
           break; /* break case N_QUANTIFIER: */
         }
       }
      }

#ifdef USE_OP_PUSH_OR_JUMP_EXACT
      if (qn->greedy && (qn->target_empty_info != 0)) {
       if (NTYPE(target) == N_QUANTIFIER) {
         QuantifierNode* tqn = &(NQUANTIFIER(target));
         if (IS_NOT_NULL(tqn->head_exact)) {
           qn->head_exact  = tqn->head_exact;
           tqn->head_exact = NULL;
         }
       }
       else {
         qn->head_exact = get_head_value_node(qn->target, 1, reg);
       }
      }
#endif
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));

      switch (en->type) {
      case EFFECT_OPTION:
       {
         OnigOptionType options = reg->options;
         reg->options = NEFFECT(node).option;
         r = setup_tree(NEFFECT(node).target, reg, state, env);
         reg->options = options;
       }
       break;

      case EFFECT_MEMORY:
       if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT)) != 0) {
         BIT_STATUS_ON_AT(env->bt_mem_start, en->regnum);
         /* SET_EFFECT_STATUS(node, NST_MEM_IN_ALT_NOT); */
       }
        r = setup_tree(en->target, reg, state, env);
        break;

      case EFFECT_STOP_BACKTRACK:
       {
         Node* target = en->target;
         r = setup_tree(target, reg, state, env);
         if (NTYPE(target) == N_QUANTIFIER) {
           QuantifierNode* tqn = &(NQUANTIFIER(target));
           if (IS_REPEAT_INFINITE(tqn->upper) && tqn->lower <= 1 &&
              tqn->greedy != 0) {  /* (?>a*), a*+ etc... */
             int qtype = NTYPE(tqn->target);
             if (IS_NODE_TYPE_SIMPLE(qtype))
              SET_EFFECT_STATUS(node, NST_STOP_BT_SIMPLE_REPEAT);
           }
         }
       }
       break;
      }
    }
    break;

  case N_ANCHOR:
    {
      AnchorNode* an = &(NANCHOR(node));

      switch (an->type) {
      case ANCHOR_PREC_READ:
       r = setup_tree(an->target, reg, state, env);
       break;
      case ANCHOR_PREC_READ_NOT:
       r = setup_tree(an->target, reg, (state | IN_NOT), env);
       break;

/* allowed node types in look-behind */
#define ALLOWED_TYPE_IN_LB  \
  ( N_LIST | N_ALT | N_STRING | N_CCLASS | N_CTYPE | \
    N_ANYCHAR | N_ANCHOR | N_EFFECT | N_QUANTIFIER | N_CALL )

#define ALLOWED_EFFECT_IN_LB       ( EFFECT_MEMORY )
#define ALLOWED_EFFECT_IN_LB_NOT   0

#define ALLOWED_ANCHOR_IN_LB \
( ANCHOR_LOOK_BEHIND | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION )
#define ALLOWED_ANCHOR_IN_LB_NOT \
( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION )

      case ANCHOR_LOOK_BEHIND:
       {
         r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
                           ALLOWED_EFFECT_IN_LB, ALLOWED_ANCHOR_IN_LB);
         if (r < 0) return r;
         if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
         r = setup_look_behind(node, reg, env);
         if (r != 0) return r;
         r = setup_tree(an->target, reg, state, env);
       }
       break;

      case ANCHOR_LOOK_BEHIND_NOT:
       {
         r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
                    ALLOWED_EFFECT_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
         if (r < 0) return r;
         if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
         r = setup_look_behind(node, reg, env);
         if (r != 0) return r;
         r = setup_tree(an->target, reg, (state | IN_NOT), env);
       }
       break;
      }
    }
    break;

  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int subexp_inf_recursive_check ( Node node,
ScanEnv env,
int  head 
) [static]

Definition at line 2724 of file regcomp.c.

{
  int type;
  int r = 0;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
    {
      Node *x;
      OnigDistance min;
      int ret;

      x = node;
      do {
       ret = subexp_inf_recursive_check(NCONS(x).left, env, head);
       if (ret < 0 || ret == RECURSION_INFINITE) return ret;
       r |= ret;
       if (head) {
         ret = get_min_match_length(NCONS(x).left, &min, env);
         if (ret != 0) return ret;
         if (min != 0) head = 0;
       }
      } while (IS_NOT_NULL(x = NCONS(x).right));
    }
    break;

  case N_ALT:
    {
      int ret;
      r = RECURSION_EXIST;
      do {
       ret = subexp_inf_recursive_check(NCONS(node).left, env, head);
       if (ret < 0 || ret == RECURSION_INFINITE) return ret;
       r &= ret;
      } while (IS_NOT_NULL(node = NCONS(node).right));
    }
    break;

  case N_QUANTIFIER:
    r = subexp_inf_recursive_check(NQUANTIFIER(node).target, env, head);
    if (r == RECURSION_EXIST) {
      if (NQUANTIFIER(node).lower == 0) r = 0;
    }
    break;

  case N_ANCHOR:
    {
      AnchorNode* an = &(NANCHOR(node));
      switch (an->type) {
      case ANCHOR_PREC_READ:
      case ANCHOR_PREC_READ_NOT:
      case ANCHOR_LOOK_BEHIND:
      case ANCHOR_LOOK_BEHIND_NOT:
       r = subexp_inf_recursive_check(an->target, env, head);
       break;
      }
    }
    break;

  case N_CALL:
    r = subexp_inf_recursive_check(NCALL(node).target, env, head);
    break;

  case N_EFFECT:
    if (IS_EFFECT_MARK2(&(NEFFECT(node))))
      return 0;
    else if (IS_EFFECT_MARK1(&(NEFFECT(node))))
      return (head == 0 ? RECURSION_EXIST : RECURSION_INFINITE);
    else {
      SET_EFFECT_STATUS(node, NST_MARK2);
      r = subexp_inf_recursive_check(NEFFECT(node).target, env, head);
      CLEAR_EFFECT_STATUS(node, NST_MARK2);
    }
    break;

  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int subexp_inf_recursive_check_trav ( Node node,
ScanEnv env 
) [static]

Definition at line 2808 of file regcomp.c.

{
  int type;
  int r = 0;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
  case N_ALT:
    do {
      r = subexp_inf_recursive_check_trav(NCONS(node).left, env);
    } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_QUANTIFIER:
    r = subexp_inf_recursive_check_trav(NQUANTIFIER(node).target, env);
    break;

  case N_ANCHOR:
    {
      AnchorNode* an = &(NANCHOR(node));
      switch (an->type) {
      case ANCHOR_PREC_READ:
      case ANCHOR_PREC_READ_NOT:
      case ANCHOR_LOOK_BEHIND:
      case ANCHOR_LOOK_BEHIND_NOT:
       r = subexp_inf_recursive_check_trav(an->target, env);
       break;
      }
    }
    break;

  case N_EFFECT:
    {
      EffectNode* en = &(NEFFECT(node));

      if (IS_EFFECT_RECURSION(en)) {
       SET_EFFECT_STATUS(node, NST_MARK1);
       r = subexp_inf_recursive_check(en->target, env, 1);
       if (r > 0) return ONIGERR_NEVER_ENDING_RECURSION;
       CLEAR_EFFECT_STATUS(node, NST_MARK1);
      }
      r = subexp_inf_recursive_check_trav(en->target, env);
    }

    break;

  default:
    break;
  }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int subexp_recursive_check ( Node node) [static]

Definition at line 2863 of file regcomp.c.

{
  int type;
  int r = 0;

  type = NTYPE(node);
  switch (type) {
  case N_LIST:
  case N_ALT:
    do {
      r |= subexp_recursive_check(NCONS(node).left);
    } while (IS_NOT_NULL(node = NCONS(node).right));
    break;

  case N_QUANTIFIER:
    r = subexp_recursive_check(NQUANTIFIER(node).target);
    break;

  case