~ubuntu-branches/ubuntu/quantal/php5/quantal

« back to all changes in this revision

Viewing changes to ext/mbstring/oniguruma/regparse.c

  • Committer: Bazaar Package Importer
  • Author(s): Sean Finney
  • Date: 2009-07-01 09:12:10 UTC
  • mto: (0.9.1) (1.1.17 upstream)
  • mto: This revision was merged to the branch mainline in revision 58.
  • Revision ID: james.westby@ubuntu.com-20090701091210-go0h6506p62on17r
Tags: upstream-5.3.0
ImportĀ upstreamĀ versionĀ 5.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
  regparse.c -  Oniguruma (regular expression library)
 
3
**********************************************************************/
 
4
/*-
 
5
 * Copyright (c) 2002-2007  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions
 
10
 * are met:
 
11
 * 1. Redistributions of source code must retain the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer.
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer in the
 
15
 *    documentation and/or other materials provided with the distribution.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
27
 * SUCH DAMAGE.
 
28
 */
 
29
 
 
30
#include "regparse.h"
 
31
 
 
32
#define WARN_BUFSIZE    256
 
33
 
 
34
OnigSyntaxType OnigSyntaxRuby = {
 
35
  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
 
36
     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
 
37
     ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
 
38
     ONIG_SYN_OP_ESC_C_CONTROL )
 
39
   & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
 
40
  , ( ONIG_SYN_OP2_QMARK_GROUP_EFFECT |
 
41
      ONIG_SYN_OP2_OPTION_RUBY |
 
42
      ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP | ONIG_SYN_OP2_ESC_K_NAMED_BACKREF |
 
43
      ONIG_SYN_OP2_ESC_G_SUBEXP_CALL |
 
44
      ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
 
45
      ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL |
 
46
      ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
 
47
      ONIG_SYN_OP2_ESC_H_XDIGIT )
 
48
  , ( SYN_GNU_REGEX_BV | 
 
49
      ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
 
50
      ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND |
 
51
      ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
 
52
      ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME |
 
53
      ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY |
 
54
      ONIG_SYN_WARN_CC_OP_NOT_ESCAPED |
 
55
      ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT )
 
56
  , ONIG_OPTION_NONE
 
57
};
 
58
 
 
59
OnigSyntaxType*  OnigDefaultSyntax = ONIG_SYNTAX_RUBY;
 
60
 
 
61
extern void onig_null_warn(const char* s) { }
 
62
 
 
63
#ifdef RUBY_PLATFORM
 
64
extern void
 
65
onig_rb_warn(const char* s)
 
66
{
 
67
  rb_warn("%s", s);
 
68
}
 
69
 
 
70
extern void
 
71
onig_rb_warning(const char* s)
 
72
{
 
73
  rb_warning("%s", s);
 
74
}
 
75
#endif
 
76
 
 
77
#ifdef DEFAULT_WARN_FUNCTION
 
78
static OnigWarnFunc onig_warn = (OnigWarnFunc )DEFAULT_WARN_FUNCTION;
 
79
#else
 
80
static OnigWarnFunc onig_warn = onig_null_warn;
 
81
#endif
 
82
 
 
83
#ifdef DEFAULT_VERB_WARN_FUNCTION
 
84
static OnigWarnFunc onig_verb_warn = (OnigWarnFunc )DEFAULT_VERB_WARN_FUNCTION;
 
85
#else
 
86
static OnigWarnFunc onig_verb_warn = onig_null_warn;
 
87
#endif
 
88
 
 
89
extern void onig_set_warn_func(OnigWarnFunc f)
 
90
{
 
91
  onig_warn = f;
 
92
}
 
93
 
 
94
extern void onig_set_verb_warn_func(OnigWarnFunc f)
 
95
{
 
96
  onig_verb_warn = f;
 
97
}
 
98
 
 
99
static void
 
100
bbuf_free(BBuf* bbuf)
 
101
{
 
102
  if (IS_NOT_NULL(bbuf)) {
 
103
    if (IS_NOT_NULL(bbuf->p)) xfree(bbuf->p);
 
104
    xfree(bbuf);
 
105
  }
 
106
}
 
107
 
 
108
static int
 
109
bbuf_clone(BBuf** rto, BBuf* from)
 
110
{
 
111
  int r;
 
112
  BBuf *to;
 
113
 
 
114
  *rto = to = (BBuf* )xmalloc(sizeof(BBuf));
 
115
  CHECK_NULL_RETURN_VAL(to, ONIGERR_MEMORY);
 
116
  r = BBUF_INIT(to, from->alloc);
 
117
  if (r != 0) return r;
 
118
  to->used = from->used;
 
119
  xmemcpy(to->p, from->p, from->used);
 
120
  return 0;
 
121
}
 
122
 
 
123
#define ONOFF(v,f,negative)    (negative) ? ((v) &= ~(f)) : ((v) |= (f))
 
124
 
 
125
#define MBCODE_START_POS(enc) \
 
126
  (OnigCodePoint )(ONIGENC_MBC_MINLEN(enc) > 1 ? 0 : 0x80)
 
127
 
 
128
#define SET_ALL_MULTI_BYTE_RANGE(enc, pbuf) \
 
129
  add_code_range_to_buf(pbuf, MBCODE_START_POS(enc), ~((OnigCodePoint )0))
 
130
 
 
131
#define ADD_ALL_MULTI_BYTE_RANGE(enc, mbuf) do {\
 
132
  if (! ONIGENC_IS_SINGLEBYTE(enc)) {\
 
133
    r = SET_ALL_MULTI_BYTE_RANGE(enc, &(mbuf));\
 
134
    if (r) return r;\
 
135
  }\
 
136
} while (0)
 
137
 
 
138
 
 
139
#define BITSET_IS_EMPTY(bs,empty) do {\
 
140
  int i;\
 
141
  empty = 1;\
 
142
  for (i = 0; i < BITSET_SIZE; i++) {\
 
143
    if ((bs)[i] != 0) {\
 
144
      empty = 0; break;\
 
145
    }\
 
146
  }\
 
147
} while (0)
 
148
 
 
149
static void
 
150
bitset_set_range(BitSetRef bs, int from, int to)
 
151
{
 
152
  int i;
 
153
  for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) {
 
154
    BITSET_SET_BIT(bs, i);
 
155
  }
 
156
}
 
157
 
 
158
#if 0
 
159
static void
 
160
bitset_set_all(BitSetRef bs)
 
161
{
 
162
  int i;
 
163
  for (i = 0; i < BITSET_SIZE; i++) {
 
164
    bs[i] = ~((Bits )0);
 
165
  }
 
166
}
 
167
#endif
 
168
 
 
169
static void
 
170
bitset_invert(BitSetRef bs)
 
171
{
 
172
  int i;
 
173
  for (i = 0; i < BITSET_SIZE; i++) {
 
174
    bs[i] = ~(bs[i]);
 
175
  }
 
176
}
 
177
 
 
178
static void
 
179
bitset_invert_to(BitSetRef from, BitSetRef to)
 
180
{
 
181
  int i;
 
182
  for (i = 0; i < BITSET_SIZE; i++) {
 
183
    to[i] = ~(from[i]);
 
184
  }
 
185
}
 
186
 
 
187
static void
 
188
bitset_and(BitSetRef dest, BitSetRef bs)
 
189
{
 
190
  int i;
 
191
  for (i = 0; i < BITSET_SIZE; i++) {
 
192
    dest[i] &= bs[i];
 
193
  }
 
194
}
 
195
 
 
196
static void
 
197
bitset_or(BitSetRef dest, BitSetRef bs)
 
198
{
 
199
  int i;
 
200
  for (i = 0; i < BITSET_SIZE; i++) {
 
201
    dest[i] |= bs[i];
 
202
  }
 
203
}
 
204
 
 
205
static void
 
206
bitset_copy(BitSetRef dest, BitSetRef bs)
 
207
{
 
208
  int i;
 
209
  for (i = 0; i < BITSET_SIZE; i++) {
 
210
    dest[i] = bs[i];
 
211
  }
 
212
}
 
213
 
 
214
extern int
 
215
onig_strncmp(const UChar* s1, const UChar* s2, int n)
 
216
{
 
217
  int x;
 
218
 
 
219
  while (n-- > 0) {
 
220
    x = *s2++ - *s1++;
 
221
    if (x) return x;
 
222
  }
 
223
  return 0;
 
224
}
 
225
 
 
226
static void
 
227
k_strcpy(UChar* dest, const UChar* src, const UChar* end)
 
228
{
 
229
  int len = end - src;
 
230
  if (len > 0) {
 
231
    xmemcpy(dest, src, len);
 
232
    dest[len] = (UChar )0;
 
233
  }
 
234
}
 
235
 
 
236
static UChar*
 
237
strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
 
238
{
 
239
  int slen, term_len, i;
 
240
  UChar *r;
 
241
 
 
242
  slen = end - s;
 
243
  term_len = ONIGENC_MBC_MINLEN(enc);
 
244
 
 
245
  r = (UChar* )xmalloc(slen + term_len);
 
246
  CHECK_NULL_RETURN(r);
 
247
  xmemcpy(r, s, slen);
 
248
 
 
249
  for (i = 0; i < term_len; i++)
 
250
    r[slen + i] = (UChar )0;
 
251
 
 
252
  return r;
 
253
}
 
254
 
 
255
 
 
256
/* scan pattern methods */
 
257
#define PEND_VALUE   0
 
258
 
 
259
#define PFETCH_READY  UChar* pfetch_prev
 
260
#define PEND         (p < end ?  0 : 1)
 
261
#define PUNFETCH     p = pfetch_prev
 
262
#define PINC       do { \
 
263
  pfetch_prev = p; \
 
264
  p += ONIGENC_MBC_ENC_LEN(enc, p); \
 
265
} while (0)
 
266
#define PFETCH(c)  do { \
 
267
  c = ONIGENC_MBC_TO_CODE(enc, p, end); \
 
268
  pfetch_prev = p; \
 
269
  p += ONIGENC_MBC_ENC_LEN(enc, p); \
 
270
} while (0)
 
271
 
 
272
#define PPEEK        (p < end ? ONIGENC_MBC_TO_CODE(enc, p, end) : PEND_VALUE)
 
273
#define PPEEK_IS(c)  (PPEEK == (OnigCodePoint )c)
 
274
 
 
275
static UChar*
 
276
k_strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end,
 
277
              int capa)
 
278
{
 
279
  UChar* r;
 
280
 
 
281
  if (dest)
 
282
    r = (UChar* )xrealloc(dest, capa + 1);
 
283
  else
 
284
    r = (UChar* )xmalloc(capa + 1);
 
285
 
 
286
  CHECK_NULL_RETURN(r);
 
287
  k_strcpy(r + (dest_end - dest), src, src_end);
 
288
  return r;
 
289
}
 
290
 
 
291
/* dest on static area */
 
292
static UChar*
 
293
strcat_capa_from_static(UChar* dest, UChar* dest_end,
 
294
                        const UChar* src, const UChar* src_end, int capa)
 
295
{
 
296
  UChar* r;
 
297
 
 
298
  r = (UChar* )xmalloc(capa + 1);
 
299
  CHECK_NULL_RETURN(r);
 
300
  k_strcpy(r, dest, dest_end);
 
301
  k_strcpy(r + (dest_end - dest), src, src_end);
 
302
  return r;
 
303
}
 
304
 
 
305
#ifdef USE_NAMED_GROUP
 
306
 
 
307
#define INIT_NAME_BACKREFS_ALLOC_NUM   8
 
308
 
 
309
typedef struct {
 
310
  UChar* name;
 
311
  int    name_len;   /* byte length */
 
312
  int    back_num;   /* number of backrefs */
 
313
  int    back_alloc;
 
314
  int    back_ref1;
 
315
  int*   back_refs;
 
316
} NameEntry;
 
317
 
 
318
#ifdef USE_ST_HASH_TABLE
 
319
 
 
320
#include "st.h"
 
321
 
 
322
typedef struct {
 
323
  unsigned char* s;
 
324
  unsigned char* end;
 
325
} st_strend_key;
 
326
 
 
327
static int strend_cmp(st_strend_key*, st_strend_key*);
 
328
static int strend_hash(st_strend_key*);
 
329
 
 
330
static struct st_hash_type type_strend_hash = {
 
331
  strend_cmp,
 
332
  strend_hash,
 
333
};
 
334
 
 
335
static st_table*
 
336
onig_st_init_strend_table_with_size(int size)
 
337
{
 
338
    return onig_st_init_table_with_size(&type_strend_hash, size);
 
339
}
 
340
 
 
341
static int
 
342
onig_st_lookup_strend(st_table *table, const UChar* str_key, const UChar* end_key, st_data_t *value)
 
343
{
 
344
    st_strend_key key;
 
345
 
 
346
    key.s   = (unsigned char* )str_key;
 
347
    key.end = (unsigned char* )end_key;
 
348
 
 
349
    return onig_st_lookup(table, (st_data_t )(&key), value);
 
350
}
 
351
 
 
352
static int
 
353
onig_st_insert_strend(st_table *table, const UChar* str_key, const UChar* end_key, st_data_t value)
 
354
{
 
355
  st_strend_key* key;
 
356
  int result;
 
357
 
 
358
  key = (st_strend_key* )xmalloc(sizeof(st_strend_key));
 
359
  key->s   = (unsigned char* )str_key;
 
360
  key->end = (unsigned char* )end_key;
 
361
  result = onig_st_insert(table, (st_data_t )key, value);
 
362
  if (result) {
 
363
    xfree(key);
 
364
  }
 
365
  return result;
 
366
}
 
367
 
 
368
static int
 
369
strend_cmp(st_strend_key* x, st_strend_key* y)
 
370
{
 
371
  unsigned char *p, *q;
 
372
  int c;
 
373
 
 
374
  if ((x->end - x->s) != (y->end - y->s))
 
375
    return 1;
 
376
 
 
377
  p = x->s;
 
378
  q = y->s;
 
379
  while (p < x->end) {
 
380
    c = (int )*p - (int )*q;
 
381
    if (c != 0) return c;
 
382
 
 
383
    p++; q++;
 
384
  }
 
385
 
 
386
  return 0;
 
387
}
 
388
 
 
389
static int
 
390
strend_hash(st_strend_key* x)
 
391
{
 
392
  int val;
 
393
  unsigned char *p;
 
394
 
 
395
  val = 0;
 
396
  p = x->s;
 
397
  while (p < x->end) {
 
398
    val = val * 997 + (int )*p++;
 
399
  }
 
400
 
 
401
  return val + (val >> 5);
 
402
}
 
403
 
 
404
typedef st_table  NameTable;
 
405
typedef st_data_t HashDataType;   /* 1.6 st.h doesn't define st_data_t type */
 
406
 
 
407
#define NAMEBUF_SIZE    24
 
408
#define NAMEBUF_SIZE_1  25
 
409
 
 
410
#ifdef ONIG_DEBUG
 
411
static int
 
412
i_print_name_entry(UChar* key, NameEntry* e, void* arg)
 
413
{
 
414
  int i;
 
415
  FILE* fp = (FILE* )arg;
 
416
 
 
417
  fprintf(fp, "%s: ", e->name);
 
418
  if (e->back_num == 0)
 
419
    fputs("-", fp);
 
420
  else if (e->back_num == 1)
 
421
    fprintf(fp, "%d", e->back_ref1);
 
422
  else {
 
423
    for (i = 0; i < e->back_num; i++) {
 
424
      if (i > 0) fprintf(fp, ", ");
 
425
      fprintf(fp, "%d", e->back_refs[i]);
 
426
    }
 
427
  }
 
428
  fputs("\n", fp);
 
429
  return ST_CONTINUE;
 
430
}
 
431
 
 
432
extern int
 
433
onig_print_names(FILE* fp, regex_t* reg)
 
434
{
 
435
  NameTable* t = (NameTable* )reg->name_table;
 
436
 
 
437
  if (IS_NOT_NULL(t)) {
 
438
    fprintf(fp, "name table\n");
 
439
    onig_st_foreach(t, i_print_name_entry, (HashDataType )fp);
 
440
    fputs("\n", fp);
 
441
  }
 
442
  return 0;
 
443
}
 
444
#endif
 
445
 
 
446
static int
 
447
i_free_name_entry(UChar* key, NameEntry* e, void* arg)
 
448
{
 
449
  xfree(e->name);
 
450
  if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
 
451
  xfree(key);
 
452
  xfree(e);
 
453
  return ST_DELETE;
 
454
}
 
455
 
 
456
static int
 
457
names_clear(regex_t* reg)
 
458
{
 
459
  NameTable* t = (NameTable* )reg->name_table;
 
460
 
 
461
  if (IS_NOT_NULL(t)) {
 
462
    onig_st_foreach(t, i_free_name_entry, 0);
 
463
  }
 
464
  return 0;
 
465
}
 
466
 
 
467
extern int
 
468
onig_names_free(regex_t* reg)
 
469
{
 
470
  int r;
 
471
  NameTable* t;
 
472
 
 
473
  r = names_clear(reg);
 
474
  if (r) return r;
 
475
 
 
476
  t = (NameTable* )reg->name_table;
 
477
  if (IS_NOT_NULL(t)) onig_st_free_table(t);
 
478
  reg->name_table = (void* )NULL;
 
479
  return 0;
 
480
}
 
481
 
 
482
static NameEntry*
 
483
name_find(regex_t* reg, const UChar* name, const UChar* name_end)
 
484
{
 
485
  NameEntry* e;
 
486
  NameTable* t = (NameTable* )reg->name_table;
 
487
 
 
488
  e = (NameEntry* )NULL;
 
489
  if (IS_NOT_NULL(t)) {
 
490
    onig_st_lookup_strend(t, name, name_end, (HashDataType* )((void* )(&e)));
 
491
  }
 
492
  return e;
 
493
}
 
494
 
 
495
typedef struct {
 
496
  int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*);
 
497
  regex_t* reg;
 
498
  void* arg;
 
499
  int ret;
 
500
  OnigEncoding enc;
 
501
} INamesArg;
 
502
 
 
503
static int
 
504
i_names(UChar* key, NameEntry* e, INamesArg* arg)
 
