~ubuntu-branches/ubuntu/intrepid/ruby1.9/intrepid-updates

« back to all changes in this revision

Viewing changes to re.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-09-04 16:01:17 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070904160117-i15zckg2nhxe9fyw
Tags: 1.9.0+20070830-2ubuntu1
* Sync from Debian; remaining changes:
  - Add -g to CFLAGS.
* Fixes build failure on ia64.
* Fixes build failure with gcc-4.2 on lpia.
* Robustify check for target_os, fixing build failure on lpia.
* Set Ubuntu maintainer address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  re.c -
4
4
 
5
 
  $Author: nobu $
 
5
  $Author: matz $
6
6
  created at: Mon Aug  9 18:24:49 JST 1993
7
7
 
8
 
  Copyright (C) 1993-2006 Yukihiro Matsumoto
 
8
  Copyright (C) 1993-2007 Yukihiro Matsumoto
9
9
 
10
10
**********************************************************************/
11
11
 
12
 
#include "ruby.h"
13
 
#include "re.h"
 
12
#include "ruby/ruby.h"
 
13
#include "ruby/re.h"
 
14
#include "ruby/encoding.h"
14
15
#include "regint.h"
15
16
#include <ctype.h>
16
17
 
21
22
 
22
23
VALUE rb_eRegexpError;
23
24
 
 
25
typedef char onig_errmsg_buffer[ONIG_MAX_ERROR_MESSAGE_LEN];
 
26
 
24
27
#define BEG(no) regs->beg[no]
25
28
#define END(no) regs->end[no]
26
29
 
194
197
    return val;
195
198
}
196
199
 
 
200
static char *
 
201
option_to_str(char str[4], int options)
 
202
{
 
203
    char *p = str;
 
204
    if (options & ONIG_OPTION_MULTILINE) *p++ = 'm';
 
205
    if (options & ONIG_OPTION_IGNORECASE) *p++ = 'i';
 
206
    if (options & ONIG_OPTION_EXTEND) *p++ = 'x';
 
207
    *p = 0;
 
208
    return str;
 
209
}
 
210
 
 
211
static const char *
 
212
arg_kcode(int options)
 
213
{
 
214
    switch (options & ARG_KCODE_MASK) {
 
215
      case ARG_KCODE_NONE: return "n";
 
216
      case ARG_KCODE_EUC:  return "e";
 
217
      case ARG_KCODE_SJIS: return "s";
 
218
      case ARG_KCODE_UTF8: return "u";
 
219
    }
 
220
    return "";
 
221
}
 
222
 
 
223
static const char *
 
224
opt_kcode(int flags)
 
225
{
 
226
    switch (flags) {
 
227
      case KCODE_NONE: return "n";
 
228
      case KCODE_EUC:  return "e";
 
229
      case KCODE_SJIS: return "s";
 
230
      case KCODE_UTF8: return "u";
 
231
    }
 
232
    return "";
 
233
}
 
234
 
197
235
extern int
198
236
rb_char_to_option_kcode(int c, int *option, int *kcode)
199
237
{
252
290
static void
253
291
set_re_kcode_by_option(struct RRegexp *re, int options)
254
292
{
 
293
    rb_encoding *enc = 0;
 
294
 
 
295
    FL_UNSET(re, KCODE_MASK);
255
296
    switch (options & ARG_KCODE_MASK) {
256
297
      case ARG_KCODE_NONE:
257
 
        FL_UNSET(re, KCODE_MASK);
 
298
        enc = rb_enc_from_index(0);
 
299
        FL_SET(re, KCODE_NONE);
258
300
        FL_SET(re, KCODE_FIXED);
259
301
        break;
260
302
      case ARG_KCODE_EUC:
261
 
        FL_UNSET(re, KCODE_MASK);
 
303
        enc = rb_enc_find("euc-jp");
262
304
        FL_SET(re, KCODE_EUC);
263
305
        FL_SET(re, KCODE_FIXED);
264
306
        break;
265
307
      case ARG_KCODE_SJIS:
266
 
        FL_UNSET(re, KCODE_MASK);
 
308
        enc = rb_enc_find("sjis");
 
309
        FL_SET(re, KCODE_FIXED);
267
310
        FL_SET(re, KCODE_SJIS);
268
 
        FL_SET(re, KCODE_FIXED);
269
311
        break;
270
312
      case ARG_KCODE_UTF8:
271
 
        FL_UNSET(re, KCODE_MASK);
 
313
        enc = rb_enc_find("utf-8");
272
314
        FL_SET(re, KCODE_UTF8);
273
315
        FL_SET(re, KCODE_FIXED);
274
316
        break;
278
320
        FL_SET(re, reg_kcode);
279
321
        break;
280
322
    }
 
323
    if (enc) {
 
324
        rb_enc_associate((VALUE)re, enc);
 
325
    }
281
326
}
282
327
 
283
328
static int
331
376
    }
