Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

Location:
EcnlProtoTool/trunk/onigmo-6.1.3
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/onigmo-6.1.3/src/regparse.c

    r321 r331  
    44/*-
    55 * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
    6  * Copyright (c) 2011-2014  K.Takata  <kentkt AT csc DOT jp>
     6 * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
    77 * All rights reserved.
    88 *
     
    3030
    3131#include "regparse.h"
    32 #include "st.h"
     32#include <stdarg.h>
    3333
    3434#define WARN_BUFSIZE    256
     
    3737
    3838
    39 OnigSyntaxType OnigSyntaxRuby = {
     39const OnigSyntaxType OnigSyntaxRuby = {
    4040  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
    4141     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
     
    5353      ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
    5454      ONIG_SYN_OP2_ESC_H_XDIGIT |
     55#ifndef RUBY
     56      ONIG_SYN_OP2_ESC_U_HEX4 |
     57#endif
    5558      ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER |
    5659      ONIG_SYN_OP2_QMARK_LPAREN_CONDITION |
    5760      ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK |
    58       ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP )
     61      ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP |
     62      ONIG_SYN_OP2_QMARK_TILDE_ABSENT )
    5963  , ( SYN_GNU_REGEX_BV |
    6064      ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
     
    6468      ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY |
    6569      ONIG_SYN_WARN_CC_OP_NOT_ESCAPED |
     70      ONIG_SYN_WARN_CC_DUP |
    6671      ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT )
    6772  , ( ONIG_OPTION_ASCII_RANGE | ONIG_OPTION_POSIX_BRACKET_ALL_RANGE |
     
    7883};
    7984
    80 OnigSyntaxType*  OnigDefaultSyntax = ONIG_SYNTAX_RUBY;
     85const OnigSyntaxType*  OnigDefaultSyntax = ONIG_SYNTAX_RUBY;
    8186
    8287extern void onig_null_warn(const char* s ARG_UNUSED) { }
     
    103108  onig_verb_warn = f;
    104109}
     110
     111static void CC_DUP_WARN(ScanEnv *env);
     112
     113
     114static unsigned int ParseDepthLimit = DEFAULT_PARSE_DEPTH_LIMIT;
     115
     116extern unsigned int
     117onig_get_parse_depth_limit(void)
     118{
     119  return ParseDepthLimit;
     120}
     121
     122extern int
     123onig_set_parse_depth_limit(unsigned int depth)
     124{
     125  if (depth == 0)
     126    ParseDepthLimit = DEFAULT_PARSE_DEPTH_LIMIT;
     127  else
     128    ParseDepthLimit = depth;
     129  return 0;
     130}
     131
    105132
    106133static void
     
    137164
    138165#define SET_ALL_MULTI_BYTE_RANGE(enc, pbuf) \
    139   add_code_range_to_buf(pbuf, MBCODE_START_POS(enc), ONIG_LAST_CODE_POINT)
     166  add_code_range_to_buf(pbuf, env, MBCODE_START_POS(enc), ONIG_LAST_CODE_POINT)
    140167
    141168#define ADD_ALL_MULTI_BYTE_RANGE(enc, mbuf) do {\
     
    146173} while (0)
    147174
     175
     176#define BITSET_SET_BIT_CHKDUP(bs, pos) do { \
     177  if (BITSET_AT(bs, pos)) CC_DUP_WARN(env); \
     178  BS_ROOM(bs, pos) |= BS_BIT(pos); \
     179} while (0)
    148180
    149181#define BITSET_IS_EMPTY(bs,empty) do {\
     
    158190
    159191static void
    160 bitset_set_range(BitSetRef bs, int from, int to)
     192bitset_set_range(ScanEnv *env, BitSetRef bs, int from, int to)
    161193{
    162194  int i;
    163195  for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) {
    164     BITSET_SET_BIT(bs, i);
     196    BITSET_SET_BIT_CHKDUP(bs, i);
    165197  }
    166198}
     
    210242}
    211243
     244#if defined(USE_NAMED_GROUP) && !defined(USE_ST_LIBRARY)
    212245extern int
    213246onig_strncmp(const UChar* s1, const UChar* s2, int n)
     
    221254  return 0;
    222255}
     256#endif
    223257
    224258extern void
     
    259293#ifdef __GNUC__
    260294/* get rid of Wunused-but-set-variable and Wuninitialized */
    261 #define PFETCH_READY  UChar* pfetch_prev = NULL; (void)pfetch_prev
     295# define PFETCH_READY  UChar* pfetch_prev = NULL; (void)pfetch_prev
    262296#else
    263 #define PFETCH_READY  UChar* pfetch_prev
     297# define PFETCH_READY  UChar* pfetch_prev
    264298#endif
    265299#define PEND         (p < end ?  0 : 1)
     
    267301#define PINC       do { \
    268302  pfetch_prev = p; \
    269   p += ONIGENC_MBC_ENC_LEN(enc, p); \
     303  p += enclen(enc, p, end); \
    270304} while (0)
    271305#define PFETCH(c)  do { \
    272   c = ONIGENC_MBC_TO_CODE(enc, p, end); \
     306  c = ((enc->max_enc_len == 1) ? *p : ONIGENC_MBC_TO_CODE(enc, p, end)); \
    273307  pfetch_prev = p; \
    274   p += ONIGENC_MBC_ENC_LEN(enc, p); \
     308  p += enclen(enc, p, end); \
    275309} while (0)
    276310
    277311#define PINC_S     do { \
    278   p += ONIGENC_MBC_ENC_LEN(enc, p); \
     312  p += enclen(enc, p, end); \
    279313} while (0)
    280314#define PFETCH_S(c) do { \
    281   c = ONIGENC_MBC_TO_CODE(enc, p, end); \
    282   p += ONIGENC_MBC_ENC_LEN(enc, p); \
     315  c = ((enc->max_enc_len == 1) ? *p : ONIGENC_MBC_TO_CODE(enc, p, end)); \
     316  p += enclen(enc, p, end); \
    283317} while (0)
    284318
     
    319353#ifdef USE_ST_LIBRARY
    320354
     355# ifdef RUBY
     356#  include "ruby/st.h"
     357# else
     358#  include "st.h"
     359# endif
     360
    321361typedef struct {
    322   UChar* s;
    323   UChar* end;
     362  const UChar* s;
     363  const UChar* end;
    324364} st_str_end_key;
    325365
    326366static int
    327 str_end_cmp(st_str_end_key* x, st_str_end_key* y)
    328 {
    329   UChar *p, *q;
     367str_end_cmp(st_data_t xp, st_data_t yp)
     368{
     369  const st_str_end_key *x, *y;
     370  const UChar *p, *q;
    330371  int c;
    331372
     373  x = (const st_str_end_key *)xp;
     374  y = (const st_str_end_key *)yp;
    332375  if ((x->end - x->s) != (y->end - y->s))
    333376    return 1;
     
    345388}
    346389
    347 static int
    348 str_end_hash(st_str_end_key* x)
    349 {
    350   UChar *p;
    351   int val = 0;
     390static st_index_t
     391str_end_hash(st_data_t xp)
     392{
     393  const st_str_end_key *x = (const st_str_end_key *)xp;
     394  const UChar *p;
     395  st_index_t val = 0;
    352396
    353397  p = x->s;
     
    360404
    361405extern hash_table_type*
    362 onig_st_init_strend_table_with_size(int size)
    363 {
    364   static struct st_hash_type hashType = {
     406onig_st_init_strend_table_with_size(st_index_t size)
     407{
     408  static const struct st_hash_type hashType = {
    365409    str_end_cmp,
    366410    str_end_hash,
     
    405449#ifdef USE_NAMED_GROUP
    406450
    407 #define INIT_NAME_BACKREFS_ALLOC_NUM   8
     451# define INIT_NAME_BACKREFS_ALLOC_NUM   8
    408452
    409453typedef struct {
     
    416460} NameEntry;
    417461
    418 #ifdef USE_ST_LIBRARY
     462# ifdef USE_ST_LIBRARY
    419463
    420464typedef st_table  NameTable;
    421465typedef st_data_t HashDataType;   /* 1.6 st.h doesn't define st_data_t type */
    422466
    423 #ifdef ONIG_DEBUG
     467#  ifdef ONIG_DEBUG
    424468static int
    425469i_print_name_entry(UChar* key, NameEntry* e, void* arg)
     
    455499  return 0;
    456500}
    457 #endif /* ONIG_DEBUG */
     501#  endif /* ONIG_DEBUG */
    458502
    459503static int
     
    518562{
    519563  int r = (*(arg->func))(e->name,
    520                         e->name + e->name_len,
    521                         e->back_num,
     564                        e->name + e->name_len,
     565                        e->back_num,
    522566                         (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
    523567                         arg->reg, arg->arg);
     
    577621
    578622extern int
    579 onig_number_of_names(regex_t* reg)
     623onig_number_of_names(const regex_t* reg)
    580624{
    581625  NameTable* t = (NameTable* )reg->name_table;
    582626
    583627  if (IS_NOT_NULL(t))
    584     return t->num_entries;
     628    return (int )t->num_entries;
    585629  else
    586630    return 0;
    587631}
    588632
    589 #else  /* USE_ST_LIBRARY */
    590 
    591 #define INIT_NAMES_ALLOC_NUM    8
     633# else  /* USE_ST_LIBRARY */
     634
     635#  define INIT_NAMES_ALLOC_NUM    8
    592636
    593637typedef struct {
     
    597641} NameTable;
    598642
    599 #ifdef ONIG_DEBUG
     643#  ifdef ONIG_DEBUG
    600644extern int
    601645onig_print_names(FILE* fp, regex_t* reg)
     
    628672  return 0;
    629673}
    630 #endif
     674#  endif
    631675
    632676static int
     
    713757
    714758extern int
    715 onig_number_of_names(regex_t* reg)
     759onig_number_of_names(const regex_t* reg)
    716760{
    717761  NameTable* t = (NameTable* )reg->name_table;
     
    723767}
    724768
    725 #endif /* else USE_ST_LIBRARY */
     769# endif /* else USE_ST_LIBRARY */
    726770
    727771static int
     
    737781  e = name_find(reg, name, name_end);
    738782  if (IS_NULL(e)) {
    739 #ifdef USE_ST_LIBRARY
     783# ifdef USE_ST_LIBRARY
    740784    if (IS_NULL(t)) {
    741785      t = onig_st_init_strend_table_with_size(5);
     
    758802    e->back_refs  = (int* )NULL;
    759803
    760 #else
     804# else
    761805
    762806    if (IS_NULL(t)) {
     
    801845    if (IS_NULL(e->name)) return ONIGERR_MEMORY;
    802846    e->name_len = name_end - name;
    803 #endif
     847# endif
    804848  }
    805849
     
    864908extern int
    865909onig_name_to_backref_number(regex_t* reg, const UChar* name,
    866                             const UChar* name_end, OnigRegion *region)
     910                            const UChar* name_end, const OnigRegion *region)
    867911{
    868912  int i, n, *nums;
     
    897941extern int
    898942onig_name_to_backref_number(regex_t* reg, const UChar* name,
    899                             const UChar* name_end, OnigRegion* region)
     943                            const UChar* name_end, const OnigRegion* region)
    900944{
    901945  return ONIG_NO_SUPPORT_CONFIG;
     
    910954
    911955extern int
    912 onig_number_of_names(regex_t* reg)
     956onig_number_of_names(const regex_t* reg)
    913957{
    914958  return 0;
     
    917961
    918962extern int
    919 onig_noname_group_capture_is_active(regex_t* reg)
     963onig_noname_group_capture_is_active(const regex_t* reg)
    920964{
    921965  if (ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_DONT_CAPTURE_GROUP))
     
    9641008  env->has_recursion       = 0;
    9651009#endif
     1010  env->parse_depth         = 0;
     1011  env->warnings_flag       = 0;
    9661012}
    9671013
     
    9801026        alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE;
    9811027        p = (Node** )xmalloc(sizeof(Node*) * alloc);
     1028        CHECK_NULL_RETURN_MEMERR(p);
    9821029        xmemcpy(p, env->mem_nodes_static,
    9831030                sizeof(Node*) * SCANENV_MEMNODES_SIZE);
     
    9861033        alloc = env->mem_alloc * 2;
    9871034        p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
    988       }
    989       CHECK_NULL_RETURN_MEMERR(p);
     1035        CHECK_NULL_RETURN_MEMERR(p);
     1036      }
    9901037
    9911038      for (i = env->num_mem + 1; i < alloc; i++)
     
    10121059
    10131060
    1014 #ifdef USE_PARSE_TREE_NODE_RECYCLE
    1015 typedef struct _FreeNode {
    1016   struct _FreeNode* next;
    1017 } FreeNode;
    1018 
    1019 static FreeNode* FreeNodeList = (FreeNode* )NULL;
    1020 #endif
    1021 
    10221061extern void
    10231062onig_node_free(Node* node)
     
    10401079      Node* next_node = NCDR(node);
    10411080
    1042 #ifdef USE_PARSE_TREE_NODE_RECYCLE
    1043       {
    1044         FreeNode* n = (FreeNode* )node;
    1045 
    1046         THREAD_ATOMIC_START;
    1047         n->next = FreeNodeList;
    1048         FreeNodeList = n;
    1049         THREAD_ATOMIC_END;
    1050       }
    1051 #else
    10521081      xfree(node);
    1053 #endif
    10541082      node = next_node;
    10551083      goto start;
     
    10611089      CClassNode* cc = NCCLASS(node);
    10621090
    1063       if (IS_NCCLASS_SHARE(cc)) return ;
    10641091      if (cc->mbuf)
    1065         bbuf_free(cc->mbuf);
     1092        bbuf_free(cc->mbuf);
    10661093    }
    10671094    break;
     
    10881115  }
    10891116
    1090 #ifdef USE_PARSE_TREE_NODE_RECYCLE
    1091   {
    1092     FreeNode* n = (FreeNode* )node;
    1093 
    1094     THREAD_ATOMIC_START;
    1095     n->next = FreeNodeList;
    1096     FreeNodeList = n;
    1097     THREAD_ATOMIC_END;
    1098   }
    1099 #else
    11001117  xfree(node);
    1101 #endif
    1102 }
    1103 
    1104 #ifdef USE_PARSE_TREE_NODE_RECYCLE
    1105 extern int
    1106 onig_free_node_list(void)
    1107 {
    1108   FreeNode* n;
    1109 
    1110   /* THREAD_ATOMIC_START; */
    1111   while (IS_NOT_NULL(FreeNodeList)) {
    1112     n = FreeNodeList;
    1113     FreeNodeList = FreeNodeList->next;
    1114     xfree(n);
    1115   }
    1116   /* THREAD_ATOMIC_END; */
    1117   return 0;
    1118 }
    1119 #endif
     1118}
    11201119
    11211120static Node*
     
    11231122{
    11241123  Node* node;
    1125 
    1126 #ifdef USE_PARSE_TREE_NODE_RECYCLE
    1127   THREAD_ATOMIC_START;
    1128   if (IS_NOT_NULL(FreeNodeList)) {
    1129     node = (Node* )FreeNodeList;
    1130     FreeNodeList = FreeNodeList->next;
    1131     THREAD_ATOMIC_END;
    1132     return node;
    1133   }
    1134   THREAD_ATOMIC_END;
    1135 #endif
    11361124
    11371125  node = (Node* )xmalloc(sizeof(Node));
     
    11391127  return node;
    11401128}
    1141 
    1142 #if defined(USE_MULTI_THREAD_SYSTEM) && \
    1143     defined(USE_SHARED_CCLASS_TABLE) && \
    1144     defined(USE_PARSE_TREE_NODE_RECYCLE)
    1145 static Node*
    1146 node_new_locked(void)
    1147 {
    1148   Node* node;
    1149 
    1150   if (IS_NOT_NULL(FreeNodeList)) {
    1151     node = (Node* )FreeNodeList;
    1152     FreeNodeList = FreeNodeList->next;
    1153     return node;
    1154   }
    1155 
    1156   node = (Node* )xmalloc(sizeof(Node));
    1157   /* xmemset(node, 0, sizeof(Node)); */
    1158   return node;
    1159 }
    1160 #endif
    11611129
    11621130static void
     
    11791147  return node;
    11801148}
    1181 
    1182 #if defined(USE_MULTI_THREAD_SYSTEM) && \
    1183     defined(USE_SHARED_CCLASS_TABLE) && \
    1184     defined(USE_PARSE_TREE_NODE_RECYCLE)
    1185 static Node*
    1186 node_new_cclass_locked(void)
    1187 {
    1188   Node* node = node_new_locked();
    1189   CHECK_NULL_RETURN(node);
    1190 
    1191   SET_NTYPE(node, NT_CCLASS);
    1192   initialize_cclass(NCCLASS(node));
    1193   return node;
    1194 }
    1195 #else
    1196 #define node_new_cclass_locked()  node_new_cclass()
    1197 #endif
    1198 
    1199 #ifdef USE_SHARED_CCLASS_TABLE
    1200 static Node*
    1201 node_new_cclass_by_codepoint_range(int not, OnigCodePoint sb_out,
    1202                                    const OnigCodePoint ranges[])
    1203 {
    1204   int n, i;
    1205   CClassNode* cc;
    1206   OnigCodePoint j;
    1207 
    1208   Node* node = node_new_cclass_locked();
    1209   CHECK_NULL_RETURN(node);
    1210 
    1211   cc = NCCLASS(node);
    1212   if (not != 0) NCCLASS_SET_NOT(cc);
    1213 
    1214   BITSET_CLEAR(cc->bs);
    1215   if (sb_out > 0 && IS_NOT_NULL(ranges)) {
    1216     n = ONIGENC_CODE_RANGE_NUM(ranges);
    1217     for (i = 0; i < n; i++) {
    1218       for (j  = ONIGENC_CODE_RANGE_FROM(ranges, i);
    1219            j <= (OnigCodePoint )ONIGENC_CODE_RANGE_TO(ranges, i); j++) {
    1220         if (j >= sb_out) goto sb_end;
    1221 
    1222         BITSET_SET_BIT(cc->bs, j);
    1223       }
    1224     }
    1225   }
    1226 
    1227  sb_end:
    1228   if (IS_NULL(ranges)) {
    1229   is_null:
    1230     cc->mbuf = NULL;
    1231   }
    1232   else {
    1233     BBuf* bbuf;
    1234 
    1235     n = ONIGENC_CODE_RANGE_NUM(ranges);
    1236     if (n == 0) goto is_null;
    1237 
    1238     bbuf = (BBuf* )xmalloc(sizeof(BBuf));
    1239     CHECK_NULL_RETURN(bbuf);
    1240     bbuf->alloc = n + 1;
    1241     bbuf->used  = n + 1;
    1242     bbuf->p     = (UChar* )((void* )ranges);
    1243 
    1244     cc->mbuf = bbuf;
    1245   }
    1246 
    1247   return node;
    1248 }
    1249 #endif /* USE_SHARED_CCLASS_TABLE */
    12501149
    12511150static Node*
     
    15351434}
    15361435
     1436#if 0
    15371437extern void
    15381438onig_node_conv_to_str_node(Node* node, int flag)
     
    15441444  NSTR(node)->end  = NSTR(node)->buf;
    15451445}
     1446#endif
    15461447
    15471448extern void
     
    16141515
    16151516  if (sn->end > sn->s) {
    1616     p = onigenc_get_prev_char_head(enc, sn->s, sn->end);
     1517    p = onigenc_get_prev_char_head(enc, sn->s, sn->end, sn->end);
    16171518    if (p && p > sn->s) { /* can be split. */
    16181519      n = node_new_str(p, sn->end);
     
    16291530{
    16301531  if (sn->end > sn->s) {
    1631     return ((enclen(enc, sn->s) < sn->end - sn->s)  ?  1 : 0);
     1532    return ((enclen(enc, sn->s, sn->end) < sn->end - sn->s)  ?  1 : 0);
    16321533  }
    16331534  return 0;
     
    17021603    else {
    17031604      PUNFETCH;
     1605      maxlen++;
    17041606      break;
    17051607    }
     
    17661668
    17671669static int
    1768 add_code_range_to_buf(BBuf** pbuf, OnigCodePoint from, OnigCodePoint to)
     1670add_code_range_to_buf0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to,
     1671        int checkdup)
    17691672{
    17701673  int r, inc_n, pos;
     
    18071710      bound = x;
    18081711  }
     1712  /* data[(low-1)*2+1] << from <= data[low*2]
     1713   * data[(high-1)*2+1] <= to << data[high*2]
     1714   */
    18091715
    18101716  inc_n = low + 1 - high;
     
    18131719
    18141720  if (inc_n != 1) {
     1721    if (checkdup && from <= data[low*2+1]
     1722        && (data[low*2] <= from || data[low*2+1] <= to))
     1723      CC_DUP_WARN(env);
    18151724    if (from > data[low*2])
    18161725      from = data[low*2];
     
    18451754
    18461755static int
    1847 add_code_range(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
     1756add_code_range_to_buf(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
     1757{
     1758  return add_code_range_to_buf0(pbuf, env, from, to, 1);
     1759}
     1760
     1761static int
     1762add_code_range0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to, int checkdup)
    18481763{
    18491764  if (from > to) {
     
    18541769  }
    18551770
    1856   return add_code_range_to_buf(pbuf, from, to);
     1771  return add_code_range_to_buf0(pbuf, env, from, to, checkdup);
    18571772}
    18581773
    18591774static int
    1860 not_code_range_buf(OnigEncoding enc, BBuf* bbuf, BBuf** pbuf)
     1775add_code_range(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
     1776{
     1777  return add_code_range0(pbuf, env, from, to, 1);
     1778}
     1779
     1780static int
     1781not_code_range_buf(OnigEncoding enc, BBuf* bbuf, BBuf** pbuf, ScanEnv* env)
    18611782{
    18621783  int r, i, n;
     
    18801801    to   = data[i*2+1];
    18811802    if (pre <= from - 1) {
    1882       r = add_code_range_to_buf(pbuf, pre, from - 1);
     1803      r = add_code_range_to_buf(pbuf, env, pre, from - 1);
    18831804      if (r != 0) return r;
    18841805    }
     
    18871808  }
    18881809  if (to < ONIG_LAST_CODE_POINT) {
    1889     r = add_code_range_to_buf(pbuf, to + 1, ONIG_LAST_CODE_POINT);
     1810    r = add_code_range_to_buf(pbuf, env, to + 1, ONIG_LAST_CODE_POINT);
    18901811  }
    18911812  return r;
     
    19011822static int
    19021823or_code_range_buf(OnigEncoding enc, BBuf* bbuf1, int not1,
    1903                   BBuf* bbuf2, int not2, BBuf** pbuf)
     1824                  BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env)
    19041825{
    19051826  int r;
     
    19271848      }
    19281849      else {
    1929         return not_code_range_buf(enc, bbuf2, pbuf);
     1850        return not_code_range_buf(enc, bbuf2, pbuf, env);
    19301851      }
    19311852    }
     
    19431864  }
    19441865  else if (not1 == 0) { /* 1 OR (not 2) */
    1945     r = not_code_range_buf(enc, bbuf2, pbuf);
     1866    r = not_code_range_buf(enc, bbuf2, pbuf, env);
    19461867  }
    19471868  if (r != 0) return r;
     
    19501871    from = data1[i*2];
    19511872    to   = data1[i*2+1];
    1952     r = add_code_range_to_buf(pbuf, from, to);
     1873    r = add_code_range_to_buf(pbuf, env, from, to);
    19531874    if (r != 0) return r;
    19541875  }
     
    19571878
    19581879static int
    1959 and_code_range1(BBuf** pbuf, OnigCodePoint from1, OnigCodePoint to1,
    1960                 OnigCodePoint* data, int n)
     1880and_code_range1(BBuf** pbuf, ScanEnv* env, OnigCodePoint from1, OnigCodePoint to1,
     1881                OnigCodePoint* data, int n)
    19611882{
    19621883  int i, r;
     
    19751896      if (to2 < to1) {
    19761897        if (from1 <= from2 - 1) {
    1977           r = add_code_range_to_buf(pbuf, from1, from2-1);
     1898          r = add_code_range_to_buf(pbuf, env, from1, from2-1);
    19781899          if (r != 0) return r;
    19791900        }
     
    19901911  }
    19911912  if (from1 <= to1) {
    1992     r = add_code_range_to_buf(pbuf, from1, to1);
     1913    r = add_code_range_to_buf(pbuf, env, from1, to1);
    19931914    if (r != 0) return r;
    19941915  }
     
    19971918
    19981919static int
    1999 and_code_range_buf(BBuf* bbuf1, int not1, BBuf* bbuf2, int not2, BBuf** pbuf)
     1920and_code_range_buf(BBuf* bbuf1, int not1, BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env)
    20001921{
    20011922  int r;
     
    20361957        from = MAX(from1, from2);
    20371958        to   = MIN(to1, to2);
    2038         r = add_code_range_to_buf(pbuf, from, to);
     1959        r = add_code_range_to_buf(pbuf, env, from, to);
    20391960        if (r != 0) return r;
    20401961      }
     
    20451966      from1 = data1[i*2];
    20461967      to1   = data1[i*2+1];
    2047       r = and_code_range1(pbuf, from1, to1, data2, n2);
     1968      r = and_code_range1(pbuf, env, from1, to1, data2, n2);
    20481969      if (r != 0) return r;
    20491970    }
     
    20541975
    20551976static int
    2056 and_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
    2057 {
     1977and_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env)
     1978{
     1979  OnigEncoding enc = env->enc;
    20581980  int r, not1, not2;
    20591981  BBuf *buf1, *buf2, *pbuf = 0;
     
    20872009  if (! ONIGENC_IS_SINGLEBYTE(enc)) {
    20882010    if (not1 != 0 && not2 != 0) {
    2089       r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf);
     2011      r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf, env);
    20902012    }
    20912013    else {
    2092       r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf);
     2014      r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf, env);
    20932015      if (r == 0 && not1 != 0) {
    20942016        BBuf *tbuf = 0;
    2095         r = not_code_range_buf(enc, pbuf, &tbuf);
     2017        r = not_code_range_buf(enc, pbuf, &tbuf, env);
    20962018        bbuf_free(pbuf);
    20972019        pbuf = tbuf;
     
    21112033
    21122034static int
    2113 or_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
    2114 {
     2035or_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env)
     2036{
     2037  OnigEncoding enc = env->enc;
    21152038  int r, not1, not2;
    21162039  BBuf *buf1, *buf2, *pbuf = 0;
     
    21442067  if (! ONIGENC_IS_SINGLEBYTE(enc)) {
    21452068    if (not1 != 0 && not2 != 0) {
    2146       r = and_code_range_buf(buf1, 0, buf2, 0, &pbuf);
     2069      r = and_code_range_buf(buf1, 0, buf2, 0, &pbuf, env);
    21472070    }
    21482071    else {
    2149       r = or_code_range_buf(enc, buf1, not1, buf2, not2, &pbuf);
     2072      r = or_code_range_buf(enc, buf1, not1, buf2, not2, &pbuf, env);
    21502073      if (r == 0 && not1 != 0) {
    21512074        BBuf *tbuf = 0;
    2152         r = not_code_range_buf(enc, pbuf, &tbuf);
     2075        r = not_code_range_buf(enc, pbuf, &tbuf, env);
    21532076        bbuf_free(pbuf);
    21542077        pbuf = tbuf;
     
    21682091}
    21692092
    2170 static int
    2171 conv_backslash_value(int c, ScanEnv* env)
     2093static void UNKNOWN_ESC_WARN(ScanEnv *env, int c);
     2094
     2095static OnigCodePoint
     2096conv_backslash_value(OnigCodePoint c, ScanEnv* env)
    21722097{
    21732098  if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) {
     
    21862111
    21872112    default:
     2113      if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
     2114          UNKNOWN_ESC_WARN(env, c);
    21882115      break;
    21892116    }
     
    21932120
    21942121#ifdef USE_NO_INVALID_QUANTIFIER
    2195 #define is_invalid_quantifier_target(node) 0
     2122# define is_invalid_quantifier_target(node) 0
    21962123#else
    21972124static int
     
    22652192
    22662193static enum ReduceType const ReduceTypeTable[6][6] = {
     2194/* '?',     '*',     '+',    '??',    '*?',    '+?'      p / c   */
    22672195  {RQ_DEL,  RQ_A,    RQ_A,   RQ_QQ,   RQ_AQ,   RQ_ASIS}, /* '?'  */
    22682196  {RQ_DEL,  RQ_DEL,  RQ_DEL, RQ_P_QQ, RQ_P_QQ, RQ_DEL},  /* '*'  */
     
    24672395  if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) {
    24682396    if (c != MC_ESC(env->syntax)) goto invalid;
     2397    if (PEND) goto invalid;
    24692398    PFETCH(c);
    24702399  }
     
    24902419/* \M-, \C-, \c, or \... */
    24912420static int
    2492 fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
     2421fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env, OnigCodePoint* val)
    24932422{
    24942423  int v;
     
    25092438      PFETCH_S(c);
    25102439      if (c == MC_ESC(env->syntax)) {
    2511         v = fetch_escaped_value(&p, end, env);
    2512         if (v < 0) return v;
    2513         c = (OnigCodePoint )v;
     2440        v = fetch_escaped_value(&p, end, env, &c);
     2441        if (v < 0) return v;
    25142442      }
    25152443      c = ((c & 0xff) | 0x80);
     
    25352463      PFETCH_S(c);
    25362464      if (c == '?') {
    2537         c = 0177;
     2465        c = 0177;
    25382466      }
    25392467      else {
    2540         if (c == MC_ESC(env->syntax)) {
    2541           v = fetch_escaped_value(&p, end, env);
    2542           if (v < 0) return v;
    2543           c = (OnigCodePoint )v;
    2544         }
    2545         c &= 0x9f;
     2468        if (c == MC_ESC(env->syntax)) {
     2469          v = fetch_escaped_value(&p, end, env, &c);
     2470          if (v < 0) return v;
     2471        }
     2472        c &= 0x9f;
    25462473      }
    25472474      break;
     
    25582485
    25592486  *src = p;
    2560   return c;
     2487  *val = c;
     2488  return 0;
    25612489}
    25622490
     
    25792507
    25802508#ifdef USE_NAMED_GROUP
    2581 #ifdef USE_BACKREF_WITH_LEVEL
     2509# ifdef RUBY
     2510#  define ONIGENC_IS_CODE_NAME(enc, c)  TRUE
     2511# else
     2512#  define ONIGENC_IS_CODE_NAME(enc, c)  ONIGENC_IS_CODE_WORD(enc, c)
     2513# endif
     2514
     2515# ifdef USE_BACKREF_WITH_LEVEL
    25822516/*
    25832517   \k<name+n>, \k<name-n>
     
    26242558      pnum_head = p;
    26252559    }
    2626     else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
     2560    else if (!ONIGENC_IS_CODE_NAME(enc, c)) {
    26272561      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
    26282562    }
     
    26392573    if (is_num != 0) {
    26402574      if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
    2641         is_num = 1;
     2575        is_num = 1;
    26422576      }
    26432577      else {
    2644         r = ONIGERR_INVALID_GROUP_NAME;
    2645         is_num = 0;
    2646       }
    2647     }
    2648     else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
     2578        r = ONIGERR_INVALID_GROUP_NAME;
     2579        is_num = 0;
     2580      }
     2581    }
     2582    else if (!ONIGENC_IS_CODE_NAME(enc, c)) {
    26492583      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
    26502584    }
     
    26562590      int flag = (c == '-' ? -1 : 1);
    26572591
     2592      if (PEND) {
     2593        r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
     2594        goto end;
     2595      }
    26582596      PFETCH(c);
    26592597      if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err;
     
    26642602      exist_level = 1;
    26652603
    2666       PFETCH(c);
    2667       if (c == end_code)
    2668         goto end;
     2604      if (!PEND) {
     2605        PFETCH(c);
     2606        if (c == end_code)
     2607          goto end;
     2608      }
    26692609    }
    26702610
     
    26932633  }
    26942634}
    2695 #endif /* USE_BACKREF_WITH_LEVEL */
     2635# endif /* USE_BACKREF_WITH_LEVEL */
    26962636
    26972637/*
     
    27302670    if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
    27312671      if (ref == 1)
    2732         is_num = 1;
    2733       else {
    2734         r = ONIGERR_INVALID_GROUP_NAME;
    2735         is_num = 0;
    2736       }
    2737     }
    2738     else if (c == '-') {
    2739       if (ref == 1) {
    2740         is_num = 2;
    2741         sign = -1;
    2742         pnum_head = p;
    2743       }
     2672        is_num = 1;
    27442673      else {
    27452674        r = ONIGERR_INVALID_GROUP_NAME;
     
    27472676      }
    27482677    }
    2749     else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
     2678    else if (c == '-') {
     2679      if (ref == 1) {
     2680        is_num = 2;
     2681        sign = -1;
     2682        pnum_head = p;
     2683      }
     2684      else {
     2685        r = ONIGERR_INVALID_GROUP_NAME;
     2686        is_num = 0;
     2687      }
     2688    }
     2689    else if (!ONIGENC_IS_CODE_NAME(enc, c)) {
    27502690      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
    27512691    }
     
    27572697      PFETCH_S(c);
    27582698      if (c == end_code || c == ')') {
    2759         if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME;
     2699        if (is_num == 2) {
     2700          r = ONIGERR_INVALID_GROUP_NAME;
     2701          goto teardown;
     2702        }
    27602703        break;
    27612704      }
    27622705
    27632706      if (is_num != 0) {
    2764         if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
    2765           is_num = 1;
    2766         }
    2767         else {
    2768           if (!ONIGENC_IS_CODE_WORD(enc, c))
    2769             r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
    2770           else
    2771             r = ONIGERR_INVALID_GROUP_NAME;
    2772           is_num = 0;
    2773         }
     2707        if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
     2708          is_num = 1;
     2709        }
     2710        else {
     2711          if (!ONIGENC_IS_CODE_WORD(enc, c))
     2712            r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
     2713          else
     2714            r = ONIGERR_INVALID_GROUP_NAME;
     2715          goto teardown;
     2716        }
    27742717      }
    27752718      else {
    2776         if (!ONIGENC_IS_CODE_WORD(enc, c)) {
    2777           r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
    2778         }
     2719        if (!ONIGENC_IS_CODE_NAME(enc, c)) {
     2720          r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
     2721          goto teardown;
     2722        }
    27792723      }
    27802724    }
     
    27832727      r = ONIGERR_INVALID_GROUP_NAME;
    27842728      name_end = end;
     2729      goto err;
    27852730    }
    27862731
     
    27892734      if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
    27902735      else if (*rback_num == 0) {
    2791         r = ONIGERR_INVALID_GROUP_NAME;
    2792         goto err;
     2736        r = ONIGERR_INVALID_GROUP_NAME;
     2737        goto err;
    27932738      }
    27942739
     
    28012746  }
    28022747  else {
     2748teardown:
    28032749    while (!PEND) {
    28042750      name_end = p;
    28052751      PFETCH_S(c);
    28062752      if (c == end_code || c == ')')
    2807         break;
     2753        break;
    28082754    }
    28092755    if (PEND)
     
    28942840#endif /* USE_NAMED_GROUP */
    28952841
     2842
    28962843static void
    2897 CC_ESC_WARN(ScanEnv* env, UChar *c)
     2844onig_syntax_warn(ScanEnv *env, const char *fmt, ...)
     2845{
     2846    va_list args;
     2847    UChar buf[WARN_BUFSIZE];
     2848    va_start(args, fmt);
     2849    onig_vsnprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
     2850                env->pattern, env->pattern_end,
     2851                (const UChar *)fmt, args);
     2852    va_end(args);
     2853#ifdef RUBY
     2854    if (env->sourcefile == NULL)
     2855      rb_warn("%s", (char *)buf);
     2856    else
     2857      rb_compile_warn(env->sourcefile, env->sourceline, "%s", (char *)buf);
     2858#else
     2859    (*onig_warn)((char* )buf);
     2860#endif
     2861}
     2862
     2863static void
     2864CC_ESC_WARN(ScanEnv *env, UChar *c)
    28982865{
    28992866  if (onig_warn == onig_null_warn) return ;
     
    29012868  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED) &&
    29022869      IS_SYNTAX_BV(env->syntax, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC)) {
    2903     UChar buf[WARN_BUFSIZE];
    2904     onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
    2905                 env->pattern, env->pattern_end,
    2906                 (UChar* )"character class has '%s' without escape", c);
    2907     (*onig_warn)((char* )buf);
     2870    onig_syntax_warn(env, "character class has '%s' without escape", c);
    29082871  }
    29092872}
     
    29152878
    29162879  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED)) {
    2917     UChar buf[WARN_BUFSIZE];
    2918     onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
    2919                 env->pattern, env->pattern_end,
    2920                 (UChar* )"regular expression has '%s' without escape", c);
    2921     (*onig_warn)((char* )buf);
    2922   }
     2880    onig_syntax_warn(env, "regular expression has '%s' without escape", c);
     2881  }
     2882}
     2883
     2884#ifndef RTEST
     2885# define RTEST(v)  1
     2886#endif
     2887
     2888static void
     2889CC_DUP_WARN(ScanEnv *env)
     2890{
     2891  if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ;
     2892
     2893  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_DUP) &&
     2894      !(env->warnings_flag & ONIG_SYN_WARN_CC_DUP)) {
     2895    env->warnings_flag |= ONIG_SYN_WARN_CC_DUP;
     2896    onig_syntax_warn(env, "character class has duplicated range");
     2897  }
     2898}
     2899
     2900static void
     2901UNKNOWN_ESC_WARN(ScanEnv *env, int c)
     2902{
     2903  if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ;
     2904  onig_syntax_warn(env, "Unknown escape \\%c is ignored", c);
    29232905}
    29242906
     
    29342916  while (p < to) {
    29352917    x = ONIGENC_MBC_TO_CODE(enc, p, to);
    2936     q = p + enclen(enc, p);
     2918    q = p + enclen(enc, p, to);
    29372919    if (x == s[0]) {
    29382920      for (i = 1; i < n && q < to; i++) {
    29392921        x = ONIGENC_MBC_TO_CODE(enc, q, to);
    29402922        if (x != s[i]) break;
    2941         q += enclen(enc, q);
     2923        q += enclen(enc, q, to);
    29422924      }
    29432925      if (i >= n) {
     
    29542936static int
    29552937str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to,
    2956                  OnigCodePoint bad, OnigEncoding enc, OnigSyntaxType* syn)
     2938                 OnigCodePoint bad, OnigEncoding enc, const OnigSyntaxType* syn)
    29572939{
    29582940  int i, in_esc;
     
    29652947    if (in_esc) {
    29662948      in_esc = 0;
    2967       p += enclen(enc, p);
     2949      p += enclen(enc, p, to);
    29682950    }
    29692951    else {
    29702952      x = ONIGENC_MBC_TO_CODE(enc, p, to);
    2971       q = p + enclen(enc, p);
     2953      q = p + enclen(enc, p, to);
    29722954      if (x == s[0]) {
    29732955        for (i = 1; i < n && q < to; i++) {
    29742956          x = ONIGENC_MBC_TO_CODE(enc, q, to);
    29752957          if (x != s[i]) break;
    2976           q += enclen(enc, q);
     2958          q += enclen(enc, q, to);
    29772959        }
    29782960        if (i >= n) return 1;
    2979         p += enclen(enc, p);
     2961        p += enclen(enc, p, to);
    29802962      }
    29812963      else {
     
    29952977  int num;
    29962978  OnigCodePoint c, c2;
    2997   OnigSyntaxType* syn = env->syntax;
     2979  const OnigSyntaxType* syn = env->syntax;
    29982980  OnigEncoding enc = env->enc;
    29992981  UChar* prev;
     
    30733055    case 'p':
    30743056    case 'P':
     3057      if (PEND) break;
     3058
    30753059      c2 = PPEEK;
    30763060      if (c2 == '{' &&
     
    30803064        tok->u.prop.not = (c == 'P' ? 1 : 0);
    30813065
    3082         if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
     3066        if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
    30833067          PFETCH(c2);
    30843068          if (c2 == '^') {
     
    30893073        }
    30903074      }
     3075      else {
     3076        onig_syntax_warn(env, "invalid Unicode Property \\%c", c);
     3077      }
    30913078      break;
    30923079
     
    31003087        if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
    31013088        if (!PEND) {
    3102           c2 = PPEEK;
    3103           if (ONIGENC_IS_CODE_XDIGIT(enc, c2))
    3104             return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
    3105         }
    3106 
    3107         if (p > prev + enclen(enc, prev) && !PEND && (PPEEK_IS('}'))) {
     3089          c2 = PPEEK;
     3090          if (ONIGENC_IS_CODE_XDIGIT(enc, c2))
     3091            return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
     3092        }
     3093
     3094        if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) {
    31083095          PINC;
    31093096          tok->type   = TK_CODE_POINT;
     
    31423129        tok->base   = 16;
    31433130        tok->u.code = (OnigCodePoint )num;
     3131      }
     3132      break;
     3133
     3134    case 'o':
     3135      if (PEND) break;
     3136
     3137      prev = p;
     3138      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_O_BRACE_OCTAL)) {
     3139        PINC;
     3140        num = scan_unsigned_octal_number(&p, end, 11, enc);
     3141        if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
     3142        if (!PEND) {
     3143          c2 = PPEEK;
     3144          if (ONIGENC_IS_CODE_DIGIT(enc, c2) && c2 < '8')
     3145            return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
     3146        }
     3147
     3148        if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) {
     3149          PINC;
     3150          tok->type   = TK_CODE_POINT;
     3151          tok->base   = 8;
     3152          tok->u.code = (OnigCodePoint )num;
     3153        }
     3154        else {
     3155          /* can't read nothing or invalid format */
     3156          p = prev;
     3157        }
    31443158      }
    31453159      break;
     
    31633177    default:
    31643178      PUNFETCH;
    3165       num = fetch_escaped_value(&p, end, env);
     3179      num = fetch_escaped_value(&p, end, env, &c2);
    31663180      if (num < 0) return num;
    3167       if (tok->u.c != num) {
    3168         tok->u.code = (OnigCodePoint )num;
     3181      if ((OnigCodePoint )tok->u.c != c2) {
     3182        tok->u.code = (OnigCodePoint )c2;
    31693183        tok->type   = TK_CODE_POINT;
    31703184      }
     
    32153229{
    32163230  int r, num;
    3217   OnigSyntaxType* syn = env->syntax;
     3231  const OnigSyntaxType* syn = env->syntax;
    32183232  UChar* prev;
    32193233  UChar* p = *src;
     
    32243238  prev = p;
    32253239
    3226 #ifdef USE_BACKREF_WITH_LEVEL
     3240# ifdef USE_BACKREF_WITH_LEVEL
    32273241  name_end = NULL_UCHARP; /* no need. escape gcc warning. */
    32283242  r = fetch_name_with_level(c, &p, end, &name_end,
     
    32303244  if (r == 1) tok->u.backref.exist_level = 1;
    32313245  else        tok->u.backref.exist_level = 0;
    3232 #else
     3246# else
    32333247  r = fetch_name(&p, end, &name_end, env, &back_num, 1);
    3234 #endif
     3248# endif
    32353249  if (r < 0) return r;
    32363250
     
    32703284    tok->type = TK_BACKREF;
    32713285    tok->u.backref.by_name = 1;
    3272     if (num == 1) {
     3286    if (num == 1 || IS_SYNTAX_BV(syn, ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP)) {
    32733287      tok->u.backref.num  = 1;
    32743288      tok->u.backref.ref1 = backs[0];
     
    32903304  OnigCodePoint c;
    32913305  OnigEncoding enc = env->enc;
    3292   OnigSyntaxType* syn = env->syntax;
     3306  const OnigSyntaxType* syn = env->syntax;
    32933307  UChar* prev;
    32943308  UChar* p = *src;
     
    35233537        if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
    35243538        if (!PEND) {
    3525           if (ONIGENC_IS_CODE_XDIGIT(enc, PPEEK))
    3526             return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
    3527         }
    3528 
    3529         if ((p > prev + enclen(enc, prev)) && !PEND && PPEEK_IS('}')) {
     3539          if (ONIGENC_IS_CODE_XDIGIT(enc, PPEEK))
     3540            return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
     3541        }
     3542
     3543        if ((p > prev + enclen(enc, prev, end)) && !PEND && PPEEK_IS('}')) {
    35303544          PINC;
    35313545          tok->type   = TK_CODE_POINT;
     
    35663580      break;
    35673581
     3582    case 'o':
     3583      if (PEND) break;
     3584
     3585      prev = p;
     3586      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_O_BRACE_OCTAL)) {
     3587        PINC;
     3588        num = scan_unsigned_octal_number(&p, end, 11, enc);
     3589        if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
     3590        if (!PEND) {
     3591          OnigCodePoint c = PPEEK;
     3592          if (ONIGENC_IS_CODE_DIGIT(enc, c) && c < '8')
     3593            return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
     3594        }
     3595
     3596        if ((p > prev + enclen(enc, prev, end)) && !PEND && PPEEK_IS('}')) {
     3597          PINC;
     3598          tok->type   = TK_CODE_POINT;
     3599          tok->u.code = (OnigCodePoint )num;
     3600        }
     3601        else {
     3602          /* can't read nothing or invalid format */
     3603          p = prev;
     3604        }
     3605      }
     3606      break;
     3607
    35683608    case '1': case '2': case '3': case '4':
    35693609    case '5': case '6': case '7': case '8': case '9':
     
    35723612      num = onig_scan_unsigned_number(&p, end, enc);
    35733613      if (num < 0 || num > ONIG_MAX_BACKREF_NUM) {
    3574         goto skip_backref;
     3614        goto skip_backref;
    35753615      }
    35763616
     
    36053645        prev = p;
    36063646        num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
    3607         if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
     3647        if (num < 0 || 0xff < num) return ONIGERR_TOO_BIG_NUMBER;
    36083648        if (p == prev) {  /* can't read nothing. */
    36093649          num = 0; /* but, it's not error */
     
    36203660#ifdef USE_NAMED_GROUP
    36213661    case 'k':
    3622       if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) {
     3662      if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) {
    36233663        PFETCH(c);
    36243664        if (c == '<' || c == '\'') {
     
    36263666          if (r < 0) return r;
    36273667        }
    3628         else
     3668        else {
    36293669          PUNFETCH;
     3670          onig_syntax_warn(env, "invalid back reference");
     3671        }
    36303672      }
    36313673      break;
     
    36343676#if defined(USE_SUBEXP_CALL) || defined(USE_NAMED_GROUP)
    36353677    case 'g':
    3636 #ifdef USE_NAMED_GROUP
    3637       if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_BRACE_BACKREF)) {
     3678# ifdef USE_NAMED_GROUP
     3679      if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_BRACE_BACKREF)) {
    36383680        PFETCH(c);
    36393681        if (c == '{') {
     
    36443686          PUNFETCH;
    36453687      }
    3646 #endif
    3647 #ifdef USE_SUBEXP_CALL
    3648       if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) {
     3688# endif
     3689# ifdef USE_SUBEXP_CALL
     3690      if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) {
    36493691        PFETCH(c);
    36503692        if (c == '<' || c == '\'') {
     
    36783720          tok->u.call.rel      = rel;
    36793721        }
    3680         else
     3722        else {
     3723          onig_syntax_warn(env, "invalid subexp call");
    36813724          PUNFETCH;
    3682       }
    3683 #endif
     3725        }
     3726      }
     3727# endif
    36843728      break;
    36853729#endif
     
    36993743        tok->u.prop.not = (c == 'P' ? 1 : 0);
    37003744
    3701         if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
     3745        if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
    37023746          PFETCH(c);
    37033747          if (c == '^') {
     
    37083752        }
    37093753      }
     3754      else {
     3755        onig_syntax_warn(env, "invalid Unicode Property \\%c", c);
     3756      }
    37103757      break;
    37113758
     
    37293776
    37303777    default:
    3731       PUNFETCH;
    3732       num = fetch_escaped_value(&p, end, env);
    3733       if (num < 0) return num;
    3734       /* set_raw: */
    3735       if (tok->u.c != num) {
    3736         tok->type = TK_CODE_POINT;
    3737         tok->u.code = (OnigCodePoint )num;
    3738       }
    3739       else { /* string */
    3740         p = tok->backp + enclen(enc, tok->backp);
     3778      {
     3779        OnigCodePoint c2;
     3780
     3781        PUNFETCH;
     3782        num = fetch_escaped_value(&p, end, env, &c2);
     3783        if (num < 0) return num;
     3784        /* set_raw: */
     3785        if ((OnigCodePoint )tok->u.c != c2) {
     3786          tok->type = TK_CODE_POINT;
     3787          tok->u.code = (OnigCodePoint )c2;
     3788        }
     3789        else { /* string */
     3790          p = tok->backp + enclen(enc, tok->backp, end);
     3791        }
    37413792      }
    37423793      break;
     
    38283879    case '(':
    38293880      if (PPEEK_IS('?') &&
    3830           IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
    3831         PINC;
    3832         if (PPEEK_IS('#')) {
    3833           PFETCH(c);
    3834           while (1) {
    3835             if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
    3836             PFETCH(c);
    3837             if (c == MC_ESC(syn)) {
    3838               if (!PEND) PFETCH(c);
    3839             }
    3840             else {
    3841               if (c == ')') break;
    3842             }
    3843           }
    3844           goto start;
    3845         }
     3881          IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
     3882        PINC;
     3883        if (PPEEK_IS('#')) {
     3884          PFETCH(c);
     3885          while (1) {
     3886            if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
     3887            PFETCH(c);
     3888            if (c == MC_ESC(syn)) {
     3889              if (!PEND) PFETCH(c);
     3890            }
     3891            else {
     3892              if (c == ')') break;
     3893            }
     3894          }
     3895          goto start;
     3896        }
    38463897#ifdef USE_PERL_SUBEXP_CALL
    38473898        /* (?&name), (?n), (?R), (?0), (?+n), (?-n) */
     
    39143965
    39153966          PINC;     /* skip 'P' */
     3967          if (PEND) return ONIGERR_UNDEFINED_GROUP_OPTION;
    39163968          PFETCH(c);
    39173969          if (c == '=') {       /* (?P=name): backref */
     
    39323984            break;
    39333985          }
    3934           PUNFETCH;
    39353986        }
    39363987#endif /* USE_CAPITAL_P_NAMED_GROUP */
    3937         PUNFETCH;
     3988        PUNFETCH;
    39383989      }
    39393990
     
    40034054static int
    40044055add_ctype_to_cc_by_range(CClassNode* cc, int ctype ARG_UNUSED, int not,
    4005                          OnigEncoding enc ARG_UNUSED,
     4056                         ScanEnv* env,
    40064057                         OnigCodePoint sb_out, const OnigCodePoint mbr[])
    40074058{
     
    40134064  if (not == 0) {
    40144065    for (i = 0; i < n; i++) {
    4015       for (j  = ONIGENC_CODE_RANGE_FROM(mbr, i);
    4016            j <= ONIGENC_CODE_RANGE_TO(mbr, i); j++) {
     4066      for (j = ONIGENC_CODE_RANGE_FROM(mbr, i);
     4067          j <= ONIGENC_CODE_RANGE_TO(mbr, i); j++) {
    40174068        if (j >= sb_out) {
    40184069          if (j > ONIGENC_CODE_RANGE_FROM(mbr, i)) {
    4019             r = add_code_range_to_buf(&(cc->mbuf), j,
     4070            r = add_code_range_to_buf(&(cc->mbuf), env, j,
    40204071                                      ONIGENC_CODE_RANGE_TO(mbr, i));
    40214072            if (r != 0) return r;
     
    40254076          goto sb_end;
    40264077        }
    4027         BITSET_SET_BIT(cc->bs, j);
     4078        BITSET_SET_BIT_CHKDUP(cc->bs, j);
    40284079      }
    40294080    }
     
    40314082  sb_end:
    40324083    for ( ; i < n; i++) {
    4033       r = add_code_range_to_buf(&(cc->mbuf),
     4084      r = add_code_range_to_buf(&(cc->mbuf), env,
    40344085                                ONIGENC_CODE_RANGE_FROM(mbr, i),
    40354086                                ONIGENC_CODE_RANGE_TO(mbr, i));
     
    40464097          goto sb_end2;
    40474098        }
    4048         BITSET_SET_BIT(cc->bs, j);
     4099        BITSET_SET_BIT_CHKDUP(cc->bs, j);
    40494100      }
    40504101      prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
    40514102    }
    40524103    for (j = prev; j < sb_out; j++) {
    4053       BITSET_SET_BIT(cc->bs, j);
     4104      BITSET_SET_BIT_CHKDUP(cc->bs, j);
    40544105    }
    40554106
     
    40594110    for (i = 0; i < n; i++) {
    40604111      if (prev < ONIGENC_CODE_RANGE_FROM(mbr, i)) {
    4061         r = add_code_range_to_buf(&(cc->mbuf), prev,
     4112        r = add_code_range_to_buf(&(cc->mbuf), env, prev,
    40624113                                  ONIGENC_CODE_RANGE_FROM(mbr, i) - 1);
    40634114        if (r != 0) return r;
     
    40664117    }
    40674118    if (prev < 0x7fffffff) {
    4068       r = add_code_range_to_buf(&(cc->mbuf), prev, 0x7fffffff);
     4119      r = add_code_range_to_buf(&(cc->mbuf), env, prev, 0x7fffffff);
    40694120      if (r != 0) return r;
    40704121    }
     
    40884139      CClassNode ccwork;
    40894140      initialize_cclass(&ccwork);
    4090       r = add_ctype_to_cc_by_range(&ccwork, ctype, not, env->enc, sb_out,
     4141      r = add_ctype_to_cc_by_range(&ccwork, ctype, not, env, sb_out,
    40914142                                   ranges);
    40924143      if (r == 0) {
    40934144        if (not) {
    4094           r = add_code_range_to_buf(&(ccwork.mbuf), 0x80, ONIG_LAST_CODE_POINT);
     4145          r = add_code_range_to_buf0(&(ccwork.mbuf), env, 0x80, ONIG_LAST_CODE_POINT, FALSE);
    40954146        }
    40964147        else {
     
    40984149          initialize_cclass(&ccascii);
    40994150          if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
    4100             add_code_range(&(ccascii.mbuf), env, 0x00, 0x7F);
     4151            r = add_code_range(&(ccascii.mbuf), env, 0x00, 0x7F);
    41014152          }
    41024153          else {
    4103             bitset_set_range(ccascii.bs, 0x00, 0x7F);
     4154            bitset_set_range(env, ccascii.bs, 0x00, 0x7F);
     4155            r = 0;
    41044156          }
    4105           r = and_cclass(&ccwork, &ccascii, enc);
     4157          if (r == 0) {
     4158            r = and_cclass(&ccwork, &ccascii, env);
     4159          }
    41064160          if (IS_NOT_NULL(ccascii.mbuf)) bbuf_free(ccascii.mbuf);
    41074161        }
    41084162        if (r == 0) {
    4109           r = or_cclass(cc, &ccwork, enc);
     4163          r = or_cclass(cc, &ccwork, env);
    41104164        }
    41114165        if (IS_NOT_NULL(ccwork.mbuf)) bbuf_free(ccwork.mbuf);
     
    41134167    }
    41144168    else {
    4115       r = add_ctype_to_cc_by_range(cc, ctype, not, env->enc, sb_out, ranges);
     4169      r = add_ctype_to_cc_by_range(cc, ctype, not, env, sb_out, ranges);
    41164170    }
    41174171    return r;
     
    41384192      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
    41394193        if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
    4140           BITSET_SET_BIT(cc->bs, c);
     4194          BITSET_SET_BIT_CHKDUP(cc->bs, c);
    41414195      }
    41424196      ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
     
    41454199      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
    41464200        if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
    4147           BITSET_SET_BIT(cc->bs, c);
     4201          BITSET_SET_BIT_CHKDUP(cc->bs, c);
    41484202      }
    41494203    }
     
    41564210        if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)
    41574211            || c >= maxcode)
    4158           BITSET_SET_BIT(cc->bs, c);
     4212          BITSET_SET_BIT_CHKDUP(cc->bs, c);
    41594213      }
    41604214      if (ascii_range)
    4161         ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
     4215        ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    41624216    }
    41634217    else {
    41644218      for (c = 0; c < maxcode; c++) {
    41654219        if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
    4166           BITSET_SET_BIT(cc->bs, c);
     4220          BITSET_SET_BIT_CHKDUP(cc->bs, c);
    41674221      }
    41684222      if (! ascii_range)
    4169         ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
     4223        ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    41704224    }
    41714225    break;
     
    41744228    if (not == 0) {
    41754229      for (c = 0; c < maxcode; c++) {
    4176         if (ONIGENC_IS_CODE_WORD(enc, c)) BITSET_SET_BIT(cc->bs, c);
     4230        if (ONIGENC_IS_CODE_WORD(enc, c)) BITSET_SET_BIT_CHKDUP(cc->bs, c);
    41774231      }
    41784232      if (! ascii_range)
    4179         ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
     4233        ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    41804234    }
    41814235    else {
    41824236      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
    4183         if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* check invalid code point */
     4237        if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* check invalid code point */
    41844238            && (! ONIGENC_IS_CODE_WORD(enc, c) || c >= maxcode))
    4185           BITSET_SET_BIT(cc->bs, c);
     4239          BITSET_SET_BIT_CHKDUP(cc->bs, c);
    41864240      }
    41874241      if (ascii_range)
    4188         ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
     4242        ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    41894243    }
    41904244    break;
     
    42454299      p = (UChar* )onigenc_step(enc, p, end, pb->len);
    42464300      if (onigenc_with_ascii_strncmp(enc, p, end, (UChar* )":]", 2) != 0)
    4247         return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
     4301        return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
    42484302
    42494303      r = add_ctype_to_cc(cc, pb->ctype, not, ascii_range, env);
     
    42764330      PFETCH_S(c);
    42774331      if (c == ']')
    4278         return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
     4332        return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
    42794333    }
    42804334  }
     
    43564410static int
    43574411next_state_class(CClassNode* cc, CClassNode* asc_cc,
    4358                 OnigCodePoint* vs, enum CCVALTYPE* type,
     4412                OnigCodePoint* vs, enum CCVALTYPE* type,
    43594413                 enum CCSTATE* state, ScanEnv* env)
    43604414{
     
    43664420  if (*state == CCS_VALUE && *type != CCV_CLASS) {
    43674421    if (*type == CCV_SB) {
    4368       BITSET_SET_BIT(cc->bs, (int )(*vs));
     4422      BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs));
    43694423      if (IS_NOT_NULL(asc_cc))
    43704424        BITSET_SET_BIT(asc_cc->bs, (int )(*vs));
     
    43744428      if (r < 0) return r;
    43754429      if (IS_NOT_NULL(asc_cc)) {
    4376         r = add_code_range(&(asc_cc->mbuf), env, *vs, *vs);
     4430        r = add_code_range0(&(asc_cc->mbuf), env, *vs, *vs, 0);
    43774431        if (r < 0) return r;
    43784432      }
     
    43874441static int
    43884442next_state_val(CClassNode* cc, CClassNode* asc_cc,
    4389                OnigCodePoint *vs, OnigCodePoint v,
    4390                int* vs_israw, int v_israw,
     4443               OnigCodePoint *from, OnigCodePoint to,
     4444               int* from_israw, int to_israw,
    43914445               enum CCVALTYPE intype, enum CCVALTYPE* type,
    43924446               enum CCSTATE* state, ScanEnv* env)
     
    43974451  case CCS_VALUE:
    43984452    if (*type == CCV_SB) {
    4399       BITSET_SET_BIT(cc->bs, (int )(*vs));
     4453      BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*from));
    44004454      if (IS_NOT_NULL(asc_cc))
    4401         BITSET_SET_BIT(asc_cc->bs, (int )(*vs));
     4455        BITSET_SET_BIT(asc_cc->bs, (int )(*from));
    44024456    }
    44034457    else if (*type == CCV_CODE_POINT) {
    4404       r = add_code_range(&(cc->mbuf), env, *vs, *vs);
     4458      r = add_code_range(&(cc->mbuf), env, *from, *from);
    44054459      if (r < 0) return r;
    44064460      if (IS_NOT_NULL(asc_cc)) {
    4407         r = add_code_range(&(asc_cc->mbuf), env, *vs, *vs);
     4461        r = add_code_range0(&(asc_cc->mbuf), env, *from, *from, 0);
    44084462        if (r < 0) return r;
    44094463      }
     
    44144468    if (intype == *type) {
    44154469      if (intype == CCV_SB) {
    4416         if (*vs > 0xff || v > 0xff)
    4417           return ONIGERR_INVALID_CODE_POINT_VALUE;
    4418 
    4419         if (*vs > v) {
     4470        if (*from > 0xff || to > 0xff)
     4471          return ONIGERR_INVALID_CODE_POINT_VALUE;
     4472
     4473        if (*from > to) {
    44204474          if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
    44214475            goto ccs_range_end;
     
    44234477            return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
    44244478        }
    4425         bitset_set_range(cc->bs, (int )*vs, (int )v);
     4479        bitset_set_range(env, cc->bs, (int )*from, (int )to);
    44264480        if (IS_NOT_NULL(asc_cc))
    4427           bitset_set_range(asc_cc->bs, (int )*vs, (int )v);
     4481          bitset_set_range(env, asc_cc->bs, (int )*from, (int )to);
    44284482      }
    44294483      else {
    4430         r = add_code_range(&(cc->mbuf), env, *vs, v);
     4484        r = add_code_range(&(cc->mbuf), env, *from, to);
    44314485        if (r < 0) return r;
    44324486        if (IS_NOT_NULL(asc_cc)) {
    4433           r = add_code_range(&(asc_cc->mbuf), env, *vs, v);
     4487          r = add_code_range0(&(asc_cc->mbuf), env, *from, to, 0);
    44344488          if (r < 0) return r;
    44354489        }
     
    44374491    }
    44384492    else {
    4439 #if 0
    4440       if (intype == CCV_CODE_POINT && *type == CCV_SB) {
    4441 #endif
    4442         if (*vs > v) {
    4443           if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
    4444             goto ccs_range_end;
    4445           else
    4446             return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
    4447         }
    4448         bitset_set_range(cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
    4449         r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*vs, v);
     4493      if (*from > to) {
     4494        if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
     4495          goto ccs_range_end;
     4496        else
     4497          return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
     4498      }
     4499      bitset_set_range(env, cc->bs, (int )*from, (int )(to < 0xff ? to : 0xff));
     4500      r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*from, to);
     4501      if (r < 0) return r;
     4502      if (IS_NOT_NULL(asc_cc)) {
     4503        bitset_set_range(env, asc_cc->bs, (int )*from, (int )(to < 0xff ? to : 0xff));
     4504        r = add_code_range0(&(asc_cc->mbuf), env, (OnigCodePoint )*from, to, 0);
    44504505        if (r < 0) return r;
    4451         if (IS_NOT_NULL(asc_cc)) {
    4452           bitset_set_range(asc_cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
    4453           r = add_code_range(&(asc_cc->mbuf), env, (OnigCodePoint )*vs, v);
    4454           if (r < 0) return r;
    4455         }
    4456 #if 0
    4457       }
    4458       else
    4459         return ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE;
    4460 #endif
     4506      }
    44614507    }
    44624508  ccs_range_end:
     
    44734519  }
    44744520
    4475   *vs_israw = v_israw;
    4476   *vs       = v;
    4477   *type     = intype;
     4521  *from_israw = to_israw;
     4522  *from       = to;
     4523  *type       = intype;
    44784524  return 0;
    44794525}
     
    45194565  int val_israw, in_israw;
    45204566
     4567  *np = *asc_np = NULL_NODE;
     4568  env->parse_depth++;
     4569  if (env->parse_depth > ParseDepthLimit)
     4570    return ONIGERR_PARSE_DEPTH_LIMIT_OVER;
    45214571  prev_cc = asc_prev_cc = (CClassNode* )NULL;
    4522   *np = *asc_np = NULL_NODE;
    45234572  r = fetch_token_in_cc(tok, src, end, env);
    45244573  if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) {
     
    46024651        }
    46034652
    4604         len = enclen(env->enc, buf);
     4653        len = enclen(env->enc, buf, buf + i);
    46054654        if (i < len) {
    46064655          r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
     
    46104659          p = psave;
    46114660          for (i = 1; i < len; i++) {
    4612             r = fetch_token_in_cc(tok, &p, end, env);
     4661            (void)fetch_token_in_cc(tok, &p, end, env);
     4662            /* no need to check the retun value (already checked above) */
    46134663          }
    46144664          fetched = 0;
     
    47104760          goto range_end_val;
    47114761        }
     4762
     4763        if (val_type == CCV_CLASS) {
     4764          r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS;
     4765          goto err;
     4766        }
     4767
    47124768        state = CCS_RANGE;
    47134769      }
     
    47574813        if (r == 0) {
    47584814          acc = NCCLASS(anode);
    4759           r = or_cclass(cc, acc, env->enc);
     4815          r = or_cclass(cc, acc, env);
    47604816        }
    47614817        if (r == 0 && IS_NOT_NULL(aasc_node)) {
    47624818          acc = NCCLASS(aasc_node);
    4763           r = or_cclass(asc_cc, acc, env->enc);
     4819          r = or_cclass(asc_cc, acc, env);
    47644820        }
    47654821        onig_node_free(anode);
     
    47814837
    47824838        if (IS_NOT_NULL(prev_cc)) {
    4783           r = and_cclass(prev_cc, cc, env->enc);
     4839          r = and_cclass(prev_cc, cc, env);
    47844840          if (r != 0) goto err;
    47854841          bbuf_free(cc->mbuf);
    47864842          if (IS_NOT_NULL(asc_cc)) {
    4787             r = and_cclass(asc_prev_cc, asc_cc, env->enc);
     4843            r = and_cclass(asc_prev_cc, asc_cc, env);
    47884844            if (r != 0) goto err;
    47894845            bbuf_free(asc_cc->mbuf);
     
    48294885
    48304886  if (IS_NOT_NULL(prev_cc)) {
    4831     r = and_cclass(prev_cc, cc, env->enc);
     4887    r = and_cclass(prev_cc, cc, env);
    48324888    if (r != 0) goto err;
    48334889    bbuf_free(cc->mbuf);
    48344890    cc = prev_cc;
    48354891    if (IS_NOT_NULL(asc_cc)) {
    4836       r = and_cclass(asc_prev_cc, asc_cc, env->enc);
     4892      r = and_cclass(asc_prev_cc, asc_cc, env);
    48374893      if (r != 0) goto err;
    48384894      bbuf_free(asc_cc->mbuf);
     
    48634919
    48644920      if (ONIGENC_IS_CODE_NEWLINE(env->enc, NEWLINE_CODE)) {
    4865         if (ONIGENC_CODE_TO_MBCLEN(env->enc, NEWLINE_CODE) == 1)
    4866           BITSET_SET_BIT(cc->bs, NEWLINE_CODE);
    4867         else {
    4868           r = add_code_range(&(cc->mbuf), env, NEWLINE_CODE, NEWLINE_CODE);
    4869           if (r < 0) goto err;
    4870         }
     4921        if (ONIGENC_CODE_TO_MBCLEN(env->enc, NEWLINE_CODE) == 1)
     4922          BITSET_SET_BIT_CHKDUP(cc->bs, NEWLINE_CODE);
     4923        else {
     4924          r = add_code_range(&(cc->mbuf), env, NEWLINE_CODE, NEWLINE_CODE);
     4925          if (r < 0) goto err;
     4926        }
    48714927      }
    48724928    }
    48734929  }
    48744930  *src = p;
     4931  env->parse_depth--;
    48754932  return 0;
    48764933
     
    49334990      *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
    49344991      break;
     4992    case '~':   /* (?~...) absent operator */
     4993      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_TILDE_ABSENT)) {
     4994        *np = node_new_enclose(ENCLOSE_ABSENT);
     4995      }
     4996      else {
     4997        return ONIGERR_UNDEFINED_GROUP_OPTION;
     4998      }
     4999      break;
    49355000
    49365001#ifdef USE_NAMED_GROUP
     
    49435008      break;
    49445009
    4945 #ifdef USE_CAPITAL_P_NAMED_GROUP
     5010# ifdef USE_CAPITAL_P_NAMED_GROUP
    49465011    case 'P':   /* (?P<name>...) */
    4947       if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP)) {
     5012      if (!PEND &&
     5013          IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP)) {
    49485014        PFETCH(c);
    49495015        if (c == '<') goto named_group1;
     
    49515017      return ONIGERR_UNDEFINED_GROUP_OPTION;
    49525018      break;
     5019# endif
    49535020#endif
    4954 #endif
    49555021
    49565022    case '<':   /* look behind (?<=...), (?<!...) */
     5023      if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
    49575024      PFETCH(c);
    49585025      if (c == '=')
     
    49725039          list_capture = 0;
    49735040
     5041# ifdef USE_CAPTURE_HISTORY
    49745042        named_group2:
     5043# endif
    49755044          name = p;
    49765045          r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
     
    50025071      break;
    50035072
     5073#ifdef USE_CAPTURE_HISTORY
    50045074    case '@':
    50055075      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) {
    5006 #ifdef USE_NAMED_GROUP
    5007         if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
     5076# ifdef USE_NAMED_GROUP
     5077        if (!PEND &&
     5078            IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
    50085079          PFETCH(c);
    50095080          if (c == '<' || c == '\'') {
     
    50135084          PUNFETCH;
    50145085        }
    5015 #endif
     5086# endif
    50165087        *np = node_new_enclose_memory(env->option, 0);
    50175088        CHECK_NULL_RETURN_MEMERR(*np);
     
    50285099      }
    50295100      break;
     5101#endif /* USE_CAPTURE_HISTORY */
    50305102
    50315103    case '(':   /* conditional expression: (?(cond)yes), (?(cond)yes|no) */
    5032       if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LPAREN_CONDITION)) {
     5104      if (!PEND &&
     5105          IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LPAREN_CONDITION)) {
    50335106        UChar *name = NULL;
    50345107        UChar *name_end;
     
    50485121          if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_STRICT_CHECK_BACKREF)) {
    50495122            if (num > env->num_mem ||
    5050                 IS_NULL(SCANENV_MEM_NODES(env)[num]))
     5123                IS_NULL(SCANENV_MEM_NODES(env)[num]))
    50515124            return ONIGERR_INVALID_BACKREF;
    50525125          }
     
    50545127#ifdef USE_NAMED_GROUP
    50555128        else if (c == '<' || c == '\'') {    /* (<name>), ('name') */
    5056           int nums;
    5057           int *backs;
    5058 
    50595129          name = p;
    5060           r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
     5130          r = fetch_named_backref_token(c, tok, &p, end, env);
    50615131          if (r < 0) return r;
    5062           PFETCH(c);
    5063           if (c != ')') return ONIGERR_UNDEFINED_GROUP_OPTION;
    5064 
    5065           nums = onig_name_to_group_numbers(env->reg, name, name_end, &backs);
    5066           if (nums <= 0) {
    5067             onig_scan_env_set_error_string(env,
    5068                      ONIGERR_UNDEFINED_NAME_REFERENCE, name, name_end);
    5069             return ONIGERR_UNDEFINED_NAME_REFERENCE;
     5132          if (!PPEEK_IS(')')) return ONIGERR_UNDEFINED_GROUP_OPTION;
     5133          PINC;
     5134
     5135          if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP)) {
     5136            num = tok->u.backref.ref1;
    50705137          }
    5071           if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_STRICT_CHECK_BACKREF)) {
    5072             int i;
    5073             for (i = 0; i < nums; i++) {
    5074               if (backs[i] > env->num_mem ||
    5075                   IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
    5076               return ONIGERR_INVALID_BACKREF;
    5077             }
     5138          else {
     5139            /* FIXME:
     5140             * Use left most named group for now. This is the same as Perl.
     5141             * However this should use the same strategy as normal back-
     5142             * references on Ruby syntax; search right to left. */
     5143            int len = tok->u.backref.num;
     5144            num = len > 1 ? tok->u.backref.refs[0] : tok->u.backref.ref1;
    50785145          }
    5079           num = backs[0];       /* XXX: use left most named group as Perl */
    50805146        }
    50815147#endif
     
    51025168
    51035169    case '^':   /* loads default options */
    5104       if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
     5170      if (!PEND && IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
    51055171        /* d-imsx */
    51065172        ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
     
    51125178      }
    51135179#if 0
    5114       else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
     5180      else if (!PEND && IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
    51155181        /* d-imx */
    51165182        ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
     
    51705236          case 'a':     /* limits \d, \s, \w and POSIX brackets to ASCII range */
    51715237            if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
    5172                 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
    5173                 (neg == 0)) {
     5238                IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
     5239                (neg == 0)) {
    51745240              ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
    51755241              ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
     
    51825248          case 'u':
    51835249            if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
    5184                 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
    5185                 (neg == 0)) {
     5250                IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
     5251                (neg == 0)) {
    51865252              ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
    51875253              ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
     
    51945260          case 'd':
    51955261            if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) &&
    5196                 (neg == 0)) {
     5262                (neg == 0)) {
    51975263              ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
    51985264            }
    51995265            else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY) &&
    5200                 (neg == 0)) {
     5266                (neg == 0)) {
    52015267              ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
    52025268              ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 0);
     
    52285294            OnigOptionType prev = env->option;
    52295295
    5230             env->option     = option;
     5296            env->option = option;
    52315297            r = fetch_token(tok, &p, end, env);
    5232             if (r < 0) return r;
     5298            if (r < 0) {
     5299              env->option = prev;
     5300              return r;
     5301            }
    52335302            r = parse_subexp(&target, tok, term, &p, end, env);
    52345303            env->option = prev;
     
    53455414
    53465415#ifdef USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
    5347       if (!IS_QUANTIFIER_BY_NUMBER(qn) && !IS_QUANTIFIER_BY_NUMBER(qnt) &&
     5416      if (nestq_num >= 0 && targetq_num >= 0 &&
    53485417          IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT)) {
    5349         UChar buf[WARN_BUFSIZE];
    5350 
    5351         switch (ReduceTypeTable[targetq_num][nestq_num]) {
    5352         case RQ_ASIS:
    5353           break;
    5354 
    5355         case RQ_DEL:
    5356           if (onig_verb_warn != onig_null_warn) {
    5357             onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
    5358                                  env->pattern, env->pattern_end,
    5359                                  (UChar* )"redundant nested repeat operator");
    5360             (*onig_verb_warn)((char* )buf);
    5361           }
    5362           goto warn_exit;
    5363           break;
    5364 
    5365         default:
    5366           if (onig_verb_warn != onig_null_warn) {
    5367             onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
    5368                                        env->pattern, env->pattern_end,
    5369             (UChar* )"nested repeat operator %s and %s was replaced with '%s'",
    5370             PopularQStr[targetq_num], PopularQStr[nestq_num],
    5371             ReduceQStr[ReduceTypeTable[targetq_num][nestq_num]]);
    5372             (*onig_verb_warn)((char* )buf);
    5373           }
    5374           goto warn_exit;
    5375           break;
    5376         }
     5418        switch (ReduceTypeTable[targetq_num][nestq_num]) {
     5419        case RQ_ASIS:
     5420          break;
     5421
     5422        case RQ_DEL:
     5423          if (onig_warn != onig_null_warn) {
     5424            onig_syntax_warn(env, "regular expression has redundant nested repeat operator '%s'",
     5425                PopularQStr[targetq_num]);
     5426          }
     5427          goto warn_exit;
     5428          break;
     5429
     5430        default:
     5431          if (onig_warn != onig_null_warn) {
     5432            onig_syntax_warn(env, "nested repeat operator '%s' and '%s' was replaced with '%s' in regular expression",
     5433                PopularQStr[targetq_num], PopularQStr[nestq_num],
     5434                ReduceQStr[ReduceTypeTable[targetq_num][nestq_num]]);
     5435          }
     5436          goto warn_exit;
     5437          break;
     5438        }
    53775439      }
    53785440
     
    54025464  return 0;
    54035465}
    5404 
    5405 
    5406 #ifdef USE_SHARED_CCLASS_TABLE
    5407 
    5408 #define THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS     8
    5409 
    5410 /* for ctype node hash table */
    5411 
    5412 typedef struct {
    5413   OnigEncoding enc;
    5414   int not;
    5415   int type;
    5416 } type_cclass_key;
    5417 
    5418 static int type_cclass_cmp(type_cclass_key* x, type_cclass_key* y)
    5419 {
    5420   if (x->type != y->type) return 1;
    5421   if (x->enc  != y->enc)  return 1;
    5422   if (x->not  != y->not)  return 1;
    5423   return 0;
    5424 }
    5425 
    5426 static int type_cclass_hash(type_cclass_key* key)
    5427 {
    5428   int i, val;
    5429   UChar *p;
    5430 
    5431   val = 0;
    5432 
    5433   p = (UChar* )&(key->enc);
    5434   for (i = 0; i < (int )sizeof(key->enc); i++) {
    5435     val = val * 997 + (int )*p++;
    5436   }
    5437 
    5438   p = (UChar* )(&key->type);
    5439   for (i = 0; i < (int )sizeof(key->type); i++) {
    5440     val = val * 997 + (int )*p++;
    5441   }
    5442 
    5443   val += key->not;
    5444   return val + (val >> 5);
    5445 }
    5446 
    5447 static struct st_hash_type type_type_cclass_hash = {
    5448     type_cclass_cmp,
    5449     type_cclass_hash,
    5450 };
    5451 
    5452 static st_table* OnigTypeCClassTable;
    5453 
    5454 
    5455 static int
    5456 i_free_shared_class(type_cclass_key* key, Node* node, void* arg ARG_UNUSED)
    5457 {
    5458   if (IS_NOT_NULL(node)) {
    5459     CClassNode* cc = NCCLASS(node);
    5460     if (IS_NOT_NULL(cc->mbuf)) xfree(cc->mbuf);
    5461     xfree(node);
    5462   }
    5463 
    5464   if (IS_NOT_NULL(key)) xfree(key);
    5465   return ST_DELETE;
    5466 }
    5467 
    5468 extern int
    5469 onig_free_shared_cclass_table(void)
    5470 {
    5471   /* THREAD_ATOMIC_START; */
    5472   if (IS_NOT_NULL(OnigTypeCClassTable)) {
    5473     onig_st_foreach(OnigTypeCClassTable, i_free_shared_class, 0);
    5474     onig_st_free_table(OnigTypeCClassTable);
    5475     OnigTypeCClassTable = NULL;
    5476   }
    5477   /* THREAD_ATOMIC_END; */
    5478 
    5479   return 0;
    5480 }
    5481 
    5482 #endif /* USE_SHARED_CCLASS_TABLE */
    54835466
    54845467
     
    55255508  CClassNode* asc_cc;
    55265509  BitSetRef bs;
    5527   int add_flag;
     5510  int add_flag, r;
    55285511
    55295512  iarg = (IApplyCaseFoldArg* )arg;
     
    55525535      if (add_flag) {
    55535536        if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
    5554           add_code_range(&(cc->mbuf), env, *to, *to);
     5537          r = add_code_range0(&(cc->mbuf), env, *to, *to, 0);
     5538          if (r < 0) return r;
    55555539        }
    55565540        else {
     
    55645548        if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
    55655549          if (IS_NCCLASS_NOT(cc)) clear_not_flag_cclass(cc, env->enc);
    5566           add_code_range(&(cc->mbuf), env, *to, *to);
     5550          r = add_code_range0(&(cc->mbuf), env, *to, *to, 0);
     5551          if (r < 0) return r;
    55675552        }
    55685553        else {
     
    56545639  Node* target2 = NULL;
    56555640  CClassNode* cc;
    5656   int num1, num2;
     5641  int num1, num2, r;
    56575642  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
    56585643
     
    56705655  cc = NCCLASS(right);
    56715656  if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
    5672     add_code_range(&(cc->mbuf), env, 0x0A, 0x0D);
     5657    r = add_code_range(&(cc->mbuf), env, 0x0A, 0x0D);
     5658    if (r != 0) goto err;
    56735659  }
    56745660  else {
    5675     bitset_set_range(cc->bs, 0x0A, 0x0D);
     5661    bitset_set_range(env, cc->bs, 0x0A, 0x0D);
    56765662  }
    56775663
     
    56795665  if (ONIGENC_IS_UNICODE(env->enc)) {
    56805666    /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
    5681     add_code_range(&(cc->mbuf), env, 0x85, 0x85);
    5682     add_code_range(&(cc->mbuf), env, 0x2028, 0x2029);
     5667    r = add_code_range(&(cc->mbuf), env, 0x85, 0x85);
     5668    if (r != 0) goto err;
     5669    r = add_code_range(&(cc->mbuf), env, 0x2028, 0x2029);
     5670    if (r != 0) goto err;
    56835671  }
    56845672
     
    57075695
    57085696static int
     5697propname2ctype(ScanEnv* env, const char* propname)
     5698{
     5699  UChar* name = (UChar* )propname;
     5700  int ctype = env->enc->property_name_to_ctype(ONIG_ENCODING_ASCII,
     5701      name, name + strlen(propname));
     5702  return ctype;
     5703}
     5704
     5705static int
    57095706node_extended_grapheme_cluster(Node** np, ScanEnv* env)
    57105707{
    5711   /* same as (?>\P{M}\p{M}*) */
     5708  Node* tmp = NULL;
    57125709  Node* np1 = NULL;
    5713   Node* np2 = NULL;
    5714   Node* qn = NULL;
    5715   Node* list1 = NULL;
     5710  Node* list = NULL;
    57165711  Node* list2 = NULL;
     5712  Node* alt = NULL;
     5713  Node* alt2 = NULL;
     5714  BBuf *pbuf1 = NULL;
    57175715  int r = 0;
     5716  int num1;
     5717  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
     5718  OnigOptionType option;
    57185719
    57195720#ifdef USE_UNICODE_PROPERTIES
    57205721  if (ONIGENC_IS_UNICODE(env->enc)) {
    57215722    /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
    5722     CClassNode* cc1;
    5723     CClassNode* cc2;
    5724     UChar* propname = (UChar* )"M";
    5725     int ctype = env->enc->property_name_to_ctype(ONIG_ENCODING_ASCII,
    5726         propname, propname + 1);
    5727     if (ctype >= 0) {
    5728       /* \P{M} */
    5729       np1 = node_new_cclass();
    5730       if (IS_NULL(np1)) goto err;
    5731       cc1 = NCCLASS(np1);
    5732       r = add_ctype_to_cc(cc1, ctype, 0, 0, env);
     5723    CClassNode* cc;
     5724    OnigCodePoint sb_out = (ONIGENC_MBC_MINLEN(env->enc) > 1) ? 0x00 : 0x80;
     5725    int extend = propname2ctype(env, "Grapheme_Cluster_Break=Extend");
     5726
     5727    /* Prepend*
     5728     * ( RI-sequence | Hangul-Syllable | !Control )
     5729     * ( Grapheme_Extend | SpacingMark )* */
     5730
     5731    /* ( Grapheme_Extend | SpacingMark )* */
     5732    np1 = node_new_cclass();
     5733    if (IS_NULL(np1)) goto err;
     5734    cc = NCCLASS(np1);
     5735    r = add_ctype_to_cc(cc, extend, 0, 0, env);
     5736    if (r != 0) goto err;
     5737    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=SpacingMark"), 0, 0, env);
     5738    if (r != 0) goto err;
     5739    r = add_code_range(&(cc->mbuf), env, 0x200D, 0x200D);
     5740    if (r != 0) goto err;
     5741
     5742    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5743    if (IS_NULL(tmp)) goto err;
     5744    NQTFR(tmp)->target = np1;
     5745    np1 = tmp;
     5746
     5747    tmp = node_new_list(np1, NULL_NODE);
     5748    if (IS_NULL(tmp)) goto err;
     5749    list = tmp;
     5750    np1 = NULL;
     5751
     5752    /* ( RI-sequence | Hangul-Syllable | !Control ) */
     5753    /* !Control */
     5754    np1 = node_new_cclass();
     5755    if (IS_NULL(np1)) goto err;
     5756    cc = NCCLASS(np1);
     5757    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Control"), 1, 0, env);
     5758    if (r != 0) goto err;
     5759    if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
     5760      BBuf *pbuf2 = NULL;
     5761      r = add_code_range(&pbuf1, env, 0x0a, 0x0a);
    57335762      if (r != 0) goto err;
    5734       NCCLASS_SET_NOT(cc1);
    5735 
    5736       /* \p{M}* */
    5737       np2 = node_new_cclass();
    5738       if (IS_NULL(np2)) goto err;
    5739       cc2 = NCCLASS(np2);
    5740       r = add_ctype_to_cc(cc2, ctype, 0, 0, env);
     5763      r = add_code_range(&pbuf1, env, 0x0d, 0x0d);
    57415764      if (r != 0) goto err;
    5742 
    5743       qn = node_new_quantifier(0, REPEAT_INFINITE, 0);
    5744       if (IS_NULL(qn)) goto err;
    5745       NQTFR(qn)->target = np2;
    5746       np2 = NULL;
    5747 
    5748       /* \P{M}\p{M}* */
    5749       list2 = node_new_list(qn, NULL_NODE);
    5750       if (IS_NULL(list2)) goto err;
    5751       qn = NULL;
    5752       list1 = node_new_list(np1, list2);
    5753       if (IS_NULL(list1)) goto err;
    5754       np1 = NULL;
    5755       list2 = NULL;
    5756 
    5757       /* (?>...) */
    5758       *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
    5759       if (IS_NULL(*np)) goto err;
    5760       NENCLOSE(*np)->target = list1;
    5761       return ONIG_NORMAL;
    5762     }
    5763   }
    5764 #endif /* USE_UNICODE_PROPERTIES */
    5765   if (IS_NULL(*np)) {
     5765      r = and_code_range_buf(cc->mbuf, 0, pbuf1, 1, &pbuf2, env);
     5766      if (r != 0) {
     5767        bbuf_free(pbuf2);
     5768        goto err;
     5769      }
     5770      bbuf_free(pbuf1);
     5771      pbuf1 = NULL;
     5772      bbuf_free(cc->mbuf);
     5773      cc->mbuf = pbuf2;
     5774    }
     5775    else {
     5776      BITSET_CLEAR_BIT(cc->bs, 0x0a);
     5777      BITSET_CLEAR_BIT(cc->bs, 0x0d);
     5778    }
     5779
     5780    tmp = onig_node_new_alt(np1, NULL_NODE);
     5781    if (IS_NULL(tmp)) goto err;
     5782    alt = tmp;
     5783    np1 = NULL;
     5784
     5785    /* Hangul-Syllable
     5786     *  := L* V+ T*
     5787     *  | L* LV V* T*
     5788     *  | L* LVT T*
     5789     *  | L+
     5790     *  | T+ */
     5791
     5792    /* T+ */
     5793    np1 = node_new_cclass();
     5794    if (IS_NULL(np1)) goto err;
     5795    cc = NCCLASS(np1);
     5796    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
     5797    if (r != 0) goto err;
     5798
     5799    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
     5800    if (IS_NULL(tmp)) goto err;
     5801    NQTFR(tmp)->target = np1;
     5802    np1 = tmp;
     5803
     5804    tmp = onig_node_new_alt(np1, alt);
     5805    if (IS_NULL(tmp)) goto err;
     5806    alt = tmp;
     5807    np1 = NULL;
     5808
     5809    /* L+ */
     5810    np1 = node_new_cclass();
     5811    if (IS_NULL(np1)) goto err;
     5812    cc = NCCLASS(np1);
     5813    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
     5814    if (r != 0) goto err;
     5815
     5816    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
     5817    if (IS_NULL(tmp)) goto err;
     5818    NQTFR(tmp)->target = np1;
     5819    np1 = tmp;
     5820
     5821    tmp = onig_node_new_alt(np1, alt);
     5822    if (IS_NULL(tmp)) goto err;
     5823    alt = tmp;
     5824    np1 = NULL;
     5825
     5826    /* L* LVT T* */
     5827    np1 = node_new_cclass();
     5828    if (IS_NULL(np1)) goto err;
     5829    cc = NCCLASS(np1);
     5830    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
     5831    if (r != 0) goto err;
     5832
     5833    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5834    if (IS_NULL(tmp)) goto err;
     5835    NQTFR(tmp)->target = np1;
     5836    np1 = tmp;
     5837
     5838    tmp = node_new_list(np1, NULL_NODE);
     5839    if (IS_NULL(tmp)) goto err;
     5840    list2 = tmp;
     5841    np1 = NULL;
     5842
     5843    np1 = node_new_cclass();
     5844    if (IS_NULL(np1)) goto err;
     5845    cc = NCCLASS(np1);
     5846    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LVT"), 0, 0, env);
     5847    if (r != 0) goto err;
     5848
     5849    tmp = node_new_list(np1, list2);
     5850    if (IS_NULL(tmp)) goto err;
     5851    list2 = tmp;
     5852    np1 = NULL;
     5853
     5854    np1 = node_new_cclass();
     5855    if (IS_NULL(np1)) goto err;
     5856    cc = NCCLASS(np1);
     5857    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
     5858    if (r != 0) goto err;
     5859
     5860    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5861    if (IS_NULL(tmp)) goto err;
     5862    NQTFR(tmp)->target = np1;
     5863    np1 = tmp;
     5864
     5865    tmp = node_new_list(np1, list2);
     5866    if (IS_NULL(tmp)) goto err;
     5867    list2 = tmp;
     5868    np1 = NULL;
     5869
     5870    tmp = onig_node_new_alt(list2, alt);
     5871    if (IS_NULL(tmp)) goto err;
     5872    alt = tmp;
     5873    list2 = NULL;
     5874
     5875    /* L* LV V* T* */
     5876    np1 = node_new_cclass();
     5877    if (IS_NULL(np1)) goto err;
     5878    cc = NCCLASS(np1);
     5879    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
     5880    if (r != 0) goto err;
     5881
     5882    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5883    if (IS_NULL(tmp)) goto err;
     5884    NQTFR(tmp)->target = np1;
     5885    np1 = tmp;
     5886
     5887    tmp = node_new_list(np1, NULL_NODE);
     5888    if (IS_NULL(tmp)) goto err;
     5889    list2 = tmp;
     5890    np1 = NULL;
     5891
     5892    np1 = node_new_cclass();
     5893    if (IS_NULL(np1)) goto err;
     5894    cc = NCCLASS(np1);
     5895    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
     5896    if (r != 0) goto err;
     5897
     5898    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5899    if (IS_NULL(tmp)) goto err;
     5900    NQTFR(tmp)->target = np1;
     5901    np1 = tmp;
     5902
     5903    tmp = node_new_list(np1, list2);
     5904    if (IS_NULL(tmp)) goto err;
     5905    list2 = tmp;
     5906    np1 = NULL;
     5907
     5908    np1 = node_new_cclass();
     5909    if (IS_NULL(np1)) goto err;
     5910    cc = NCCLASS(np1);
     5911    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LV"), 0, 0, env);
     5912    if (r != 0) goto err;
     5913
     5914    tmp = node_new_list(np1, list2);
     5915    if (IS_NULL(tmp)) goto err;
     5916    list2 = tmp;
     5917    np1 = NULL;
     5918
     5919    np1 = node_new_cclass();
     5920    if (IS_NULL(np1)) goto err;
     5921    cc = NCCLASS(np1);
     5922    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
     5923    if (r != 0) goto err;
     5924
     5925    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5926    if (IS_NULL(tmp)) goto err;
     5927    NQTFR(tmp)->target = np1;
     5928    np1 = tmp;
     5929
     5930    tmp = node_new_list(np1, list2);
     5931    if (IS_NULL(tmp)) goto err;
     5932    list2 = tmp;
     5933    np1 = NULL;
     5934
     5935    tmp = onig_node_new_alt(list2, alt);
     5936    if (IS_NULL(tmp)) goto err;
     5937    alt = tmp;
     5938    list2 = NULL;
     5939
     5940    /* L* V+ T* */
     5941    np1 = node_new_cclass();
     5942    if (IS_NULL(np1)) goto err;
     5943    cc = NCCLASS(np1);
     5944    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
     5945    if (r != 0) goto err;
     5946
     5947    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5948    if (IS_NULL(tmp)) goto err;
     5949    NQTFR(tmp)->target = np1;
     5950    np1 = tmp;
     5951
     5952    tmp = node_new_list(np1, NULL_NODE);
     5953    if (IS_NULL(tmp)) goto err;
     5954    list2 = tmp;
     5955    np1 = NULL;
     5956
     5957    np1 = node_new_cclass();
     5958    if (IS_NULL(np1)) goto err;
     5959    cc = NCCLASS(np1);
     5960    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
     5961    if (r != 0) goto err;
     5962
     5963    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
     5964    if (IS_NULL(tmp)) goto err;
     5965    NQTFR(tmp)->target = np1;
     5966    np1 = tmp;
     5967
     5968    tmp = node_new_list(np1, list2);
     5969    if (IS_NULL(tmp)) goto err;
     5970    list2 = tmp;
     5971    np1 = NULL;
     5972
     5973    np1 = node_new_cclass();
     5974    if (IS_NULL(np1)) goto err;
     5975    cc = NCCLASS(np1);
     5976    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
     5977    if (r != 0) goto err;
     5978
     5979    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     5980    if (IS_NULL(tmp)) goto err;
     5981    NQTFR(tmp)->target = np1;
     5982    np1 = tmp;
     5983
     5984    tmp = node_new_list(np1, list2);
     5985    if (IS_NULL(tmp)) goto err;
     5986    list2 = tmp;
     5987    np1 = NULL;
     5988
     5989    tmp = onig_node_new_alt(list2, alt);
     5990    if (IS_NULL(tmp)) goto err;
     5991    alt = tmp;
     5992    list2 = NULL;
     5993
     5994    /* Emoji sequence := (E_Base | EBG) Extend* E_Modifier?
     5995     *                   (ZWJ (Glue_After_Zwj | EBG Extend* E_Modifier?) )* */
     5996
     5997    /* ZWJ (Glue_After_Zwj | E_Base_GAZ Extend* E_Modifier?) */
     5998    np1 = node_new_cclass();
     5999    if (IS_NULL(np1)) goto err;
     6000    cc = NCCLASS(np1);
     6001    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
     6002    if (r != 0) goto err;
     6003
     6004    tmp = node_new_quantifier(0, 1, 0);
     6005    if (IS_NULL(tmp)) goto err;
     6006    NQTFR(tmp)->target = np1;
     6007    np1 = tmp;
     6008
     6009    tmp = node_new_list(np1, NULL_NODE);
     6010    if (IS_NULL(tmp)) goto err;
     6011    list2 = tmp;
     6012    np1 = NULL;
     6013
     6014    np1 = node_new_cclass();
     6015    if (IS_NULL(np1)) goto err;
     6016    cc = NCCLASS(np1);
     6017    r = add_ctype_to_cc(cc, extend, 0, 0, env);
     6018    if (r != 0) goto err;
     6019
     6020    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     6021    if (IS_NULL(tmp)) goto err;
     6022    NQTFR(tmp)->target = np1;
     6023    np1 = tmp;
     6024
     6025    tmp = node_new_list(np1, list2);
     6026    if (IS_NULL(tmp)) goto err;
     6027    list2 = tmp;
     6028    np1 = NULL;
     6029
     6030    np1 = node_new_cclass();
     6031    if (IS_NULL(np1)) goto err;
     6032    cc = NCCLASS(np1);
     6033    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
     6034    if (r != 0) goto err;
     6035
     6036    tmp = node_new_list(np1, list2);
     6037    if (IS_NULL(tmp)) goto err;
     6038    list2 = tmp;
     6039    np1 = NULL;
     6040
     6041    tmp = onig_node_new_alt(list2, NULL_NODE);
     6042    if (IS_NULL(tmp)) goto err;
     6043    alt2 = tmp;
     6044    list2 = NULL;
     6045
     6046    /* Glue_After_Zwj */
     6047    np1 = node_new_cclass();
     6048    if (IS_NULL(np1)) goto err;
     6049    cc = NCCLASS(np1);
     6050    r = add_ctype_to_cc(cc, extend, 0, 0, env);
     6051    if (r != 0) goto err;
     6052
     6053    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     6054    if (IS_NULL(tmp)) goto err;
     6055    NQTFR(tmp)->target = np1;
     6056    np1 = tmp;
     6057
     6058    tmp = node_new_list(np1, NULL_NODE);
     6059    if (IS_NULL(tmp)) goto err;
     6060    list2 = tmp;
     6061    np1 = NULL;
     6062
     6063    np1 = node_new_cclass();
     6064    if (IS_NULL(np1)) goto err;
     6065    cc = NCCLASS(np1);
     6066    {
     6067      static const OnigCodePoint ranges[] = {
     6068        13,
     6069        0x1F308, 0x1F308,
     6070        0x1F33E, 0x1F33E,
     6071        0x1F373, 0x1F373,
     6072        0x1F393, 0x1F393,
     6073        0x1F3A4, 0x1F3A4,
     6074        0x1F3A8, 0x1F3A8,
     6075        0x1F3EB, 0x1F3EB,
     6076        0x1F3ED, 0x1F3ED,
     6077        0x1F4BB, 0x1F4BC,
     6078        0x1F527, 0x1F527,
     6079        0x1F52C, 0x1F52C,
     6080        0x1F680, 0x1F680,
     6081        0x1F692, 0x1F692,
     6082      };
     6083      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
     6084      if (r != 0) goto err;
     6085    }
     6086    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
     6087    if (r != 0) goto err;
     6088
     6089    tmp = node_new_list(np1, list2);
     6090    if (IS_NULL(tmp)) goto err;
     6091    list2 = tmp;
     6092    np1 = NULL;
     6093
     6094    tmp = onig_node_new_alt(list2, alt2);
     6095    if (IS_NULL(tmp)) goto err;
     6096    alt2 = tmp;
     6097    list2 = NULL;
     6098
     6099    /* Emoji variation sequence
     6100     * http://unicode.org/Public/emoji/4.0/emoji-zwj-sequences.txt
     6101     */
     6102    r = ONIGENC_CODE_TO_MBC(env->enc, 0xfe0f, buf);
     6103    if (r < 0) goto err;
     6104    np1 = node_new_str_raw(buf, buf + r);
     6105    if (IS_NULL(np1)) goto err;
     6106
     6107    tmp = node_new_quantifier(0, 1, 0);
     6108    if (IS_NULL(tmp)) goto err;
     6109    NQTFR(tmp)->target = np1;
     6110    np1 = tmp;
     6111
     6112    tmp = node_new_list(np1, NULL_NODE);
     6113    if (IS_NULL(tmp)) goto err;
     6114    list2 = tmp;
     6115    np1 = NULL;
     6116
     6117    np1 = node_new_cclass();
     6118    if (IS_NULL(np1)) goto err;
     6119    cc = NCCLASS(np1);
     6120    {
     6121      static const OnigCodePoint ranges[] = {
     6122        4,
     6123        0x2640, 0x2640,
     6124        0x2642, 0x2642,
     6125        0x2695, 0x2696,
     6126        0x2708, 0x2708,
     6127      };
     6128      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
     6129      if (r != 0) goto err;
     6130    }
     6131
     6132    tmp = node_new_list(np1, list2);
     6133    if (IS_NULL(tmp)) goto err;
     6134    list2 = tmp;
     6135    np1 = NULL;
     6136
     6137    tmp = onig_node_new_alt(list2, alt2);
     6138    if (IS_NULL(tmp)) goto err;
     6139    alt2 = tmp;
     6140    list2 = NULL;
     6141
     6142    tmp = node_new_list(alt2, NULL_NODE);
     6143    if (IS_NULL(tmp)) goto err;
     6144    list2 = tmp;
     6145    alt2 = NULL;
     6146
     6147    /* ZWJ */
     6148    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
     6149    if (r < 0) goto err;
     6150    np1 = node_new_str_raw(buf, buf + r);
     6151    if (IS_NULL(np1)) goto err;
     6152
     6153    tmp = node_new_list(np1, list2);
     6154    if (IS_NULL(tmp)) goto err;
     6155    list2 = tmp;
     6156    np1 = NULL;
     6157
     6158    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     6159    if (IS_NULL(tmp)) goto err;
     6160    NQTFR(tmp)->target = list2;
     6161    np1 = tmp;
     6162    list2 = NULL;
     6163
     6164    tmp = node_new_list(np1, NULL_NODE);
     6165    if (IS_NULL(tmp)) goto err;
     6166    list2 = tmp;
     6167    np1 = NULL;
     6168
     6169    /* E_Modifier? */
     6170    np1 = node_new_cclass();
     6171    if (IS_NULL(np1)) goto err;
     6172    cc = NCCLASS(np1);
     6173    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
     6174    if (r != 0) goto err;
     6175
     6176    tmp = node_new_quantifier(0, 1, 0);
     6177    if (IS_NULL(tmp)) goto err;
     6178    NQTFR(tmp)->target = np1;
     6179    np1 = tmp;
     6180
     6181    tmp = node_new_list(np1, list2);
     6182    if (IS_NULL(tmp)) goto err;
     6183    list2 = tmp;
     6184    np1 = NULL;
     6185
     6186    /* Extend* */
     6187    np1 = node_new_cclass();
     6188    if (IS_NULL(np1)) goto err;
     6189    cc = NCCLASS(np1);
     6190    r = add_ctype_to_cc(cc, extend, 0, 0, env);
     6191    if (r != 0) goto err;
     6192
     6193    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     6194    if (IS_NULL(tmp)) goto err;
     6195    NQTFR(tmp)->target = np1;
     6196    np1 = tmp;
     6197
     6198    tmp = node_new_list(np1, list2);
     6199    if (IS_NULL(tmp)) goto err;
     6200    list2 = tmp;
     6201    np1 = NULL;
     6202
     6203    /* (E_Base | EBG) */
     6204    np1 = node_new_cclass();
     6205    if (IS_NULL(np1)) goto err;
     6206    cc = NCCLASS(np1);
     6207    {
     6208      static const OnigCodePoint ranges[] = {
     6209        8,
     6210        0x1F3C2, 0x1F3C2,
     6211        0x1F3C7, 0x1F3C7,
     6212        0x1F3CC, 0x1F3CC,
     6213        0x1F3F3, 0x1F3F3,
     6214        0x1F441, 0x1F441,
     6215        0x1F46F, 0x1F46F,
     6216        0x1F574, 0x1F574,
     6217        0x1F6CC, 0x1F6CC,
     6218      };
     6219      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
     6220      if (r != 0) goto err;
     6221    }
     6222    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base"), 0, 0, env);
     6223    if (r != 0) goto err;
     6224    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
     6225    if (r != 0) goto err;
     6226
     6227    tmp = node_new_list(np1, list2);
     6228    if (IS_NULL(tmp)) goto err;
     6229    list2 = tmp;
     6230    np1 = NULL;
     6231
     6232    tmp = onig_node_new_alt(list2, alt);
     6233    if (IS_NULL(tmp)) goto err;
     6234    alt = tmp;
     6235    list2 = NULL;
     6236
     6237    /* ZWJ (E_Base_GAZ | Glue_After_Zwj) E_Modifier? */
     6238    /* a sequence starting with ZWJ seems artificial, but GraphemeBreakTest
     6239     * has such examples.
     6240     * http://www.unicode.org/Public/9.0.0/ucd/auxiliary/GraphemeBreakTest.html
     6241     */
     6242    np1 = node_new_cclass();
     6243    if (IS_NULL(np1)) goto err;
     6244    cc = NCCLASS(np1);
     6245    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
     6246    if (r != 0) goto err;
     6247
     6248    tmp = node_new_quantifier(0, 1, 0);
     6249    if (IS_NULL(tmp)) goto err;
     6250    NQTFR(tmp)->target = np1;
     6251    np1 = tmp;
     6252
     6253    tmp = node_new_list(np1, NULL_NODE);
     6254    if (IS_NULL(tmp)) goto err;
     6255    list2 = tmp;
     6256    np1 = NULL;
     6257
     6258    np1 = node_new_cclass();
     6259    if (IS_NULL(np1)) goto err;
     6260    cc = NCCLASS(np1);
     6261    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
     6262    if (r != 0) goto err;
     6263    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
     6264    if (r != 0) goto err;
     6265
     6266    tmp = node_new_list(np1, list2);
     6267    if (IS_NULL(tmp)) goto err;
     6268    list2 = tmp;
     6269    np1 = NULL;
     6270
     6271    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
     6272    if (r < 0) goto err;
     6273    np1 = node_new_str_raw(buf, buf + r);
     6274    if (IS_NULL(np1)) goto err;
     6275
     6276    tmp = node_new_list(np1, list2);
     6277    if (IS_NULL(tmp)) goto err;
     6278    list2 = tmp;
     6279    np1 = NULL;
     6280
     6281    tmp = onig_node_new_alt(list2, alt);
     6282    if (IS_NULL(tmp)) goto err;
     6283    alt = tmp;
     6284    list2 = NULL;
     6285
     6286    /* RI-Sequence := Regional_Indicator{2} */
     6287    np1 = node_new_cclass();
     6288    if (IS_NULL(np1)) goto err;
     6289    cc = NCCLASS(np1);
     6290    r = add_code_range(&(cc->mbuf), env, 0x1F1E6, 0x1F1FF);
     6291    if (r != 0) goto err;
     6292
     6293    tmp = node_new_quantifier(2, 2, 0);
     6294    if (IS_NULL(tmp)) goto err;
     6295    NQTFR(tmp)->target = np1;
     6296    np1 = tmp;
     6297
     6298    tmp = node_new_list(np1, list2);
     6299    if (IS_NULL(tmp)) goto err;
     6300    list2 = tmp;
     6301    np1 = NULL;
     6302
     6303    tmp = onig_node_new_alt(list2, alt);
     6304    if (IS_NULL(tmp)) goto err;
     6305    alt = tmp;
     6306    list2 = NULL;
     6307
     6308    tmp = node_new_list(alt, list);
     6309    if (IS_NULL(tmp)) goto err;
     6310    list = tmp;
     6311    alt = NULL;
     6312
     6313    /* Prepend* */
     6314    np1 = node_new_cclass();
     6315    if (IS_NULL(np1)) goto err;
     6316    cc = NCCLASS(np1);
     6317    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
     6318    if (r != 0) goto err;
     6319
     6320    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
     6321    if (IS_NULL(tmp)) goto err;
     6322    NQTFR(tmp)->target = np1;
     6323    np1 = tmp;
     6324
     6325    tmp = node_new_list(np1, list);
     6326    if (IS_NULL(tmp)) goto err;
     6327    list = tmp;
     6328    np1 = NULL;
     6329
    57666330    /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
    5767     OnigOptionType option;
    57686331    np1 = node_new_anychar();
    57696332    if (IS_NULL(np1)) goto err;
     
    57716334    option = env->option;
    57726335    ONOFF(option, ONIG_OPTION_MULTILINE, 0);
     6336    tmp = node_new_option(option);
     6337    if (IS_NULL(tmp)) goto err;
     6338    NENCLOSE(tmp)->target = np1;
     6339    np1 = tmp;
     6340
     6341    tmp = onig_node_new_alt(np1, NULL_NODE);
     6342    if (IS_NULL(tmp)) goto err;
     6343    alt = tmp;
     6344    np1 = NULL;
     6345
     6346    /* Prepend+ */
     6347    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
     6348    if (r < 0) goto err;
     6349    np1 = node_new_str_raw(buf, buf + r);
     6350    if (IS_NULL(np1)) goto err;
     6351
     6352    tmp = node_new_quantifier(0, 1, 0);
     6353    if (IS_NULL(tmp)) goto err;
     6354    NQTFR(tmp)->target = np1;
     6355    np1 = tmp;
     6356
     6357    tmp = node_new_list(np1, NULL_NODE);
     6358    if (IS_NULL(tmp)) goto err;
     6359    list2 = tmp;
     6360    np1 = NULL;
     6361
     6362    np1 = node_new_cclass();
     6363    if (IS_NULL(np1)) goto err;
     6364    cc = NCCLASS(np1);
     6365    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
     6366    if (r != 0) goto err;
     6367
     6368    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
     6369    if (IS_NULL(tmp)) goto err;
     6370    NQTFR(tmp)->target = np1;
     6371    np1 = tmp;
     6372
     6373    tmp = node_new_list(np1, list2);
     6374    if (IS_NULL(tmp)) goto err;
     6375    list2 = tmp;
     6376    np1 = NULL;
     6377
     6378    tmp = onig_node_new_alt(list2, alt);
     6379    if (IS_NULL(tmp)) goto err;
     6380    alt = tmp;
     6381    list2 = NULL;
     6382
     6383    tmp = onig_node_new_alt(list, alt);
     6384    if (IS_NULL(tmp)) goto err;
     6385    alt = tmp;
     6386    list = NULL;
     6387  }
     6388  else
     6389#endif /* USE_UNICODE_PROPERTIES */
     6390  {
     6391    /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
     6392    np1 = node_new_anychar();
     6393    if (IS_NULL(np1)) goto err;
     6394
     6395    option = env->option;
     6396    ONOFF(option, ONIG_OPTION_MULTILINE, 0);
     6397    tmp = node_new_option(option);
     6398    if (IS_NULL(tmp)) goto err;
     6399    NENCLOSE(tmp)->target = np1;
     6400    np1 = tmp;
     6401
     6402    alt = onig_node_new_alt(np1, NULL_NODE);
     6403    if (IS_NULL(alt)) goto err;
     6404    np1 = NULL;
     6405  }
     6406
     6407  /* \x0D\x0A */
     6408  r = ONIGENC_CODE_TO_MBC(env->enc, 0x0D, buf);
     6409  if (r < 0) goto err;
     6410  num1 = r;
     6411  r = ONIGENC_CODE_TO_MBC(env->enc, 0x0A, buf + num1);
     6412  if (r < 0) goto err;
     6413  np1 = node_new_str_raw(buf, buf + num1 + r);
     6414  if (IS_NULL(np1)) goto err;
     6415
     6416  tmp = onig_node_new_alt(np1, alt);
     6417  if (IS_NULL(tmp)) goto err;
     6418  alt = tmp;
     6419  np1 = NULL;
     6420
     6421  /* (?>\x0D\x0A|...) */
     6422  tmp = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
     6423  if (IS_NULL(tmp)) goto err;
     6424  NENCLOSE(tmp)->target = alt;
     6425  np1 = tmp;
     6426
     6427#ifdef USE_UNICODE_PROPERTIES
     6428  if (ONIGENC_IS_UNICODE(env->enc)) {
     6429    /* Don't ignore case. */
     6430    option = env->option;
     6431    ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
    57736432    *np = node_new_option(option);
    57746433    if (IS_NULL(*np)) goto err;
    57756434    NENCLOSE(*np)->target = np1;
    57766435  }
     6436  else
     6437#endif
     6438  {
     6439    *np = np1;
     6440  }
    57776441  return ONIG_NORMAL;
    57786442
    57796443 err:
    57806444  onig_node_free(np1);
    5781   onig_node_free(np2);
    5782   onig_node_free(qn);
    5783   onig_node_free(list1);
     6445  onig_node_free(list);
    57846446  onig_node_free(list2);
     6447  onig_node_free(alt);
     6448  onig_node_free(alt2);
     6449  bbuf_free(pbuf1);
    57856450  return (r == 0) ? ONIGERR_MEMORY : r;
    57866451}
     
    58156480      c = data[0];
    58166481      if (((c < SINGLE_BYTE_SIZE) && BITSET_AT(cc->bs, c))) {
    5817         /* skip if c is included in the bitset */
     6482        /* skip if c is included in the bitset */
    58186483        c = not_found;
    58196484      }
     
    58296494    if (b1 != 0) {
    58306495      if (((b1 & (b1 - 1)) == 0) && (c == not_found)) {
    5831         c = BITS_IN_ROOM * i + countbits(b1 - 1);
     6496        c = BITS_IN_ROOM * i + countbits(b1 - 1);
    58326497      } else {
    5833         return 0;  /* the character class contains multiple chars */
     6498        return 0;  /* the character class contains multiple chars */
    58346499      }
    58356500    }
     
    58766541      env->option = NENCLOSE(*np)->option;
    58776542      r = fetch_token(tok, src, end, env);
    5878       if (r < 0) return r;
     6543      if (r < 0) {
     6544        env->option = prev;
     6545        return r;
     6546      }
    58796547      r = parse_subexp(&target, tok, term, src, end, env);
    58806548      env->option = prev;
     
    59496617      while (1) {
    59506618        if (len >= ONIGENC_MBC_MINLEN(env->enc)) {
    5951           if (len == enclen(env->enc, NSTR(*np)->s)) {
     6619          if (len == enclen(env->enc, NSTR(*np)->s, NSTR(*np)->end)) {
    59526620            r = fetch_token(tok, src, end, env);
    59536621            NSTRING_CLEAR_RAW(*np);
     
    60296697          CClassNode* cc;
    60306698
    6031 #ifdef USE_SHARED_CCLASS_TABLE
    6032           const OnigCodePoint *mbr;
    6033           OnigCodePoint sb_out;
    6034 
    6035           r = ONIGENC_GET_CTYPE_CODE_RANGE(env->enc, tok->u.prop.ctype,
    6036                                            &sb_out, &mbr);
    6037           if (r == 0 &&
    6038               ! IS_ASCII_RANGE(env->option) &&
    6039               ONIGENC_CODE_RANGE_NUM(mbr)
    6040               >= THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS) {
    6041             type_cclass_key  key;
    6042             type_cclass_key* new_key;
    6043 
    6044             key.enc  = env->enc;
    6045             key.not  = tok->u.prop.not;
    6046             key.type = tok->u.prop.ctype;
    6047 
    6048             THREAD_ATOMIC_START;
    6049 
    6050             if (IS_NULL(OnigTypeCClassTable)) {
    6051               OnigTypeCClassTable
    6052                 = onig_st_init_table_with_size(&type_type_cclass_hash, 10);
    6053               if (IS_NULL(OnigTypeCClassTable)) {
    6054                 THREAD_ATOMIC_END;
    6055                 return ONIGERR_MEMORY;
    6056               }
    6057             }
    6058             else {
    6059               if (onig_st_lookup(OnigTypeCClassTable, (st_data_t )&key,
    6060                                  (st_data_t* )np)) {
    6061                 THREAD_ATOMIC_END;
    6062                 break;
    6063               }
    6064             }
    6065 
    6066             *np = node_new_cclass_by_codepoint_range(tok->u.prop.not,
    6067                                                      sb_out, mbr);
    6068             if (IS_NULL(*np)) {
    6069               THREAD_ATOMIC_END;
    6070               return ONIGERR_MEMORY;
    6071             }
    6072 
    6073             cc = NCCLASS(*np);
    6074             NCCLASS_SET_SHARE(cc);
    6075             new_key = (type_cclass_key* )xmalloc(sizeof(type_cclass_key));
    6076             xmemcpy(new_key, &key, sizeof(type_cclass_key));
    6077             onig_st_add_direct(OnigTypeCClassTable, (st_data_t )new_key,
    6078                                (st_data_t )*np);
    6079 
    6080             THREAD_ATOMIC_END;
    6081           }
    6082           else {
    6083 #endif
    6084             *np = node_new_cclass();
    6085             CHECK_NULL_RETURN_MEMERR(*np);
    6086             cc = NCCLASS(*np);
    6087             r = add_ctype_to_cc(cc, tok->u.prop.ctype, 0,
    6088                             IS_ASCII_RANGE(env->option), env);
    6089             if (r != 0) return r;
    6090             if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
    6091 #ifdef USE_SHARED_CCLASS_TABLE
    6092           }
    6093 #endif
     6699          *np = node_new_cclass();
     6700          CHECK_NULL_RETURN_MEMERR(*np);
     6701          cc = NCCLASS(*np);
     6702          r = add_ctype_to_cc(cc, tok->u.prop.ctype, 0,
     6703              IS_ASCII_RANGE(env->option), env);
     6704          if (r != 0) return r;
     6705          if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
    60946706        }
    60956707        break;
     
    63216933
    63226934  *top = NULL;
     6935  env->parse_depth++;
     6936  if (env->parse_depth > ParseDepthLimit)
     6937    return ONIGERR_PARSE_DEPTH_LIMIT_OVER;
    63236938  r = parse_branch(&node, tok, term, src, end, env);
    63246939  if (r < 0) {
     
    63586973  }
    63596974
     6975  env->parse_depth--;
    63606976  return r;
    63616977}
Note: See TracChangeset for help on using the changeset viewer.