505
{
 
506
  int r = (*(arg->func))(e->name,
 
507
                   /*e->name + onigenc_str_bytelen_null(arg->enc, e->name), */
 
508
                         e->name + e->name_len,
 
509
                         e->back_num,
 
510
                         (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
 
511
                         arg->reg, arg->arg);
 
512
  if (r != 0) {
 
513
    arg->ret = r;
 
514
    return ST_STOP;
 
515
  }
 
516
  return ST_CONTINUE;
 
517
}
 
518
 
 
519
extern int
 
520
onig_foreach_name(regex_t* reg,
 
521
           int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
 
522
           void* arg)
 
523
{
 
524
  INamesArg narg;
 
525
  NameTable* t = (NameTable* )reg->name_table;
 
526
 
 
527
  narg.ret = 0;
 
528
  if (IS_NOT_NULL(t)) {
 
529
    narg.func = func;
 
530
    narg.reg  = reg;
 
531
    narg.arg  = arg;
 
532
    narg.enc  = reg->enc; /* should be pattern encoding. */
 
533
    onig_st_foreach(t, i_names, (HashDataType )&narg);
 
534
  }
 
535
  return narg.ret;
 
536
}
 
537
 
 
538
static int
 
539
i_renumber_name(UChar* key, NameEntry* e, GroupNumRemap* map)
 
540
{
 
541
  int i;
 
542
 
 
543
  if (e->back_num > 1) {
 
544
    for (i = 0; i < e->back_num; i++) {
 
545
      e->back_refs[i] = map[e->back_refs[i]].new_val;
 
546
    }
 
547
  }
 
548
  else if (e->back_num == 1) {
 
549
    e->back_ref1 = map[e->back_ref1].new_val;
 
550
  }
 
551
 
 
552
  return ST_CONTINUE;
 
553
}
 
554
 
 
555
extern int
 
556
onig_renumber_name_table(regex_t* reg, GroupNumRemap* map)
 
557
{
 
558
  NameTable* t = (NameTable* )reg->name_table;
 
559
 
 
560
  if (IS_NOT_NULL(t)) {
 
561
    onig_st_foreach(t, i_renumber_name, (HashDataType )map);
 
562
  }
 
563
  return 0;
 
564
}
 
565
 
 
566
 
 
567
extern int
 
568
onig_number_of_names(regex_t* reg)
 
569
{
 
570
  NameTable* t = (NameTable* )reg->name_table;
 
571
 
 
572
  if (IS_NOT_NULL(t))
 
573
    return t->num_entries;
 
574
  else
 
575
    return 0;
 
576
}
 
577
 
 
578
#else  /* USE_ST_HASH_TABLE */
 
579
 
 
580
#define INIT_NAMES_ALLOC_NUM    8
 
581
 
 
582
typedef struct {
 
583
  NameEntry* e;
 
584
  int        num;
 
585
  int        alloc;
 
586
} NameTable;
 
587
 
 
588
 
 
589
#ifdef ONIG_DEBUG
 
590
extern int
 
591
onig_print_names(FILE* fp, regex_t* reg)
 
592
{
 
593
  int i, j;
 
594
  NameEntry* e;
 
595
  NameTable* t = (NameTable* )reg->name_table;
 
596
 
 
597
  if (IS_NOT_NULL(t) && t->num > 0) {
 
598
    fprintf(fp, "name table\n");
 
599
    for (i = 0; i < t->num; i++) {
 
600
      e = &(t->e[i]);
 
601
      fprintf(fp, "%s: ", e->name);
 
602
      if (e->back_num == 0) {
 
603
        fputs("-", fp);
 
604
      }
 
605
      else if (e->back_num == 1) {
 
606
        fprintf(fp, "%d", e->back_ref1);
 
607
      }
 
608
      else {
 
609
        for (j = 0; j < e->back_num; j++) {
 
610
          if (j > 0) fprintf(fp, ", ");
 
611
          fprintf(fp, "%d", e->back_refs[j]);
 
612
        }
 
613
      }
 
614
      fputs("\n", fp);
 
615
    }
 
616
    fputs("\n", fp);
 
617
  }
 
618
  return 0;
 
619
}
 
620
#endif
 
621
 
 
622
static int
 
623
names_clear(regex_t* reg)
 
624
{
 
625
  int i;
 
626
  NameEntry* e;
 
627
  NameTable* t = (NameTable* )reg->name_table;
 
628
 
 
629
  if (IS_NOT_NULL(t)) {
 
630
    for (i = 0; i < t->num; i++) {
 
631
      e = &(t->e[i]);
 
632
      if (IS_NOT_NULL(e->name)) {
 
633
        xfree(e->name);
 
634
        e->name       = NULL;
 
635
        e->name_len   = 0;
 
636
        e->back_num   = 0;
 
637
        e->back_alloc = 0;
 
638
        if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
 
639
        e->back_refs = (int* )NULL;
 
640
      }
 
641
    }
 
642
    if (IS_NOT_NULL(t->e)) {
 
643
      xfree(t->e);
 
644
      t->e = NULL;
 
645
    }
 
646
    t->num = 0;
 
647
  }
 
648
  return 0;
 
649
}
 
650
 
 
651
extern int
 
652
onig_names_free(regex_t* reg)
 
653
{
 
654
  int r;
 
655
  NameTable* t;
 
656
 
 
657
  r = names_clear(reg);
 
658
  if (r) return r;
 
659
 
 
660
  t = (NameTable* )reg->name_table;
 
661
  if (IS_NOT_NULL(t)) xfree(t);
 
662
  reg->name_table = NULL;
 
663
  return 0;
 
664
}
 
665
 
 
666
static NameEntry*
 
667
name_find(regex_t* reg, UChar* name, UChar* name_end)
 
668
{
 
669
  int i, len;
 
670
  NameEntry* e;
 
671
  NameTable* t = (NameTable* )reg->name_table;
 
672
 
 
673
  if (IS_NOT_NULL(t)) {
 
674
    len = name_end - name;
 
675
    for (i = 0; i < t->num; i++) {
 
676
      e = &(t->e[i]);
 
677
      if (len == e->name_len && onig_strncmp(name, e->name, len) == 0)
 
678
        return e;
 
679
    }
 
680
  }
 
681
  return (NameEntry* )NULL;
 
682
}
 
683
 
 
684
extern int
 
685
onig_foreach_name(regex_t* reg,
 
686
           int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
 
687
           void* arg)
 
688
{
 
689
  int i, r;
 
690
  NameEntry* e;
 
691
  NameTable* t = (NameTable* )reg->name_table;
 
692
 
 
693
  if (IS_NOT_NULL(t)) {
 
694
    for (i = 0; i < t->num; i++) {
 
695
      e = &(t->e[i]);
 
696
      r = (*func)(e->name, e->name + e->name_len, e->back_num,
 
697
                  (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
 
698
                  reg, arg);
 
699
      if (r != 0) return r;
 
700
    }
 
701
  }
 
702
  return 0;
 
703
}
 
704
 
 
705
extern int
 
706
onig_number_of_names(regex_t* reg)
 
707
{
 
708
  NameTable* t = (NameTable* )reg->name_table;
 
709
 
 
710
  if (IS_NOT_NULL(t))
 
711
    return t->num;
 
712
  else
 
713
    return 0;
 
714
}
 
715
 
 
716
#endif /* else USE_ST_HASH_TABLE */
 
717
 
 
718
static int
 
719
name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
 
720
{
 
721
  int alloc;
 
722
  NameEntry* e;
 
723
  NameTable* t = (NameTable* )reg->name_table;
 
724
 
 
725
  if (name_end - name <= 0)
 
726
    return ONIGERR_EMPTY_GROUP_NAME;
 
727
 
 
728
  e = name_find(reg, name, name_end);
 
729
  if (IS_NULL(e)) {
 
730
#ifdef USE_ST_HASH_TABLE
 
731
    if (IS_NULL(t)) {
 
732
      t = onig_st_init_strend_table_with_size(5);
 
733
      reg->name_table = (void* )t;
 
734
    }
 
735
    e = (NameEntry* )xmalloc(sizeof(NameEntry));
 
736
    CHECK_NULL_RETURN_VAL(e, ONIGERR_MEMORY);
 
737
 
 
738
    e->name = strdup_with_null(reg->enc, name, name_end);
 
739
    if (IS_NULL(e->name)) return ONIGERR_MEMORY;
 
740
    onig_st_insert_strend(t, e->name, (e->name + (name_end - name)),
 
741
                          (HashDataType )e);
 
742
 
 
743
    e->name_len   = name_end - name;
 
744
    e->back_num   = 0;
 
745
    e->back_alloc = 0;
 
746
    e->back_refs  = (int* )NULL;
 
747
 
 
748
#else
 
749
 
 
750
    if (IS_NULL(t)) {
 
751
      alloc = INIT_NAMES_ALLOC_NUM;
 
752
      t = (NameTable* )xmalloc(sizeof(NameTable));
 
753
      CHECK_NULL_RETURN_VAL(t, ONIGERR_MEMORY);
 
754
      t->e     = NULL;
 
755
      t->alloc = 0;
 
756
      t->num   = 0;
 
757
 
 
758
      t->e = (NameEntry* )xmalloc(sizeof(NameEntry) * alloc);
 
759
      if (IS_NULL(t->e)) {
 
760
        xfree(t);
 
761
        return ONIGERR_MEMORY;
 
762
      }
 
763
      t->alloc = alloc;
 
764
      reg->name_table = t;
 
765
      goto clear;
 
766
    }
 
767
    else if (t->num == t->alloc) {
 
768
      int i;
 
769
 
 
770
      alloc = t->alloc * 2;
 
771
      t->e = (NameEntry* )xrealloc(t->e, sizeof(NameEntry) * alloc);
 
772
      CHECK_NULL_RETURN_VAL(t->e, ONIGERR_MEMORY);
 
773
      t->alloc = alloc;
 
774
 
 
775
    clear:
 
776
      for (i = t->num; i < t->alloc; i++) {
 
777
        t->e[i].name       = NULL;
 
778
        t->e[i].name_len   = 0;
 
779
        t->e[i].back_num   = 0;
 
780
        t->e[i].back_alloc = 0;
 
781
        t->e[i].back_refs  = (int* )NULL;
 
782
      }
 
783
    }
 
784
    e = &(t->e[t->num]);
 
785
    t->num++;
 
786
    e->name = strdup_with_null(reg->enc, name, name_end);
 
787
    e->name_len = name_end - name;
 
788
#endif
 
789
  }
 
790
 
 
791
  if (e->back_num >= 1 &&
 
792
      ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME)) {
 
793
    onig_scan_env_set_error_string(env, ONIGERR_MULTIPLEX_DEFINED_NAME,
 
794
                                    name, name_end);
 
795
    return ONIGERR_MULTIPLEX_DEFINED_NAME;
 
796
  }
 
797
 
 
798
  e->back_num++;
 
799
  if (e->back_num == 1) {
 
800
    e->back_ref1 = backref;
 
801
  }
 
802
  else {
 
803
    if (e->back_num == 2) {
 
804
      alloc = INIT_NAME_BACKREFS_ALLOC_NUM;
 
805
      e->back_refs = (int* )xmalloc(sizeof(int) * alloc);
 
806
      CHECK_NULL_RETURN_VAL(e->back_refs, ONIGERR_MEMORY);
 
807
      e->back_alloc = alloc;
 
808
      e->back_refs[0] = e->back_ref1;
 
809
      e->back_refs[1] = backref;
 
810
    }
 
811
    else {
 
812
      if (e->back_num > e->back_alloc) {
 
813
        alloc = e->back_alloc * 2;
 
814
        e->back_refs = (int* )xrealloc(e->back_refs, sizeof(int) * alloc);
 
815
        CHECK_NULL_RETURN_VAL(e->back_refs, ONIGERR_MEMORY);
 
816
        e->back_alloc = alloc;
 
817
      }
 
818
      e->back_refs[e->back_num - 1] = backref;
 
819
    }
 
820
  }
 
821
 
 
822
  return 0;
 
823
}
 
824
 
 
825
extern int
 
826
onig_name_to_group_numbers(regex_t* reg, const UChar* name,
 
827
                           const UChar* name_end, int** nums)
 
828
{
 
829
  NameEntry* e;
 
830
 
 
831
  e = name_find(reg, name, name_end);
 
832
  if (IS_NULL(e)) return ONIGERR_UNDEFINED_NAME_REFERENCE;
 
833
 
 
834
  switch (e->back_num) {
 
835
  case 0:
 
836
    break;
 
837
  case 1:
 
838
    *nums = &(e->back_ref1);
 
839
    break;
 
840
  default:
 
841
    *nums = e->back_refs;
 
842
    break;
 
843
  }
 
844
  return e->back_num;
 
845
}
 
846
 
 
847
extern int
 
848
onig_name_to_backref_number(regex_t* reg, const UChar* name,
 
849
                            const UChar* name_end, OnigRegion *region)
 
850
{
 
851
  int i, n, *nums;
 
852
 
 
853
  n = onig_name_to_group_numbers(reg, name, name_end, &nums);
 
854
  if (n < 0)
 
855
    return n;
 
856
  else if (n == 0)
 
857
    return ONIGERR_PARSER_BUG;
 
858
  else if (n == 1)
 
859
    return nums[0];
 
860
  else {
 
861
    if (IS_NOT_NULL(region)) {
 
862
      for (i = n - 1; i >= 0; i--) {
 
863
        if (region->beg[nums[i]] != ONIG_REGION_NOTPOS)
 
864
          return nums[i];
 
865
      }
 
866
    }
 
867
    return nums[n - 1];
 
868
  }
 
869
}
 
870
 
 
871
#else /* USE_NAMED_GROUP */
 
872
 
 
873
extern int
 
874
onig_name_to_group_numbers(regex_t* reg, const UChar* name,
 
875
                           const UChar* name_end, int** nums)
 
876
{
 
877
  return ONIG_NO_SUPPORT_CONFIG;
 
878
}
 
879
 
 
880
extern int
 
881
onig_name_to_backref_number(regex_t* reg, const UChar* name,
 
882
                            const UChar* name_end, OnigRegion* region)
 
883
{
 
884
  return ONIG_NO_SUPPORT_CONFIG;
 
885
}
 
886
 
 
887
extern int
 
888
onig_foreach_name(regex_t* reg,
 
889
           int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
 
890
           void* arg)
 
891
{
 
892
  return ONIG_NO_SUPPORT_CONFIG;
 
893
}
 
894
 
 
895
extern int
 
896
onig_number_of_names(regex_t* reg)
 
897
{
 
898
  return 0;
 
899
}
 
900
#endif /* else USE_NAMED_GROUP */
 
901
 
 
902
extern int
 
903
onig_noname_group_capture_is_active(regex_t* reg)
 
904
{
 
905
  if (ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_DONT_CAPTURE_GROUP))
 
906
    return 0;
 
907
 
 
908
#ifdef USE_NAMED_GROUP
 
909
  if (onig_number_of_names(reg) > 0 &&
 
910
      IS_SYNTAX_BV(reg->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
 
911
      !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
 
912
    return 0;
 
913
  }
 
914
#endif
 
915
 
 
916
  return 1;
 
917
}
 
918
 
 
919
 
 
920
#define INIT_SCANENV_MEMNODES_ALLOC_SIZE   16
 
921
 
 
922
static void
 
923
scan_env_clear(ScanEnv* env)
 
924
{
 
925
  int i;
 
926
 
 
927
  BIT_STATUS_CLEAR(env->capture_history);
 
928
  BIT_STATUS_CLEAR(env->bt_mem_start);
 
929
  BIT_STATUS_CLEAR(env->bt_mem_end);
 
930
  BIT_STATUS_CLEAR(env->backrefed_mem);
 
931
  env->error             = (UChar* )NULL;
 
932
  env->error_end         = (UChar* )NULL;
 
933
  env->num_call          = 0;
 
934
  env->num_mem           = 0;
 
935
#ifdef USE_NAMED_GROUP
 
936
  env->num_named         = 0;
 
937
#endif
 
938
  env->mem_alloc         = 0;
 
939
  env->mem_nodes_dynamic = (Node** )NULL;
 
940
 
 
941
  for (i = 0; i < SCANENV_MEMNODES_SIZE; i++)
 
942
    env->mem_nodes_static[i] = NULL_NODE;
 
943
 
 
944
#ifdef USE_COMBINATION_EXPLOSION_CHECK
 
945
  env->num_comb_exp_check  = 0;
 
946
  env->comb_exp_max_regnum = 0;
 
947
  env->curr_max_regnum     = 0;
 
948
  env->has_recursion       = 0;
 
949
#endif
 
950
}
 
951
 
 
952
static int
 
953
scan_env_add_mem_entry(ScanEnv* env)
 
954
{
 
955
  int i, need, alloc;
 
956
  Node** p;
 
957
 
 
958
  need = env->num_mem + 1;
 
959
  if (need >= SCANENV_MEMNODES_SIZE) {
 
960
    if (env->mem_alloc <= need) {
 
961
      if (IS_NULL(env->mem_nodes_dynamic)) {
 
962
        alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE;
 
963
        p = (Node** )xmalloc(sizeof(Node*) * alloc);
 
964
        xmemcpy(p, env->mem_nodes_static,
 
965
                sizeof(Node*) * SCANENV_MEMNODES_SIZE);
 
966
      }
 
967
      else {
 
968
        alloc = env->mem_alloc * 2;
 
969
        p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
 
970
      }
 
971
      CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
 
972
 
 
973
      for (i = env->num_mem + 1; i < alloc; i++)
 
974
        p[i] = NULL_NODE;
 
975
 
 
976
      env->mem_nodes_dynamic = p;
 
977
      env->mem_alloc = alloc;
 
978
    }
 
979
  }
 
980
 
 
981
  env->num_mem++;
 
982
  return env->num_mem;
 
983
}
 
984
 
 
985
static int
 
986
scan_env_set_mem_node(ScanEnv* env, int num, Node* node)
 
987
{
 
988
  if (env->num_mem >= num)
 
989
    SCANENV_MEM_NODES(env)[num] = node;
 
990
  else
 
991
    return ONIGERR_PARSER_BUG;
 
992
  return 0;
 
993
}
 
994
 
 
995
 
 
996
#ifdef USE_RECYCLE_NODE
 
997
typedef struct _FreeNode {
 
998
  struct _FreeNode* next;
 
999
} FreeNode;
 
1000
 
 
1001
static FreeNode* FreeNodeList = (FreeNode* )NULL;
 
1002
#endif
 
1003
 
 
1004
extern void
 
1005
onig_node_free(Node* node)
 
1006
{
 
1007
 start:
 
1008
  if (IS_NULL(node)) return ;
 
1009
 
 
1010
  switch (NTYPE(node)) {
 
1011
  case N_STRING:
 
1012
    if (IS_NOT_NULL(NSTRING(node).s) && NSTRING(node).s != NSTRING(node).buf) {
 
1013
      xfree(NSTRING(node).s);
 
1014
    }
 
1015
    break;
 
1016
 
 
1017
  case N_LIST:
 
1018
  case N_ALT:
 
1019
    onig_node_free(NCONS(node).left);
 
1020
    /* onig_node_free(NCONS(node).right); */
 
1021
    {
 
1022
      Node* next_node = NCONS(node).right;
 
1023
 
 
1024
#ifdef USE_RECYCLE_NODE
 
1025
      {
 
1026
        FreeNode* n = (FreeNode* )node;
 
1027
 
 
1028
        THREAD_ATOMIC_START;
 
1029
        n->next = FreeNodeList;
 
1030
        FreeNodeList = n;
 
1031
        THREAD_ATOMIC_END;
 
1032
      }
 
1033
#else
 
1034
      xfree(node);
 
1035
#endif
 
1036
 
 
1037
      node = next_node;
 
1038
      goto start;
 
1039
    }
 
1040
    break;
 
1041
 
 
1042
  case N_CCLASS:
 
1043
    {
 
1044
      CClassNode* cc = &(NCCLASS(node));
 
1045
 
 
1046
      if (IS_CCLASS_SHARE(cc))
 
1047
        return ;
 
1048
 
 
1049
      if (cc->mbuf)
 
1050
        bbuf_free(cc->mbuf);
 
1051
    }
 
1052
    break;
 
1053
 
 
1054
  case N_QUANTIFIER:
 
1055
    if (NQUANTIFIER(node).target)
 
1056
      onig_node_free(NQUANTIFIER(node).target);
 
1057
    break;
 
1058
 
 
1059
  case N_EFFECT:
 
1060
    if (NEFFECT(node).target)
 
1061
      onig_node_free(NEFFECT(node).target);
 
1062
    break;
 
1063
 
 
1064
  case N_BACKREF:
 
1065
    if (IS_NOT_NULL(NBACKREF(node).back_dynamic))
 
1066
      xfree(NBACKREF(node).back_dynamic);
 
1067
    break;
 
1068
 
 
1069
  case N_ANCHOR:
 
1070
    if (NANCHOR(node).target)
 
1071
      onig_node_free(NANCHOR(node).target);
 
1072
    break;
 
1073
  }
 
1074
 
 
1075
#ifdef USE_RECYCLE_NODE
 
1076
  {
 
1077
    FreeNode* n = (FreeNode* )node;
 
1078
 
 
1079
    THREAD_ATOMIC_START;
 
1080
    n->next = FreeNodeList;
 
1081
    FreeNodeList = n;
 
1082
    THREAD_ATOMIC_END;
 
1083
  }
 
1084
#else
 
1085
  xfree(node);
 
1086
#endif
 
1087
}
 
1088
 
 
1089
#ifdef USE_RECYCLE_NODE
 
1090
extern int
 
1091
onig_free_node_list(void)
 
1092
{
 
1093
  FreeNode* n;
 
1094
 
 
1095
  /* THREAD_ATOMIC_START; */
 
1096
  while (IS_NOT_NULL(FreeNodeList)) {
 
1097
    n = FreeNodeList;
 
1098
    FreeNodeList = FreeNodeList->next;
 
1099
    xfree(n);
 
1100
  }
 
1101
  /* THREAD_ATOMIC_END; */
 
1102
  return 0;
 
1103
}
 
1104
#endif
 
1105
 
 
1106
static Node*
 
1107
node_new(void)
 
1108
{
 
1109
  Node* node;
 
1110
 
 
1111
#ifdef USE_RECYCLE_NODE
 
1112
  THREAD_ATOMIC_START;
 
1113
  if (IS_NOT_NULL(FreeNodeList)) {
 
1114
    node = (Node* )FreeNodeList;
 
1115
    FreeNodeList = FreeNodeList->next;
 
1116
    THREAD_ATOMIC_END;
 
1117
    return node;
 
1118
  }
 
1119
  THREAD_ATOMIC_END;
 
1120
#endif
 
1121
 
 
1122
  node = (Node* )xmalloc(sizeof(Node));
 
1123
  return node;
 
1124
}
 
1125
 
 
1126
 
 
1127
static void
 
1128
initialize_cclass(CClassNode* cc)
 
1129
{
 
1130
  BITSET_CLEAR(cc->bs);
 
1131
  cc->flags = 0;
 
1132
  cc->mbuf  = NULL;
 
1133
}
 
1134
 
 
1135
static Node*
 
1136
node_new_cclass(void)
 
1137
{
 
1138
  Node* node = node_new();
 
1139
  CHECK_NULL_RETURN(node);
 
1140
  node->type = N_CCLASS;
 
1141
 
 
1142
  initialize_cclass(&(NCCLASS(node)));
 
1143
  return node;
 
1144
}
 
1145
 
 
1146
static Node*
 
1147
node_new_cclass_by_codepoint_range(int not,
 
1148
                   const OnigCodePoint sbr[], const OnigCodePoint mbr[])
 
1149
{
 
1150
  CClassNode* cc;
 
1151
  int n, i, j;
 
1152
 
 
1153
  Node* node = node_new();
 
1154
  CHECK_NULL_RETURN(node);
 
1155
  node->type = N_CCLASS;
 
1156
 
 
1157
  cc = &(NCCLASS(node));
 
1158
  cc->flags = 0;
 
1159
  if (not != 0) CCLASS_SET_NOT(cc);
 
1160
 
 
1161
  BITSET_CLEAR(cc->bs);
 
1162
  if (IS_NOT_NULL(sbr)) {
 
1163
    n = ONIGENC_CODE_RANGE_NUM(sbr);
 
1164
    for (i = 0; i < n; i++) {
 
1165
      for (j  = ONIGENC_CODE_RANGE_FROM(sbr, i);
 
1166
           j <= (int )ONIGENC_CODE_RANGE_TO(sbr, i); j++) {
 
1167
        BITSET_SET_BIT(cc->bs, j);
 
1168
      }
 
1169
    }
 
1170
  }
 
1171
 
 
1172
  if (IS_NULL(mbr)) {
 
1173
  is_null:
 
1174
    cc->mbuf = NULL;
 
1175
  }
 
1176
  else {
 
1177
    BBuf* bbuf;
 
1178
 
 
1179
    n = ONIGENC_CODE_RANGE_NUM(mbr);
 
1180
    if (n == 0) goto is_null;
 
1181
 
 
1182
    bbuf = (BBuf* )xmalloc(sizeof(BBuf));
 
1183
    CHECK_NULL_RETURN_VAL(bbuf, NULL);
 
1184
    bbuf->alloc = n + 1;
 
1185
    bbuf->used  = n + 1;
 
1186
    bbuf->p     = (UChar* )((void* )mbr);
 
1187
 
 
1188
    cc->mbuf = bbuf;
 
1189
  }
 
1190
 
 
1191
  return node;
 
1192
}
 
1193
 
 
1194
static Node*
 
1195
node_new_ctype(int type)
 
1196
{
 
1197
  Node* node = node_new();
 
1198
  CHECK_NULL_RETURN(node);
 
1199
  node->type = N_CTYPE;
 
1200
  NCTYPE(node).type = type;
 
1201
  return node;
 
1202
}
 
1203
 
 
1204
static Node*
 
1205
node_new_anychar(void)
 
1206
{
 
1207
  Node* node = node_new();
 
1208
  CHECK_NULL_RETURN(node);
 
1209
  node->type = N_ANYCHAR;
 
1210
  return node;
 
1211
}
 
1212
 
 
1213
static Node*
 
1214
node_new_list(Node* left, Node* right)
 
1215
{
 
1216
  Node* node = node_new();
 
1217
  CHECK_NULL_RETURN(node);
 
1218
  node->type = N_LIST;
 
1219
  NCONS(node).left  = left;
 
1220
  NCONS(node).right = right;
 
1221
  return node;
 
1222
}
 
1223
 
 
1224
extern Node*
 
1225
onig_node_new_list(Node* left, Node* right)
 
1226
{
 
1227
  return node_new_list(left, right);
 
1228
}
 
1229
 
 
1230
static Node*
 
1231
node_new_alt(Node* left, Node* right)
 
1232
{
 
1233
  Node* node = node_new();
 
1234
  CHECK_NULL_RETURN(node);
 
1235
  node->type = N_ALT;
 
1236
  NCONS(node).left  = left;
 
1237
  NCONS(node).right = right;
 
1238
  return node;
 
1239
}
 
1240
 
 
1241
extern Node*
 
1242
onig_node_new_anchor(int type)
 
1243
{
 
1244
  Node* node = node_new();
 
1245
  CHECK_NULL_RETURN(node);
 
1246
  node->type = N_ANCHOR;
 
1247
  NANCHOR(node).type     = type;
 
1248
  NANCHOR(node).target   = NULL;
 
1249
  NANCHOR(node).char_len = -1;
 
1250
  return node;
 
1251
}
 
1252
 
 
1253
static Node*
 
1254
node_new_backref(int back_num, int* backrefs, int by_name,
 
1255
#ifdef USE_BACKREF_AT_LEVEL
 
1256
                 int exist_level, int nest_level,
 
1257
#endif
 
1258
                 ScanEnv* env)
 
1259
{
 
1260
  int i;
 
1261
  Node* node = node_new();
 
1262
 
 
1263
  CHECK_NULL_RETURN(node);
 
1264
  node->type = N_BACKREF;
 
1265
  NBACKREF(node).state    = 0;
 
1266
  NBACKREF(node).back_num = back_num;
 
1267
  NBACKREF(node).back_dynamic = (int* )NULL;
 
1268
  if (by_name != 0)
 
1269
    NBACKREF(node).state |= NST_NAME_REF;
 
1270
 
 
1271
#ifdef USE_BACKREF_AT_LEVEL
 
1272
  if (exist_level != 0) {
 
1273
    NBACKREF(node).state |= NST_NEST_LEVEL;
 
1274
    NBACKREF(node).nest_level  = nest_level;
 
1275
  }
 
1276
#endif
 
1277
 
 
1278
  for (i = 0; i < back_num; i++) {
 
1279
    if (backrefs[i] <= env->num_mem &&
 
1280
        IS_NULL(SCANENV_MEM_NODES(env)[backrefs[i]])) {
 
1281
      NBACKREF(node).state |= NST_RECURSION;   /* /...(\1).../ */
 
1282
      break;
 
1283
    }
 
1284
  }
 
1285
 
 
1286
  if (back_num <= NODE_BACKREFS_SIZE) {
 
1287
    for (i = 0; i < back_num; i++)
 
1288
      NBACKREF(node).back_static[i] = backrefs[i];
 
1289
  }
 
1290
  else {
 
1291
    int* p = (int* )xmalloc(sizeof(int) * back_num);
 
1292
    if (IS_NULL(p)) {
 
1293
      onig_node_free(node);
 
1294
      return NULL;
 
1295
    }
 
1296
    NBACKREF(node).back_dynamic = p;
 
1297
    for (i = 0; i < back_num; i++)
 
1298
      p[i] = backrefs[i];
 
1299
  }
 
1300
  return node;
 
1301
}
 
1302
 
 
1303
#ifdef USE_SUBEXP_CALL
 
1304
static Node*
 
1305
node_new_call(UChar* name, UChar* name_end)
 
1306
{
 
1307
  Node* node = node_new();
 
1308
  CHECK_NULL_RETURN(node);
 
1309
 
 
1310
  node->type = N_CALL;
 
1311
  NCALL(node).state    = 0;
 
1312
  NCALL(node).ref_num  = CALLNODE_REFNUM_UNDEF;
 
1313
  NCALL(node).target   = NULL_NODE;
 
1314
  NCALL(node).name     = name;
 
1315
  NCALL(node).name_end = name_end;
 
1316
  return node;
 
1317
}
 
1318
#endif
 
1319
 
 
1320
static Node*
 
1321
node_new_quantifier(int lower, int upper, int by_number)
 
1322
{
 
1323
  Node* node = node_new();
 
1324
  CHECK_NULL_RETURN(node);
 
1325
  node->type = N_QUANTIFIER;
 
1326
  NQUANTIFIER(node).state  = 0;
 
1327
  NQUANTIFIER(node).target = NULL;
 
1328
  NQUANTIFIER(node).lower  = lower;
 
1329
  NQUANTIFIER(node).upper  = upper;
 
1330
  NQUANTIFIER(node).greedy = 1;
 
1331
  NQUANTIFIER(node).target_empty_info = NQ_TARGET_ISNOT_EMPTY;
 
1332
  NQUANTIFIER(node).head_exact        = NULL_NODE;
 
1333
  NQUANTIFIER(node).next_head_exact   = NULL_NODE;
 
1334
  NQUANTIFIER(node).is_refered        = 0;
 
1335
  if (by_number != 0)
 
1336
    NQUANTIFIER(node).state |= NST_BY_NUMBER;
 
1337
 
 
1338
#ifdef USE_COMBINATION_EXPLOSION_CHECK
 
1339
  NQUANTIFIER(node).comb_exp_check_num = 0;
 
1340
#endif
 
1341
 
 
1342
  return node;
 
1343
}
 
1344
 
 
1345
static Node*
 
1346
node_new_effect(int type)
 
1347
{
 
1348
  Node* node = node_new();
 
1349
  CHECK_NULL_RETURN(node);
 
1350
  node->type = N_EFFECT;
 
1351
  NEFFECT(node).type      = type;
 
1352
  NEFFECT(node).state     =  0;
 
1353
  NEFFECT(node).regnum    =  0;
 
1354
  NEFFECT(node).option    =  0;
 
1355
  NEFFECT(node).target    = NULL;
 
1356
  NEFFECT(node).call_addr = -1;
 
1357
  NEFFECT(node).opt_count =  0;
 
1358
  return node;
 
1359
}
 
1360
 
 
1361
extern Node*
 
1362
onig_node_new_effect(int type)
 
1363
{
 
1364
  return node_new_effect(type);
 
1365
}
 
1366
 
 
1367
static Node*
 
1368
node_new_effect_memory(OnigOptionType option, int is_named)
 
1369
{
 
1370
  Node* node = node_new_effect(EFFECT_MEMORY);
 
1371
  CHECK_NULL_RETURN(node);
 
1372
  if (is_named != 0)
 
1373
    SET_EFFECT_STATUS(node, NST_NAMED_GROUP);
 
1374
 
 
1375
#ifdef USE_SUBEXP_CALL
 
1376
  NEFFECT(node).option = option;
 
1377
#endif
 
1378
  return node;
 
1379
}
 
1380
 
 
1381
static Node*
 
1382
node_new_option(OnigOptionType option)
 
1383
{
 
1384
  Node* node = node_new_effect(EFFECT_OPTION);
 
1385
  CHECK_NULL_RETURN(node);
 
1386
  NEFFECT(node).option = option;
 
1387
  return node;
 
1388
}
 
1389
 
 
1390
extern int
 
1391
onig_node_str_cat(Node* node, const UChar* s, const UChar* end)
 
1392
{
 
1393
  int addlen = end - s;
 
1394
 
 
1395
  if (addlen > 0) {
 
1396
    int len  = NSTRING(node).end - NSTRING(node).s;
 
1397
 
 
1398
    if (NSTRING(node).capa > 0 || (len + addlen > NODE_STR_BUF_SIZE - 1)) {
 
1399
      UChar* p;
 
1400
      int capa = len + addlen + NODE_STR_MARGIN;
 
1401
 
 
1402
      if (capa <= NSTRING(node).capa) {
 
1403
        k_strcpy(NSTRING(node).s + len, s, end);
 
1404
      }
 
1405
      else {
 
1406
        if (NSTRING(node).s == NSTRING(node).buf)
 
1407
          p = strcat_capa_from_static(NSTRING(node).s, NSTRING(node).end,
 
1408
                                      s, end, capa);
 
1409
        else
 
1410
          p = k_strcat_capa(NSTRING(node).s, NSTRING(node).end, s, end, capa);
 
1411
 
 
1412
        CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
 
1413
        NSTRING(node).s    = p;
 
1414
        NSTRING(node).capa = capa;
 
1415
      }
 
1416
    }
 
1417
    else {
 
1418
      k_strcpy(NSTRING(node).s + len, s, end);
 
1419
    }
 
1420
    NSTRING(node).end = NSTRING(node).s + len + addlen;
 
1421
  }
 
1422
 
 
1423
  return 0;
 
1424
}
 
1425
 
 
1426
static int
 
1427
node_str_cat_char(Node* node, UChar c)
 
1428
{
 
1429
  UChar s[1];
 
1430
 
 
1431
  s[0] = c;
 
1432
  return onig_node_str_cat(node, s, s + 1);
 
1433
}
 
1434
 
 
1435
extern void
 
1436
onig_node_conv_to_str_node(Node* node, int flag)
 
1437
{
 
1438
  node->type = N_STRING;
 
1439
 
 
1440
  NSTRING(node).flag = flag;
 
1441
  NSTRING(node).capa = 0;
 
1442
  NSTRING(node).s    = NSTRING(node).buf;
 
1443
  NSTRING(node).end  = NSTRING(node).buf;
 
1444
}
 
1445
 
 
1446
extern void
 
1447
onig_node_str_clear(Node* node)
 
1448
{
 
1449
  if (NSTRING(node).capa != 0 &&
 
1450
      IS_NOT_NULL(NSTRING(node).s) && NSTRING(node).s != NSTRING(node).buf) {
 
1451
    xfree(NSTRING(node).s);
 
1452
  }
 
1453
 
 
1454
  NSTRING(node).capa = 0;
 
1455
  NSTRING(node).flag = 0;
 
1456
  NSTRING(node).s    = NSTRING(node).buf;
 
1457
  NSTRING(node).end  = NSTRING(node).buf;
 
1458
}
 
1459
 
 
1460
static Node*
 
1461
node_new_str(const UChar* s, const UChar* end)
 
1462
{
 
1463
  Node* node = node_new();
 
1464
  CHECK_NULL_RETURN(node);
 
1465
 
 
1466
  node->type = N_STRING;
 
1467
  NSTRING(node).capa = 0;
 
1468
  NSTRING(node).flag = 0;
 
1469
  NSTRING(node).s    = NSTRING(node).buf;
 
1470
  NSTRING(node).end  = NSTRING(node).buf;
 
1471
  if (onig_node_str_cat(node, s, end)) {
 
1472
    onig_node_free(node);
 
1473
    return NULL;
 
1474
  }
 
1475
  return node;
 
1476
}
 
1477
 
 
1478
extern Node*
 
1479
onig_node_new_str(const UChar* s, const UChar* end)
 
1480
{
 
1481
  return node_new_str(s, end);
 
1482
}
 
1483
 
 
1484
#ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
 
1485
static Node*
 
1486
node_new_str_raw(UChar* s, UChar* end)
 
1487
{
 
1488
  Node* node = node_new_str(s, end);
 
1489
  NSTRING_SET_RAW(node);
 
1490
  return node;
 
1491
}
 
1492
#endif
 
1493
 
 
1494
static Node*
 
1495
node_new_empty(void)
 
1496
{
 
1497
  return node_new_str(NULL, NULL);
 
1498
}
 
1499
 
 
1500
static Node*
 
1501
node_new_str_char(UChar c)
 
1502
{
 
1503
  UChar p[1];
 
1504
 
 
1505
  p[0] = c;
 
1506
  return node_new_str(p, p + 1);
 
1507
}
 
1508
 
 
1509
static Node*
 
1510
str_node_split_last_char(StrNode* sn, OnigEncoding enc)
 
1511
{
 
1512
  const UChar *p;
 
1513
  Node* n = NULL_NODE;
 
1514
 
 
1515
  if (sn->end > sn->s) {
 
1516
    p = onigenc_get_prev_char_head(enc, sn->s, sn->end);
 
1517
    if (p && p > sn->s) { /* can be splitted. */
 
1518
      n = node_new_str(p, sn->end);
 
1519
      if ((sn->flag & NSTR_RAW) != 0)
 
1520
        NSTRING_SET_RAW(n);
 
1521
      sn->end = (UChar* )p;
 
1522
    }
 
1523
  }
 
1524
  return n;
 
1525
}
 
1526
 
 
1527
static int
 
1528
str_node_can_be_split(StrNode* sn, OnigEncoding enc)
 
1529
{
 
1530
  if (sn->end > sn->s) {
 
1531
    return ((enc_len(enc, sn->s) < sn->end - sn->s)  ?  1 : 0);
 
1532
  }
 
1533
  return 0;
 
1534
}
 
1535
 
 
1536
#ifdef USE_PAD_TO_SHORT_BYTE_CHAR
 
1537
static int
 
1538
node_str_head_pad(StrNode* sn, int num, UChar val)
 
1539
{
 
1540
  UChar buf[NODE_STR_BUF_SIZE];
 
1541
  int i, len;
 
1542
 
 
1543
  len = sn->end - sn->s;
 
1544
  onig_strcpy(buf, sn->s, sn->end);
 
1545
  onig_strcpy(&(sn->s[num]), buf, buf + len);
 
1546
  sn->end += num;
 
1547
 
 
1548
  for (i = 0; i < num; i++) {
 
1549
    sn->s[i] = val;
 
1550
  }
 
1551
}
 
1552
#endif
 
1553
 
 
1554
extern int
 
1555
onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc)
 