332
377
}
333
378
 
334
 
int
335
 
rb_reg_mbclen2(unsigned int c, VALUE re)
336
 
{
337
 
    int len;
338
 
    unsigned char uc = (unsigned char)c;
339
 
 
340
 
    if (!FL_TEST(re, KCODE_FIXED))
341
 
        return mbclen(uc);
342
 
    kcode_set_option(re);
343
 
    len = mbclen(uc);
344
 
    kcode_reset_option();
345
 
    return len;
346
 
}
347
 
 
348
379
static void
349
380
rb_reg_check(VALUE re)
350
381
{
356
387
static void
357
388
rb_reg_expr_str(VALUE str, const char *s, long len)
358
389
{
 
390
    rb_encoding *enc = rb_enc_get(str);
359
391
    const char *p, *pend;
360
392
    int need_escape = 0;
361
393
 
362
394
    p = s; pend = p + len;
363
395
    while (p<pend) {
364
 
        if (*p == '/' || (!ISPRINT(*p) && !ismbchar(*p))) {
 
396
        if (*p == '/' || (!rb_enc_isprint(*p, enc) && !ismbchar(p, enc))) {
365
397
            need_escape = 1;
366
398
            break;
367
399
        }
368
 
        p += mbclen(*p);
 
400
        p += mbclen(p, enc);
369
401
    }
370
402
    if (!need_escape) {
371
403
        rb_str_buf_cat(str, s, len);
374
406
        p = s;
375
407
        while (p<pend) {
376
408
            if (*p == '\\') {
377
 
                int n = mbclen(p[1]) + 1;
 
409
                int n = mbclen(p+1, enc) + 1;
378
410
                rb_str_buf_cat(str, p, n);
379
411
                p += n;
380
412
                continue;
384
416
                rb_str_buf_cat(str, &c, 1);
385
417
                rb_str_buf_cat(str, p, 1);
386
418
            }
387
 
            else if (ismbchar(*p)) {
388
 
                rb_str_buf_cat(str, p, mbclen(*p));
389
 
                p += mbclen(*p);
 
419
            else if (ismbchar(p, enc)) {
 
420
                rb_str_buf_cat(str, p, mbclen(p, enc));
 
421
                p += mbclen(p, enc);
390
422
                continue;
391
423
            }
392
 
            else if (ISPRINT(*p)) {
 
424
            else if (rb_enc_isprint(*p, enc)) {
393
425
                rb_str_buf_cat(str, p, 1);
394
426
            }
395
 
            else if (!ISSPACE(*p)) {
 
427
            else if (!rb_enc_isspace(*p, enc)) {
396
428
                char b[8];
397
429
 
398
430
                sprintf(b, "\\%03o", *p & 0377);
414
446
    rb_reg_expr_str(str, s, len);
415
447
    rb_str_buf_cat2(str, "/");
416
448
    if (re) {
 
449
        char opts[4];
417
450
        rb_reg_check(re);
418
 
        if (RREGEXP(re)->ptr->options & ONIG_OPTION_MULTILINE)
419
 
            rb_str_buf_cat2(str, "m");
420
 
        if (RREGEXP(re)->ptr->options & ONIG_OPTION_IGNORECASE)
421
 
            rb_str_buf_cat2(str, "i");
422
 
        if (RREGEXP(re)->ptr->options & ONIG_OPTION_EXTEND)
423
 
            rb_str_buf_cat2(str, "x");
 
451
        if (*option_to_str(opts, RREGEXP(re)->ptr->options))
 
452
            rb_str_buf_cat2(str, opts);
424
453
 
425
454
        if (FL_TEST(re, KCODE_FIXED)) {
426
 
            switch ((RBASIC(re)->flags & KCODE_MASK)) {
427
 
              case KCODE_NONE:
428
 
                rb_str_buf_cat2(str, "n");
429
 
                break;
430
 
              case KCODE_EUC:
431
 
                rb_str_buf_cat2(str, "e");
432
 
                break;
433
 
              case KCODE_SJIS:
434
 
                rb_str_buf_cat2(str, "s");
435
 
                break;
436
 
              case KCODE_UTF8:
437
 
                rb_str_buf_cat2(str, "u");
438
 
                break;
439
 
            }
 
455
            rb_str_buf_cat2(str, opt_kcode(RBASIC(re)->flags & KCODE_MASK));
440
456
        }
441
457
    }
442
458
    OBJ_INFECT(str, re);
511
527
    long len;
512
528
    const UChar* ptr;
513
529
    VALUE str = rb_str_buf_new2("(?");
 
530
    char optbuf[5];
514
531
 
515
532
    rb_reg_check(re);
516
533
 
575
592
        }
576
593
    }
577
594
 
578
 
    if (options & ONIG_OPTION_MULTILINE) rb_str_buf_cat2(str, "m");
579
 
    if (options & ONIG_OPTION_IGNORECASE) rb_str_buf_cat2(str, "i");
580
 
    if (options & ONIG_OPTION_EXTEND) rb_str_buf_cat2(str, "x");
 
595
    if (*option_to_str(optbuf, options)) rb_str_buf_cat2(str, optbuf);
581
596
 
582
597
    if ((options & embeddable) != embeddable) {
583
 
        rb_str_buf_cat2(str, "-");
584
 
        if (!(options & ONIG_OPTION_MULTILINE)) rb_str_buf_cat2(str, "m");
585
 
        if (!(options & ONIG_OPTION_IGNORECASE)) rb_str_buf_cat2(str, "i");
586
 
        if (!(options & ONIG_OPTION_EXTEND)) rb_str_buf_cat2(str, "x");
 
598
        optbuf[0] = '-';
 
599
        option_to_str(optbuf + 1, ~options);
 
600
        rb_str_buf_cat2(str, optbuf);
587
601
    }
588
602
 
589
603
    rb_str_buf_cat2(str, ":");
595
609
}
596
610
 
597
611
static void
598
 
rb_reg_raise(const char *s, long len, const char *err, VALUE re, int ce)
 
612
rb_reg_raise(const char *s, long len, const char *err, VALUE re)
599
613
{
600
614
    VALUE desc = rb_reg_desc(s, len, re);
601
615
 
602
 
    if (ce)
603
 
        rb_compile_error("%s: %s", err, RSTRING_PTR(desc));
604
 
    else
605
 
        rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING_PTR(desc));
 
616
    rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING_PTR(desc));
 
617
}
 
618
 
 
619
static VALUE
 
620
rb_reg_error_desc(VALUE str, int options, const char *err)
 
621
{
 
622
    char opts[6];
 
623
    VALUE desc = rb_str_buf_new2(err);
 
624
 
 
625
    rb_str_buf_cat2(desc, ": /");
 
626
    rb_reg_expr_str(desc, RSTRING_PTR(str), RSTRING_LEN(str));
 
627
    opts[0] = '/';
 
628
    option_to_str(opts + 1, options);
 
629
    strlcat(opts, arg_kcode(options), sizeof(opts));
 
630
    rb_str_buf_cat2(desc, opts);
 
631
    return rb_exc_new3(rb_eRegexpError, desc);
 
632
}
 
633
 
 
634
static void
 
635
rb_reg_raise_str(VALUE str, int options, const char *err)
 
636
{
 
637
    rb_exc_raise(rb_reg_error_desc(str, options, err));
606
638
}
607
639
 
608
640
 
685
717
}
686
718
 
687
719
static Regexp*
688
 
make_regexp(const char *s, long len, int flags, int ce)
 
720
make_regexp(const char *s, long len, int flags, onig_errmsg_buffer err)
689
721
{
690
722
    Regexp *rp;
691
 
    char err[ONIG_MAX_ERROR_MESSAGE_LEN];
692
723
    int r;
693
724
    OnigErrorInfo einfo;
694
725
 
705
736
                        OnigDefaultSyntax);
706
737
    if (r) {
707
738
        onig_error_code_to_str((UChar*)err, r);
708
 
        rb_reg_raise(s, len, err, 0, ce);
 
739
        return 0;
709
740
    }
710
741
 
711
742
    r = onig_compile(rp, (UChar*)s, (UChar*)(s + len), &einfo);
713
744
    if (r != 0) {
714
745
        onig_free(rp);
715
746
        (void )onig_error_code_to_str((UChar*)err, r, &einfo);
716
 
        rb_reg_raise(s, len, err, 0, ce);
717
747
        return 0;
718
748
    }
719
749
    return rp;
907
937
    }
908
938
 
909
939
    if (need_recompile) {
910
 
        char err[ONIG_MAX_ERROR_MESSAGE_LEN];
 
940
        onig_errmsg_buffer err;
911
941
        int r;
912
942
        OnigErrorInfo einfo;
913
943
        regex_t *reg, *reg2;
924
954
                     reg->options, onigenc_get_default_encoding(),
925
955
                     OnigDefaultSyntax, &einfo);
926
956
        if (r) {
927
 
          onig_error_code_to_str((UChar*)err, r, &einfo);
928
 
          rb_reg_raise((char* )pattern, RREGEXP(re)->len, err, re, Qfalse);
 
957
            onig_error_code_to_str((UChar*)err, r, &einfo);
 
958
            rb_reg_raise((char* )pattern, RREGEXP(re)->len, err, re);
929
959
        }
930
960
 
931
961
        RREGEXP(re)->ptr = reg2;
1016
1046
            return result;
1017
1047
        }
1018
1048
        else {
1019
 
            char err[ONIG_MAX_ERROR_MESSAGE_LEN];
 
1049
            onig_errmsg_buffer err;
1020
1050
            onig_error_code_to_str((UChar*)err, result);
1021
 
            rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, 0, Qfalse);
 
1051
            rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, 0);