1556
{
 
1557
  unsigned int num, val;
 
1558
  OnigCodePoint c;
 
1559
  UChar* p = *src;
 
1560
  PFETCH_READY;
 
1561
 
 
1562
  num = 0;
 
1563
  while (!PEND) {
 
1564
    PFETCH(c);
 
1565
    if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
 
1566
      val = (unsigned int )DIGITVAL(c);
 
1567
      if ((INT_MAX_LIMIT - val) / 10UL < num)
 
1568
        return -1;  /* overflow */
 
1569
 
 
1570
      num = num * 10 + val;
 
1571
    }
 
1572
    else {
 
1573
      PUNFETCH;
 
1574
      break;
 
1575
    }
 
1576
  }
 
1577
  *src = p;
 
1578
  return num;
 
1579
}
 
1580
 
 
1581
static int
 
1582
scan_unsigned_hexadecimal_number(UChar** src, UChar* end, int maxlen,
 
1583
                                 OnigEncoding enc)
 
1584
{
 
1585
  OnigCodePoint c;
 
1586
  unsigned int num, val;
 
1587
  UChar* p = *src;
 
1588
  PFETCH_READY;
 
1589
 
 
1590
  num = 0;
 
1591
  while (!PEND && maxlen-- != 0) {
 
1592
    PFETCH(c);
 
1593
    if (ONIGENC_IS_CODE_XDIGIT(enc, c)) {
 
1594
      val = (unsigned int )XDIGITVAL(enc,c);
 
1595
      if ((INT_MAX_LIMIT - val) / 16UL < num)
 
1596
        return -1;  /* overflow */
 
1597
 
 
1598
      num = (num << 4) + XDIGITVAL(enc,c);
 
1599
    }
 
1600
    else {
 
1601
      PUNFETCH;
 
1602
      break;
 
1603
    }
 
1604
  }
 
1605
  *src = p;
 
1606
  return num;
 
1607
}
 
1608
 
 
1609
static int
 
1610
scan_unsigned_octal_number(UChar** src, UChar* end, int maxlen,
 
1611
                           OnigEncoding enc)
 
1612
{
 
1613
  OnigCodePoint c;
 
1614
  unsigned int num, val;
 
1615
  UChar* p = *src;
 
1616
  PFETCH_READY;
 
1617
 
 
1618
  num = 0;
 
1619
  while (!PEND && maxlen-- != 0) {
 
1620
    PFETCH(c);
 
1621
    if (ONIGENC_IS_CODE_DIGIT(enc, c) && c < '8') {
 
1622
      val = ODIGITVAL(c);
 
1623
      if ((INT_MAX_LIMIT - val) / 8UL < num)
 
1624
        return -1;  /* overflow */
 
1625
 
 
1626
      num = (num << 3) + val;
 
1627
    }
 
1628
    else {
 
1629
      PUNFETCH;
 
1630
      break;
 
1631
    }
 
1632
  }
 
1633
  *src = p;
 
1634
  return num;
 
1635
}
 
1636
 
 
1637
 
 
1638
#define BBUF_WRITE_CODE_POINT(bbuf,pos,code) \
 
1639
    BBUF_WRITE(bbuf, pos, &(code), SIZE_CODE_POINT)
 
1640
 
 
1641
/* data format:
 
1642
     [n][from-1][to-1][from-2][to-2] ... [from-n][to-n]
 
1643
     (all data size is OnigCodePoint)
 
1644
 */
 
1645
static int
 
1646
new_code_range(BBuf** pbuf)
 
1647
{
 
1648
#define INIT_MULTI_BYTE_RANGE_SIZE  (SIZE_CODE_POINT * 5)
 
1649
  int r;
 
1650
  OnigCodePoint n;
 
1651
  BBuf* bbuf;
 
1652
 
 
1653
  bbuf = *pbuf = (BBuf* )xmalloc(sizeof(BBuf));
 
1654
  CHECK_NULL_RETURN_VAL(*pbuf, ONIGERR_MEMORY);
 
1655
  r = BBUF_INIT(*pbuf, INIT_MULTI_BYTE_RANGE_SIZE);
 
1656
  if (r) return r;
 
1657
 
 
1658
  n = 0;
 
1659
  BBUF_WRITE_CODE_POINT(bbuf, 0, n);
 
1660
  return 0;
 
1661
}
 
1662
 
 
1663
static int
 
1664
add_code_range_to_buf(BBuf** pbuf, OnigCodePoint from, OnigCodePoint to)
 
1665
{
 
1666
  int r, inc_n, pos;
 
1667
  int low, high, bound, x;
 
1668
  OnigCodePoint n, *data;
 
1669
  BBuf* bbuf;
 
1670
 
 
1671
  if (from > to) {
 
1672
    n = from; from = to; to = n;
 
1673
  }
 
1674
 
 
1675
  if (IS_NULL(*pbuf)) {
 
1676
    r = new_code_range(pbuf);
 
1677
    if (r) return r;
 
1678
    bbuf = *pbuf;
 
1679
    n = 0;
 
1680
  }
 
1681
  else {
 
1682
    bbuf = *pbuf;
 
1683
    GET_CODE_POINT(n, bbuf->p);
 
1684
  }
 
1685
  data = (OnigCodePoint* )(bbuf->p);
 
1686
  data++;
 
1687
 
 
1688
  for (low = 0, bound = n; low < bound; ) {
 
1689
    x = (low + bound) >> 1;
 
1690
    if (from > data[x*2 + 1])
 
1691
      low = x + 1;
 
1692
    else
 
1693
      bound = x;
 
1694
  }
 
1695
 
 
1696
  for (high = low, bound = n; high < bound; ) {
 
1697
    x = (high + bound) >> 1;
 
1698
    if (to >= data[x*2] - 1)
 
1699
      high = x + 1;
 
1700
    else
 
1701
      bound = x;
 
1702
  }
 
1703
 
 
1704
  inc_n = low + 1 - high;
 
1705
  if (n + inc_n > ONIG_MAX_MULTI_BYTE_RANGES_NUM)
 
1706
    return ONIGERR_TOO_MANY_MULTI_BYTE_RANGES;
 
1707
 
 
1708
  if (inc_n != 1) {
 
1709
    if (from > data[low*2])
 
1710
      from = data[low*2];
 
1711
    if (to < data[(high - 1)*2 + 1])
 
1712
      to = data[(high - 1)*2 + 1];
 
1713
  }
 
1714
 
 
1715
  if (inc_n != 0 && (OnigCodePoint )high < n) {
 
1716
    int from_pos = SIZE_CODE_POINT * (1 + high * 2);
 
1717
    int to_pos   = SIZE_CODE_POINT * (1 + (low + 1) * 2);
 
1718
    int size = (n - high) * 2 * SIZE_CODE_POINT;
 
1719
 
 
1720
    if (inc_n > 0) {
 
1721
      BBUF_MOVE_RIGHT(bbuf, from_pos, to_pos, size);
 
1722
    }
 
1723
    else {
 
1724
      BBUF_MOVE_LEFT_REDUCE(bbuf, from_pos, to_pos);
 
1725
    }
 
1726
  }
 
1727
 
 
1728
  pos = SIZE_CODE_POINT * (1 + low * 2);
 
1729
  BBUF_ENSURE_SIZE(bbuf, pos + SIZE_CODE_POINT * 2);
 
1730
  BBUF_WRITE_CODE_POINT(bbuf, pos, from);
 
1731
  BBUF_WRITE_CODE_POINT(bbuf, pos + SIZE_CODE_POINT, to);
 
1732
  n += inc_n;
 
1733
  BBUF_WRITE_CODE_POINT(bbuf, 0, n);
 
1734
 
 
1735
  return 0;
 
1736
}
 
1737
 
 
1738
static int
 
1739
add_code_range(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
 
1740
{
 
1741
  if (from > to) {
 
1742
    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
 
1743
      return 0;
 
1744
    else
 
1745
      return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
 
1746
  }
 
1747
 
 
1748
  return add_code_range_to_buf(pbuf, from, to);
 
1749
}
 
1750
 
 
1751
static int
 
1752
not_code_range_buf(OnigEncoding enc, BBuf* bbuf, BBuf** pbuf)
 
1753
{
 
1754
  int r, i, n;
 
1755
  OnigCodePoint pre, from, *data, to = 0;
 
1756
 
 
1757
  *pbuf = (BBuf* )NULL;
 
1758
  if (IS_NULL(bbuf)) {
 
1759
  set_all:
 
1760
    return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
 
1761
  }
 
1762
 
 
1763
  data = (OnigCodePoint* )(bbuf->p);
 
1764
  GET_CODE_POINT(n, data);
 
1765
  data++;
 
1766
  if (n <= 0) goto set_all;
 
1767
 
 
1768
  r = 0;
 
1769
  pre = MBCODE_START_POS(enc);
 
1770
  for (i = 0; i < n; i++) {
 
1771
    from = data[i*2];
 
1772
    to   = data[i*2+1];
 
1773
    if (pre <= from - 1) {
 
1774
      r = add_code_range_to_buf(pbuf, pre, from - 1);
 
1775
      if (r != 0) return r;
 
1776
    }
 
1777
    if (to == ~((OnigCodePoint )0)) break;
 
1778
    pre = to + 1;
 
1779
  }
 
1780
  if (to < ~((OnigCodePoint )0)) {
 
1781
    r = add_code_range_to_buf(pbuf, to + 1, ~((OnigCodePoint )0));
 
1782
  }
 
1783
  return r;
 
1784
}
 
1785
 
 
1786
#define SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2) do {\
 
1787
  BBuf *tbuf; \
 
1788
  int  tnot; \
 
1789
  tnot = not1;  not1  = not2;  not2  = tnot; \
 
1790
  tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf; \
 
1791
} while (0)
 
1792
 
 
1793
static int
 
1794
or_code_range_buf(OnigEncoding enc, BBuf* bbuf1, int not1,
 
1795
                  BBuf* bbuf2, int not2, BBuf** pbuf)
 
1796
{
 
1797
  int r;
 
1798
  OnigCodePoint i, n1, *data1;
 
1799
  OnigCodePoint from, to;
 
1800
 
 
1801
  *pbuf = (BBuf* )NULL;
 
1802
  if (IS_NULL(bbuf1) && IS_NULL(bbuf2)) {
 
1803
    if (not1 != 0 || not2 != 0)
 
1804
      return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
 
1805
    return 0;
 
1806
  }
 
1807
 
 
1808
  r = 0;
 
1809
  if (IS_NULL(bbuf2))
 
1810
    SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
 
1811
 
 
1812
  if (IS_NULL(bbuf1)) {
 
1813
    if (not1 != 0) {
 
1814
      return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
 
1815
    }
 
1816
    else {
 
1817
      if (not2 == 0) {
 
1818
        return bbuf_clone(pbuf, bbuf2);
 
1819
      }
 
1820
      else {
 
1821
        return not_code_range_buf(enc, bbuf2, pbuf);
 
1822
      }
 
1823
    }
 
1824
  }
 
1825
 
 
1826
  if (not1 != 0)
 
1827
    SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
 
1828
 
 
1829
  data1 = (OnigCodePoint* )(bbuf1->p);
 
1830
  GET_CODE_POINT(n1, data1);
 
1831
  data1++;
 
1832
 
 
1833
  if (not2 == 0 && not1 == 0) { /* 1 OR 2 */
 
1834
    r = bbuf_clone(pbuf, bbuf2);
 
1835
  }
 
1836
  else if (not1 == 0) { /* 1 OR (not 2) */
 
1837
    r = not_code_range_buf(enc, bbuf2, pbuf);
 
1838
  }
 
1839
  if (r != 0) return r;
 
1840
 
 
1841
  for (i = 0; i < n1; i++) {
 
1842
    from = data1[i*2];
 
1843
    to   = data1[i*2+1];
 
1844
    r = add_code_range_to_buf(pbuf, from, to);
 
1845
    if (r != 0) return r;
 
1846
  }
 
1847
  return 0;
 
1848
}
 
1849
 
 
1850
static int
 
1851
and_code_range1(BBuf** pbuf, OnigCodePoint from1, OnigCodePoint to1,
 
1852
                OnigCodePoint* data, int n)
 
1853
{
 
1854
  int i, r;
 
1855
  OnigCodePoint from2, to2;
 
1856
 
 
1857
  for (i = 0; i < n; i++) {
 
1858
    from2 = data[i*2];
 
1859
    to2   = data[i*2+1];
 
1860
    if (from2 < from1) {
 
1861
      if (to2 < from1) continue;
 
1862
      else {
 
1863
        from1 = to2 + 1;
 
1864
      }
 
1865
    }
 
1866
    else if (from2 <= to1) {
 
1867
      if (to2 < to1) {
 
1868
        if (from1 <= from2 - 1) {
 
1869
          r = add_code_range_to_buf(pbuf, from1, from2-1);
 
1870
          if (r != 0) return r;
 
1871
        }
 
1872
        from1 = to2 + 1;
 
1873
      }
 
1874
      else {
 
1875
        to1 = from2 - 1;
 
1876
      }
 
1877
    }
 
1878
    else {
 
1879
      from1 = from2;
 
1880
    }
 
1881
    if (from1 > to1) break;
 
1882
  }
 
1883
  if (from1 <= to1) {
 
1884
    r = add_code_range_to_buf(pbuf, from1, to1);
 
1885
    if (r != 0) return r;
 
1886
  }
 
1887
  return 0;
 
1888
}
 
1889
 
 
1890
static int
 
1891
and_code_range_buf(BBuf* bbuf1, int not1, BBuf* bbuf2, int not2, BBuf** pbuf)
 
1892
{
 
1893
  int r;
 
1894
  OnigCodePoint i, j, n1, n2, *data1, *data2;
 
1895
  OnigCodePoint from, to, from1, to1, from2, to2;
 
1896
 
 
1897
  *pbuf = (BBuf* )NULL;
 
1898
  if (IS_NULL(bbuf1)) {
 
1899
    if (not1 != 0 && IS_NOT_NULL(bbuf2)) /* not1 != 0 -> not2 == 0 */
 
1900
      return bbuf_clone(pbuf, bbuf2);
 
1901
    return 0;
 
1902
  }
 
1903
  else if (IS_NULL(bbuf2)) {
 
1904
    if (not2 != 0)
 
1905
      return bbuf_clone(pbuf, bbuf1);
 
1906
    return 0;
 
1907
  }
 
1908
 
 
1909
  if (not1 != 0)
 
1910
    SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
 
1911
 
 
1912
  data1 = (OnigCodePoint* )(bbuf1->p);
 
1913
  data2 = (OnigCodePoint* )(bbuf2->p);
 
1914
  GET_CODE_POINT(n1, data1);
 
1915
  GET_CODE_POINT(n2, data2);
 
1916
  data1++;
 
1917
  data2++;
 
1918
 
 
1919
  if (not2 == 0 && not1 == 0) { /* 1 AND 2 */
 
1920
    for (i = 0; i < n1; i++) {
 
1921
      from1 = data1[i*2];
 
1922
      to1   = data1[i*2+1];
 
1923
      for (j = 0; j < n2; j++) {
 
1924
        from2 = data2[j*2];
 
1925
        to2   = data2[j*2+1];
 
1926
        if (from2 > to1) break;
 
1927
        if (to2 < from1) continue;
 
1928
        from = MAX(from1, from2);
 
1929
        to   = MIN(to1, to2);
 
1930
        r = add_code_range_to_buf(pbuf, from, to);
 
1931
        if (r != 0) return r;
 
1932
      }
 
1933
    }
 
1934
  }
 
1935
  else if (not1 == 0) { /* 1 AND (not 2) */
 
1936
    for (i = 0; i < n1; i++) {
 
1937
      from1 = data1[i*2];
 
1938
      to1   = data1[i*2+1];
 
1939
      r = and_code_range1(pbuf, from1, to1, data2, n2);
 
1940
      if (r != 0) return r;
 
1941
    }
 
1942
  }
 
1943
 
 
1944
  return 0;
 
1945
}
 
1946
 
 
1947
static int
 
1948
and_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
 
1949
{
 
1950
  int r, not1, not2;
 
1951
  BBuf *buf1, *buf2, *pbuf;
 
1952
  BitSetRef bsr1, bsr2;
 
1953
  BitSet bs1, bs2;
 
1954
 
 
1955
  not1 = IS_CCLASS_NOT(dest);
 
1956
  bsr1 = dest->bs;
 
1957
  buf1 = dest->mbuf;
 
1958
  not2 = IS_CCLASS_NOT(cc);
 
1959
  bsr2 = cc->bs;
 
1960
  buf2 = cc->mbuf;
 
1961
 
 
1962
  if (not1 != 0) {
 
1963
    bitset_invert_to(bsr1, bs1);
 
1964
    bsr1 = bs1;
 
1965
  }
 
1966
  if (not2 != 0) {
 
1967
    bitset_invert_to(bsr2, bs2);
 
1968
    bsr2 = bs2;
 
1969
  }
 
1970
  bitset_and(bsr1, bsr2);
 
1971
  if (bsr1 != dest->bs) {
 
1972
    bitset_copy(dest->bs, bsr1);
 
1973
    bsr1 = dest->bs;
 
1974
  }
 
1975
  if (not1 != 0) {
 
1976
    bitset_invert(dest->bs);
 
1977
  }
 
1978
 
 
1979
  if (! ONIGENC_IS_SINGLEBYTE(enc)) {
 
1980
    if (not1 != 0 && not2 != 0) {
 
1981
      r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf);
 
1982
    }
 
1983
    else {
 
1984
      r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf);
 
1985
      if (r == 0 && not1 != 0) {
 
1986
        BBuf *tbuf;
 
1987
        r = not_code_range_buf(enc, pbuf, &tbuf);
 
1988
        if (r != 0) {
 
1989
          bbuf_free(pbuf);
 
1990
          return r;
 
1991
        }
 
1992
        bbuf_free(pbuf);
 
1993
        pbuf = tbuf;
 
1994
      }
 
1995
    }
 
1996
    if (r != 0) return r;
 
1997
 
 
1998
    dest->mbuf = pbuf;
 
1999
    bbuf_free(buf1);
 
2000
    return r;
 
2001
  }
 
2002
  return 0;
 
2003
}
 
2004
 
 
2005
static int
 
2006
or_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
 
2007
{
 
2008
  int r, not1, not2;
 
2009
  BBuf *buf1, *buf2, *pbuf;
 
2010
  BitSetRef bsr1, bsr2;
 
2011
  BitSet bs1, bs2;
 
2012
 
 
2013
  not1 = IS_CCLASS_NOT(dest);
 
2014
  bsr1 = dest->bs;
 
2015
  buf1 = dest->mbuf;
 
2016
  not2 = IS_CCLASS_NOT(cc);
 
2017
  bsr2 = cc->bs;
 
2018
  buf2 = cc->mbuf;
 
2019
 
 
2020
  if (not1 != 0) {
 
2021
    bitset_invert_to(bsr1, bs1);
 
2022
    bsr1 = bs1;
 
2023
  }
 
2024
  if (not2 != 0) {
 
2025
    bitset_invert_to(bsr2, bs2);
 
2026
    bsr2 = bs2;
 
2027
  }
 
2028
  bitset_or(bsr1, bsr2);
 
2029
  if (bsr1 != dest->bs) {
 
2030
    bitset_copy(dest->bs, bsr1);
 
2031
    bsr1 = dest->bs;
 
2032
  }
 
2033
  if (not1 != 0) {
 
2034
    bitset_invert(dest->bs);
 
2035
  }
 
2036
 
 
2037
  if (! ONIGENC_IS_SINGLEBYTE(enc)) {
 
2038
    if (not1 != 0 && not2 != 0) {
 
2039
      r = and_code_range_buf(buf1, 0, buf2, 0, &pbuf);
 
2040
    }
 
2041
    else {
 
2042
      r = or_code_range_buf(enc, buf1, not1, buf2, not2, &pbuf);
 
2043
      if (r == 0 && not1 != 0) {
 
2044
        BBuf *tbuf;
 
2045
        r = not_code_range_buf(enc, pbuf, &tbuf);
 
2046
        if (r != 0) {
 
2047
          bbuf_free(pbuf);
 
2048
          return r;
 
2049
        }
 
2050
        bbuf_free(pbuf);
 
2051
        pbuf = tbuf;
 
2052
      }
 
2053
    }
 
2054
    if (r != 0) return r;
 
2055
 
 
2056
    dest->mbuf = pbuf;
 
2057
    bbuf_free(buf1);
 
2058
    return r;
 
2059
  }
 
2060
  else
 
2061
    return 0;
 
2062
}
 
2063
 
 
2064
static int
 
2065
conv_backslash_value(int c, ScanEnv* env)
 
2066
{
 
2067
  if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) {
 
2068
    switch (c) {
 
2069
    case 'n':  return '\n';
 
2070
    case 't':  return '\t';
 
2071
    case 'r':  return '\r';
 
2072
    case 'f':  return '\f';
 
2073
    case 'a':  return '\007';
 
2074
    case 'b':  return '\010';
 
2075
    case 'e':  return '\033';
 
2076
    case 'v':
 
2077
      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_V_VTAB))
 
2078
        return '\v';
 
2079
      break;
 
2080
 
 
2081
    default:
 
2082
      break;
 
2083
    }
 
2084
  }
 
2085
  return c;
 
2086
}
 
2087
 
 
2088
static int
 
2089
is_invalid_quantifier_target(Node* node)
 
2090
{
 
2091
  switch (NTYPE(node)) {
 
2092
  case N_ANCHOR:
 
2093
    return 1;
 
2094
    break;
 
2095
 
 
2096
  case N_EFFECT:
 
2097
    if (NEFFECT(node).type == EFFECT_OPTION)
 
2098
      return is_invalid_quantifier_target(NEFFECT(node).target);
 
2099
    break;
 
2100
 
 
2101
  case N_LIST: /* ex. (?:\G\A)* */
 
2102
    do {
 
2103
      if (! is_invalid_quantifier_target(NCONS(node).left)) return 0;
 
2104
    } while (IS_NOT_NULL(node = NCONS(node).right));
 
2105
    return 0;
 
2106
    break;
 
2107
 
 
2108
  case N_ALT:  /* ex. (?:abc|\A)* */
 
2109
    do {
 
2110
      if (is_invalid_quantifier_target(NCONS(node).left)) return 1;
 
2111
    } while (IS_NOT_NULL(node = NCONS(node).right));
 
2112
    break;
 
2113
 
 
2114
  default:
 
2115
    break;
 
2116
  }
 
2117
  return 0;
 
2118
}
 
2119
 
 
2120
/* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
 
2121
static int
 
2122
popular_quantifier_num(QuantifierNode* qf)
 
2123
{
 
2124
  if (qf->greedy) {
 
2125
    if (qf->lower == 0) {
 
2126
      if (qf->upper == 1) return 0;
 
2127
      else if (IS_REPEAT_INFINITE(qf->upper)) return 1;
 
2128
    }
 
2129
    else if (qf->lower == 1) {
 
2130
      if (IS_REPEAT_INFINITE(qf->upper)) return 2;
 
2131
    }
 
2132
  }
 
2133
  else {
 
2134
    if (qf->lower == 0) {
 
2135
      if (qf->upper == 1) return 3;
 
2136
      else if (IS_REPEAT_INFINITE(qf->upper)) return 4;
 
2137
    }
 
2138
    else if (qf->lower == 1) {
 
2139
      if (IS_REPEAT_INFINITE(qf->upper)) return 5;
 
2140
    }
 
2141
  }
 
2142
  return -1;
 
2143
}
 
2144
 
 
2145
 
 
2146
enum ReduceType {
 
2147
  RQ_ASIS = 0, /* as is */
 
2148
  RQ_DEL  = 1, /* delete parent */
 
2149
  RQ_A,        /* to '*'    */
 
2150
  RQ_AQ,       /* to '*?'   */
 
2151
  RQ_QQ,       /* to '??'   */
 
2152
  RQ_P_QQ,     /* to '+)??' */
 
2153
  RQ_PQ_Q      /* to '+?)?' */
 
2154
};
 
2155
 
 
2156
static enum ReduceType ReduceTypeTable[6][6] = {
 
2157
  {RQ_DEL,  RQ_A,    RQ_A,   RQ_QQ,   RQ_AQ,   RQ_ASIS}, /* '?'  */
 
2158
  {RQ_DEL,  RQ_DEL,  RQ_DEL, RQ_P_QQ, RQ_P_QQ, RQ_DEL},  /* '*'  */
 
2159
  {RQ_A,    RQ_A,    RQ_DEL, RQ_ASIS, RQ_P_QQ, RQ_DEL},  /* '+'  */
 
2160
  {RQ_DEL,  RQ_AQ,   RQ_AQ,  RQ_DEL,  RQ_AQ,   RQ_AQ},   /* '??' */
 
2161
  {RQ_DEL,  RQ_DEL,  RQ_DEL, RQ_DEL,  RQ_DEL,  RQ_DEL},  /* '*?' */
 
2162
  {RQ_ASIS, RQ_PQ_Q, RQ_DEL, RQ_AQ,   RQ_AQ,   RQ_DEL}   /* '+?' */
 
2163
};
 
2164
 
 
2165
extern void
 
2166
onig_reduce_nested_quantifier(Node* pnode, Node* cnode)
 
2167
{
 
2168
  int pnum, cnum;
 
2169
  QuantifierNode *p, *c;
 
2170
 
 
2171
  p = &(NQUANTIFIER(pnode));
 
2172
  c = &(NQUANTIFIER(cnode));
 
2173
  pnum = popular_quantifier_num(p);
 
2174
  cnum = popular_quantifier_num(c);
 
2175
 
 
2176
  switch(ReduceTypeTable[cnum][pnum]) {
 
2177
  case RQ_DEL:
 
2178
    *p = *c;
 
2179
    break;
 
2180
  case RQ_A:
 
2181
    p->target = c->target;
 
2182
    p->lower  = 0;  p->upper = REPEAT_INFINITE;  p->greedy = 1;
 
2183
    break;
 
2184
  case RQ_AQ:
 
2185
    p->target = c->target;
 
2186
    p->lower  = 0;  p->upper = REPEAT_INFINITE;  p->greedy = 0;
 
2187
    break;
 
2188
  case RQ_QQ:
 
2189
    p->target = c->target;
 
2190
    p->lower  = 0;  p->upper = 1;  p->greedy = 0;
 
2191
    break;
 
2192
  case RQ_P_QQ:
 
2193
    p->target = cnode;
 
2194
    p->lower  = 0;  p->upper = 1;  p->greedy = 0;
 
2195
    c->lower  = 1;  c->upper = REPEAT_INFINITE;  c->greedy = 1;
 
2196
    return ;
 
2197
    break;
 
2198
  case RQ_PQ_Q:
 
2199
    p->target = cnode;
 
2200
    p->lower  = 0;  p->upper = 1;  p->greedy = 1;
 
2201
    c->lower  = 1;  c->upper = REPEAT_INFINITE;  c->greedy = 0;
 
2202
    return ;
 
2203
    break;
 
2204
  case RQ_ASIS:
 
2205
    p->target = cnode;
 
2206
    return ;
 
2207
    break;
 
2208
  }
 
2209
 
 
2210
  c->target = NULL_NODE;
 
2211
  onig_node_free(cnode);
 
2212
}
 
2213
 
 
2214
 
 
2215
enum TokenSyms {
 
2216
  TK_EOT      = 0,   /* end of token */
 
2217
  TK_RAW_BYTE = 1,
 
2218
  TK_CHAR,
 
2219
  TK_STRING,
 
2220
  TK_CODE_POINT,
 
2221
  TK_ANYCHAR,
 
2222
  TK_CHAR_TYPE,
 
2223
  TK_BACKREF,
 
2224
  TK_CALL,
 
2225
  TK_ANCHOR,
 
2226
  TK_OP_REPEAT,
 
2227
  TK_INTERVAL,
 
2228
  TK_ANYCHAR_ANYTIME,  /* SQL '%' == .* */
 
2229
  TK_ALT,
 
2230
  TK_SUBEXP_OPEN,
 
2231
  TK_SUBEXP_CLOSE,
 
2232
  TK_CC_OPEN,
 
2233
  TK_QUOTE_OPEN,
 
2234
  TK_CHAR_PROPERTY,    /* \p{...}, \P{...} */
 
2235
  /* in cc */
 
2236
  TK_CC_CLOSE,
 
2237
  TK_CC_RANGE,
 
2238
  TK_POSIX_BRACKET_OPEN,
 
2239
  TK_CC_AND,             /* && */
 
2240
  TK_CC_CC_OPEN          /* [ */
 
2241
};
 
2242
 
 
2243
typedef struct {
 
2244
  enum TokenSyms type;
 
2245
  int escaped;
 
2246
  int base;   /* is number: 8, 16 (used in [....]) */
 
2247
  UChar* backp;
 
2248
  union {
 
2249
    UChar* s;
 
2250
    int   c;
 
2251
    OnigCodePoint code;
 
2252
    int   anchor;
 
2253
    int   subtype;
 
2254
    struct {
 
2255
      int lower;
 
2256
      int upper;
 
2257
      int greedy;
 
2258
      int possessive;
 
2259
    } repeat;
 
2260
    struct {
 
2261
      int  num;
 
2262
      int  ref1;
 
2263
      int* refs;
 
2264
      int  by_name;
 
2265
#ifdef USE_BACKREF_AT_LEVEL
 
2266
      int  exist_level;
 
2267
      int  level;   /* \k<name+n> */
 
2268
#endif
 
2269
    } backref;
 
2270
    struct {
 
2271
      UChar* name;
 
2272
      UChar* name_end;
 
2273
    } call;
 
2274
    struct {
 
2275
      int not;
 
2276
    } prop;
 
2277
  } u;
 
2278
} OnigToken;
 
2279
 
 
2280
 
 
2281
static int
 
2282
fetch_range_quantifier(UChar** src, UChar* end, OnigToken* tok, ScanEnv* env)
 
2283
{
 
2284
  int low, up, syn_allow, non_low = 0;
 
2285
  int r = 0;
 
2286
  OnigCodePoint c;
 
2287
  OnigEncoding enc = env->enc;
 
2288
  UChar* p = *src;
 
2289
  PFETCH_READY;
 
2290
 
 
2291
  syn_allow = IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INVALID_INTERVAL);
 
2292
 
 
2293
  if (PEND) {
 
2294
    if (syn_allow)
 
2295
      return 1;  /* "....{" : OK! */
 
2296
    else
 
2297
      return ONIGERR_END_PATTERN_AT_LEFT_BRACE;  /* "....{" syntax error */
 
2298
  }
 
2299
 
 
2300
  if (! syn_allow) {
 
2301
    c = PPEEK;
 
2302
    if (c == ')' || c == '(' || c == '|') {
 
2303
      return ONIGERR_END_PATTERN_AT_LEFT_BRACE;
 
2304
    }
 
2305
  }
 
2306
 
 
2307
  low = onig_scan_unsigned_number(&p, end, env->enc);
 
2308
  if (low < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
 
2309
  if (low > ONIG_MAX_REPEAT_NUM)
 
2310
    return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
 
2311
 
 
2312
  if (p == *src) { /* can't read low */
 
2313
    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV)) {
 
2314
      /* allow {,n} as {0,n} */
 
2315
      low = 0;
 
2316
      non_low = 1;
 
2317
    }
 
2318
    else
 
2319
      goto invalid;
 
2320
  }
 
2321
 
 
2322
  if (PEND) goto invalid;
 
2323
  PFETCH(c);
 
2324
  if (c == ',') {
 
2325
    UChar* prev = p;
 
2326
    up = onig_scan_unsigned_number(&p, end, env->enc);
 
2327
    if (up < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
 
2328
    if (up > ONIG_MAX_REPEAT_NUM)
 
2329
      return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
 
2330
 
 
2331
    if (p == prev) {
 
2332
      if (non_low != 0)
 
2333
        goto invalid;
 
2334
      up = REPEAT_INFINITE;  /* {n,} : {n,infinite} */
 
2335
    }
 
2336
  }
 
2337
  else {
 
2338
    if (non_low != 0)
 
2339
      goto invalid;
 
2340
 
 
2341
    PUNFETCH;
 
2342
    up = low;  /* {n} : exact n times */
 
2343
    r = 2;     /* fixed */
 
2344
  }
 
2345
 
 
2346
  if (PEND) goto invalid;
 
2347
  PFETCH(c);
 
2348
  if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) {
 
2349
    if (c != MC_ESC(enc)) goto invalid;
 
2350
    PFETCH(c);
 
2351
  }
 
2352
  if (c != '}') goto invalid;
 
2353
 
 
2354
  if (!IS_REPEAT_INFINITE(up) && low > up) {
 
2355
    return ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE;
 
2356
  }
 
2357
 
 
2358
  tok->type = TK_INTERVAL;
 
2359
  tok->u.repeat.lower = low;
 
2360
  tok->u.repeat.upper = up;
 
2361
  *src = p;
 
2362
  return r; /* 0: normal {n,m}, 2: fixed {n} */
 
2363
 
 
2364
 invalid:
 
2365
  if (syn_allow)
 
2366
    return 1;  /* OK */
 
2367
  else
 
2368
    return ONIGERR_INVALID_REPEAT_RANGE_PATTERN;
 
2369
}
 
2370
 
 
2371
/* \M-, \C-, \c, or \... */
 
2372
static int
 
2373
fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
 
2374
{
 
2375
  int v;
 
2376
  OnigCodePoint c;
 
2377
  OnigEncoding enc = env->enc;
 
2378
  UChar* p = *src;
 
2379
  PFETCH_READY;
 
2380
 
 
2381
  if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
 
2382
 
 
2383
  PFETCH(c);
 
2384
  switch (c) {
 
2385
  case 'M':
 
2386
    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META)) {
 
2387
      if (PEND) return ONIGERR_END_PATTERN_AT_META;
 
2388
      PFETCH(c);
 
2389
      if (c != '-') return ONIGERR_META_CODE_SYNTAX;
 
2390
      if (PEND) return ONIGERR_END_PATTERN_AT_META;
 
2391
      PFETCH(c);
 
2392
      if (c == MC_ESC(enc)) {
 
2393
        v = fetch_escaped_value(&p, end, env);
 
2394
        if (v < 0) return v;
 
2395
        c = (OnigCodePoint )v;
 
2396
      }
 
2397
      c = ((c & 0xff) | 0x80);
 
2398
    }
 
2399
    else
 
2400
      goto backslash;
 
2401
    break;
 
2402
 
 
2403
  case 'C':
 
2404
    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL)) {
 
2405
      if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
 
2406
      PFETCH(c);
 
2407
      if (c != '-') return ONIGERR_CONTROL_CODE_SYNTAX;
 
2408
      goto control;
 
2409
    }
 
2410
    else
 
2411
      goto backslash;
 
2412
 
 
2413
  case 'c':
 
2414
    if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_C_CONTROL)) {
 
2415
    control:
 
2416
      if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
 
2417
      PFETCH(c);
 
2418
      if (c == '?') {
 
2419
        c = 0177;
 
2420
      }
 
2421
      else {
 
2422
        if (c == MC_ESC(enc)) {
 
2423
          v = fetch_escaped_value(&p, end, env);
 
2424
          if (v < 0) return v;
 
2425
          c = (OnigCodePoint )v;
 
2426
        }
 
2427
        c &= 0x9f;
 
2428
      }
 
2429
      break;
 
2430
    }
 
2431
    /* fall through */
 
2432
 
 
2433
  default:
 
2434
    {
 
2435
    backslash:
 
2436
      c = conv_backslash_value(c, env);
 
2437
    }
 
2438
    break;
 
2439
  }
 
2440
 
 
2441
  *src = p;
 
2442
  return c;
 
2443
}
 
2444
 
 
2445
static int fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env);
 
2446
 
 
2447
#ifdef USE_NAMED_GROUP
 
2448
#ifdef USE_BACKREF_AT_LEVEL
 
2449
/*
 
2450
   \k<name+n>, \k<name-n>
 
2451
*/
 
2452
static int
 
2453
fetch_name_with_level(UChar** src, UChar* end, UChar** rname_end
 
2454
                      , ScanEnv* env, int* level)
 
2455
{
 
2456
  int r, exist_level = 0;
 
2457
  OnigCodePoint c = 0;
 
2458
  OnigCodePoint first_code;
 
2459
  OnigEncoding enc = env->enc;
 
2460
  UChar *name_end;
 
2461
  UChar *p = *src;
 
2462
  PFETCH_READY;
 
2463
 
 
2464
  name_end = end;
 
2465
  r = 0;
 
2466
  if (PEND) {
 
2467
    return ONIGERR_EMPTY_GROUP_NAME;
 
2468
  }
 
2469
  else {
 
2470
    PFETCH(c);
 
2471
    first_code = c;
 
2472
    if (c == '>')
 
2473
      return ONIGERR_EMPTY_GROUP_NAME;
 
2474
 
 
2475
    if (!ONIGENC_IS_CODE_WORD(enc, c)) {
 
2476
      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
 
2477
    }
 
2478
  }
 
2479
 
 
2480
  while (!PEND) {
 
2481
    name_end = p;
 
2482
    PFETCH(c);
 
2483
    if (c == '>' || c == ')' || c == '+' || c == '-') break;
 
2484
 
 
2485
    if (!ONIGENC_IS_CODE_WORD(enc, c)) {
 
2486
      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
 
2487
    }
 
2488
  }
 
2489
 
 
2490
  if (c != '>') {
 
2491
    if (c == '+' || c == '-') {
 
2492
      int num;
 
2493
      int flag = (c == '-' ? -1 : 1);
 
2494
 
 
2495
      PFETCH(c);
 
2496
      if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err;
 
2497
      PUNFETCH;
 
2498
      num = onig_scan_unsigned_number(&p, end, enc);
 
2499
      if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
 
2500
      *level = (num * flag);
 
2501
      exist_level = 1;
 
2502
 
 
2503
      PFETCH(c);
 
2504
      if (c == '>')
 
2505
        goto first_check;
 
2506
    }
 
2507
 
 
2508
  err:
 
2509
    r = ONIGERR_INVALID_GROUP_NAME;
 
2510
    name_end = end;
 
2511
  }
 
2512
  else {
 
2513
  first_check:
 
2514
    if (ONIGENC_IS_CODE_ASCII(first_code) &&
 
2515
        ONIGENC_IS_CODE_UPPER(enc, first_code))
 
2516
      r = ONIGERR_INVALID_GROUP_NAME;
 
2517
  }
 
2518
 
 
2519
  if (r == 0) {
 
2520
    *rname_end = name_end;
 
2521
    *src = p;
 
2522
    return (exist_level ? 1 : 0);
 
2523
  }
 
2524
  else {
 
2525
    onig_scan_env_set_error_string(env, r, *src, name_end);
 
2526
    return r;
 
2527
  }
 
2528
}
 
2529
#endif /* USE_BACKREF_AT_LEVEL */
 
2530
 
 
2531
/*
 
2532
  def: 0 -> define name    (don't allow number name)
 
2533
       1 -> reference name (allow number name)
 
2534
*/
 
2535
static int
 
2536
fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
 
2537
{
 
2538
  int r, is_num;
 
2539
  OnigCodePoint c = 0;
 
2540
  OnigCodePoint first_code;
 
2541
  OnigEncoding enc = env->enc;
 
2542
  UChar *name_end;
 
2543
  UChar *p = *src;
 
2544
  PFETCH_READY;
 
2545
 
 
2546
  name_end = end;
 
2547
  r = 0;
 
2548
  is_num = 0;
 
2549
  if (PEND) {
 
2550
    return ONIGERR_EMPTY_GROUP_NAME;
 
2551
  }
 
2552
  else {
 
2553
    PFETCH(c);
 
2554
    first_code = c;
 
2555
    if (c == '>')
 
2556
      return ONIGERR_EMPTY_GROUP_NAME;
 
2557
 
 
2558
    if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
 
2559
      if (ref == 1)
 
2560
        is_num = 1;
 
2561
      else {
 
2562
        r = ONIGERR_INVALID_GROUP_NAME;
 
2563
      }
 
2564
    }
 
2565
    else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
 
2566
      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
 
2567
    }
 
2568
  }
 
2569
 
 
2570
  while (!PEND) {
 
2571
    name_end = p;
 
2572
    PFETCH(c);
 
2573
    if (c == '>' || c == ')') break;
 
2574
 
 
2575
    if (is_num == 1) {
 
2576
      if (! ONIGENC_IS_CODE_DIGIT(enc, c)) {
 
2577
        if (!ONIGENC_IS_CODE_WORD(enc, c))
 
2578
          r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
 
2579
        else
 
2580
          r = ONIGERR_INVALID_GROUP_NAME;
 
2581
      }
 
2582
    }
 
2583
    else {
 
2584
      if (!ONIGENC_IS_CODE_WORD(enc, c)) {
 
2585
        r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
 
2586
      }
 
2587
    }
 
2588
  }
 
2589
 
 
2590
  if (c != '>') {
 
2591
    r = ONIGERR_INVALID_GROUP_NAME;
 
2592
    name_end = end;
 
2593
  }
 
2594
  else {
 
2595
    if (ONIGENC_IS_CODE_ASCII(first_code) &&
 
2596
        ONIGENC_IS_CODE_UPPER(enc, first_code))
 
2597
      r = ONIGERR_INVALID_GROUP_NAME;
 
2598
  }
 
2599
 
 
2600
  if (r == 0) {
 
2601
    *rname_end = name_end;
 
2602
    *src = p;
 
2603
    return 0;
 
2604
  }
 
2605
  else {
 
2606
    onig_scan_env_set_error_string(env, r, *src, name_end);
 
2607
    return r;
 
2608
  }
 
2609
}
 
2610
#else
 
2611
static int
 
2612
fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
 
2613
{
 
2614
  int r, len;
 
2615
  OnigCodePoint c = 0;
 
2616
  UChar *name_end;
 
2617
  OnigEncoding enc = env->enc;
 
2618
  UChar *p = *src;
 
2619
  PFETCH_READY;
 
2620
 
 
2621
  r = 0;
 
2622
  while (!PEND) {
 
2623
    name_end = p;
 
2624
    if (enc_len(enc, p) > 1)
 
2625
      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
 
2626
 
 
2627
    PFETCH(c);
 
2628
    if (c == '>' || c == ')') break;
 
2629
    if (! ONIGENC_IS_CODE_DIGIT(enc, c))
 
2630
      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
 
2631
  }
 
2632
  if (c != '>') {
 
2633
    r = ONIGERR_INVALID_GROUP_NAME;
 
2634
    name_end = end;
 
2635
  }
 
2636
 
 
2637
  if (r == 0) {
 
2638
    *rname_end = name_end;
 
2639
    *src = p;
 
2640
    return 0;
 
2641
  }
 
2642
  else {
 
2643
  err:
 
2644
    onig_scan_env_set_error_string(env, r, *src, name_end);
 
2645
    return r;
 
2646
  }
 
2647
}
 
2648
#endif
 
2649
 
 
2650
static void
 
2651
CC_ESC_WARN(ScanEnv* env, UChar *c)
 
2652
{
 
2653
  if (onig_warn == onig_null_warn) return ;
 
2654
 
 
2655
  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED) &&
 
2656
      IS_SYNTAX_BV(env->syntax, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC)) {
 
2657
    UChar buf[WARN_BUFSIZE];
 
2658
    onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
 
2659
                env->pattern, env->pattern_end,
 
2660
                (UChar* )"character class has '%s' without escape", c);
 
2661
    (*onig_warn)((char* )buf);
 
2662
  }
 
2663
}
 
2664
 
 
2665
static void
 
2666
CCEND_ESC_WARN(ScanEnv* env, UChar* c)
 
2667
{
 
2668
  if (onig_warn == onig_null_warn) return ;
 
2669
 
 
2670
  if (IS_SYNTAX_BV((env)->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED)) {
 
2671
    UChar buf[WARN_BUFSIZE];
 
2672
    onig_snprintf_with_pattern(buf, WARN_BUFSIZE, (env)->enc,
 
2673
                (env)->pattern, (env)->pattern_end,
 
2674
                (UChar* )"regular expression has '%s' without escape", c);
 
2675
    (*onig_warn)((char* )buf);
 
2676
  }
 
2677
}
 
2678
 
 
2679
static UChar*
 
2680
find_str_position(OnigCodePoint s[], int n, UChar* from, UChar* to,
 
2681
                  UChar **next, OnigEncoding enc)
 