1022
1052
        }
1023
1053
    }
1024
1054
 
1076
1106
    if (start == -1) return Qnil;
1077
1107
    end = RMATCH(match)->END(nth);
1078
1108
    len = end - start;
1079
 
    str = rb_str_substr(RMATCH(match)->str, start, len);
 
1109
    str = rb_str_subseq(RMATCH(match)->str, start, len);
1080
1110
    OBJ_INFECT(str, match);
1081
1111
    return str;
1082
1112
}
1106
1136
 
1107
1137
    if (NIL_P(match)) return Qnil;
1108
1138
    if (RMATCH(match)->BEG(0) == -1) return Qnil;
1109
 
    str = rb_str_substr(RMATCH(match)->str, 0, RMATCH(match)->BEG(0));
 
1139
    str = rb_str_subseq(RMATCH(match)->str, 0, RMATCH(match)->BEG(0));
1110
1140
    if (OBJ_TAINTED(match)) OBJ_TAINT(str);
1111
1141
    return str;
1112
1142
}
1133
1163
    if (RMATCH(match)->BEG(0) == -1) return Qnil;
1134
1164
    str = RMATCH(match)->str;
1135
1165
    pos = RMATCH(match)->END(0);
1136
 
    str = rb_str_substr(str, pos, RSTRING_LEN(str) - pos);
 