2682
{
 
2683
  int i;
 
2684
  OnigCodePoint x;
 
2685
  UChar *q;
 
2686
  UChar *p = from;
 
2687
  
 
2688
  while (p < to) {
 
2689
    x = ONIGENC_MBC_TO_CODE(enc, p, to);
 
2690
    q = p + enc_len(enc, p);
 
2691
    if (x == s[0]) {
 
2692
      for (i = 1; i < n && q < to; i++) {
 
2693
        x = ONIGENC_MBC_TO_CODE(enc, q, to);
 
2694
        if (x != s[i]) break;
 
2695
        q += enc_len(enc, q);
 
2696
      }
 
2697
      if (i >= n) {
 
2698
        if (IS_NOT_NULL(next))
 
2699
          *next = q;
 
2700
        return p;
 
2701
      }
 
2702
    }
 
2703
    p = q;
 
2704
  }
 
2705
  return NULL_UCHARP;
 
2706
}
 
2707
 
 
2708
static int
 
2709
str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to,
 
2710
                         OnigCodePoint bad, OnigEncoding enc)
 
2711
{
 
2712
  int i, in_esc;
 
2713
  OnigCodePoint x;
 
2714
  UChar *q;
 
2715
  UChar *p = from;
 
2716
 
 
2717
  in_esc = 0;
 
2718
  while (p < to) {
 
2719
    if (in_esc) {
 
2720
      in_esc = 0;
 
2721
      p += enc_len(enc, p);
 
2722
    }
 
2723
    else {
 
2724
      x = ONIGENC_MBC_TO_CODE(enc, p, to);
 
2725
      q = p + enc_len(enc, p);
 
2726
      if (x == s[0]) {
 
2727
        for (i = 1; i < n && q < to; i++) {
 
2728
          x = ONIGENC_MBC_TO_CODE(enc, q, to);
 
2729
          if (x != s[i]) break;
 
2730
          q += enc_len(enc, q);
 
2731
        }
 
2732
        if (i >= n) return 1;
 
2733
        p += enc_len(enc, p);
 
2734
      }
 
2735
      else {
 
2736
        x = ONIGENC_MBC_TO_CODE(enc, p, to);
 
2737
        if (x == bad) return 0;
 
2738
        else if (x == MC_ESC(enc)) in_esc = 1;
 
2739
        p = q;
 
2740
      }
 
2741
    }
 
2742
  }
 
2743
  return 0;
 
2744
}
 
2745
 
 
2746
static int
 
2747
fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
 
2748
{
 
2749
  int num;
 
2750
  OnigCodePoint c, c2;
 
2751
  OnigSyntaxType* syn = env->syntax;
 
2752
  OnigEncoding enc = env->enc;
 
2753
  UChar* prev;
 
2754
  UChar* p = *src;
 
2755
  PFETCH_READY;
 
2756
 
 
2757
  if (PEND) {
 
2758
    tok->type = TK_EOT;
 
2759
    return tok->type;
 
2760
  }
 
2761
 
 
2762
  PFETCH(c);
 
2763
  tok->type = TK_CHAR;
 
2764
  tok->base = 0;
 
2765
  tok->u.c  = c;
 
2766
  tok->escaped = 0;
 
2767
 
 
2768
  if (c == ']') {
 
2769
    tok->type = TK_CC_CLOSE;
 
2770
  }
 
2771
  else if (c == '-') {
 
2772
    tok->type = TK_CC_RANGE;
 
2773
  }
 
2774
  else if (c == MC_ESC(enc)) {
 
2775
    if (! IS_SYNTAX_BV(syn, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC))
 
2776
      goto end;
 
2777
 
 
2778
    if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
 
2779
 
 
2780
    PFETCH(c);
 
2781
    tok->escaped = 1;
 
2782
    tok->u.c = c;
 
2783
    switch (c) {
 
2784
    case 'w':
 
2785
      tok->type = TK_CHAR_TYPE;
 
2786
      tok->u.subtype = CTYPE_WORD;
 
2787
      break;
 
2788
    case 'W':
 
2789
      tok->type = TK_CHAR_TYPE;
 
2790
      tok->u.subtype = CTYPE_NOT_WORD;
 
2791
      break;
 
2792
    case 'd':
 
2793
      tok->type = TK_CHAR_TYPE;
 
2794
      tok->u.subtype = CTYPE_DIGIT;
 
2795
      break;
 
2796
    case 'D':
 
2797
      tok->type = TK_CHAR_TYPE;
 
2798
      tok->u.subtype = CTYPE_NOT_DIGIT;
 
2799
      break;
 
2800
    case 's':
 
2801
      tok->type = TK_CHAR_TYPE;
 
2802
      tok->u.subtype = CTYPE_WHITE_SPACE;
 
2803
      break;
 
2804
    case 'S':
 
2805
      tok->type = TK_CHAR_TYPE;
 
2806
      tok->u.subtype = CTYPE_NOT_WHITE_SPACE;
 
2807
      break;
 
2808
    case 'h':
 
2809
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
 
2810
      tok->type = TK_CHAR_TYPE;
 
2811
      tok->u.subtype = CTYPE_XDIGIT;
 
2812
      break;
 
2813
    case 'H':
 
2814
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
 
2815
      tok->type = TK_CHAR_TYPE;
 
2816
      tok->u.subtype = CTYPE_NOT_XDIGIT;
 
2817
      break;
 
2818
 
 
2819
    case 'p':
 
2820
    case 'P':
 
2821
      c2 = PPEEK;
 
2822
      if (c2 == '{' &&
 
2823
          IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
 
2824
        PINC;
 
2825
        tok->type = TK_CHAR_PROPERTY;
 
2826
        tok->u.prop.not = (c == 'P' ? 1 : 0);
 
2827
 
 
2828
        if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
 
2829
          PFETCH(c2);
 
2830
          if (c2 == '^') {
 
2831
            tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
 
2832
          }
 
2833
          else
 
2834
            PUNFETCH;
 
2835
        }
 
2836
      }
 
2837
      break;
 
2838
 
 
2839
    case 'x':
 
2840
      if (PEND) break;
 
2841
 
 
2842
      prev = p;
 
2843
      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
 
2844
        PINC;
 
2845
        num = scan_unsigned_hexadecimal_number(&p, end, 8, enc);
 
2846
        if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
 
2847
        if (!PEND) {
 
2848
          c2 = PPEEK;
 
2849
          if (ONIGENC_IS_CODE_XDIGIT(enc, c2))
 
2850
            return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
 
2851
        }
 
2852
 
 
2853
        if (p > prev + enc_len(enc, prev) && !PEND && (PPEEK_IS('}'))) {
 
2854
          PINC;
 
2855
          tok->type   = TK_CODE_POINT;
 
2856
          tok->base   = 16;
 
2857
          tok->u.code = (OnigCodePoint )num;
 
2858
        }
 
2859
        else {
 
2860
          /* can't read nothing or invalid format */
 
2861
          p = prev;
 
2862
        }
 
2863
      }
 
2864
      else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
 
2865
        num = scan_unsigned_hexadecimal_number(&p, end, 2, enc);
 
2866
        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
 
2867
        if (p == prev) {  /* can't read nothing. */
 
2868
          num = 0; /* but, it's not error */
 
2869
        }
 
2870
        tok->type = TK_RAW_BYTE;
 
2871
        tok->base = 16;
 
2872
        tok->u.c  = num;
 
2873
      }
 
2874
      break;
 
2875
 
 
2876
    case 'u':
 
2877
      if (PEND) break;
 
2878
 
 
2879
      prev = p;
 
2880
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
 
2881
        num = scan_unsigned_hexadecimal_number(&p, end, 4, enc);
 
2882
        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
 
2883
        if (p == prev) {  /* can't read nothing. */
 
2884
          num = 0; /* but, it's not error */
 
2885
        }
 
2886
        tok->type   = TK_CODE_POINT;
 
2887
        tok->base   = 16;
 
2888
        tok->u.code = (OnigCodePoint )num;
 
2889
      }
 
2890
      break;
 
2891
 
 
2892
    case '0':
 
2893
    case '1': case '2': case '3': case '4': case '5': case '6': case '7':
 
2894
      if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
 
2895
        PUNFETCH;
 
2896
        prev = p;
 
2897
        num = scan_unsigned_octal_number(&p, end, 3, enc);
 
2898
        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
 
2899
        if (p == prev) {  /* can't read nothing. */
 
2900
          num = 0; /* but, it's not error */
 
2901
        }
 
2902
        tok->type = TK_RAW_BYTE;
 
2903
        tok->base = 8;
 
2904
        tok->u.c  = num;
 
2905
      }
 
2906
      break;
 
2907
 
 
2908
    default:
 
2909
      PUNFETCH;
 
2910
      num = fetch_escaped_value(&p, end, env);
 
2911
      if (num < 0) return num;
 
2912
      if (tok->u.c != num) {
 
2913
        tok->u.code = (OnigCodePoint )num;
 
2914
        tok->type   = TK_CODE_POINT;
 
2915
      }
 
2916
      break;
 
2917
    }
 
2918
  }
 
2919
  else if (c == '[') {
 
2920
    if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_POSIX_BRACKET) && (PPEEK_IS(':'))) {
 
2921
      OnigCodePoint send[] = { (OnigCodePoint )':', (OnigCodePoint )']' };
 
2922
      tok->backp = p; /* point at '[' is readed */
 
2923
      PINC;
 
2924
      if (str_exist_check_with_esc(send, 2, p, end,
 
2925
                                   (OnigCodePoint )']', enc)) {
 
2926
        tok->type = TK_POSIX_BRACKET_OPEN;
 
2927
      }
 
2928
      else {
 
2929
        PUNFETCH;
 
2930
        goto cc_in_cc;
 
2931
      }
 
2932
    }
 
2933
    else {
 
2934
    cc_in_cc:
 
2935
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP)) {
 
2936
        tok->type = TK_CC_CC_OPEN;
 
2937
      }
 
2938
      else {
 
2939
        CC_ESC_WARN(env, (UChar* )"[");
 
2940
      }
 
2941
    }
 
2942
  }
 
2943
  else if (c == '&') {
 
2944
    if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP) &&
 
2945
        !PEND && (PPEEK_IS('&'))) {
 
2946
      PINC;
 
2947
      tok->type = TK_CC_AND;
 
2948
    }
 
2949
  }
 
2950
 
 
2951
 end:
 
2952
  *src = p;
 
2953
  return tok->type;
 
2954
}
 
2955
 
 
2956
static int
 
2957
fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
 
2958
{
 
2959
  int r, num;
 
2960
  OnigCodePoint c;
 
2961
  OnigEncoding enc = env->enc;
 
2962
  OnigSyntaxType* syn = env->syntax;
 
2963
  UChar* prev;
 
2964
  UChar* p = *src;
 
2965
  PFETCH_READY;
 
2966
 
 
2967
 start:
 
2968
  if (PEND) {
 
2969
    tok->type = TK_EOT;
 
2970
    return tok->type;
 
2971
  }
 
2972
 
 
2973
  tok->type  = TK_STRING;
 
2974
  tok->base  = 0;
 
2975
  tok->backp = p;
 
2976
 
 
2977
  PFETCH(c);
 
2978
  if (IS_MC_ESC_CODE(c, enc, syn)) {
 
2979
    if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
 
2980
 
 
2981
    tok->backp = p;
 
2982
    PFETCH(c);
 
2983
 
 
2984
    tok->u.c = c;
 
2985
    tok->escaped = 1;
 
2986
    switch (c) {
 
2987
    case '*':
 
2988
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF)) break;
 
2989
      tok->type = TK_OP_REPEAT;
 
2990
      tok->u.repeat.lower = 0;
 
2991
      tok->u.repeat.upper = REPEAT_INFINITE;
 
2992
      goto greedy_check;
 
2993
      break;
 
2994
 
 
2995
    case '+':
 
2996
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_PLUS_ONE_INF)) break;
 
2997
      tok->type = TK_OP_REPEAT;
 
2998
      tok->u.repeat.lower = 1;
 
2999
      tok->u.repeat.upper = REPEAT_INFINITE;
 
3000
      goto greedy_check;
 
3001
      break;
 
3002
 
 
3003
    case '?':
 
3004
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_QMARK_ZERO_ONE)) break;
 
3005
      tok->type = TK_OP_REPEAT;
 
3006
      tok->u.repeat.lower = 0;
 
3007
      tok->u.repeat.upper = 1;
 
3008
    greedy_check:
 
3009
      if (!PEND && PPEEK_IS('?') &&
 
3010
          IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_NON_GREEDY)) {
 
3011
        PFETCH(c);
 
3012
        tok->u.repeat.greedy     = 0;
 
3013
        tok->u.repeat.possessive = 0;
 
3014
      }
 
3015
      else {
 
3016
      possessive_check:
 
3017
        if (!PEND && PPEEK_IS('+') &&
 
3018
            ((IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT) &&
 
3019
              tok->type != TK_INTERVAL)  ||
 
3020
             (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL) &&
 
3021
              tok->type == TK_INTERVAL))) {
 
3022
          PFETCH(c);
 
3023
          tok->u.repeat.greedy     = 1;
 
3024
          tok->u.repeat.possessive = 1;
 
3025
        }
 
3026
        else {
 
3027
          tok->u.repeat.greedy     = 1;
 
3028
          tok->u.repeat.possessive = 0;
 
3029
        }
 
3030
      }
 
3031
      break;
 
3032
 
 
3033
    case '{':
 
3034
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) break;
 
3035
      r = fetch_range_quantifier(&p, end, tok, env);
 
3036
      if (r < 0) return r;  /* error */
 
3037
      if (r == 0) goto greedy_check;
 
3038
      else if (r == 2) { /* {n} */
 
3039
        if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
 
3040
          goto possessive_check;
 
3041
 
 
3042
        goto greedy_check;
 
3043
      }
 
3044
      /* r == 1 : normal char */
 
3045
      break;
 
3046
 
 
3047
    case '|':
 
3048
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_VBAR_ALT)) break;
 
3049
      tok->type = TK_ALT;
 
3050
      break;
 
3051
 
 
3052
    case '(':
 
3053
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
 
3054
      tok->type = TK_SUBEXP_OPEN;
 
3055
      break;
 
3056
 
 
3057
    case ')':
 
3058
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
 
3059
      tok->type = TK_SUBEXP_CLOSE;
 
3060
      break;
 
3061
 
 
3062
    case 'w':
 
3063
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
 
3064
      tok->type = TK_CHAR_TYPE;
 
3065
      tok->u.subtype = CTYPE_WORD;
 
3066
      break;
 
3067
 
 
3068
    case 'W':
 
3069
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
 
3070
      tok->type = TK_CHAR_TYPE;
 
3071
      tok->u.subtype = CTYPE_NOT_WORD;
 
3072
      break;
 
3073
 
 
3074
    case 'b':
 
3075
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
 
3076
      tok->type = TK_ANCHOR;
 
3077
      tok->u.anchor = ANCHOR_WORD_BOUND;
 
3078
      break;
 
3079
 
 
3080
    case 'B':
 
3081
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
 
3082
      tok->type = TK_ANCHOR;
 
3083
      tok->u.anchor = ANCHOR_NOT_WORD_BOUND;
 
3084
      break;
 
3085
 
 
3086
#ifdef USE_WORD_BEGIN_END
 
3087
    case '<':
 
3088
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
 
3089
      tok->type = TK_ANCHOR;
 
3090
      tok->u.anchor = ANCHOR_WORD_BEGIN;
 
3091
      break;
 
3092
 
 
3093
    case '>':
 
3094
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
 
3095
      tok->type = TK_ANCHOR;
 
3096
      tok->u.anchor = ANCHOR_WORD_END;
 
3097
      break;
 
3098
#endif
 
3099
 
 
3100
    case 's':
 
3101
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
 
3102
      tok->type = TK_CHAR_TYPE;
 
3103
      tok->u.subtype = CTYPE_WHITE_SPACE;
 
3104
      break;
 
3105
 
 
3106
    case 'S':
 
3107
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
 
3108
      tok->type = TK_CHAR_TYPE;
 
3109
      tok->u.subtype = CTYPE_NOT_WHITE_SPACE;
 
3110
      break;
 
3111
 
 
3112
    case 'd':
 
3113
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
 
3114
      tok->type = TK_CHAR_TYPE;
 
3115
      tok->u.subtype = CTYPE_DIGIT;
 
3116
      break;
 
3117
 
 
3118
    case 'D':
 
3119
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
 
3120
      tok->type = TK_CHAR_TYPE;
 
3121
      tok->u.subtype = CTYPE_NOT_DIGIT;
 
3122
      break;
 
3123
 
 
3124
    case 'h':
 
3125
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
 
3126
      tok->type = TK_CHAR_TYPE;
 
3127
      tok->u.subtype = CTYPE_XDIGIT;
 
3128
      break;
 
3129
 
 
3130
    case 'H':
 
3131
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
 
3132
      tok->type = TK_CHAR_TYPE;
 
3133
      tok->u.subtype = CTYPE_NOT_XDIGIT;
 
3134
      break;
 
3135
 
 
3136
    case 'A':
 
3137
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
 
3138
    begin_buf:
 
3139
      tok->type = TK_ANCHOR;
 
3140
      tok->u.subtype = ANCHOR_BEGIN_BUF;
 
3141
      break;
 
3142
 
 
3143
    case 'Z':
 
3144
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
 
3145
      tok->type = TK_ANCHOR;
 
3146
      tok->u.subtype = ANCHOR_SEMI_END_BUF;
 
3147
      break;
 
3148
 
 
3149
    case 'z':
 
3150
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
 
3151
    end_buf:
 
3152
      tok->type = TK_ANCHOR;
 
3153
      tok->u.subtype = ANCHOR_END_BUF;
 
3154
      break;
 
3155
 
 
3156
    case 'G':
 
3157
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR)) break;
 
3158
      tok->type = TK_ANCHOR;
 
3159
      tok->u.subtype = ANCHOR_BEGIN_POSITION;
 
3160
      break;
 
3161
 
 
3162
    case '`':
 
3163
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
 
3164
      goto begin_buf;
 
3165
      break;
 
3166
 
 
3167
    case '\'':
 
3168
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
 
3169
      goto end_buf;
 
3170
      break;
 
3171
 
 
3172
    case 'x':
 
3173
      if (PEND) break;
 
3174
 
 
3175
      prev = p;
 
3176
      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
 
3177
        PINC;
 
3178
        num = scan_unsigned_hexadecimal_number(&p, end, 8, enc);
 
3179
        if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
 
3180
        if (!PEND) {
 
3181
          if (ONIGENC_IS_CODE_XDIGIT(enc, PPEEK))
 
3182
            return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
 
3183
        }
 
3184
 
 
3185
        if ((p > prev + enc_len(enc, prev)) && !PEND && PPEEK_IS('}')) {
 
3186
          PINC;
 
3187
          tok->type   = TK_CODE_POINT;
 
3188
          tok->u.code = (OnigCodePoint )num;
 
3189
        }
 
3190
        else {
 
3191
          /* can't read nothing or invalid format */
 
3192
          p = prev;
 
3193
        }
 
3194
      }
 
3195
      else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
 
3196
        num = scan_unsigned_hexadecimal_number(&p, end, 2, enc);
 
3197
        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
 
3198
        if (p == prev) {  /* can't read nothing. */
 
3199
          num = 0; /* but, it's not error */
 
3200
        }
 
3201
        tok->type = TK_RAW_BYTE;
 
3202
        tok->base = 16;
 
3203
        tok->u.c  = num;
 
3204
      }
 
3205
      break;
 
3206
 
 
3207
    case 'u':
 
3208
      if (PEND) break;
 
3209
 
 
3210
      prev = p;
 
3211
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
 
3212
        num = scan_unsigned_hexadecimal_number(&p, end, 4, enc);
 
3213
        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
 
3214
        if (p == prev) {  /* can't read nothing. */
 
3215
          num = 0; /* but, it's not error */
 
3216
        }
 
3217
        tok->type   = TK_CODE_POINT;
 
3218
        tok->base   = 16;
 
3219
        tok->u.code = (OnigCodePoint )num;
 
3220
      }
 
3221
      break;
 
3222
 
 
3223
    case '1': case '2': case '3': case '4':
 
3224
    case '5': case '6': case '7': case '8': case '9':
 
3225
      PUNFETCH;
 
3226
      prev = p;
 
3227
      num = onig_scan_unsigned_number(&p, end, enc);
 
3228
      if (num < 0 || num > ONIG_MAX_BACKREF_NUM) {
 
3229
        goto skip_backref;
 
3230
      }
 
3231
 
 
3232
      if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_DECIMAL_BACKREF) && 
 
3233
          (num <= env->num_mem || num <= 9)) { /* This spec. from GNU regex */
 
3234
        if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
 
3235
          if (num > env->num_mem || IS_NULL(SCANENV_MEM_NODES(env)[num]))
 
3236
            return ONIGERR_INVALID_BACKREF;
 
3237
        }
 
3238
 
 
3239
        tok->type = TK_BACKREF;
 
3240
        tok->u.backref.num     = 1;
 
3241
        tok->u.backref.ref1    = num;
 
3242
        tok->u.backref.by_name = 0;
 
3243
#ifdef USE_BACKREF_AT_LEVEL
 
3244
        tok->u.backref.exist_level = 0;
 
3245
#endif
 
3246
        break;
 
3247
      }
 
3248
 
 
3249
    skip_backref:
 
3250
      if (c == '8' || c == '9') {
 
3251
        /* normal char */
 
3252
        p = prev; PINC;
 
3253
        break;
 
3254
      }
 
3255
 
 
3256
      p = prev;
 
3257
      /* fall through */
 
3258
    case '0':
 
3259
      if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
 
3260
        prev = p;
 
3261
        num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
 
3262
        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
 
3263
        if (p == prev) {  /* can't read nothing. */
 
3264
          num = 0; /* but, it's not error */
 
3265
        }
 
3266
        tok->type = TK_RAW_BYTE;
 
3267
        tok->base = 8;
 
3268
        tok->u.c  = num;
 
3269
      }
 
3270
      else if (c != '0') {
 
3271
        PINC;
 
3272
      }
 
3273
      break;
 
3274
 
 
3275
#ifdef USE_NAMED_GROUP
 
3276
    case 'k':
 
3277
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) {
 
3278
        PFETCH(c);
 
3279
        if (c == '<') {
 
3280
          UChar* name_end;
 
3281
          int* backs;
 
3282
 
 
3283
          prev = p;
 
3284
 
 
3285
#ifdef USE_BACKREF_AT_LEVEL
 
3286
          name_end = NULL_UCHARP; /* no need. escape gcc warning. */
 
3287
          r = fetch_name_with_level(&p, end, &name_end, env, &tok->u.backref.level);
 
3288
          if (r == 1) tok->u.backref.exist_level = 1;
 
3289
          else        tok->u.backref.exist_level = 0;
 
3290
#else
 
3291
          r = fetch_name(&p, end, &name_end, env, 1);
 
3292
#endif
 
3293
          if (r < 0) return r;
 
3294
 
 
3295
          num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
 
3296
          if (num <= 0) {
 
3297
            onig_scan_env_set_error_string(env,
 
3298
                            ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end);
 
3299
            return ONIGERR_UNDEFINED_NAME_REFERENCE;
 
3300
          }
 
3301
          if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
 
3302
            int i;
 
3303
            for (i = 0; i < num; i++) {
 
3304
              if (backs[i] > env->num_mem ||
 
3305
                  IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
 
3306
                return ONIGERR_INVALID_BACKREF;
 
3307
            }
 
3308
          }
 
3309
 
 
3310
          tok->type = TK_BACKREF;
 
3311
          tok->u.backref.by_name = 1;
 
3312
          if (num == 1) {
 
3313
            tok->u.backref.num  = 1;
 
3314
            tok->u.backref.ref1 = backs[0];
 
3315
          }
 
3316
          else {
 
3317
            tok->u.backref.num  = num;
 
3318
            tok->u.backref.refs = backs;
 
3319
          }
 
3320
        }
 
3321
        else
 
3322
          PUNFETCH;
 
3323
      }
 
3324
      break;
 
3325
#endif
 
3326
 
 
3327
#ifdef USE_SUBEXP_CALL
 
3328
    case 'g':
 
3329
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) {
 
3330
        PFETCH(c);
 
3331
        if (c == '<') {
 
3332
          UChar* name_end;
 
3333
 
 
3334
          prev = p;
 
3335
          r = fetch_name(&p, end, &name_end, env, 1);
 
3336
          if (r < 0) return r;
 
3337
 
 
3338
          tok->type = TK_CALL;
 
3339
          tok->u.call.name     = prev;
 
3340
          tok->u.call.name_end = name_end;
 
3341
        }
 
3342
        else
 
3343
          PUNFETCH;
 
3344
      }
 
3345
      break;
 
3346
#endif
 
3347
 
 
3348
    case 'Q':
 
3349
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE)) {
 
3350
        tok->type = TK_QUOTE_OPEN;
 
3351
      }
 
3352
      break;
 
3353
 
 
3354
    case 'p':
 
3355
    case 'P':
 
3356
      if (PPEEK_IS('{') &&
 
3357
          IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
 
3358
        PINC;
 
3359
        tok->type = TK_CHAR_PROPERTY;
 
3360
        tok->u.prop.not = (c == 'P' ? 1 : 0);
 
3361
 
 
3362
        if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
 
3363
          PFETCH(c);
 
3364
          if (c == '^') {
 
3365
            tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
 
3366
          }
 
3367
          else
 
3368
            PUNFETCH;
 
3369
        }
 
3370
      }
 
3371
      break;
 
3372
 
 
3373
    default:
 
3374
      PUNFETCH;
 
3375
      num = fetch_escaped_value(&p, end, env);
 
3376
      if (num < 0) return num;
 
3377
      /* set_raw: */
 
3378
      if (tok->u.c != num) {
 
3379
        tok->type = TK_CODE_POINT;
 
3380
        tok->u.code = (OnigCodePoint )num;
 
3381
      }
 
3382
      else { /* string */
 
3383
        p = tok->backp + enc_len(enc, tok->backp);
 
3384
      }
 
3385
      break;
 
3386
    }
 
3387
  }
 
3388
  else {
 
3389
    tok->u.c = c;
 
3390
    tok->escaped = 0;
 
3391
 
 
3392
#ifdef USE_VARIABLE_META_CHARS
 
3393
    if ((c != ONIG_INEFFECTIVE_META_CHAR) &&
 
3394
        IS_SYNTAX_OP(syn, ONIG_SYN_OP_VARIABLE_META_CHARACTERS)) {
 
3395
      if (c == MC_ANYCHAR(enc))
 
3396
        goto any_char;
 
3397
      else if (c == MC_ANYTIME(enc))
 
3398
        goto anytime;
 
3399
      else if (c == MC_ZERO_OR_ONE_TIME(enc))
 
3400
        goto zero_or_one_time;
 
3401
      else if (c == MC_ONE_OR_MORE_TIME(enc))
 
3402
        goto one_or_more_time;
 
3403
      else if (c == MC_ANYCHAR_ANYTIME(enc)) {
 
3404
        tok->type = TK_ANYCHAR_ANYTIME;
 
3405
        goto out;
 
3406
      }
 
3407
    }
 
3408
#endif
 
3409
 
 
3410
    switch (c) {
 
3411
    case '.':
 
3412
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_DOT_ANYCHAR)) break;
 
3413
#ifdef USE_VARIABLE_META_CHARS
 
3414
    any_char:
 
3415
#endif
 
3416
      tok->type = TK_ANYCHAR;
 
3417
      break;
 
3418
 
 
3419
    case '*':
 
3420
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ASTERISK_ZERO_INF)) break;
 
3421
#ifdef USE_VARIABLE_META_CHARS
 
3422
    anytime:
 
3423
#endif
 
3424
      tok->type = TK_OP_REPEAT;
 
3425
      tok->u.repeat.lower = 0;
 
3426
      tok->u.repeat.upper = REPEAT_INFINITE;
 
3427
      goto greedy_check;
 
3428
      break;
 
3429
 
 
3430
    case '+':
 
3431
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_PLUS_ONE_INF)) break;
 
3432
#ifdef USE_VARIABLE_META_CHARS
 
3433
    one_or_more_time:
 
3434
#endif
 
3435
      tok->type = TK_OP_REPEAT;
 
3436
      tok->u.repeat.lower = 1;
 
3437
      tok->u.repeat.upper = REPEAT_INFINITE;
 
3438
      goto greedy_check;
 
3439
      break;
 
3440
 
 
3441
    case '?':
 
3442
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_ZERO_ONE)) break;
 
3443
#ifdef USE_VARIABLE_META_CHARS
 
3444
    zero_or_one_time:
 
3445
#endif
 
3446
      tok->type = TK_OP_REPEAT;
 
3447
      tok->u.repeat.lower = 0;
 
3448
      tok->u.repeat.upper = 1;
 
3449
      goto greedy_check;
 
3450
      break;
 
3451
 
 
3452
    case '{':
 
3453
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACE_INTERVAL)) break;
 
3454
      r = fetch_range_quantifier(&p, end, tok, env);
 
3455
      if (r < 0) return r;  /* error */
 
3456
      if (r == 0) goto greedy_check;
 
3457
      else if (r == 2) { /* {n} */
 
3458
        if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
 
3459
          goto possessive_check;
 
3460
 
 
3461
        goto greedy_check;
 
3462
      }
 
3463
      /* r == 1 : normal char */
 
3464
      break;
 
3465
 
 
3466
    case '|':
 
3467
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_VBAR_ALT)) break;
 
3468
      tok->type = TK_ALT;
 
3469
      break;
 
3470
 
 
3471
    case '(':
 
3472
      if (PPEEK_IS('?') &&
 
3473
          IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
 
3474
        PINC;
 
3475
        if (PPEEK_IS('#')) {
 
3476
          PFETCH(c);
 
3477
          while (1) {
 
3478
            if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
 
3479
            PFETCH(c);
 
3480
            if (c == MC_ESC(enc)) {
 
3481
              if (!PEND) PFETCH(c);
 
3482
            }
 
3483
            else {
 
3484
              if (c == ')') break;
 
3485
            }
 
3486
          }
 
3487
          goto start;
 
3488
        }
 
3489
        PUNFETCH;
 
3490
      }
 
3491
 
 
3492
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
 
3493
      tok->type = TK_SUBEXP_OPEN;
 
3494
      break;
 
3495
 
 
3496
    case ')':
 
3497
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
 
3498
      tok->type = TK_SUBEXP_CLOSE;
 
3499
      break;
 
3500
 
 
3501
    case '^':
 
3502
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
 
3503
      tok->type = TK_ANCHOR;
 
3504
      tok->u.subtype = (IS_SINGLELINE(env->option)
 
3505
                        ? ANCHOR_BEGIN_BUF : ANCHOR_BEGIN_LINE);
 
3506
      break;
 
3507
 
 
3508
    case '$':
 
3509
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
 
3510
      tok->type = TK_ANCHOR;
 
3511
      tok->u.subtype = (IS_SINGLELINE(env->option)
 
3512
                        ? ANCHOR_SEMI_END_BUF : ANCHOR_END_LINE);
 
3513
      break;
 
3514
 
 
3515
    case '[':
 
3516
      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACKET_CC)) break;
 
3517
      tok->type = TK_CC_OPEN;
 
3518
      break;
 
3519
 
 
3520
    case ']':
 
3521
      if (*src > env->pattern)   /* /].../ is allowed. */
 
3522
        CCEND_ESC_WARN(env, (UChar* )"]");
 
3523
      break;
 
3524
 
 
3525
    case '#':
 
3526
      if (IS_EXTEND(env->option)) {
 
3527
        while (!PEND) {
 
3528
          PFETCH(c);
 
3529
          if (ONIGENC_IS_CODE_NEWLINE(enc, c))
 
3530
            break;
 
3531
        }
 
3532
        goto start;
 
3533
        break;
 
3534
      }
 
3535
      break;
 
3536
 
 
3537
    case ' ': case '\t': case '\n': case '\r': case '\f':
 
3538
      if (IS_EXTEND(env->option))
 
3539
        goto start;
 
3540
      break;
 
3541
 
 
3542
    default:
 
3543
      /* string */
 
3544
      break;
 
3545
    }
 
3546
  }
 
3547
 
 
3548
#ifdef USE_VARIABLE_META_CHARS
 
3549
 out:
 
3550
#endif
 
3551
  *src = p;
 
3552
  return tok->type;
 
3553
}
 
3554
 
 
3555
static int
 
3556
add_ctype_to_cc_by_range(CClassNode* cc, int ctype, int not, OnigEncoding enc,
 
3557
                         const OnigCodePoint sbr[], const OnigCodePoint mbr[])
 
3558
{
 
3559
  int i, r;
 
3560
  OnigCodePoint j;
 
3561
 
 
3562
  int nsb = ONIGENC_CODE_RANGE_NUM(sbr);
 
3563
  int nmb = ONIGENC_CODE_RANGE_NUM(mbr);
 
3564
 
 
3565
  if (not == 0) {
 
3566
    for (i = 0; i < nsb; i++) {
 
3567
      for (j  = ONIGENC_CODE_RANGE_FROM(sbr, i);
 
3568
           j <= ONIGENC_CODE_RANGE_TO(sbr, i); j++) {
 
3569
        BITSET_SET_BIT(cc->bs, j);
 
3570
      }
 
3571
    }
 
3572
 
 
3573
    for (i = 0; i < nmb; i++) {
 
3574
      r = add_code_range_to_buf(&(cc->mbuf),
 
3575
                                ONIGENC_CODE_RANGE_FROM(mbr, i),
 
3576
                                ONIGENC_CODE_RANGE_TO(mbr, i));
 
3577
      if (r != 0) return r;
 
3578
    }
 
3579
  }
 
3580
  else {
 
3581
    OnigCodePoint prev = 0;
 
3582
 
 
3583
    if (ONIGENC_MBC_MINLEN(enc) == 1) {
 
3584
      for (i = 0; i < nsb; i++) {
 
3585
        for (j = prev;
 
3586
             j < ONIGENC_CODE_RANGE_FROM(sbr, i); j++) {
 
3587
          BITSET_SET_BIT(cc->bs, j);
 
3588
        }
 
3589
        prev = ONIGENC_CODE_RANGE_TO(sbr, i) + 1;
 
3590
      }
 
3591
      if (prev < 0x7f) {
 
3592
        for (j = prev; j < 0x7f; j++) {
 
3593
          BITSET_SET_BIT(cc->bs, j);
 
3594
        }
 
3595
      }
 
3596
 
 
3597
      prev = 0x80;
 
3598
    }
 
3599
 
 
3600
    for (i = 0; i < nmb; i++) {
 
3601
      if (prev < ONIGENC_CODE_RANGE_FROM(mbr, i)) {
 
3602
        r = add_code_range_to_buf(&(cc->mbuf), prev,
 
3603
                                  ONIGENC_CODE_RANGE_FROM(mbr, i) - 1);
 
3604
        if (r != 0) return r;
 
3605
      }
 
3606
      prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
 
3607
    }
 
3608
    if (prev < 0x7fffffff) {
 
3609
      r = add_code_range_to_buf(&(cc->mbuf), prev, 0x7fffffff);
 
3610
      if (r != 0) return r;
 
3611
    }
 
3612
  }
 
3613
 
 
3614
  return 0;
 
3615
}
 
3616
 
 
3617
static int
 
3618
add_ctype_to_cc(CClassNode* cc, int ctype, int not, ScanEnv* env)
 
3619
{
 
3620
  int c, r;
 
3621
  const OnigCodePoint *sbr, *mbr;
 
3622
  OnigEncoding enc = env->enc;
 
3623
 
 
3624
  r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sbr, &mbr);
 
3625
  if (r == 0) {
 
3626
    return add_ctype_to_cc_by_range(cc, ctype, not, env->enc, sbr, mbr);
 
3627
  }
 
3628
  else if (r != ONIG_NO_SUPPORT_CONFIG) {
 
3629
    return r;
 
3630
  }
 
3631
 
 
3632
  r = 0;
 
3633
  switch (ctype) {
 
3634
  case ONIGENC_CTYPE_ALPHA:
 
3635
  case ONIGENC_CTYPE_BLANK:
 
3636
  case ONIGENC_CTYPE_CNTRL:
 
3637
  case ONIGENC_CTYPE_DIGIT:
 
3638
  case ONIGENC_CTYPE_LOWER:
 
3639
  case ONIGENC_CTYPE_PUNCT:
 
3640
  case ONIGENC_CTYPE_SPACE:
 
3641
  case ONIGENC_CTYPE_UPPER:
 
3642
  case ONIGENC_CTYPE_XDIGIT:
 
3643
  case ONIGENC_CTYPE_ASCII:
 
3644
  case ONIGENC_CTYPE_ALNUM:
 
3645
    if (not != 0) {
 
3646
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
 
3647
        if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
 
3648
          BITSET_SET_BIT(cc->bs, c);
 
3649
      }
 
3650
      ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
 
3651
    }
 
3652
    else {
 
3653
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
 
3654
        if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
 
3655
          BITSET_SET_BIT(cc->bs, c);
 
3656
      }
 
3657
    }
 
3658
    break;
 
3659
 
 
3660
  case ONIGENC_CTYPE_GRAPH:
 
3661
  case ONIGENC_CTYPE_PRINT:
 
3662
    if (not != 0) {
 
3663
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
 
3664
        if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
 
3665
          BITSET_SET_BIT(cc->bs, c);
 
3666
      }
 
3667
    }
 
3668
    else {
 
3669
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
 
3670
        if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
 
3671
          BITSET_SET_BIT(cc->bs, c);
 
3672
      }
 
3673
      ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
 
3674
    }
 
3675
    break;
 
3676
 
 
3677
  case ONIGENC_CTYPE_WORD:
 
3678
    if (not == 0) {
 
3679
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
 
3680
        if (ONIGENC_IS_CODE_SB_WORD(enc, c)) BITSET_SET_BIT(cc->bs, c);
 
3681
      }
 
3682
      ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
 
3683
    }
 
3684
    else {
 
3685
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
 
3686
        if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0)  /* 0: invalid code point */
 
3687
            && ! ONIGENC_IS_CODE_WORD(enc, c))
 
3688
          BITSET_SET_BIT(cc->bs, c);
 
3689
      }
 
3690
    }
 
3691
    break;
 
3692
 
 
3693
  default:
 
3694
    return ONIGERR_PARSER_BUG;
 
3695
    break;
 
3696
  }
 
3697
 
 
3698
  return r;
 
3699
}
 
3700
 
 
3701
static int
 
3702
parse_ctype_to_enc_ctype(int pctype, int* not)
 
3703
{
 
3704
  int ctype;
 
3705
 
 
3706
  switch (pctype) {
 
3707
  case CTYPE_WORD:
 
3708
    ctype = ONIGENC_CTYPE_WORD;
 
3709
    *not = 0;
 
3710
    break;
 
3711
  case CTYPE_NOT_WORD:
 
3712
    ctype = ONIGENC_CTYPE_WORD;
 
3713
    *not = 1;
 
3714
    break;
 
3715
  case CTYPE_WHITE_SPACE:
 
3716
    ctype = ONIGENC_CTYPE_SPACE;
 
3717
    *not = 0;
 
3718
    break;
 
3719
  case CTYPE_NOT_WHITE_SPACE:
 
3720
    ctype = ONIGENC_CTYPE_SPACE;
 
3721
    *not = 1;
 
3722
    break;
 
3723
  case CTYPE_DIGIT:
 
3724
    ctype = ONIGENC_CTYPE_DIGIT;
 
3725
    *not = 0;
 
3726
    break;
 
3727
  case CTYPE_NOT_DIGIT:
 
3728
    ctype = ONIGENC_CTYPE_DIGIT;
 
3729
    *not = 1;
 
3730
    break;
 
3731
  case CTYPE_XDIGIT:
 
3732
    ctype = ONIGENC_CTYPE_XDIGIT;
 
3733
    *not = 0;
 
3734
    break;
 
3735
  case CTYPE_NOT_XDIGIT:
 
3736
    ctype = ONIGENC_CTYPE_XDIGIT;
 
3737
    *not = 1;
 
3738
    break;
 
3739
  default:
 
3740
    return ONIGERR_PARSER_BUG;
 
3741
    break;
 
3742
  }
 
3743
  return ctype;
 
3744
}
 
3745
 
 
3746
typedef struct {
 
3747
  UChar    *name;
 
3748
  int       ctype;
 
3749
  short int len;
 
3750
} PosixBracketEntryType;
 
3751
 
 
3752
static int
 
3753
parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env)
 
3754
{
 
3755
#define POSIX_BRACKET_CHECK_LIMIT_LENGTH  20
 
3756
#define POSIX_BRACKET_NAME_MAX_LEN         6
 
3757
 
 
3758
  static PosixBracketEntryType PBS[] = {
 
3759
    { (UChar* )"alnum",  ONIGENC_CTYPE_ALNUM,  5 },
 
3760
    { (UChar* )"alpha",  ONIGENC_CTYPE_ALPHA,  5 },
 
3761
    { (UChar* )"blank",  ONIGENC_CTYPE_BLANK,  5 },
 
3762
    { (UChar* )"cntrl",  ONIGENC_CTYPE_CNTRL,  5 },
 
3763
    { (UChar* )"digit",  ONIGENC_CTYPE_DIGIT,  5 },
 
3764
    { (UChar* )"graph",  ONIGENC_CTYPE_GRAPH,  5 },
 
3765
    { (UChar* )"lower",  ONIGENC_CTYPE_LOWER,  5 },
 
3766
    { (UChar* )"print",  ONIGENC_CTYPE_PRINT,  5 },
 
3767
    { (UChar* )"punct",  ONIGENC_CTYPE_PUNCT,  5 },
 
3768
    { (UChar* )"space",  ONIGENC_CTYPE_SPACE,  5 },
 
3769
    { (UChar* )"upper",  ONIGENC_CTYPE_UPPER,  5 },
 
3770
    { (UChar* )"xdigit", ONIGENC_CTYPE_XDIGIT, 6 },
 
3771
    { (UChar* )"ascii",  ONIGENC_CTYPE_ASCII,  5 },
 
3772
    { (UChar* )NULL, -1, 0 }
 
3773
  };
 
3774
 
 
3775
  PosixBracketEntryType *pb;
 
3776
  int not, i, r;
 
3777
  OnigCodePoint c;
 
3778
  OnigEncoding enc = env->enc;
 
3779
  UChar *p = *src;
 
3780
  PFETCH_READY;
 
3781
 
 
3782
  if (PPEEK_IS('^')) {
 
3783
    PINC;
 
3784
    not = 1;
 
3785
  }
 
3786
  else
 
3787
    not = 0;
 
3788
 
 
3789
  if (onigenc_strlen(enc, p, end) < POSIX_BRACKET_NAME_MAX_LEN + 2)
 
3790
    goto not_posix_bracket;
 
3791
 
 
3792
  for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
 
3793
    if (onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0) {
 
3794
      p = (UChar* )onigenc_step(enc, p, end, pb->len);
 
3795
      if (onigenc_with_ascii_strncmp(enc, p, end, (UChar* )":]", 2) != 0)
 
3796
        return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
 
3797
 
 
3798
      r = add_ctype_to_cc(cc, pb->ctype, not, env);
 
3799
      if (r != 0) return r;
 
3800
 
 
3801
      PINC; PINC;
 
3802
      *src = p;
 
3803
      return 0;
 
3804
    }
 
3805
  }
 
3806
 
 
3807
 not_posix_bracket:
 
3808
  c = 0;
 
3809
  i = 0;
 
3810
  while (!PEND && ((c = PPEEK) != ':') && c != ']') {
 
3811
    PINC;
 
3812
    if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
 
3813
  }
 
3814
  if (c == ':' && ! PEND) {
 
3815
    PINC;
 
3816
    if (! PEND) {
 
3817
      PFETCH(c);
 
3818
      if (c == ']')
 
3819
        return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
 
3820
    }
 
3821
  }
 
3822
 
 
3823
  return 1;   /* 1: is not POSIX bracket, but no error. */
 
3824
}
 
3825
 
 
3826
static int
 
3827
property_name_to_ctype(UChar* p, UChar* end, OnigEncoding enc)
 
3828
{
 
3829
  static PosixBracketEntryType PBS[] = {
 
3830
    { (UChar* )"Alnum",  ONIGENC_CTYPE_ALNUM,  5 },
 
3831
    { (UChar* )"Alpha",  ONIGENC_CTYPE_ALPHA,  5 },
 
3832
    { (UChar* )"Blank",  ONIGENC_CTYPE_BLANK,  5 },
 
3833
    { (UChar* )"Cntrl",  ONIGENC_CTYPE_CNTRL,  5 },
 
3834
    { (UChar* )"Digit",  ONIGENC_CTYPE_DIGIT,  5 },
 
3835
    { (UChar* )"Graph",  ONIGENC_CTYPE_GRAPH,  5 },
 
3836
    { (UChar* )"Lower",  ONIGENC_CTYPE_LOWER,  5 },
 
3837
    { (UChar* )"Print",  ONIGENC_CTYPE_PRINT,  5 },
 
3838
    { (UChar* )"Punct",  ONIGENC_CTYPE_PUNCT,  5 },
 
3839
    { (UChar* )"Space",  ONIGENC_CTYPE_SPACE,  5 },
 
3840
    { (UChar* )"Upper",  ONIGENC_CTYPE_UPPER,  5 },
 
3841
    { (UChar* )"XDigit", ONIGENC_CTYPE_XDIGIT, 6 },
 
3842
    { (UChar* )"ASCII",  ONIGENC_CTYPE_ASCII,  5 },
 
3843
    { (UChar* )NULL, -1, 0 }
 
3844
  };
 
3845
 
 
3846
  PosixBracketEntryType *pb;
 
3847
  int len;
 
3848
 
 
3849
  len = onigenc_strlen(enc, p, end);
 
3850
  for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
 
3851
    if (len == pb->len &&
 
3852
        onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0)
 
3853
      return pb->ctype;
 
3854
  }
 
3855
 
 
3856
  return -1;
 
3857
}
 
3858
 
 
3859
static int
 
3860
fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env)
 
3861
{
 
3862
  int ctype;
 
3863
  OnigCodePoint c;
 
3864
  OnigEncoding enc = env->enc;
 
3865
  UChar *prev, *start, *p = *src;
 
3866
  PFETCH_READY;
 
3867
 
 
3868
  /* 'IsXXXX' => 'XXXX' */
 
3869
  if (!PEND &&
 
3870
      IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS)) {
 
3871
    c = PPEEK;
 
3872
    if (c == 'I') {
 
3873
      PINC;
 
3874
      if (! PEND) {
 
3875
        c = PPEEK;
 
3876
        if (c == 's')
 
3877
          PINC;
 
3878
        else
 
3879
          PUNFETCH;
 
3880
      }
 
3881
    }
 
3882
  }
 
3883
 
 
3884
  start = prev = p;
 
3885
 
 
3886
  while (!PEND) {
 
3887
    prev = p;
 
3888
    PFETCH(c);
 
3889
    if (c == '}') {
 
3890
      ctype = property_name_to_ctype(start, prev, enc);
 
3891
      if (ctype < 0) break;
 
3892
 
 
3893
      *src = p;
 
3894
      return ctype;
 
3895
    }
 
3896
    else if (c == '(' || c == ')' || c == '{' || c == '|')
 
3897
      break;
 
3898
  }
 
3899
 
 
3900
  onig_scan_env_set_error_string(env, ONIGERR_INVALID_CHAR_PROPERTY_NAME,
 
3901
                                 *src, prev);
 
3902
  return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
 
3903
}
 
3904
 
 
3905
static int
 
3906
parse_char_property(Node** np, OnigToken* tok, UChar** src, UChar* end,
 
3907
                    ScanEnv* env)
 
3908
{
 
3909
  int r, ctype;
 
3910
  CClassNode* cc;
 
3911
 
 
3912
  ctype = fetch_char_property_to_ctype(src, end, env);
 
3913
  if (ctype < 0) return ctype;
 
3914
 
 
3915
  *np = node_new_cclass();
 
3916
  CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
3917
  cc = &(NCCLASS(*np));
 
3918
  r = add_ctype_to_cc(cc, ctype, 0, env);
 
3919
  if (r != 0) return r;
 
3920
  if (tok->u.prop.not != 0) CCLASS_SET_NOT(cc);
 
3921
 
 
3922
  return 0;
 
3923
}
 
3924
 
 
3925
 
 
3926
enum CCSTATE {
 
3927
  CCS_VALUE,
 
3928
  CCS_RANGE,
 
3929
  CCS_COMPLETE,
 
3930
  CCS_START
 
3931
};
 
3932
 
 
3933
enum CCVALTYPE {
 
3934
  CCV_SB,
 
3935
  CCV_CODE_POINT,
 
3936
  CCV_CLASS
 
3937
};
 
3938
 
 
3939
static int
 
3940
next_state_class(CClassNode* cc, OnigCodePoint* vs, enum CCVALTYPE* type,
 
3941
                 enum CCSTATE* state, ScanEnv* env)
 
3942
{
 
3943
  int r;
 
3944
 
 
3945
  if (*state == CCS_RANGE)
 
3946
    return ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE;
 
3947
 
 
3948
  if (*state == CCS_VALUE && *type != CCV_CLASS) {
 
3949
    if (*type == CCV_SB)
 
3950
      BITSET_SET_BIT(cc->bs, (int )(*vs));
 
3951
    else if (*type == CCV_CODE_POINT) {
 
3952
      r = add_code_range(&(cc->mbuf), env, *vs, *vs);
 
3953
      if (r < 0) return r;
 
3954
    }
 
3955
  }
 
3956
 
 
3957
  *state = CCS_VALUE;
 
3958
  *type  = CCV_CLASS;
 
3959
  return 0;
 
3960
}
 
3961
 
 
3962
static int
 
3963
next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v,
 
3964
               int* vs_israw, int v_israw,
 
3965
               enum CCVALTYPE intype, enum CCVALTYPE* type,
 
3966
               enum CCSTATE* state, ScanEnv* env)
 
3967
{
 
3968
  int r;
 
3969
 
 
3970
  switch (*state) {
 
3971
  case CCS_VALUE:
 
3972
    if (*type == CCV_SB)
 
3973
      BITSET_SET_BIT(cc->bs, (int )(*vs));
 
3974
    else if (*type == CCV_CODE_POINT) {
 
3975
      r = add_code_range(&(cc->mbuf), env, *vs, *vs);
 
3976
      if (r < 0) return r;
 
3977
    }
 
3978
    break;
 
3979
 
 
3980
  case CCS_RANGE:
 
3981
    if (intype == *type) {
 
3982
      if (intype == CCV_SB) {
 
3983
        if (*vs > 0xff || v > 0xff)
 
3984
          return ONIGERR_INVALID_WIDE_CHAR_VALUE;
 
3985
 
 
3986
        if (*vs > v) {
 
3987
          if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
 
3988
            goto ccs_range_end;
 
3989
          else
 
3990
            return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
 
3991
        }
 
3992
        bitset_set_range(cc->bs, (int )*vs, (int )v);
 
3993
      }
 
3994
      else {
 
3995
        r = add_code_range(&(cc->mbuf), env, *vs, v);
 
3996
        if (r < 0) return r;
 
3997
      }
 
3998
    }
 
3999
    else {
 
4000
#if 0
 
4001
      if (intype == CCV_CODE_POINT && *type == CCV_SB) {
 
4002
#endif
 
4003
        if (*vs > v) {
 
4004
          if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
 
4005
            goto ccs_range_end;
 
4006
          else
 
4007
            return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
 
4008
        }
 
4009
        bitset_set_range(cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
 
4010
        r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*vs, v);
 
4011
        if (r < 0) return r;
 
4012
#if 0
 
4013
      }
 
4014
      else
 
4015
        return ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE;
 
4016
#endif
 
4017
    }
 
4018
  ccs_range_end:
 
4019
    *state = CCS_COMPLETE;
 
4020
    break;
 
4021
 
 
4022
  case CCS_COMPLETE:
 
4023
  case CCS_START:
 
4024
    *state = CCS_VALUE;
 
4025
    break;
 
4026
 
 
4027
  default:
 
4028
    break;
 
4029
  }
 
4030
 
 
4031
  *vs_israw = v_israw;
 
4032
  *vs       = v;
 
4033
  *type     = intype;
 
4034
  return 0;
 
4035
}
 