1166
    str = rb_str_subseq(str, pos, RSTRING_LEN(str) - pos);
1137
1167
    if (OBJ_TAINTED(match)) OBJ_TAINT(str);
1138
1168
    return str;
1139
1169
}
1190
1220
            rb_ary_push(ary, Qnil);
1191
1221
        }
1192
1222
        else {
1193
 
            VALUE str = rb_str_substr(target, regs->beg[i], regs->end[i]-regs->beg[i]);
 
1223
            VALUE str = rb_str_subseq(target, regs->beg[i], regs->end[i]-regs->beg[i]);
1194
1224
            if (taint) OBJ_TAINT(str);
1195
1225
            rb_ary_push(ary, str);
1196
1226
        }
1385
1415
        int taint = OBJ_TAINTED(match);
1386
1416
 
1387
1417
        for (i=0; i<regs->num_regs; i++) {
1388
 
            VALUE str = rb_str_substr(target, regs->beg[i], regs->end[i]-regs->beg[i]);
 
1418
            VALUE str = rb_str_subseq(target, regs->beg[i], regs->end[i]-regs->beg[i]);
1389
1419
            if (taint) OBJ_TAINT(str);
1390
1420
            if (RTEST(rb_yield(str))) {
1391
1421
                rb_ary_push(result, str);
1434
1464
    return RMATCH(match)->str;  /* str is frozen */
1435
1465
}
1436
1466
 
 
1467
static VALUE
 
1468
match_inspect(VALUE match)
 
1469
{
 
1470
    char *cname = rb_obj_classname(match);
 
1471
    VALUE str;
 
1472
    int i;
 
1473
 
 
1474
    str = rb_str_buf_new2("#<");
 
1475
    rb_str_buf_cat2(str, cname);
 
1476
 
 
1477
    for (i = 0; i < RMATCH(match)->regs->num_regs; i++) {
 
1478
        VALUE v;
 
1479
        rb_str_buf_cat2(str, " ");
 
1480
        v = rb_reg_nth_match(i, match);
 
1481
        if (v == Qnil)
 
1482
            rb_str_buf_cat2(str, "nil");
 
1483
        else
 
1484
            rb_str_buf_append(str, rb_str_inspect(v));
 
1485
    }
 
1486
    rb_str_buf_cat2(str, ">");
 
1487
 
 
1488
    return str;
 
1489
}
 
1490
 
1437
1491
VALUE rb_cRegexp;
1438
1492
 
1439
 
static void
1440
 
rb_reg_initialize(VALUE obj, const char *s, long len,
1441
 
    int options,
1442
 
    int ce)                     /* call rb_compile_error() */
 
1493
static int
 
1494
rb_reg_initialize(VALUE obj, const char *s, int len, rb_encoding *enc,
 
1495
                  int options, onig_errmsg_buffer err)
1443
1496
{
1444
1497
    struct RRegexp *re = RREGEXP(obj);
1445
1498
 
1453
1506
    re->ptr = 0;
1454
1507
    re->str = 0;
1455
1508
 
1456
 
    set_re_kcode_by_option(re, options);
 
1509
    if (options & ARG_KCODE_MASK) {
 
1510
        set_re_kcode_by_option(re, options);
 
1511
    }
 
1512
    else {
 
1513
        rb_enc_associate((VALUE)re, enc);
 
1514
    }
1457
1515
 
1458
1516
    if (options & ARG_KCODE_MASK) {
1459
1517
        kcode_set_option((VALUE)re);
1462
1520
        options |= ONIG_OPTION_IGNORECASE;
1463
1521
        FL_SET(re, REG_CASESTATE);
1464
1522
    }
1465
 
    re->ptr = make_regexp(s, len, options & ARG_REG_OPTION_MASK, ce);
 
1523
    re->ptr = make_regexp(s, len, options & ARG_REG_OPTION_MASK, err);
 
1524
    if (!re->ptr) return -1;
1466
1525
    re->str = ALLOC_N(char, len+1);
1467
1526
    memcpy(re->str, s, len);
1468
1527
    re->str[len] = '\0';
1470
1529
    if (options & ARG_KCODE_MASK) {
1471
1530
        kcode_reset_option();
1472
1531
    }
1473
 
    if (ce) FL_SET(obj, REG_LITERAL);
 
1532
    return 0;
 
1533
}
 
1534
 
 
1535
static int
 
1536
rb_reg_initialize_str(VALUE obj, VALUE str, int options, onig_errmsg_buffer err)
 
1537
{
 
1538
    return rb_reg_initialize(obj, RSTRING_PTR(str), RSTRING_LEN(str), rb_enc_get(str),
 
1539
                             options, err);
1474
1540
}
1475
1541
 
1476
1542
static VALUE
1487
1553
}
1488
1554
 