4036
 
 
4037
static int
 
4038
code_exist_check(OnigCodePoint c, UChar* from, UChar* end, int ignore_escaped,
 
4039
                 OnigEncoding enc)
 
4040
{
 
4041
  int in_esc;
 
4042
  OnigCodePoint code;
 
4043
  UChar* p = from;
 
4044
  PFETCH_READY;
 
4045
 
 
4046
  in_esc = 0;
 
4047
  while (! PEND) {
 
4048
    if (ignore_escaped && in_esc) {
 
4049
      in_esc = 0;
 
4050
    }
 
4051
    else {
 
4052
      PFETCH(code);
 
4053
      if (code == c) return 1;
 
4054
      if (code == MC_ESC(enc)) in_esc = 1;
 
4055
    }
 
4056
  }
 
4057
  return 0;
 
4058
}
 
4059
 
 
4060
static int
 
4061
parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
 
4062
                 ScanEnv* env)
 
4063
{
 
4064
  int r, neg, len, fetched, and_start;
 
4065
  OnigCodePoint v, vs;
 
4066
  UChar *p;
 
4067
  Node* node;
 
4068
  CClassNode *cc, *prev_cc;
 
4069
  CClassNode work_cc;
 
4070
 
 
4071
  enum CCSTATE state;
 
4072
  enum CCVALTYPE val_type, in_type;
 
4073
  int val_israw, in_israw;
 
4074
 
 
4075
  prev_cc = (CClassNode* )NULL;
 
4076
  *np = NULL_NODE;
 
4077
  r = fetch_token_in_cc(tok, src, end, env);
 
4078
  if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) {
 
4079
    neg = 1;
 
4080
    r = fetch_token_in_cc(tok, src, end, env);
 
4081
  }
 
4082
  else {
 
4083
    neg = 0;
 
4084
  }
 
4085
 
 
4086
  if (r < 0) return r;
 
4087
  if (r == TK_CC_CLOSE) {
 
4088
    if (! code_exist_check((OnigCodePoint )']',
 
4089
                           *src, env->pattern_end, 1, env->enc))
 
4090
      return ONIGERR_EMPTY_CHAR_CLASS;
 
4091
 
 
4092
    CC_ESC_WARN(env, (UChar* )"]");
 
4093
    r = tok->type = TK_CHAR;  /* allow []...] */
 
4094
  }
 
4095
 
 
4096
  *np = node = node_new_cclass();
 
4097
  CHECK_NULL_RETURN_VAL(node, ONIGERR_MEMORY);
 
4098
  cc = &(NCCLASS(node));
 
4099
 
 
4100
  and_start = 0;
 
4101
  state = CCS_START;
 
4102
  p = *src;
 
4103
  while (r != TK_CC_CLOSE) {
 
4104
    fetched = 0;
 
4105
    switch (r) {
 
4106
    case TK_CHAR:
 
4107
      len = ONIGENC_CODE_TO_MBCLEN(env->enc, tok->u.c);
 
4108
      if (len > 1) {
 
4109
        in_type = CCV_CODE_POINT;
 
4110
      }
 
4111
      else {
 
4112
      sb_char:
 
4113
        in_type = CCV_SB;
 
4114
      }
 
4115
      v = (OnigCodePoint )tok->u.c;
 
4116
      in_israw = 0;
 
4117
      goto val_entry2;
 
4118
      break;
 
4119
 
 
4120
    case TK_RAW_BYTE:
 
4121
      /* tok->base != 0 : octal or hexadec. */
 
4122
      if (! ONIGENC_IS_SINGLEBYTE(env->enc) && tok->base != 0) {
 
4123
        UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
 
4124
        UChar* bufe = buf + ONIGENC_CODE_TO_MBC_MAXLEN;
 
4125
        UChar* psave = p;
 
4126
        int i, base = tok->base;
 
4127
 
 
4128
        buf[0] = tok->u.c;
 
4129
        for (i = 1; i < ONIGENC_MBC_MAXLEN(env->enc); i++) {
 
4130
          r = fetch_token_in_cc(tok, &p, end, env);
 
4131
          if (r < 0) goto err;
 
4132
          if (r != TK_RAW_BYTE || tok->base != base) {
 
4133
            fetched = 1;
 
4134
            break;
 
4135
          }
 
4136
          buf[i] = tok->u.c;
 
4137
        }
 
4138
 
 
4139
        if (i < ONIGENC_MBC_MINLEN(env->enc)) {
 
4140
          r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
 
4141
          goto err;
 
4142
        }
 
4143
 
 
4144
        len = enc_len(env->enc, buf);
 
4145
        if (i < len) {
 
4146
          r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
 
4147
          goto err;
 
4148
        }
 
4149
        else if (i > len) { /* fetch back */
 
4150
          p = psave;
 
4151
          for (i = 1; i < len; i++) {
 
4152
            r = fetch_token_in_cc(tok, &p, end, env);
 
4153
          }
 
4154
          fetched = 0;
 
4155
        }
 
4156
 
 
4157
        if (i == 1) {
 
4158
          v = (OnigCodePoint )buf[0];
 
4159
          goto raw_single;
 
4160
        }
 
4161
        else {
 
4162
          v = ONIGENC_MBC_TO_CODE(env->enc, buf, bufe);
 
4163
          in_type = CCV_CODE_POINT;
 
4164
        }
 
4165
      }
 
4166
      else {
 
4167
        v = (OnigCodePoint )tok->u.c;
 
4168
      raw_single:
 
4169
        in_type = CCV_SB;
 
4170
      }
 
4171
      in_israw = 1;
 
4172
      goto val_entry2;
 
4173
      break;
 
4174
 
 
4175
    case TK_CODE_POINT:
 
4176
      v = tok->u.code;
 
4177
      in_israw = 1;
 
4178
    val_entry:
 
4179
      len = ONIGENC_CODE_TO_MBCLEN(env->enc, v);
 
4180
      if (len < 0) {
 
4181
        r = len;
 
4182
        goto err;
 
4183
      }
 
4184
      in_type = (len == 1 ? CCV_SB : CCV_CODE_POINT);
 
4185
    val_entry2:
 
4186
      r = next_state_val(cc, &vs, v, &val_israw, in_israw, in_type, &val_type,
 
4187
                         &state, env);
 
4188
      if (r != 0) goto err;
 
4189
      break;
 
4190
 
 
4191
    case TK_POSIX_BRACKET_OPEN:
 
4192
      r = parse_posix_bracket(cc, &p, end, env);
 
4193
      if (r < 0) goto err;
 
4194
      if (r == 1) {  /* is not POSIX bracket */
 
4195
        CC_ESC_WARN(env, (UChar* )"[");
 
4196
        p = tok->backp;
 
4197
        v = (OnigCodePoint )tok->u.c;
 
4198
        in_israw = 0;
 
4199
        goto val_entry;
 
4200
      }
 
4201
      goto next_class;
 
4202
      break;
 
4203
 
 
4204
    case TK_CHAR_TYPE:
 
4205
      {
 
4206
        int ctype, not;
 
4207
        ctype = parse_ctype_to_enc_ctype(tok->u.subtype, &not);
 
4208
        r = add_ctype_to_cc(cc, ctype, not, env);
 
4209
        if (r != 0) return r;
 
4210
      }
 
4211
 
 
4212
    next_class:
 
4213
      r = next_state_class(cc, &vs, &val_type, &state, env);
 
4214
      if (r != 0) goto err;
 
4215
      break;
 
4216
 
 
4217
    case TK_CHAR_PROPERTY:
 
4218
      {
 
4219
        int ctype;
 
4220
 
 
4221
        ctype = fetch_char_property_to_ctype(&p, end, env);
 
4222
        if (ctype < 0) return ctype;
 
4223
        r = add_ctype_to_cc(cc, ctype, tok->u.prop.not, env);
 
4224
        if (r != 0) return r;
 
4225
        goto next_class;
 
4226
      }
 
4227
      break;
 
4228
 
 
4229
    case TK_CC_RANGE:
 
4230
      if (state == CCS_VALUE) {
 
4231
        r = fetch_token_in_cc(tok, &p, end, env);
 
4232
        if (r < 0) goto err;
 
4233
        fetched = 1;
 
4234
        if (r == TK_CC_CLOSE) { /* allow [x-] */
 
4235
        range_end_val:
 
4236
          v = (OnigCodePoint )'-';
 
4237
          in_israw = 0;
 
4238
          goto val_entry;
 
4239
        }
 
4240
        else if (r == TK_CC_AND) {
 
4241
          CC_ESC_WARN(env, (UChar* )"-");
 
4242
          goto range_end_val;
 
4243
        }
 
4244
        state = CCS_RANGE;
 
4245
      }
 
4246
      else if (state == CCS_START) {
 
4247
        /* [-xa] is allowed */
 
4248
        v = (OnigCodePoint )tok->u.c;
 
4249
        in_israw = 0;
 
4250
 
 
4251
        r = fetch_token_in_cc(tok, &p, end, env);
 
4252
        if (r < 0) goto err;
 
4253
        fetched = 1;
 
4254
        /* [--x] or [a&&-x] is warned. */
 
4255
        if (r == TK_CC_RANGE || and_start != 0)
 
4256
          CC_ESC_WARN(env, (UChar* )"-");
 
4257
 
 
4258
        goto val_entry;
 
4259
      }
 
4260
      else if (state == CCS_RANGE) {
 
4261
        CC_ESC_WARN(env, (UChar* )"-");
 
4262
        goto sb_char;  /* [!--x] is allowed */
 
4263
      }
 
4264
      else { /* CCS_COMPLETE */
 
4265
        r = fetch_token_in_cc(tok, &p, end, env);
 
4266
        if (r < 0) goto err;
 
4267
        fetched = 1;
 
4268
        if (r == TK_CC_CLOSE) goto range_end_val; /* allow [a-b-] */
 
4269
        else if (r == TK_CC_AND) {
 
4270
          CC_ESC_WARN(env, (UChar* )"-");
 
4271
          goto range_end_val;
 
4272
        }
 
4273
        
 
4274
        if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC)) {
 
4275
          CC_ESC_WARN(env, (UChar* )"-");
 
4276
          goto sb_char;   /* [0-9-a] is allowed as [0-9\-a] */
 
4277
        }
 
4278
        r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS;
 
4279
        goto err;
 
4280
      }
 
4281
      break;
 
4282
 
 
4283
    case TK_CC_CC_OPEN: /* [ */
 
4284
      {
 
4285
        Node *anode;
 
4286
        CClassNode* acc;
 
4287
 
 
4288
        r = parse_char_class(&anode, tok, &p, end, env);
 
4289
        if (r != 0) goto cc_open_err;
 
4290
        acc = &(NCCLASS(anode));
 
4291
        r = or_cclass(cc, acc, env->enc);
 
4292
 
 
4293
        onig_node_free(anode);
 
4294
      cc_open_err:
 
4295
        if (r != 0) goto err;
 
4296
      }
 
4297
      break;
 
4298
 
 
4299
    case TK_CC_AND: /* && */
 
4300
      {
 
4301
        if (state == CCS_VALUE) {
 
4302
          r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type,
 
4303
                             &val_type, &state, env);
 
4304
          if (r != 0) goto err;
 
4305
        }
 
4306
        /* initialize local variables */
 
4307
        and_start = 1;
 
4308
        state = CCS_START;
 
4309
 
 
4310
        if (IS_NOT_NULL(prev_cc)) {
 
4311
          r = and_cclass(prev_cc, cc, env->enc);
 
4312
          if (r != 0) goto err;
 
4313
          bbuf_free(cc->mbuf);
 
4314
        }
 
4315
        else {
 
4316
          prev_cc = cc;
 
4317
          cc = &work_cc;
 
4318
        }
 
4319
        initialize_cclass(cc);
 
4320
      }
 
4321
      break;
 
4322
 
 
4323
    case TK_EOT:
 
4324
      r = ONIGERR_PREMATURE_END_OF_CHAR_CLASS;
 
4325
      goto err;
 
4326
      break;
 
4327
    default:
 
4328
      r = ONIGERR_PARSER_BUG;
 
4329
      goto err;
 
4330
      break;
 
4331
    }
 
4332
 
 
4333
    if (fetched)
 
4334
      r = tok->type;
 
4335
    else {
 
4336
      r = fetch_token_in_cc(tok, &p, end, env);
 
4337
      if (r < 0) goto err;
 
4338
    }
 
4339
  }
 
4340
 
 
4341
  if (state == CCS_VALUE) {
 
4342
    r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type,
 
4343
                       &val_type, &state, env);
 
4344
    if (r != 0) goto err;
 
4345
  }
 
4346
 
 
4347
  if (IS_NOT_NULL(prev_cc)) {
 
4348
    r = and_cclass(prev_cc, cc, env->enc);
 
4349
    if (r != 0) goto err;
 
4350
    bbuf_free(cc->mbuf);
 
4351
    cc = prev_cc;
 
4352
  }
 
4353
 
 
4354
  if (neg != 0)
 
4355
    CCLASS_SET_NOT(cc);
 
4356
  else
 
4357
    CCLASS_CLEAR_NOT(cc);
 
4358
  if (IS_CCLASS_NOT(cc) &&
 
4359
      IS_SYNTAX_BV(env->syntax, ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC)) {
 
4360
    int is_empty;
 
4361
 
 
4362
    is_empty = (IS_NULL(cc->mbuf) ? 1 : 0);
 
4363
    if (is_empty != 0)
 
4364
      BITSET_IS_EMPTY(cc->bs, is_empty);
 
4365
 
 
4366
    if (is_empty == 0) {
 
4367
#define NEWLINE_CODE    0x0a
 
4368
 
 
4369
      if (ONIGENC_IS_CODE_NEWLINE(env->enc, NEWLINE_CODE)) {
 
4370
        if (ONIGENC_CODE_TO_MBCLEN(env->enc, NEWLINE_CODE) == 1)
 
4371
          BITSET_SET_BIT(cc->bs, NEWLINE_CODE);
 
4372
        else
 
4373
          add_code_range(&(cc->mbuf), env, NEWLINE_CODE, NEWLINE_CODE);
 
4374
      }
 
4375
    }
 
4376
  }
 
4377
  *src = p;
 
4378
  return 0;
 
4379
 
 
4380
 err:
 
4381
  if (cc != &(NCCLASS(*np)))
 
4382
    bbuf_free(cc->mbuf);
 
4383
  onig_node_free(*np);
 
4384
  return r;
 
4385
}
 
4386
 
 
4387
static int parse_subexp(Node** top, OnigToken* tok, int term,
 
4388
                        UChar** src, UChar* end, ScanEnv* env);
 
4389
 
 
4390
static int
 
4391
parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
 
4392
             ScanEnv* env)
 
4393
{
 
4394
  int r, num;
 
4395
  int list_capture;
 
4396
  Node *target;
 
4397
  OnigOptionType option;
 
4398
  OnigEncoding enc = env->enc;
 
4399
  OnigCodePoint c;
 
4400
  UChar* p = *src;
 
4401
  PFETCH_READY;
 
4402
 
 
4403
  *np = NULL;
 
4404
  if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
 
4405
 
 
4406
  option = env->option;
 
4407
  if (PPEEK_IS('?') &&
 
4408
      IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
 
4409
    PINC;
 
4410
    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
 
4411
 
 
4412
    PFETCH(c);
 
4413
    switch (c) {
 
4414
    case ':':   /* (?:...) grouping only */
 
4415
    group:
 
4416
      r = fetch_token(tok, &p, end, env);
 
4417
      if (r < 0) return r;
 
4418
      r = parse_subexp(np, tok, term, &p, end, env);
 
4419
      if (r < 0) return r;
 
4420
      *src = p;
 
4421
      return 1; /* group */
 
4422
      break;
 
4423
 
 
4424
    case '=':
 
4425
      *np = onig_node_new_anchor(ANCHOR_PREC_READ);
 
4426
      break;
 
4427
    case '!':  /*         preceding read */
 
4428
      *np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT);
 
4429
      break;
 
4430
    case '>':            /* (?>...) stop backtrack */
 
4431
      *np = node_new_effect(EFFECT_STOP_BACKTRACK);
 
4432
      break;
 
4433
 
 
4434
    case '<':   /* look behind (?<=...), (?<!...) */
 
4435
      PFETCH(c);
 
4436
      if (c == '=')
 
4437
        *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND);
 
4438
      else if (c == '!')
 
4439
        *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT);
 
4440
#ifdef USE_NAMED_GROUP
 
4441
      else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
 
4442
        UChar *name;
 
4443
        UChar *name_end;
 
4444
 
 
4445
        PUNFETCH;
 
4446
        list_capture = 0;
 
4447
 
 
4448
      named_group:
 
4449
        name = p;
 
4450
        r = fetch_name(&p, end, &name_end, env, 0);
 
4451
        if (r < 0) return r;
 
4452
 
 
4453
        num = scan_env_add_mem_entry(env);
 
4454
        if (num < 0) return num;
 
4455
        if (list_capture != 0 && num >= BIT_STATUS_BITS_NUM)
 
4456
          return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
 
4457
 
 
4458
        r = name_add(env->reg, name, name_end, num, env);
 
4459
        if (r != 0) return r;
 
4460
        *np = node_new_effect_memory(env->option, 1);
 
4461
        CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4462
        NEFFECT(*np).regnum = num;
 
4463
        if (list_capture != 0)
 
4464
          BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
 
4465
        env->num_named++;
 
4466
      }
 
4467
#endif
 
4468
      else
 
4469
        return ONIGERR_UNDEFINED_GROUP_OPTION;
 
4470
      break;
 
4471
 
 
4472
    case '@':
 
4473
      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) {
 
4474
#ifdef USE_NAMED_GROUP
 
4475
        if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
 
4476
          PFETCH(c);
 
4477
          if (c == '<') {
 
4478
            list_capture = 1;
 
4479
            goto named_group; /* (?@<name>...) */
 
4480
          }
 
4481
          PUNFETCH;
 
4482
        }
 
4483
#endif
 
4484
        *np = node_new_effect_memory(env->option, 0);
 
4485
        CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4486
        num = scan_env_add_mem_entry(env);
 
4487
        if (num < 0) {
 
4488
          onig_node_free(*np);
 
4489
          return num;
 
4490
        }
 
4491
        else if (num >= BIT_STATUS_BITS_NUM) {
 
4492
          onig_node_free(*np);
 
4493
          return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
 
4494
        }
 
4495
        NEFFECT(*np).regnum = num;
 
4496
        BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
 
4497
      }
 
4498
      else {
 
4499
        return ONIGERR_UNDEFINED_GROUP_OPTION;
 
4500
      }
 
4501
      break;
 
4502
 
 
4503
#ifdef USE_POSIXLINE_OPTION
 
4504
    case 'p':
 
4505
#endif
 
4506
    case '-': case 'i': case 'm': case 's': case 'x':
 
4507
      {
 
4508
        int neg = 0;
 
4509
 
 
4510
        while (1) {
 
4511
          switch (c) {
 
4512
          case ':':
 
4513
          case ')':
 
4514
          break;
 
4515
 
 
4516
          case '-':  neg = 1; break;
 
4517
          case 'x':  ONOFF(option, ONIG_OPTION_EXTEND,     neg); break;
 
4518
          case 'i':  ONOFF(option, ONIG_OPTION_IGNORECASE, neg); break;
 
4519
          case 's':
 
4520
            if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
 
4521
              ONOFF(option, ONIG_OPTION_MULTILINE,  neg);
 
4522
            }
 
4523
            else
 
4524
              return ONIGERR_UNDEFINED_GROUP_OPTION;
 
4525
            break;
 
4526
 
 
4527
          case 'm':
 
4528
            if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
 
4529
              ONOFF(option, ONIG_OPTION_SINGLELINE, (neg == 0 ? 1 : 0));
 
4530
            }
 
4531
            else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
 
4532
              ONOFF(option, ONIG_OPTION_MULTILINE,  neg);
 
4533
            }
 
4534
            else
 
4535
              return ONIGERR_UNDEFINED_GROUP_OPTION;
 
4536
            break;
 
4537
#ifdef USE_POSIXLINE_OPTION
 
4538
          case 'p':
 
4539
            ONOFF(option, ONIG_OPTION_MULTILINE|ONIG_OPTION_SINGLELINE, neg);
 
4540
            break;
 
4541
#endif
 
4542
          default:
 
4543
            return ONIGERR_UNDEFINED_GROUP_OPTION;
 
4544
          }
 
4545
 
 
4546
          if (c == ')') {
 
4547
            *np = node_new_option(option);
 
4548
            CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4549
            *src = p;
 
4550
            return 2; /* option only */
 
4551
          }
 
4552
          else if (c == ':') {
 
4553
            OnigOptionType prev = env->option;
 
4554
 
 
4555
            env->option     = option;
 
4556
            r = fetch_token(tok, &p, end, env);
 
4557
            if (r < 0) return r;
 
4558
            r = parse_subexp(&target, tok, term, &p, end, env);
 
4559
            env->option = prev;
 
4560
            if (r < 0) return r;
 
4561
            *np = node_new_option(option);
 
4562
            CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4563
            NEFFECT(*np).target = target;
 
4564
            *src = p;
 
4565
            return 0;
 
4566
          }
 
4567
 
 
4568
          if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
 
4569
          PFETCH(c);
 
4570
        }
 
4571
      }
 
4572
      break;
 
4573
 
 
4574
    default:
 
4575
      return ONIGERR_UNDEFINED_GROUP_OPTION;
 
4576
    }
 
4577
  }
 
4578
  else {
 
4579
    if (ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_DONT_CAPTURE_GROUP))
 
4580
      goto group;
 
4581
 
 
4582
    *np = node_new_effect_memory(env->option, 0);
 
4583
    CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4584
    num = scan_env_add_mem_entry(env);
 
4585
    if (num < 0) return num;
 
4586
    NEFFECT(*np).regnum = num;
 
4587
  }
 
4588
 
 
4589
  CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4590
  r = fetch_token(tok, &p, end, env);
 
4591
  if (r < 0) return r;
 
4592
  r = parse_subexp(&target, tok, term, &p, end, env);
 
4593
  if (r < 0) return r;
 
4594
 
 
4595
  if (NTYPE(*np) == N_ANCHOR)
 
4596
    NANCHOR(*np).target = target;
 
4597
  else {
 
4598
    NEFFECT(*np).target = target;
 
4599
    if (NEFFECT(*np).type == EFFECT_MEMORY) {
 
4600
      /* Don't move this to previous of parse_subexp() */
 
4601
      r = scan_env_set_mem_node(env, NEFFECT(*np).regnum, *np);
 
4602
      if (r != 0) return r;
 
4603
    }
 
4604
  }
 
4605
 
 
4606
  *src = p;
 
4607
  return 0;
 
4608
}
 
4609
 
 
4610
static const char* PopularQStr[] = {
 
4611
  "?", "*", "+", "??", "*?", "+?"
 
4612
};
 
4613
 
 
4614
static const char* ReduceQStr[] = {
 
4615
  "", "", "*", "*?", "??", "+ and ??", "+? and ?"
 
4616
};
 
4617
 
 
4618
static int
 
4619
set_quantifier(Node* qnode, Node* target, int group, ScanEnv* env)
 