1489
1555
VALUE
1490
 
rb_reg_new(const char *s, long len, int options)
 
1556
rb_reg_new(VALUE s, int options)
1491
1557
{
1492
1558
    VALUE re = rb_reg_s_alloc(rb_cRegexp);
1493
 
 
1494
 
    rb_reg_initialize(re, s, len, options, Qfalse);
1495
 
    return (VALUE)re;
 
1559
    onig_errmsg_buffer err;
 
1560
 
 
1561
    if (rb_reg_initialize_str(re, s, options, err) != 0) {
 
1562
        rb_reg_raise_str(s, options, err);
 
1563
    }
 
1564
 
 
1565
    return re;
1496
1566
}
1497
1567
 
1498
1568
VALUE
1499
 
rb_reg_compile(const char *s, long len, int options)
 
1569
rb_reg_compile(VALUE str, int options)
1500
1570
{
1501
1571
    VALUE re = rb_reg_s_alloc(rb_cRegexp);
 
1572
    onig_errmsg_buffer err;
1502
1573
 
1503
 
    rb_reg_initialize(re, s, len, options, Qtrue);
1504
 
    return (VALUE)re;
 
1574
    if (!str) str = rb_str_new(0,0);
 
1575
    if (rb_reg_initialize_str(re, str, options, err) != 0) {
 
1576
        rb_set_errinfo(rb_reg_error_desc(str, options, err));
 
1577
        return Qnil;
 
1578
    }
 
1579
    FL_SET(re, REG_LITERAL);
 
1580
    return re;
1505
1581
}
1506
1582
 
1507
1583
static int case_cache;
1520
1596
 
1521
1597
    case_cache = ruby_ignorecase;
1522
1598
    kcode_cache = reg_kcode;
1523
 
    return reg_cache = rb_reg_new(RSTRING_PTR(save_str), RSTRING_LEN(save_str),
1524
 
                                  ruby_ignorecase);
 
1599
    return reg_cache = rb_reg_new(save_str, ruby_ignorecase);
1525
1600
}
1526
1601
 
1527
1602
static int
1781
1856
static VALUE
1782
1857
rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
1783
1858
{
1784
 
    const char *s;
1785
 
    long len;
 
1859
    onig_errmsg_buffer err;
1786
1860
    int flags = 0;
 
1861
    VALUE str;
1787
1862
 
1788
1863
    if (argc == 0 || argc > 3) {
1789
1864
        rb_raise(rb_eArgError, "wrong number of arguments");
1797
1872
        if (FL_TEST(argv[0], KCODE_FIXED)) {
1798
1873
            flags |= re_to_kcode_arg_value(argv[0]);
1799
1874
        }
1800
 
        s = RREGEXP(argv[0])->str;
1801
 
        len = RREGEXP(argv[0])->len;
 
1875
        str = rb_enc_str_new(RREGEXP(argv[0])->str, RREGEXP(argv[0])->len,
 
1876
                             rb_enc_get(argv[0]));
1802
1877
    }
1803
1878
    else {
1804
1879
        if (argc >= 2) {
1811
1886
            flags &= ~ARG_KCODE_MASK;
1812
1887
            flags |= char_to_arg_kcode((int )kcode[0]);
1813
1888
        }
1814
 
        s = StringValuePtr(argv[0]);
1815
 
        len = RSTRING_LEN(argv[0]);
1816
 
    }
1817
 
    rb_reg_initialize(self, s, len, flags, Qfalse);
 
1889
        str = argv[0];
 
1890
    }
 
1891
    if (rb_reg_initialize_str(self, str, flags, err) != 0) {
 
1892
        rb_reg_raise_str(str, flags, err);
 
1893
    }
1818
1894
    return self;
1819
1895
}
1820
1896
 