4620
{
 
4621
  QuantifierNode* qn;
 
4622
 
 
4623
  qn = &(NQUANTIFIER(qnode));
 
4624
  if (qn->lower == 1 && qn->upper == 1) {
 
4625
    return 1;
 
4626
  }
 
4627
 
 
4628
  switch (NTYPE(target)) {
 
4629
  case N_STRING:
 
4630
    if (! group) {
 
4631
      StrNode* sn = &(NSTRING(target));
 
4632
      if (str_node_can_be_split(sn, env->enc)) {
 
4633
        Node* n = str_node_split_last_char(sn, env->enc);
 
4634
        if (IS_NOT_NULL(n)) {
 
4635
          qn->target = n;
 
4636
          return 2;
 
4637
        }
 
4638
      }
 
4639
    }
 
4640
    break;
 
4641
 
 
4642
  case N_QUANTIFIER:
 
4643
    { /* check redundant double repeat. */
 
4644
      /* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
 
4645
      QuantifierNode* qnt = &(NQUANTIFIER(target));
 
4646
      int nestq_num   = popular_quantifier_num(qn);
 
4647
      int targetq_num = popular_quantifier_num(qnt);
 
4648
 
 
4649
#ifdef USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
 
4650
      if (!IS_QUANTIFIER_BY_NUMBER(qn) && !IS_QUANTIFIER_BY_NUMBER(qnt) &&
 
4651
          IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT)) {
 
4652
        UChar buf[WARN_BUFSIZE];
 
4653
 
 
4654
        switch(ReduceTypeTable[targetq_num][nestq_num]) {
 
4655
        case RQ_ASIS:
 
4656
          break;
 
4657
 
 
4658
        case RQ_DEL:
 
4659
          if (onig_verb_warn != onig_null_warn) {
 
4660
            onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
 
4661
                                 env->pattern, env->pattern_end,
 
4662
                                 (UChar* )"redundant nested repeat operator");
 
4663
            (*onig_verb_warn)((char* )buf);
 
4664
          }
 
4665
          goto warn_exit;
 
4666
          break;
 
4667
 
 
4668
        default:
 
4669
          if (onig_verb_warn != onig_null_warn) {
 
4670
            onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
 
4671
                                       env->pattern, env->pattern_end,
 
4672
            (UChar* )"nested repeat operator %s and %s was replaced with '%s'",
 
4673
            PopularQStr[targetq_num], PopularQStr[nestq_num],
 
4674
            ReduceQStr[ReduceTypeTable[targetq_num][nestq_num]]);
 
4675
            (*onig_verb_warn)((char* )buf);
 
4676
          }
 
4677
          goto warn_exit;
 
4678
          break;
 
4679
        }
 
4680
      }
 
4681
 
 
4682
    warn_exit:
 
4683
#endif
 
4684
      if (targetq_num >= 0) {
 
4685
        if (nestq_num >= 0) {
 
4686
          onig_reduce_nested_quantifier(qnode, target);
 
4687
          goto q_exit;
 
4688
        }
 
4689
        else if (targetq_num == 1 || targetq_num == 2) { /* * or + */
 
4690
          /* (?:a*){n,m}, (?:a+){n,m} => (?:a*){n,n}, (?:a+){n,n} */
 
4691
          if (! IS_REPEAT_INFINITE(qn->upper) && qn->upper > 1 && qn->greedy) {
 
4692
            qn->upper = (qn->lower == 0 ? 1 : qn->lower);
 
4693
          }
 
4694
        }
 
4695
      }
 
4696
    }
 
4697
    break;
 
4698
 
 
4699
  default:
 
4700
    break;
 
4701
  }
 
4702
 
 
4703
  qn->target = target;
 
4704
 q_exit:
 
4705
  return 0;
 
4706
}
 
4707
 
 
4708
#ifdef USE_SHARED_CCLASS_TABLE
 
4709
 
 
4710
#define THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS     8
 
4711
 
 
4712
/* for ctype node hash table */
 
4713
 
 
4714
typedef struct {
 
4715
  OnigEncoding enc;
 
4716
  int not;
 
4717
  int type;
 
4718
} type_cclass_key;
 
4719
 
 
4720
static int type_cclass_cmp(type_cclass_key* x, type_cclass_key* y)
 
4721
{
 
4722
  if (x->type != y->type) return 1;
 
4723
  if (x->enc  != y->enc)  return 1;
 
4724
  if (x->not  != y->not)  return 1;
 
4725
  return 0;
 
4726
}
 
4727
 
 
4728
static int type_cclass_hash(type_cclass_key* key)
 
4729
{
 
4730
  int i, val;
 
4731
  unsigned char *p;
 
4732
 
 
4733
  val = 0;
 
4734
 
 
4735
  p = (unsigned char* )&(key->enc);
 
4736
  for (i = 0; i < sizeof(key->enc); i++) {
 
4737
    val = val * 997 + (int )*p++;
 
4738
  }
 
4739
 
 
4740
  p = (unsigned char* )(&key->type);
 
4741
  for (i = 0; i < sizeof(key->type); i++) {
 
4742
    val = val * 997 + (int )*p++;
 
4743
  }
 
4744
 
 
4745
  val += key->not;
 
4746
  return val + (val >> 5);
 
4747
}
 
4748
 
 
4749
static struct st_hash_type type_type_cclass_hash = {
 
4750
    type_cclass_cmp,
 
4751
    type_cclass_hash,
 
4752
};
 
4753
 
 
4754
static st_table* OnigTypeCClassTable;
 
4755
 
 
4756
 
 
4757
static int
 
4758
i_free_shared_class(type_cclass_key* key, Node* node, void* arg)
 
4759
{
 
4760
  if (IS_NOT_NULL(node)) {
 
4761
    CClassNode* cc = &(NCCLASS(node));
 
4762
    if (IS_NOT_NULL(cc->mbuf)) xfree(cc->mbuf);
 
4763
    xfree(node);
 
4764
  }
 
4765
 
 
4766
  if (IS_NOT_NULL(key)) xfree(key);
 
4767
  return ST_DELETE;
 
4768
}
 
4769
 
 
4770
extern int
 
4771
onig_free_shared_cclass_table(void)
 
4772
{
 
4773
  if (IS_NOT_NULL(OnigTypeCClassTable)) {
 
4774
    onig_st_foreach(OnigTypeCClassTable, i_free_shared_class, 0);
 
4775
    onig_st_free_table(OnigTypeCClassTable);
 
4776
    OnigTypeCClassTable = NULL;
 
4777
  }
 
4778
 
 
4779
  return 0;
 
4780
}
 
4781
 
 
4782
#endif /* USE_SHARED_CCLASS_TABLE */
 
4783
 
 
4784
 
 
4785
static int
 
4786
parse_exp(Node** np, OnigToken* tok, int term,
 
4787
          UChar** src, UChar* end, ScanEnv* env)
 
4788
{
 
4789
  int r, len, group = 0;
 
4790
  Node* qn;
 
4791
  Node** targetp;
 
4792
 
 
4793
  *np = NULL;
 
4794
  if (tok->type == term)
 
4795
    goto end_of_token;
 
4796
 
 
4797
  switch (tok->type) {
 
4798
  case TK_ALT:
 
4799
  case TK_EOT:
 
4800
  end_of_token:
 
4801
  *np = node_new_empty();
 
4802
  return tok->type;
 
4803
  break;
 
4804
 
 
4805
  case TK_SUBEXP_OPEN:
 
4806
    r = parse_effect(np, tok, TK_SUBEXP_CLOSE, src, end, env);
 
4807
    if (r < 0) return r;
 
4808
    if (r == 1) group = 1;
 
4809
    else if (r == 2) { /* option only */
 
4810
      Node* target;
 
4811
      OnigOptionType prev = env->option;
 
4812
 
 
4813
      env->option = NEFFECT(*np).option;
 
4814
      r = fetch_token(tok, src, end, env);
 
4815
      if (r < 0) return r;
 
4816
      r = parse_subexp(&target, tok, term, src, end, env);
 
4817
      env->option = prev;
 
4818
      if (r < 0) return r;
 
4819
      NEFFECT(*np).target = target;     
 
4820
      return tok->type;
 
4821
    }
 
4822
    break;
 
4823
 
 
4824
  case TK_SUBEXP_CLOSE:
 
4825
    if (! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP))
 
4826
      return ONIGERR_UNMATCHED_CLOSE_PARENTHESIS;
 
4827
 
 
4828
    if (tok->escaped) goto tk_raw_byte;
 
4829
    else goto tk_byte;
 
4830
    break;
 
4831
 
 
4832
  case TK_STRING:
 
4833
  tk_byte:
 
4834
    {
 
4835
      *np = node_new_str(tok->backp, *src);
 
4836
      CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4837
 
 
4838
      while (1) {
 
4839
        r = fetch_token(tok, src, end, env);
 
4840
        if (r < 0) return r;
 
4841
        if (r != TK_STRING) break;
 
4842
 
 
4843
        r = onig_node_str_cat(*np, tok->backp, *src);
 
4844
        if (r < 0) return r;
 
4845
      }
 
4846
 
 
4847
    string_end:
 
4848
      targetp = np;
 
4849
      goto repeat;
 
4850
    }
 
4851
    break;
 
4852
 
 
4853
  case TK_RAW_BYTE:
 
4854
  tk_raw_byte:
 
4855
    {
 
4856
      *np = node_new_str_char((UChar )tok->u.c);
 
4857
      CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4858
      len = 1;
 
4859
      while (1) {
 
4860
        if (len >= ONIGENC_MBC_MINLEN(env->enc)) {
 
4861
          if (len == enc_len(env->enc, NSTRING(*np).s)) {
 
4862
            r = fetch_token(tok, src, end, env);
 
4863
            goto string_end;
 
4864
          }
 
4865
        }
 
4866
 
 
4867
        r = fetch_token(tok, src, end, env);
 
4868
        if (r < 0) return r;
 
4869
        if (r != TK_RAW_BYTE) {
 
4870
#ifdef USE_PAD_TO_SHORT_BYTE_CHAR
 
4871
          int rem;
 
4872
          if (len < ONIGENC_MBC_MINLEN(env->enc)) {
 
4873
            rem = ONIGENC_MBC_MINLEN(env->enc) - len;
 
4874
            (void )node_str_head_pad(&NSTRING(*np), rem, (UChar )0);
 
4875
            if (len + rem == enc_len(env->enc, NSTRING(*np).s)) {
 
4876
              goto string_end;
 
4877
            }
 
4878
          }
 
4879
#endif
 
4880
          return ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
 
4881
        }
 
4882
 
 
4883
        r = node_str_cat_char(*np, (UChar )tok->u.c);
 
4884
        if (r < 0) return r;
 
4885
 
 
4886
        len++;
 
4887
      }
 
4888
    }
 
4889
    break;
 
4890
 
 
4891
  case TK_CODE_POINT:
 
4892
    {
 
4893
      UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
 
4894
      int num = ONIGENC_CODE_TO_MBC(env->enc, tok->u.code, buf);
 
4895
      if (num < 0) return num;
 
4896
#ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
 
4897
      *np = node_new_str_raw(buf, buf + num);
 
4898
#else
 
4899
      *np = node_new_str(buf, buf + num);
 
4900
#endif
 
4901
      CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4902
    }
 
4903
    break;
 
4904
 
 
4905
  case TK_QUOTE_OPEN:
 
4906
    {
 
4907
      OnigCodePoint end_op[2];
 
4908
      UChar *qstart, *qend, *nextp;
 
4909
 
 
4910
      end_op[0] = (OnigCodePoint )MC_ESC(env->enc);
 
4911
      end_op[1] = (OnigCodePoint )'E';
 
4912
      qstart = *src;
 
4913
      qend = find_str_position(end_op, 2, qstart, end, &nextp, env->enc);
 
4914
      if (IS_NULL(qend)) {
 
4915
        nextp = qend = end;
 
4916
      }
 
4917
      *np = node_new_str(qstart, qend);
 
4918
      CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4919
      *src = nextp;
 
4920
    }
 
4921
    break;
 
4922
 
 
4923
  case TK_CHAR_TYPE:
 
4924
    {
 
4925
      switch (tok->u.subtype) {
 
4926
      case CTYPE_WORD:
 
4927
      case CTYPE_NOT_WORD:
 
4928
        *np = node_new_ctype(tok->u.subtype);
 
4929
        CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4930
        break;
 
4931
 
 
4932
      case CTYPE_WHITE_SPACE:
 
4933
      case CTYPE_NOT_WHITE_SPACE:
 
4934
      case CTYPE_DIGIT:
 
4935
      case CTYPE_NOT_DIGIT:
 
4936
      case CTYPE_XDIGIT:
 
4937
      case CTYPE_NOT_XDIGIT:
 
4938
        {
 
4939
          CClassNode* cc;
 
4940
          int ctype, not;
 
4941
 
 
4942
#ifdef USE_SHARED_CCLASS_TABLE
 
4943
          const OnigCodePoint *sbr, *mbr;
 
4944
 
 
4945
          ctype = parse_ctype_to_enc_ctype(tok->u.subtype, &not);
 
4946
          r = ONIGENC_GET_CTYPE_CODE_RANGE(env->enc, ctype, &sbr, &mbr);
 
4947
          if (r == 0 &&
 
4948
              ONIGENC_CODE_RANGE_NUM(mbr)
 
4949
              >= THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS) {
 
4950
            type_cclass_key  key;
 
4951
            type_cclass_key* new_key;
 
4952
 
 
4953
            key.enc  = env->enc;
 
4954
            key.not  = not;
 
4955
            key.type = ctype;
 
4956
 
 
4957
            THREAD_ATOMIC_START;
 
4958
 
 
4959
            if (IS_NULL(OnigTypeCClassTable)) {
 
4960
              OnigTypeCClassTable
 
4961
                = onig_st_init_table_with_size(&type_type_cclass_hash, 10);
 
4962
              if (IS_NULL(OnigTypeCClassTable)) {
 
4963
                THREAD_ATOMIC_END;
 
4964
                return ONIGERR_MEMORY;
 
4965
              }
 
4966
            }
 
4967
            else {
 
4968
              if (onig_st_lookup(OnigTypeCClassTable, (st_data_t )&key,
 
4969
                                 (st_data_t* )np)) {
 
4970
                THREAD_ATOMIC_END;
 
4971
                break;
 
4972
              }
 
4973
            }
 
4974
 
 
4975
            *np = node_new_cclass_by_codepoint_range(not, sbr, mbr);
 
4976
            if (IS_NULL(*np)) {
 
4977
              THREAD_ATOMIC_END;
 
4978
              return ONIGERR_MEMORY;
 
4979
            }
 
4980
 
 
4981
            CCLASS_SET_SHARE(&(NCCLASS(*np)));
 
4982
            new_key = (type_cclass_key* )xmalloc(sizeof(type_cclass_key));
 
4983
            onig_st_add_direct(OnigTypeCClassTable, (st_data_t )new_key,
 
4984
                               (st_data_t )*np);
 
4985
            
 
4986
            THREAD_ATOMIC_END;
 
4987
          }
 
4988
          else {
 
4989
#endif
 
4990
            ctype = parse_ctype_to_enc_ctype(tok->u.subtype, &not);
 
4991
            *np = node_new_cclass();
 
4992
            CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
4993
            cc = &(NCCLASS(*np));
 
4994
            add_ctype_to_cc(cc, ctype, 0, env);
 
4995
            if (not != 0) CCLASS_SET_NOT(cc);
 
4996
#ifdef USE_SHARED_CCLASS_TABLE
 
4997
          }
 
4998
#endif
 
4999
        }
 
5000
        break;
 
5001
 
 
5002
      default:
 
5003
        return ONIGERR_PARSER_BUG;
 
5004
        break;
 
5005
      }
 
5006
    }
 
5007
    break;
 
5008
 
 
5009
  case TK_CHAR_PROPERTY:
 
5010
    r = parse_char_property(np, tok, src, end, env);
 
5011
    if (r != 0) return r;
 
5012
    break;
 
5013
 
 
5014
  case TK_CC_OPEN:
 
5015
    {
 
5016
      CClassNode* cc;
 
5017
 
 
5018
      r = parse_char_class(np, tok, src, end, env);
 
5019
      if (r != 0) return r;
 
5020
 
 
5021
      cc = &(NCCLASS(*np));
 
5022
 
 
5023
      if (IS_IGNORECASE(env->option)) {
 
5024
        int i, n, in_cc;
 
5025
        const OnigPairAmbigCodes* ccs;
 
5026
        BitSetRef bs = cc->bs;
 
5027
        OnigAmbigType amb;
 
5028
 
 
5029
        for (amb = 0x01; amb <= ONIGENC_AMBIGUOUS_MATCH_LIMIT; amb <<= 1) {
 
5030
          if ((amb & env->ambig_flag) == 0)  continue;
 
5031
 
 
5032
          n = ONIGENC_GET_ALL_PAIR_AMBIG_CODES(env->enc, amb, &ccs);
 
5033
          for (i = 0; i < n; i++) {
 
5034
            in_cc = onig_is_code_in_cc(env->enc, ccs[i].from, cc);
 
5035
 
 
5036
            if ((in_cc != 0 && !IS_CCLASS_NOT(cc)) ||
 
5037
                (in_cc == 0 && IS_CCLASS_NOT(cc))) {
 
5038
              if (ONIGENC_MBC_MINLEN(env->enc) > 1 ||
 
5039
                  ccs[i].from >= SINGLE_BYTE_SIZE) {
 
5040
                /* if (cc->not) clear_not_flag_cclass(cc, env->enc); */
 
5041
                add_code_range(&(cc->mbuf), env, ccs[i].to, ccs[i].to);
 
5042
              }
 
5043
              else {
 
5044
                if (BITSET_AT(bs, ccs[i].from)) {
 
5045
                  /* /(?i:[^A-C])/.match("a") ==> fail. */
 
5046
                  BITSET_SET_BIT(bs, ccs[i].to);
 
5047
                }
 
5048
                if (BITSET_AT(bs, ccs[i].to)) {
 
5049
                  BITSET_SET_BIT(bs, ccs[i].from);
 
5050
                }
 
5051
              }
 
5052
            }
 
5053
          }
 
5054
        }
 
5055
      }
 
5056
    }
 
5057
    break;
 
5058
 
 
5059
  case TK_ANYCHAR:
 
5060
    *np = node_new_anychar();
 
5061
    CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
5062
    break;
 
5063
 
 
5064
  case TK_ANYCHAR_ANYTIME:
 
5065
    *np = node_new_anychar();
 
5066
    CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
5067
    qn = node_new_quantifier(0, REPEAT_INFINITE, 0);
 
5068
    CHECK_NULL_RETURN_VAL(qn, ONIGERR_MEMORY);
 
5069
    NQUANTIFIER(qn).target = *np;
 
5070
    *np = qn;
 
5071
    break;
 
5072
 
 
5073
  case TK_BACKREF:
 
5074
    len = tok->u.backref.num;
 
5075
    *np = node_new_backref(len,
 
5076
                   (len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)),
 
5077
                           tok->u.backref.by_name,
 
5078
#ifdef USE_BACKREF_AT_LEVEL
 
5079
                           tok->u.backref.exist_level,
 
5080
                           tok->u.backref.level,
 
5081
#endif
 
5082
                           env);
 
5083
    CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
5084
    break;
 
5085
 
 
5086
#ifdef USE_SUBEXP_CALL
 
5087
  case TK_CALL:
 
5088
    *np = node_new_call(tok->u.call.name, tok->u.call.name_end);
 
5089
    CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
 
5090
    env->num_call++;
 
5091
    break;
 
5092
#endif
 
5093
 
 
5094
  case TK_ANCHOR:
 
5095
    *np = onig_node_new_anchor(tok->u.anchor);
 
5096
    break;
 
5097
 
 
5098
  case TK_OP_REPEAT:
 
5099
  case TK_INTERVAL:
 
5100
    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS)) {
 
5101
      if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS))
 
5102
        return ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED;
 
5103
      else
 
5104
        *np = node_new_empty();
 
5105
    }
 
5106
    else {
 
5107
      goto tk_byte;
 
5108
    }
 
5109
    break;
 
5110
 
 
5111
  default:
 
5112
    return ONIGERR_PARSER_BUG;
 
5113
    break;
 
5114
  }
 
5115
 
 
5116
  {
 
5117
    targetp = np;
 
5118
 
 
5119
  re_entry:
 
5120
    r = fetch_token(tok, src, end, env);
 
5121
    if (r < 0) return r;
 
5122
 
 
5123
  repeat:
 
5124
    if (r == TK_OP_REPEAT || r == TK_INTERVAL) {
 
5125
      if (is_invalid_quantifier_target(*targetp))
 
5126
        return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID;
 
5127
 
 
5128
      qn = node_new_quantifier(tok->u.repeat.lower, tok->u.repeat.upper,
 
5129
                              (r == TK_INTERVAL ? 1 : 0));
 
5130
      CHECK_NULL_RETURN_VAL(qn, ONIGERR_MEMORY);
 
5131
      NQUANTIFIER(qn).greedy = tok->u.repeat.greedy;
 
5132
      r = set_quantifier(qn, *targetp, group, env);
 
5133
      if (r < 0) return r;
 
5134
      
 
5135
      if (tok->u.repeat.possessive != 0) {
 
5136
        Node* en;
 
5137
        en = node_new_effect(EFFECT_STOP_BACKTRACK);
 
5138
        CHECK_NULL_RETURN_VAL(en, ONIGERR_MEMORY);
 
5139
        NEFFECT(en).target = qn;
 
5140
        qn = en;
 
5141
      }
 
5142
 
 
5143
      if (r == 0) {
 
5144
        *targetp = qn;
 
5145
      }
 
5146
      else if (r == 2) { /* split case: /abc+/ */
 
5147
        Node *tmp;
 
5148
 
 
5149
        *targetp = node_new_list(*targetp, NULL);
 
5150
        CHECK_NULL_RETURN_VAL(*targetp, ONIGERR_MEMORY);
 
5151
        tmp = NCONS(*targetp).right = node_new_list(qn, NULL);
 
5152
        CHECK_NULL_RETURN_VAL(tmp, ONIGERR_MEMORY);
 
5153
        targetp = &(NCONS(tmp).left);
 
5154
      }
 
5155
      goto re_entry;
 
5156
    }
 
5157
  }
 
5158
 
 
5159
  return r;
 
5160
}
 
5161
 
 
5162
static int
 
5163
parse_branch(Node** top, OnigToken* tok, int term,
 
5164
             UChar** src, UChar* end, ScanEnv* env)
 
5165
{
 
5166
  int r;
 
5167
  Node *node, **headp;
 
5168
 
 
5169
  *top = NULL;
 
5170
  r = parse_exp(&node, tok, term, src, end, env);
 
5171
  if (r < 0) return r;
 
5172
 
 
5173
  if (r == TK_EOT || r == term || r == TK_ALT) {
 
5174
    *top = node;
 
5175
  }
 
5176
  else {
 
5177
    *top  = node_new_list(node, NULL);
 
5178
    headp = &(NCONS(*top).right);
 
5179
    while (r != TK_EOT && r != term && r != TK_ALT) {
 
5180
      r = parse_exp(&node, tok, term, src, end, env);
 
5181
      if (r < 0) return r;
 
5182
 
 
5183
      if (NTYPE(node) == N_LIST) {
 
5184
        *headp = node;
 
5185
        while (IS_NOT_NULL(NCONS(node).right)) node = NCONS(node).right;
 
5186
        headp = &(NCONS(node).right);
 
5187
      }
 
5188
      else {
 
5189
        *headp = node_new_list(node, NULL);
 
5190
        headp = &(NCONS(*headp).right);
 
5191
      }
 
5192
    }
 
5193
  }
 
5194
 
 
5195
  return r;
 
5196
}
 
5197
 
 
5198
/* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
 
5199
static int
 
5200
parse_subexp(Node** top, OnigToken* tok, int term,
 
5201
             UChar** src, UChar* end, ScanEnv* env)
 
5202
{
 
5203
  int r;
 
5204
  Node *node, **headp;
 
5205
 
 
5206
  *top = NULL;
 
5207
  r = parse_branch(&node, tok, term, src, end, env);
 
5208
  if (r < 0) {
 
5209
    onig_node_free(node);
 
5210
    return r;
 
5211
  }
 
5212
 
 
5213
  if (r == term) {
 
5214
    *top = node;
 
5215
  }
 
5216
  else if (r == TK_ALT) {
 
5217
    *top  = node_new_alt(node, NULL);
 
5218
    headp = &(NCONS(*top).right);
 
5219
    while (r == TK_ALT) {
 
5220
      r = fetch_token(tok, src, end, env);
 
5221
      if (r < 0) return r;
 
5222
      r = parse_branch(&node, tok, term, src, end, env);
 
5223
      if (r < 0) return r;
 
5224
 
 
5225
      *headp = node_new_alt(node, NULL);
 
5226
      headp = &(NCONS(*headp).right);
 
5227
    }
 
5228
 
 
5229
    if (tok->type != term)
 
5230
      goto err;
 
5231
  }
 
5232
  else {
 
5233
  err:
 
5234
    if (term == TK_SUBEXP_CLOSE)
 
5235
      return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
 
5236
    else
 
5237
      return ONIGERR_PARSER_BUG;
 
5238
  }
 
5239
 
 
5240
  return r;
 
5241
}
 
5242
 
 
5243
static int
 
5244
parse_regexp(Node** top, UChar** src, UChar* end, ScanEnv* env)
 
5245
{
 
5246
  int r;
 
5247
  OnigToken tok;
 
5248
 
 
5249
  r = fetch_token(&tok, src, end, env);
 
5250
  if (r < 0) return r;
 
5251
  r = parse_subexp(top, &tok, TK_EOT, src, end, env);
 
5252
  if (r < 0) return r;
 
5253
  return 0;
 
5254
}
 
5255
 
 
5256
extern int
 
5257
onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_t* reg,
 
5258
                      ScanEnv* env)
 
5259
{
 
5260
  int r;
 
5261
  UChar* p;
 
5262
 
 
5263
#ifdef USE_NAMED_GROUP
 
5264
  names_clear(reg);
 
5265
#endif
 
5266
 
 
5267
  scan_env_clear(env);
 
5268
  env->option      = reg->options;
 
5269
  env->ambig_flag  = reg->ambig_flag;
 
5270
  env->enc         = reg->enc;
 
5271
  env->syntax      = reg->syntax;
 
5272
  env->pattern     = (UChar* )pattern;
 
5273
  env->pattern_end = (UChar* )end;
 
5274
  env->reg         = reg;
 
5275
 
 
5276
  *root = NULL;
 
5277
  p = (UChar* )pattern;
 
5278
  r = parse_regexp(root, &p, (UChar* )end, env);
 
5279
  reg->num_mem = env->num_mem;
 
5280
  return r;
 
5281
}
 
5282
 
 
5283
extern void
 
5284
onig_scan_env_set_error_string(ScanEnv* env, int ecode,
 
5285
                                UChar* arg, UChar* arg_end)
 
5286
{
 
5287
  env->error     = arg;
 
5288
  env->error_end = arg_end;
 
5289
}