1821
1897
VALUE
1822
1898
rb_reg_quote(VALUE str)
1823
1899
{
 
1900
    rb_encoding *enc = rb_enc_get(str);
1824
1901
    char *s, *send, *t;
1825
1902
    VALUE tmp;
1826
1903
    int c;
1829
1906
    send = s + RSTRING_LEN(str);
1830
1907
    for (; s < send; s++) {
1831
1908
        c = *s;
1832
 
        if (ismbchar(*s)) {
1833
 
            int n = mbclen(*s);
 
1909
        if (ismbchar(s, enc)) {
 
1910
            int n = mbclen(s, enc);
1834
1911
 
1835
1912
            while (n-- && s < send)
1836
1913
                s++;
1858
1935
 
1859
1936
    for (; s < send; s++) {
1860
1937
        c = *s;
1861
 
        if (ismbchar(*s)) {
1862
 
            int n = mbclen(*s);
 
1938
        if (ismbchar(s, enc)) {
 
1939
            int n = mbclen(s, enc);
1863
1940
 
1864
1941
            while (n-- && s < send)
1865
1942
                *t++ = *s++;
1964
2041
    return options;
1965
2042
}
1966
2043
 
 
2044
VALUE
 
2045
rb_check_regexp_type(VALUE re)
 
2046
{
 
2047
    return rb_check_convert_type(re, T_REGEXP, "Regexp", "to_regexp");
 
2048
}
 
2049
 
 
2050
/*
 
2051
 *  call-seq:
 
2052
 *     Regexp.try_convert(obj) -> re or nil
 
2053
 *
 
2054
 *  Try to convert <i>obj</i> into a Regexp, using to_regexp method.
 
2055
 *  Returns converted regexp or nil if <i>obj</i> cannot be converted
 
2056
 *  for any reason.
 
2057
 *
 
2058
 *     Regexp.try_convert(/re/)      # => /re/
 
2059
 *     Regexp.try_convert("re")      # => nil
 
2060
 */
 
2061
static VALUE
 
2062
rb_reg_s_try_convert(VALUE dummy, VALUE re)
 
2063
{
 
2064
    return rb_check_regexp_type(re);
 
2065
}
1967
2066
 
1968
2067
/*
1969
2068
 *  call-seq:
1989
2088
    }
1990
2089
    else if (argc == 1) {
1991
2090
        VALUE v;
1992
 
        v = rb_check_convert_type(argv[0], T_REGEXP, "Regexp", "to_regexp");
 
2091
        v = rb_check_regexp_type(argv[0]);
1993
2092
        if (!NIL_P(v))
1994
2093
            return v;
1995
2094
        else {
2007
2106
            volatile VALUE v;
2008
2107
            if (0 < i)
2009
2108
                rb_str_buf_cat2(source, "|");
2010
 
            v = rb_check_convert_type(argv[i], T_REGEXP, "Regexp", "to_regexp");
 
2109
            v = rb_check_regexp_type(argv[i]);
2011
2110
            if (!NIL_P(v)) {
2012
2111
                if (FL_TEST(v, KCODE_FIXED)) {
2013
2112
                    if (kcode == -1) {
2032
2131
        }
2033
2132
        args[0] = source;
2034
2133
        args[1] = Qnil;
2035
 
        switch (kcode) {
2036
 
          case -1:
 
2134
        if (kcode == -1) {
2037
2135
            args[2] = Qnil;
2038
 
            break;
2039
 
          case KCODE_NONE:
2040
 
            args[2] = rb_str_new2("n");
2041
 
            break;
2042
 
          case KCODE_EUC:
2043
 
            args[2] = rb_str_new2("e");
2044
 
            break;
2045
 
          case KCODE_SJIS:
2046
 
            args[2] = rb_str_new2("s");
2047
 
            break;
2048
 
          case KCODE_UTF8:
2049
 
            args[2] = rb_str_new2("u");
2050
 
            break;
 
2136
        }
 
2137
        else {
 
2138
            args[2] = rb_str_new2(opt_kcode(kcode));
2051
2139
        }
2052
2140
        return rb_class_new_instance(3, args, rb_cRegexp);
2053
2141
    }
2057
2145
static VALUE
2058
2146
rb_reg_init_copy(VALUE copy, VALUE re)
2059
2147
{
 
2148
    onig_errmsg_buffer err;
 
2149
    const char *s;
 
2150
    long len;
 
2151
 
2060
2152
    if (copy == re) return copy;
2061
2153
    rb_check_frozen(copy);
2062
2154
    /* need better argument type check */
2064
2156
        rb_raise(rb_eTypeError, "wrong argument type");
2065
2157
    }
2066
2158
    rb_reg_check(re);
2067
 
    rb_reg_initialize(copy, RREGEXP(re)->str, RREGEXP(re)->len,
2068
 
                      rb_reg_options(re), Qfalse);
 
2159
    s = RREGEXP(re)->str;
 
2160
    len = RREGEXP(re)->len;
 
2161
    if (rb_reg_initialize(copy, s, len, rb_enc_get(re), rb_reg_options(re), err) != 0) {
 
2162
        rb_reg_raise(s, len, err, re);
 
2163
    }
2069
2164
    return copy;
2070
2165
}
2071
2166
 
2076
2171
    char *p, *s, *e;
2077
2172
    unsigned char uc;
2078
2173
    int no;
2079
 
 
2080
 
 
 
2174
    rb_encoding *enc = rb_enc_check(str, src);
 
2175
 
 
2176
    rb_enc_check(str, regexp);
2081
2177
    p = s = RSTRING_PTR(str);
2082
2178
    e = s + RSTRING_LEN(str);
2083
2179
 
2084
2180
    while (s < e) {
2085
 
        char *ss = s;
 
2181
        char *ss = s++;
2086
2182
 
2087
 
        uc = (unsigned char)*s++;
2088
 
        if (ismbchar(uc)) {
2089
 
            s += mbclen(uc) - 1;
 
2183
        if (ismbchar(ss, enc)) {
 
2184
            s += mbclen(ss, enc) - 1;
2090
2185
            continue;
2091
2186
        }
2092
 
        if (uc != '\\' || s == e) continue;
 
2187
        if (*ss != '\\' || s == e) continue;
2093
2188
 
2094
2189
        if (!val) {
2095
2190
            val = rb_str_buf_new(ss-p);
2119
2214
              name_end = name = s + 1;
2120
2215
              while (name_end < e) {
2121
2216
                if (*name_end == '>') break;
2122
 
                uc = (unsigned char)*name_end;
2123
 
                name_end += mbclen(uc);
 
2217
                name_end += mbclen(name_end, enc);
2124
2218
              }
2125
2219
              if (name_end < e) {
2126
2220
                no = name_to_backref_number(regs, regexp, name, name_end);
2289
2383
 *  <code>MatchData</code> object.
2290
2384
 *
2291
2385
 *     /c(.)t/ =~ 'cat'       #=> 0
2292
 
 *     Regexp.last_match      #=> #<MatchData:0x401b3d30>
 
2386
 *     Regexp.last_match      #=> #<MatchData "cat" "a">
2293
2387
 *     Regexp.last_match(0)   #=> "cat"
2294
2388
 *     Regexp.last_match(1)   #=> "a"
2295
2389
 *     Regexp.last_match(2)   #=> nil
2354
2448
    rb_define_singleton_method(rb_cRegexp, "escape", rb_reg_s_quote, -1);
2355
2449
    rb_define_singleton_method(rb_cRegexp, "union", rb_reg_s_union, -1);
2356
2450
    rb_define_singleton_method(rb_cRegexp, "last_match", rb_reg_s_last_match, -1);
 
2451
    rb_define_singleton_method(rb_cRegexp, "try_convert", rb_reg_s_try_convert, 1);
2357
2452
 
2358
2453
    rb_define_method(rb_cRegexp, "initialize", rb_reg_initialize_m, -1);
2359
2454
    rb_define_method(rb_cRegexp, "initialize_copy", rb_reg_init_copy, 1);
2396
2491
    rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
2397
2492
    rb_define_method(rb_cMatch, "post_match", rb_reg_match_post, 0);
2398
2493
    rb_define_method(rb_cMatch, "to_s", match_to_s, 0);
2399
 
    rb_define_method(rb_cMatch, "inspect", rb_any_to_s, 0); /* in object.c */
 
2494
    rb_define_method(rb_cMatch, "inspect", match_inspect, 0);
2400
2495
    rb_define_method(rb_cMatch, "string", match_string, 0);
2401
2496
}