Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

strscan.c
Go to the documentation of this file.
1 /*
2 $Id: strscan.c 44903 2014-02-10 11:45:14Z naruse $
3
4 Copyright (c) 1999-2006 Minero Aoki
5
6 This program is free software.
7 You can distribute/modify this program under the terms of
8 the Ruby License. For details, see the file COPYING.
9 */
10
11 #include "ruby/ruby.h"
12 #include "ruby/re.h"
13 #include "ruby/encoding.h"
14 #include "regint.h"
15
16 #define STRSCAN_VERSION "0.7.0"
17
18 /* =======================================================================
19 Data Type Definitions
20 ======================================================================= */
21
22 static VALUE StringScanner;
23 static VALUE ScanError;
24 static ID id_byteslice;
25
26 struct strscanner
27 {
28 /* multi-purpose flags */
29 unsigned long flags;
30 #define FLAG_MATCHED (1 << 0)
31
32 /* the string to scan */
33 VALUE str;
34
35 /* scan pointers */
36 long prev; /* legal only when MATCHED_P(s) */
37 long curr; /* always legal */
38
39 /* the regexp register; legal only when MATCHED_P(s) */
40 struct re_registers regs;
41
42 /* regexp used for last scan */
43 VALUE regex;
44 };
45
46 #define MATCHED_P(s) ((s)->flags & FLAG_MATCHED)
47 #define MATCHED(s) (s)->flags |= FLAG_MATCHED
48 #define CLEAR_MATCH_STATUS(s) (s)->flags &= ~FLAG_MATCHED
49
50 #define S_PBEG(s) (RSTRING_PTR((s)->str))
51 #define S_LEN(s) (RSTRING_LEN((s)->str))
52 #define S_PEND(s) (S_PBEG(s) + S_LEN(s))
53 #define CURPTR(s) (S_PBEG(s) + (s)->curr)
54 #define S_RESTLEN(s) (S_LEN(s) - (s)->curr)
55
56 #define EOS_P(s) ((s)->curr >= RSTRING_LEN(p->str))
57
58 #define GET_SCANNER(obj,var) do {\
59 (var) = check_strscan(obj);\
60 if (NIL_P((var)->str)) rb_raise(rb_eArgError, "uninitialized StringScanner object");\
61 } while (0)
62
63 /* =======================================================================
64 Function Prototypes
65 ======================================================================= */
66
67 static VALUE infect _((VALUE str, struct strscanner *p));
68 static VALUE extract_range _((struct strscanner *p, long beg_i, long end_i));
69 static VALUE extract_beg_len _((struct strscanner *p, long beg_i, long len));
70
71 static struct strscanner *check_strscan _((VALUE obj));
72 static void strscan_mark _((void *p));
73 static void strscan_free _((void *p));
74 static size_t strscan_memsize _((const void *p));
75 static VALUE strscan_s_allocate _((VALUE klass));
76 static VALUE strscan_initialize _((int argc, VALUE *argv, VALUE self));
77 static VALUE strscan_init_copy _((VALUE vself, VALUE vorig));
78
79 static VALUE strscan_s_mustc _((VALUE self));
80 static VALUE strscan_terminate _((VALUE self));
81 static VALUE strscan_clear _((VALUE self));
82 static VALUE strscan_get_string _((VALUE self));
83 static VALUE strscan_set_string _((VALUE self, VALUE str));
84 static VALUE strscan_concat _((VALUE self, VALUE str));
85 static VALUE strscan_get_pos _((VALUE self));
86 static VALUE strscan_set_pos _((VALUE self, VALUE pos));
87 static VALUE strscan_do_scan _((VALUE self, VALUE regex,
88 int succptr, int getstr, int headonly));
89 static VALUE strscan_scan _((VALUE self, VALUE re));
90 static VALUE strscan_match_p _((VALUE self, VALUE re));
91 static VALUE strscan_skip _((VALUE self, VALUE re));
92 static VALUE strscan_check _((VALUE self, VALUE re));
93 static VALUE strscan_scan_full _((VALUE self, VALUE re,
94 VALUE succp, VALUE getp));
95 static VALUE strscan_scan_until _((VALUE self, VALUE re));
96 static VALUE strscan_skip_until _((VALUE self, VALUE re));
97 static VALUE strscan_check_until _((VALUE self, VALUE re));
98 static VALUE strscan_search_full _((VALUE self, VALUE re,
99 VALUE succp, VALUE getp));
100 static void adjust_registers_to_matched _((struct strscanner *p));
101 static VALUE strscan_getch _((VALUE self));
102 static VALUE strscan_get_byte _((VALUE self));
103 static VALUE strscan_getbyte _((VALUE self));
104 static VALUE strscan_peek _((VALUE self, VALUE len));
105 static VALUE strscan_peep _((VALUE self, VALUE len));
106 static VALUE strscan_unscan _((VALUE self));
107 static VALUE strscan_bol_p _((VALUE self));
108 static VALUE strscan_eos_p _((VALUE self));
109 static VALUE strscan_empty_p _((VALUE self));
110 static VALUE strscan_rest_p _((VALUE self));
111 static VALUE strscan_matched_p _((VALUE self));
112 static VALUE strscan_matched _((VALUE self));
113 static VALUE strscan_matched_size _((VALUE self));
114 static VALUE strscan_aref _((VALUE self, VALUE idx));
115 static VALUE strscan_pre_match _((VALUE self));
116 static VALUE strscan_post_match _((VALUE self));
117 static VALUE strscan_rest _((VALUE self));
118 static VALUE strscan_rest_size _((VALUE self));
119
120 static VALUE strscan_inspect _((VALUE self));
121 static VALUE inspect1 _((struct strscanner *p));
122 static VALUE inspect2 _((struct strscanner *p));
123
124 /* =======================================================================
125 Utils
126 ======================================================================= */
127
128 static VALUE
129 infect(VALUE str, struct strscanner *p)
130 {
131 OBJ_INFECT(str, p->str);
132 return str;
133 }
134
135 static VALUE
136 str_new(struct strscanner *p, const char *ptr, long len)
137 {
138 VALUE str = rb_str_new(ptr, len);
139 rb_enc_copy(str, p->str);
140 return str;
141 }
142
143 static VALUE
144 extract_range(struct strscanner *p, long beg_i, long end_i)
145 {
146 if (beg_i > S_LEN(p)) return Qnil;
147 if (end_i > S_LEN(p))
148 end_i = S_LEN(p);
149 return infect(str_new(p, S_PBEG(p) + beg_i, end_i - beg_i), p);
150 }
151
152 static VALUE
153 extract_beg_len(struct strscanner *p, long beg_i, long len)
154 {
155 if (beg_i > S_LEN(p)) return Qnil;
156 if (beg_i + len > S_LEN(p))
157 len = S_LEN(p) - beg_i;
158 return infect(str_new(p, S_PBEG(p) + beg_i, len), p);
159 }
160
161 /* =======================================================================
162 Constructor
163 ======================================================================= */
164
165 static void
166 strscan_mark(void *ptr)
167 {
168 struct strscanner *p = ptr;
169 rb_gc_mark(p->str);
170 }
171
172 static void
173 strscan_free(void *ptr)
174 {
175 struct strscanner *p = ptr;
176 onig_region_free(&(p->regs), 0);
177 ruby_xfree(p);
178 }
179
180 static size_t
181 strscan_memsize(const void *ptr)
182 {
183 const struct strscanner *p = ptr;
184 size_t size = 0;
185 if (p) {
186 size = sizeof(*p) - sizeof(p->regs) + onig_region_memsize(&p->regs);
187 }
188 return size;
189 }
190
191 static const rb_data_type_t strscanner_type = {
192 "StringScanner",
193 {strscan_mark, strscan_free, strscan_memsize},
194 NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
195 };
196
197 static VALUE
198 strscan_s_allocate(VALUE klass)
199 {
200 struct strscanner *p;
201
202 p = ALLOC(struct strscanner);
203 MEMZERO(p, struct strscanner, 1);
204 CLEAR_MATCH_STATUS(p);
205 onig_region_init(&(p->regs));
206 p->str = Qnil;
207 return TypedData_Wrap_Struct(klass, &strscanner_type, p);
208 }
209
210 /*
211 * call-seq: StringScanner.new(string, dup = false)
212 *
213 * Creates a new StringScanner object to scan over the given +string+.
214 * +dup+ argument is obsolete and not used now.
215 */
216 static VALUE
217 strscan_initialize(int argc, VALUE *argv, VALUE self)
218 {
219 struct strscanner *p;
220 VALUE str, need_dup;
221
222 p = check_strscan(self);
223 rb_scan_args(argc, argv, "11", &str, &need_dup);
224 StringValue(str);
225 p->str = str;
226
227 return self;
228 }
229
230 static struct strscanner *
231 check_strscan(VALUE obj)
232 {
233 return rb_check_typeddata(obj, &strscanner_type);
234 }
235
236 /*
237 * call-seq:
238 * dup
239 * clone
240 *
241 * Duplicates a StringScanner object.
242 */
243 static VALUE
244 strscan_init_copy(VALUE vself, VALUE vorig)
245 {
246 struct strscanner *self, *orig;
247
248 self = check_strscan(vself);
249 orig = check_strscan(vorig);
250 if (self != orig) {
251 self->flags = orig->flags;
252 self->str = orig->str;
253 self->prev = orig->prev;
254 self->curr = orig->curr;
255 onig_region_copy(&self->regs, &orig->regs);
256 }
257
258 return vself;
259 }
260
261 /* =======================================================================
262 Instance Methods
263 ======================================================================= */
264
265 /*
266 * call-seq: StringScanner.must_C_version
267 *
268 * This method is defined for backward compatibility.
269 */
270 static VALUE
271 strscan_s_mustc(VALUE self)
272 {
273 return self;
274 }
275
276 /*
277 * Reset the scan pointer (index 0) and clear matching data.
278 */
279 static VALUE
280 strscan_reset(VALUE self)
281 {
282 struct strscanner *p;
283
284 GET_SCANNER(self, p);
285 p->curr = 0;
286 CLEAR_MATCH_STATUS(p);
287 return self;
288 }
289
290 /*
291 * call-seq:
292 * terminate
293 * clear
294 *
295 * Set the scan pointer to the end of the string and clear matching data.
296 */
297 static VALUE
298 strscan_terminate(VALUE self)
299 {
300 struct strscanner *p;
301
302 GET_SCANNER(self, p);
303 p->curr = S_LEN(p);
304 CLEAR_MATCH_STATUS(p);
305 return self;
306 }
307
308 /*
309 * Equivalent to #terminate.
310 * This method is obsolete; use #terminate instead.
311 */
312 static VALUE
313 strscan_clear(VALUE self)
314 {
315 rb_warning("StringScanner#clear is obsolete; use #terminate instead");
316 return strscan_terminate(self);
317 }
318
319 /*
320 * Returns the string being scanned.
321 */
322 static VALUE
323 strscan_get_string(VALUE self)
324 {
325 struct strscanner *p;
326
327 GET_SCANNER(self, p);
328 return p->str;
329 }
330
331 /*
332 * call-seq: string=(str)
333 *
334 * Changes the string being scanned to +str+ and resets the scanner.
335 * Returns +str+.
336 */
337 static VALUE
338 strscan_set_string(VALUE self, VALUE str)
339 {
340 struct strscanner *p = check_strscan(self);
341
342 StringValue(str);
343 p->str = str;
344 p->curr = 0;
345 CLEAR_MATCH_STATUS(p);
346 return str;
347 }
348
349 /*
350 * call-seq:
351 * concat(str)
352 * <<(str)
353 *
354 * Appends +str+ to the string being scanned.
355 * This method does not affect scan pointer.
356 *
357 * s = StringScanner.new("Fri Dec 12 1975 14:39")
358 * s.scan(/Fri /)
359 * s << " +1000 GMT"
360 * s.string # -> "Fri Dec 12 1975 14:39 +1000 GMT"
361 * s.scan(/Dec/) # -> "Dec"
362 */
363 static VALUE
364 strscan_concat(VALUE self, VALUE str)
365 {
366 struct strscanner *p;
367
368 GET_SCANNER(self, p);
369 StringValue(str);
370 rb_str_append(p->str, str);
371 return self;
372 }
373
374 /*
375 * Returns the byte position of the scan pointer. In the 'reset' position, this
376 * value is zero. In the 'terminated' position (i.e. the string is exhausted),
377 * this value is the bytesize of the string.
378 *
379 * In short, it's a 0-based index into bytes of the string.
380 *
381 * s = StringScanner.new('test string')
382 * s.pos # -> 0
383 * s.scan_until /str/ # -> "test str"
384 * s.pos # -> 8
385 * s.terminate # -> #<StringScanner fin>
386 * s.pos # -> 11
387 */
388 static VALUE
389 strscan_get_pos(VALUE self)
390 {
391 struct strscanner *p;
392
393 GET_SCANNER(self, p);
394 return INT2FIX(p->curr);
395 }
396
397 /*
398 * Returns the character position of the scan pointer. In the 'reset' position, this
399 * value is zero. In the 'terminated' position (i.e. the string is exhausted),
400 * this value is the size of the string.
401 *
402 * In short, it's a 0-based index into the string.
403 *
404 * s = StringScanner.new("abcädeföghi")
405 * s.charpos # -> 0
406 * s.scan_until(/ä/) # -> "abcä"
407 * s.pos # -> 5
408 * s.charpos # -> 4
409 */
410 static VALUE
411 strscan_get_charpos(VALUE self)
412 {
413 struct strscanner *p;
414 VALUE substr;
415
416 GET_SCANNER(self, p);
417
418 substr = rb_funcall(p->str, id_byteslice, 2, INT2FIX(0), INT2NUM(p->curr));
419
420 return rb_str_length(substr);
421 }
422
423 /*
424 * call-seq: pos=(n)
425 *
426 * Set the byte position of the scan pointer.
427 *
428 * s = StringScanner.new('test string')
429 * s.pos = 7 # -> 7
430 * s.rest # -> "ring"
431 */
432 static VALUE
433 strscan_set_pos(VALUE self, VALUE v)
434 {
435 struct strscanner *p;
436 long i;
437
438 GET_SCANNER(self, p);
439 i = NUM2INT(v);
440 if (i < 0) i += S_LEN(p);
441 if (i < 0) rb_raise(rb_eRangeError, "index out of range");
442 if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range");
443 p->curr = i;
444 return INT2NUM(i);
445 }
446
447 static VALUE
448 strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
449 {
450 regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
451 struct strscanner *p;
452 regex_t *re;
453 long ret;
454 int tmpreg;
455
456 Check_Type(regex, T_REGEXP);
457 GET_SCANNER(self, p);
458
459 CLEAR_MATCH_STATUS(p);
460 if (S_RESTLEN(p) < 0) {
461 return Qnil;
462 }
463
464 p->regex = regex;
465 re = rb_reg_prepare_re(regex, p->str);
466 tmpreg = re != RREGEXP(regex)->ptr;
467 if (!tmpreg) RREGEXP(regex)->usecnt++;
468
469 if (headonly) {
470 ret = onig_match(re, (UChar* )CURPTR(p),
471 (UChar* )(CURPTR(p) + S_RESTLEN(p)),
472 (UChar* )CURPTR(p), &(p->regs), ONIG_OPTION_NONE);
473 }
474 else {
475 ret = onig_search(re,
476 (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
477 (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
478 &(p->regs), ONIG_OPTION_NONE);
479 }
480 if (!tmpreg) RREGEXP(regex)->usecnt--;
481 if (tmpreg) {
482 if (RREGEXP(regex)->usecnt) {
483 onig_free(re);
484 }
485 else {
486 onig_free(RREGEXP(regex)->ptr);
487 RREGEXP(regex)->ptr = re;
488 }
489 }
490
491 if (ret == -2) rb_raise(ScanError, "regexp buffer overflow");
492 if (ret < 0) {
493 /* not matched */
494 return Qnil;
495 }
496
497 MATCHED(p);
498 p->prev = p->curr;
499 if (succptr) {
500 p->curr += p->regs.end[0];
501 }
502 if (getstr) {
503 return extract_beg_len(p, p->prev, p->regs.end[0]);
504 }
505 else {
506 return INT2FIX(p->regs.end[0]);
507 }
508 }
509
510 /*
511 * call-seq: scan(pattern) => String
512 *
513 * Tries to match with +pattern+ at the current position. If there's a match,
514 * the scanner advances the "scan pointer" and returns the matched string.
515 * Otherwise, the scanner returns +nil+.
516 *
517 * s = StringScanner.new('test string')
518 * p s.scan(/\w+/) # -> "test"
519 * p s.scan(/\w+/) # -> nil
520 * p s.scan(/\s+/) # -> " "
521 * p s.scan(/\w+/) # -> "string"
522 * p s.scan(/./) # -> nil
523 *
524 */
525 static VALUE
526 strscan_scan(VALUE self, VALUE re)
527 {
528 return strscan_do_scan(self, re, 1, 1, 1);
529 }
530
531 /*
532 * call-seq: match?(pattern)
533 *
534 * Tests whether the given +pattern+ is matched from the current scan pointer.
535 * Returns the length of the match, or +nil+. The scan pointer is not advanced.
536 *
537 * s = StringScanner.new('test string')
538 * p s.match?(/\w+/) # -> 4
539 * p s.match?(/\w+/) # -> 4
540 * p s.match?(/\s+/) # -> nil
541 */
542 static VALUE
543 strscan_match_p(VALUE self, VALUE re)
544 {
545 return strscan_do_scan(self, re, 0, 0, 1);
546 }
547
548 /*
549 * call-seq: skip(pattern)
550 *
551 * Attempts to skip over the given +pattern+ beginning with the scan pointer.
552 * If it matches, the scan pointer is advanced to the end of the match, and the
553 * length of the match is returned. Otherwise, +nil+ is returned.
554 *
555 * It's similar to #scan, but without returning the matched string.
556 *
557 * s = StringScanner.new('test string')
558 * p s.skip(/\w+/) # -> 4
559 * p s.skip(/\w+/) # -> nil
560 * p s.skip(/\s+/) # -> 1
561 * p s.skip(/\w+/) # -> 6
562 * p s.skip(/./) # -> nil
563 *
564 */
565 static VALUE
566 strscan_skip(VALUE self, VALUE re)
567 {
568 return strscan_do_scan(self, re, 1, 0, 1);
569 }
570
571 /*
572 * call-seq: check(pattern)
573 *
574 * This returns the value that #scan would return, without advancing the scan
575 * pointer. The match register is affected, though.
576 *
577 * s = StringScanner.new("Fri Dec 12 1975 14:39")
578 * s.check /Fri/ # -> "Fri"
579 * s.pos # -> 0
580 * s.matched # -> "Fri"
581 * s.check /12/ # -> nil
582 * s.matched # -> nil
583 *
584 * Mnemonic: it "checks" to see whether a #scan will return a value.
585 */
586 static VALUE
587 strscan_check(VALUE self, VALUE re)
588 {
589 return strscan_do_scan(self, re, 0, 1, 1);
590 }
591
592 /*
593 * call-seq: scan_full(pattern, advance_pointer_p, return_string_p)
594 *
595 * Tests whether the given +pattern+ is matched from the current scan pointer.
596 * Advances the scan pointer if +advance_pointer_p+ is true.
597 * Returns the matched string if +return_string_p+ is true.
598 * The match register is affected.
599 *
600 * "full" means "#scan with full parameters".
601 */
602 static VALUE
603 strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f)
604 {
605 return strscan_do_scan(self, re, RTEST(s), RTEST(f), 1);
606 }
607
608 /*
609 * call-seq: scan_until(pattern)
610 *
611 * Scans the string _until_ the +pattern+ is matched. Returns the substring up
612 * to and including the end of the match, advancing the scan pointer to that
613 * location. If there is no match, +nil+ is returned.
614 *
615 * s = StringScanner.new("Fri Dec 12 1975 14:39")
616 * s.scan_until(/1/) # -> "Fri Dec 1"
617 * s.pre_match # -> "Fri Dec "
618 * s.scan_until(/XYZ/) # -> nil
619 */
620 static VALUE
621 strscan_scan_until(VALUE self, VALUE re)
622 {
623 return strscan_do_scan(self, re, 1, 1, 0);
624 }
625
626 /*
627 * call-seq: exist?(pattern)
628 *
629 * Looks _ahead_ to see if the +pattern+ exists _anywhere_ in the string,
630 * without advancing the scan pointer. This predicates whether a #scan_until
631 * will return a value.
632 *
633 * s = StringScanner.new('test string')
634 * s.exist? /s/ # -> 3
635 * s.scan /test/ # -> "test"
636 * s.exist? /s/ # -> 2
637 * s.exist? /e/ # -> nil
638 */
639 static VALUE
640 strscan_exist_p(VALUE self, VALUE re)
641 {
642 return strscan_do_scan(self, re, 0, 0, 0);
643 }
644
645 /*
646 * call-seq: skip_until(pattern)
647 *
648 * Advances the scan pointer until +pattern+ is matched and consumed. Returns
649 * the number of bytes advanced, or +nil+ if no match was found.
650 *
651 * Look ahead to match +pattern+, and advance the scan pointer to the _end_
652 * of the match. Return the number of characters advanced, or +nil+ if the
653 * match was unsuccessful.
654 *
655 * It's similar to #scan_until, but without returning the intervening string.
656 *
657 * s = StringScanner.new("Fri Dec 12 1975 14:39")
658 * s.skip_until /12/ # -> 10
659 * s #
660 */
661 static VALUE
662 strscan_skip_until(VALUE self, VALUE re)
663 {
664 return strscan_do_scan(self, re, 1, 0, 0);
665 }
666
667 /*
668 * call-seq: check_until(pattern)
669 *
670 * This returns the value that #scan_until would return, without advancing the
671 * scan pointer. The match register is affected, though.
672 *
673 * s = StringScanner.new("Fri Dec 12 1975 14:39")
674 * s.check_until /12/ # -> "Fri Dec 12"
675 * s.pos # -> 0
676 * s.matched # -> 12
677 *
678 * Mnemonic: it "checks" to see whether a #scan_until will return a value.
679 */
680 static VALUE
681 strscan_check_until(VALUE self, VALUE re)
682 {
683 return strscan_do_scan(self, re, 0, 1, 0);
684 }
685
686 /*
687 * call-seq: search_full(pattern, advance_pointer_p, return_string_p)
688 *
689 * Scans the string _until_ the +pattern+ is matched.
690 * Advances the scan pointer if +advance_pointer_p+, otherwise not.
691 * Returns the matched string if +return_string_p+ is true, otherwise
692 * returns the number of bytes advanced.
693 * This method does affect the match register.
694 */
695 static VALUE
696 strscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f)
697 {
698 return strscan_do_scan(self, re, RTEST(s), RTEST(f), 0);
699 }
700
701 static void
702 adjust_registers_to_matched(struct strscanner *p)
703 {
704 onig_region_clear(&(p->regs));
705 onig_region_set(&(p->regs), 0, 0, (int)(p->curr - p->prev));
706 }
707
708 /*
709 * Scans one character and returns it.
710 * This method is multibyte character sensitive.
711 *
712 * s = StringScanner.new("ab")
713 * s.getch # => "a"
714 * s.getch # => "b"
715 * s.getch # => nil
716 *
717 * $KCODE = 'EUC'
718 * s = StringScanner.new("\244\242")
719 * s.getch # => "\244\242" # Japanese hira-kana "A" in EUC-JP
720 * s.getch # => nil
721 */
722 static VALUE
723 strscan_getch(VALUE self)
724 {
725 struct strscanner *p;
726 long len;
727
728 GET_SCANNER(self, p);
729 CLEAR_MATCH_STATUS(p);
730 if (EOS_P(p))
731 return Qnil;
732
733 len = rb_enc_mbclen(CURPTR(p), S_PEND(p), rb_enc_get(p->str));
734 if (p->curr + len > S_LEN(p)) {
735 len = S_LEN(p) - p->curr;
736 }
737 p->prev = p->curr;
738 p->curr += len;
739 MATCHED(p);
740 adjust_registers_to_matched(p);
741 return extract_range(p, p->prev + p->regs.beg[0],
742 p->prev + p->regs.end[0]);
743 }
744
745 /*
746 * Scans one byte and returns it.
747 * This method is not multibyte character sensitive.
748 * See also: #getch.
749 *
750 * s = StringScanner.new('ab')
751 * s.get_byte # => "a"
752 * s.get_byte # => "b"
753 * s.get_byte # => nil
754 *
755 * $KCODE = 'EUC'
756 * s = StringScanner.new("\244\242")
757 * s.get_byte # => "\244"
758 * s.get_byte # => "\242"
759 * s.get_byte # => nil
760 */
761 static VALUE
762 strscan_get_byte(VALUE self)
763 {
764 struct strscanner *p;
765
766 GET_SCANNER(self, p);
767 CLEAR_MATCH_STATUS(p);
768 if (EOS_P(p))
769 return Qnil;
770
771 p->prev = p->curr;
772 p->curr++;
773 MATCHED(p);
774 adjust_registers_to_matched(p);
775 return extract_range(p, p->prev + p->regs.beg[0],
776 p->prev + p->regs.end[0]);
777 }
778
779 /*
780 * Equivalent to #get_byte.
781 * This method is obsolete; use #get_byte instead.
782 */
783 static VALUE
784 strscan_getbyte(VALUE self)
785 {
786 rb_warning("StringScanner#getbyte is obsolete; use #get_byte instead");
787 return strscan_get_byte(self);
788 }
789
790 /*
791 * call-seq: peek(len)
792 *
793 * Extracts a string corresponding to <tt>string[pos,len]</tt>, without
794 * advancing the scan pointer.
795 *
796 * s = StringScanner.new('test string')
797 * s.peek(7) # => "test st"
798 * s.peek(7) # => "test st"
799 *
800 */
801 static VALUE
802 strscan_peek(VALUE self, VALUE vlen)
803 {
804 struct strscanner *p;
805 long len;
806
807 GET_SCANNER(self, p);
808
809 len = NUM2LONG(vlen);
810 if (EOS_P(p))
811 return infect(str_new(p, "", 0), p);
812
813 if (p->curr + len > S_LEN(p))
814 len = S_LEN(p) - p->curr;
815 return extract_beg_len(p, p->curr, len);
816 }
817
818 /*
819 * Equivalent to #peek.
820 * This method is obsolete; use #peek instead.
821 */
822 static VALUE
823 strscan_peep(VALUE self, VALUE vlen)
824 {
825 rb_warning("StringScanner#peep is obsolete; use #peek instead");
826 return strscan_peek(self, vlen);
827 }
828
829 /*
830 * Set the scan pointer to the previous position. Only one previous position is
831 * remembered, and it changes with each scanning operation.
832 *
833 * s = StringScanner.new('test string')
834 * s.scan(/\w+/) # => "test"
835 * s.unscan
836 * s.scan(/../) # => "te"
837 * s.scan(/\d/) # => nil
838 * s.unscan # ScanError: unscan failed: previous match record not exist
839 */
840 static VALUE
841 strscan_unscan(VALUE self)
842 {
843 struct strscanner *p;
844
845 GET_SCANNER(self, p);
846 if (! MATCHED_P(p))
847 rb_raise(ScanError, "unscan failed: previous match record not exist");
848 p->curr = p->prev;
849 CLEAR_MATCH_STATUS(p);
850 return self;
851 }
852
853 /*
854 * Returns +true+ iff the scan pointer is at the beginning of the line.
855 *
856 * s = StringScanner.new("test\ntest\n")
857 * s.bol? # => true
858 * s.scan(/te/)
859 * s.bol? # => false
860 * s.scan(/st\n/)
861 * s.bol? # => true
862 * s.terminate
863 * s.bol? # => true
864 */
865 static VALUE
866 strscan_bol_p(VALUE self)
867 {
868 struct strscanner *p;
869
870 GET_SCANNER(self, p);
871 if (CURPTR(p) > S_PEND(p)) return Qnil;
872 if (p->curr == 0) return Qtrue;
873 return (*(CURPTR(p) - 1) == '\n') ? Qtrue : Qfalse;
874 }
875
876 /*
877 * Returns +true+ if the scan pointer is at the end of the string.
878 *
879 * s = StringScanner.new('test string')
880 * p s.eos? # => false
881 * s.scan(/test/)
882 * p s.eos? # => false
883 * s.terminate
884 * p s.eos? # => true
885 */
886 static VALUE
887 strscan_eos_p(VALUE self)
888 {
889 struct strscanner *p;
890
891 GET_SCANNER(self, p);
892 return EOS_P(p) ? Qtrue : Qfalse;
893 }
894
895 /*
896 * Equivalent to #eos?.
897 * This method is obsolete, use #eos? instead.
898 */
899 static VALUE
900 strscan_empty_p(VALUE self)
901 {
902 rb_warning("StringScanner#empty? is obsolete; use #eos? instead");
903 return strscan_eos_p(self);
904 }
905
906 /*
907 * Returns true iff there is more data in the string. See #eos?.
908 * This method is obsolete; use #eos? instead.
909 *
910 * s = StringScanner.new('test string')
911 * s.eos? # These two
912 * s.rest? # are opposites.
913 */
914 static VALUE
915 strscan_rest_p(VALUE self)
916 {
917 struct strscanner *p;
918
919 GET_SCANNER(self, p);
920 return EOS_P(p) ? Qfalse : Qtrue;
921 }
922
923 /*
924 * Returns +true+ iff the last match was successful.
925 *
926 * s = StringScanner.new('test string')
927 * s.match?(/\w+/) # => 4
928 * s.matched? # => true
929 * s.match?(/\d+/) # => nil
930 * s.matched? # => false
931 */
932 static VALUE
933 strscan_matched_p(VALUE self)
934 {
935 struct strscanner *p;
936
937 GET_SCANNER(self, p);
938 return MATCHED_P(p) ? Qtrue : Qfalse;
939 }
940
941 /*
942 * Returns the last matched string.
943 *
944 * s = StringScanner.new('test string')
945 * s.match?(/\w+/) # -> 4
946 * s.matched # -> "test"
947 */
948 static VALUE
949 strscan_matched(VALUE self)
950 {
951 struct strscanner *p;
952
953 GET_SCANNER(self, p);
954 if (! MATCHED_P(p)) return Qnil;
955 return extract_range(p, p->prev + p->regs.beg[0],
956 p->prev + p->regs.end[0]);
957 }
958
959 /*
960 * Returns the size of the most recent match (see #matched), or +nil+ if there
961 * was no recent match.
962 *
963 * s = StringScanner.new('test string')
964 * s.check /\w+/ # -> "test"
965 * s.matched_size # -> 4
966 * s.check /\d+/ # -> nil
967 * s.matched_size # -> nil
968 */
969 static VALUE
970 strscan_matched_size(VALUE self)
971 {
972 struct strscanner *p;
973
974 GET_SCANNER(self, p);
975 if (! MATCHED_P(p)) return Qnil;
976 return INT2NUM(p->regs.end[0] - p->regs.beg[0]);
977 }
978
979 static int
980 name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name, const char* name_end)
981 {
982 int num;
983
984 num = onig_name_to_backref_number(RREGEXP(regexp)->ptr,
985 (const unsigned char* )name, (const unsigned char* )name_end, regs);
986 if (num >= 1) {
987 return num;
988 }
989 else {
990 VALUE s = rb_str_new(name, (long )(name_end - name));
991 rb_raise(rb_eIndexError, "undefined group name reference: %s",
992 StringValuePtr(s));
993 }
994
995 UNREACHABLE;
996 }
997
998 /*
999 * call-seq: [](n)
1000 *
1001 * Return the n-th subgroup in the most recent match.
1002 *
1003 * s = StringScanner.new("Fri Dec 12 1975 14:39")
1004 * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
1005 * s[0] # -> "Fri Dec 12 "
1006 * s[1] # -> "Fri"
1007 * s[2] # -> "Dec"
1008 * s[3] # -> "12"
1009 * s.post_match # -> "1975 14:39"
1010 * s.pre_match # -> ""
1011 *
1012 * s.reset
1013 * s.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /) # -> "Fri Dec 12 "
1014 * s[0] # -> "Fri Dec 12 "
1015 * s[1] # -> "Fri"
1016 * s[2] # -> "Dec"
1017 * s[3] # -> "12"
1018 * s[:wday] # -> "Fri"
1019 * s[:month] # -> "Dec"
1020 * s[:day] # -> "12"
1021 * s.post_match # -> "1975 14:39"
1022 * s.pre_match # -> ""
1023 */
1024 static VALUE
1025 strscan_aref(VALUE self, VALUE idx)
1026 {
1027 const char *name;
1028 struct strscanner *p;
1029 long i;
1030
1031 GET_SCANNER(self, p);
1032 if (! MATCHED_P(p)) return Qnil;
1033
1034 switch (TYPE(idx)) {
1035 case T_SYMBOL:
1036 name = rb_id2name(SYM2ID(idx));
1037 goto name_to_backref;
1038 break;
1039 case T_STRING:
1040 name = StringValuePtr(idx);
1041 name_to_backref:
1042 i = name_to_backref_number(&(p->regs), p->regex, name, name + strlen(name));
1043 break;
1044 default:
1045 i = NUM2LONG(idx);
1046 }
1047
1048 if (i < 0)
1049 i += p->regs.num_regs;
1050 if (i < 0) return Qnil;
1051 if (i >= p->regs.num_regs) return Qnil;
1052 if (p->regs.beg[i] == -1) return Qnil;
1053
1054 return extract_range(p, p->prev + p->regs.beg[i],
1055 p->prev + p->regs.end[i]);
1056 }
1057
1058 /*
1059 * Return the <i><b>pre</b>-match</i> (in the regular expression sense) of the last scan.
1060 *
1061 * s = StringScanner.new('test string')
1062 * s.scan(/\w+/) # -> "test"
1063 * s.scan(/\s+/) # -> " "
1064 * s.pre_match # -> "test"
1065 * s.post_match # -> "string"
1066 */
1067 static VALUE
1068 strscan_pre_match(VALUE self)
1069 {
1070 struct strscanner *p;
1071
1072 GET_SCANNER(self, p);
1073 if (! MATCHED_P(p)) return Qnil;
1074 return extract_range(p, 0, p->prev + p->regs.beg[0]);
1075 }
1076
1077 /*
1078 * Return the <i><b>post</b>-match</i> (in the regular expression sense) of the last scan.
1079 *
1080 * s = StringScanner.new('test string')
1081 * s.scan(/\w+/) # -> "test"
1082 * s.scan(/\s+/) # -> " "
1083 * s.pre_match # -> "test"
1084 * s.post_match # -> "string"
1085 */
1086 static VALUE
1087 strscan_post_match(VALUE self)
1088 {
1089 struct strscanner *p;
1090
1091 GET_SCANNER(self, p);
1092 if (! MATCHED_P(p)) return Qnil;
1093 return extract_range(p, p->prev + p->regs.end[0], S_LEN(p));
1094 }
1095
1096 /*
1097 * Returns the "rest" of the string (i.e. everything after the scan pointer).
1098 * If there is no more data (eos? = true), it returns <tt>""</tt>.
1099 */
1100 static VALUE
1101 strscan_rest(VALUE self)
1102 {
1103 struct strscanner *p;
1104
1105 GET_SCANNER(self, p);
1106 if (EOS_P(p)) {
1107 return infect(str_new(p, "", 0), p);
1108 }
1109 return extract_range(p, p->curr, S_LEN(p));
1110 }
1111
1112 /*
1113 * <tt>s.rest_size</tt> is equivalent to <tt>s.rest.size</tt>.
1114 */
1115 static VALUE
1116 strscan_rest_size(VALUE self)
1117 {
1118 struct strscanner *p;
1119 long i;
1120
1121 GET_SCANNER(self, p);
1122 if (EOS_P(p)) {
1123 return INT2FIX(0);
1124 }
1125 i = S_LEN(p) - p->curr;
1126 return INT2FIX(i);
1127 }
1128
1129 /*
1130 * <tt>s.restsize</tt> is equivalent to <tt>s.rest_size</tt>.
1131 * This method is obsolete; use #rest_size instead.
1132 */
1133 static VALUE
1134 strscan_restsize(VALUE self)
1135 {
1136 rb_warning("StringScanner#restsize is obsolete; use #rest_size instead");
1137 return strscan_rest_size(self);
1138 }
1139
1140 #define INSPECT_LENGTH 5
1141 #define BUFSIZE 256
1142
1143 /*
1144 * Returns a string that represents the StringScanner object, showing:
1145 * - the current position
1146 * - the size of the string
1147 * - the characters surrounding the scan pointer
1148 *
1149 * s = StringScanner.new("Fri Dec 12 1975 14:39")
1150 * s.inspect # -> '#<StringScanner 0/21 @ "Fri D...">'
1151 * s.scan_until /12/ # -> "Fri Dec 12"
1152 * s.inspect # -> '#<StringScanner 10/21 "...ec 12" @ " 1975...">'
1153 */
1154 static VALUE
1155 strscan_inspect(VALUE self)
1156 {
1157 struct strscanner *p;
1158 VALUE a, b;
1159
1160 p = check_strscan(self);
1161 if (NIL_P(p->str)) {
1162 a = rb_sprintf("#<%"PRIsVALUE" (uninitialized)>", rb_obj_class(self));
1163 return infect(a, p);
1164 }
1165 if (EOS_P(p)) {
1166 a = rb_sprintf("#<%"PRIsVALUE" fin>", rb_obj_class(self));
1167 return infect(a, p);
1168 }
1169 if (p->curr == 0) {
1170 b = inspect2(p);
1171 a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld @ %"PRIsVALUE">",
1172 rb_obj_class(self),
1173 p->curr, S_LEN(p),
1174 b);
1175 return infect(a, p);
1176 }
1177 a = inspect1(p);
1178 b = inspect2(p);
1179 a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld %"PRIsVALUE" @ %"PRIsVALUE">",
1180 rb_obj_class(self),
1181 p->curr, S_LEN(p),
1182 a, b);
1183 return infect(a, p);
1184 }
1185
1186 static VALUE
1187 inspect1(struct strscanner *p)
1188 {
1189 VALUE str;
1190 long len;
1191
1192 if (p->curr == 0) return rb_str_new2("");
1193 if (p->curr > INSPECT_LENGTH) {
1194 str = rb_str_new_cstr("...");
1195 len = INSPECT_LENGTH;
1196 }
1197 else {
1198 str = rb_str_new(0, 0);
1199 len = p->curr;
1200 }
1201 rb_str_cat(str, CURPTR(p) - len, len);
1202 return rb_str_dump(str);
1203 }
1204
1205 static VALUE
1206 inspect2(struct strscanner *p)
1207 {
1208 VALUE str;
1209 long len;
1210
1211 if (EOS_P(p)) return rb_str_new2("");
1212 len = S_LEN(p) - p->curr;
1213 if (len > INSPECT_LENGTH) {
1214 str = rb_str_new(CURPTR(p), INSPECT_LENGTH);
1215 rb_str_cat2(str, "...");
1216 }
1217 else {
1218 str = rb_str_new(CURPTR(p), len);
1219 }
1220 return rb_str_dump(str);
1221 }
1222
1223 /* =======================================================================
1224 Ruby Interface
1225 ======================================================================= */
1226
1227 /*
1228 * Document-class: StringScanner
1229 *
1230 * StringScanner provides for lexical scanning operations on a String. Here is
1231 * an example of its usage:
1232 *
1233 * s = StringScanner.new('This is an example string')
1234 * s.eos? # -> false
1235 *
1236 * p s.scan(/\w+/) # -> "This"
1237 * p s.scan(/\w+/) # -> nil
1238 * p s.scan(/\s+/) # -> " "
1239 * p s.scan(/\s+/) # -> nil
1240 * p s.scan(/\w+/) # -> "is"
1241 * s.eos? # -> false
1242 *
1243 * p s.scan(/\s+/) # -> " "
1244 * p s.scan(/\w+/) # -> "an"
1245 * p s.scan(/\s+/) # -> " "
1246 * p s.scan(/\w+/) # -> "example"
1247 * p s.scan(/\s+/) # -> " "
1248 * p s.scan(/\w+/) # -> "string"
1249 * s.eos? # -> true
1250 *
1251 * p s.scan(/\s+/) # -> nil
1252 * p s.scan(/\w+/) # -> nil
1253 *
1254 * Scanning a string means remembering the position of a <i>scan pointer</i>,
1255 * which is just an index. The point of scanning is to move forward a bit at
1256 * a time, so matches are sought after the scan pointer; usually immediately
1257 * after it.
1258 *
1259 * Given the string "test string", here are the pertinent scan pointer
1260 * positions:
1261 *
1262 * t e s t s t r i n g
1263 * 0 1 2 ... 1
1264 * 0
1265 *
1266 * When you #scan for a pattern (a regular expression), the match must occur
1267 * at the character after the scan pointer. If you use #scan_until, then the
1268 * match can occur anywhere after the scan pointer. In both cases, the scan
1269 * pointer moves <i>just beyond</i> the last character of the match, ready to
1270 * scan again from the next character onwards. This is demonstrated by the
1271 * example above.
1272 *
1273 * == Method Categories
1274 *
1275 * There are other methods besides the plain scanners. You can look ahead in
1276 * the string without actually scanning. You can access the most recent match.
1277 * You can modify the string being scanned, reset or terminate the scanner,
1278 * find out or change the position of the scan pointer, skip ahead, and so on.
1279 *
1280 * === Advancing the Scan Pointer
1281 *
1282 * - #getch
1283 * - #get_byte
1284 * - #scan
1285 * - #scan_until
1286 * - #skip
1287 * - #skip_until
1288 *
1289 * === Looking Ahead
1290 *
1291 * - #check
1292 * - #check_until
1293 * - #exist?
1294 * - #match?
1295 * - #peek
1296 *
1297 * === Finding Where we Are
1298 *
1299 * - #beginning_of_line? (#bol?)
1300 * - #eos?
1301 * - #rest?
1302 * - #rest_size
1303 * - #pos
1304 *
1305 * === Setting Where we Are
1306 *
1307 * - #reset
1308 * - #terminate
1309 * - #pos=
1310 *
1311 * === Match Data
1312 *
1313 * - #matched
1314 * - #matched?
1315 * - #matched_size
1316 * - []
1317 * - #pre_match
1318 * - #post_match
1319 *
1320 * === Miscellaneous
1321 *
1322 * - <<
1323 * - #concat
1324 * - #string
1325 * - #string=
1326 * - #unscan
1327 *
1328 * There are aliases to several of the methods.
1329 */
1330 void
1331 Init_strscan()
1332 {
1333 ID id_scanerr = rb_intern("ScanError");
1334 VALUE tmp;
1335
1336 id_byteslice = rb_intern("byteslice");
1337
1338 StringScanner = rb_define_class("StringScanner", rb_cObject);
1339 ScanError = rb_define_class_under(StringScanner, "Error", rb_eStandardError);
1340 if (!rb_const_defined(rb_cObject, id_scanerr)) {
1341 rb_const_set(rb_cObject, id_scanerr, ScanError);
1342 }
1343 tmp = rb_str_new2(STRSCAN_VERSION);
1344 rb_obj_freeze(tmp);
1345 rb_const_set(StringScanner, rb_intern("Version"), tmp);
1346 tmp = rb_str_new2("$Id: strscan.c 44903 2014-02-10 11:45:14Z naruse $");
1347 rb_obj_freeze(tmp);
1348 rb_const_set(StringScanner, rb_intern("Id"), tmp);
1349
1350 rb_define_alloc_func(StringScanner, strscan_s_allocate);
1351 rb_define_private_method(StringScanner, "initialize", strscan_initialize, -1);
1352 rb_define_private_method(StringScanner, "initialize_copy", strscan_init_copy, 1);
1353 rb_define_singleton_method(StringScanner, "must_C_version", strscan_s_mustc, 0);
1354 rb_define_method(StringScanner, "reset", strscan_reset, 0);
1355 rb_define_method(StringScanner, "terminate", strscan_terminate, 0);
1356 rb_define_method(StringScanner, "clear", strscan_clear, 0);
1357 rb_define_method(StringScanner, "string", strscan_get_string, 0);
1358 rb_define_method(StringScanner, "string=", strscan_set_string, 1);
1359 rb_define_method(StringScanner, "concat", strscan_concat, 1);
1360 rb_define_method(StringScanner, "<<", strscan_concat, 1);
1361 rb_define_method(StringScanner, "pos", strscan_get_pos, 0);
1362 rb_define_method(StringScanner, "pos=", strscan_set_pos, 1);
1363 rb_define_method(StringScanner, "charpos", strscan_get_charpos, 0);
1364 rb_define_method(StringScanner, "pointer", strscan_get_pos, 0);
1365 rb_define_method(StringScanner, "pointer=", strscan_set_pos, 1);
1366
1367 rb_define_method(StringScanner, "scan", strscan_scan, 1);
1368 rb_define_method(StringScanner, "skip", strscan_skip, 1);
1369 rb_define_method(StringScanner, "match?", strscan_match_p, 1);
1370 rb_define_method(StringScanner, "check", strscan_check, 1);
1371 rb_define_method(StringScanner, "scan_full", strscan_scan_full, 3);
1372
1373 rb_define_method(StringScanner, "scan_until", strscan_scan_until, 1);
1374 rb_define_method(StringScanner, "skip_until", strscan_skip_until, 1);
1375 rb_define_method(StringScanner, "exist?", strscan_exist_p, 1);
1376 rb_define_method(StringScanner, "check_until", strscan_check_until, 1);
1377 rb_define_method(StringScanner, "search_full", strscan_search_full, 3);
1378
1379 rb_define_method(StringScanner, "getch", strscan_getch, 0);
1380 rb_define_method(StringScanner, "get_byte", strscan_get_byte, 0);
1381 rb_define_method(StringScanner, "getbyte", strscan_getbyte, 0);
1382 rb_define_method(StringScanner, "peek", strscan_peek, 1);
1383 rb_define_method(StringScanner, "peep", strscan_peep, 1);
1384
1385 rb_define_method(StringScanner, "unscan", strscan_unscan, 0);
1386
1387 rb_define_method(StringScanner, "beginning_of_line?", strscan_bol_p, 0);
1388 rb_alias(StringScanner, rb_intern("bol?"), rb_intern("beginning_of_line?"));
1389 rb_define_method(StringScanner, "eos?", strscan_eos_p, 0);
1390 rb_define_method(StringScanner, "empty?", strscan_empty_p, 0);
1391 rb_define_method(StringScanner, "rest?", strscan_rest_p, 0);
1392
1393 rb_define_method(StringScanner, "matched?", strscan_matched_p, 0);
1394 rb_define_method(StringScanner, "matched", strscan_matched, 0);
1395 rb_define_method(StringScanner, "matched_size", strscan_matched_size, 0);
1396 rb_define_method(StringScanner, "[]", strscan_aref, 1);
1397 rb_define_method(StringScanner, "pre_match", strscan_pre_match, 0);
1398 rb_define_method(StringScanner, "post_match", strscan_post_match, 0);
1399
1400 rb_define_method(StringScanner, "rest", strscan_rest, 0);
1401 rb_define_method(StringScanner, "rest_size", strscan_rest_size, 0);
1402 rb_define_method(StringScanner, "restsize", strscan_restsize, 0);
1403
1404 rb_define_method(StringScanner, "inspect", strscan_inspect, 0);
1405 }
strscan_match_p
static VALUE strscan_match_p(VALUE self, VALUE re)
Definition: strscan.c:543
strscan_set_pos
static VALUE strscan_set_pos(VALUE self, VALUE v)
Definition: strscan.c:433
T_SYMBOL
#define T_SYMBOL
Definition: ruby.h:494
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:546
strscan_memsize
static size_t strscan_memsize(const void *ptr)
Definition: strscan.c:181
strscan_rest_size
static VALUE strscan_rest_size(VALUE self)
Definition: strscan.c:1116
strscan_set_string
static VALUE strscan_set_string(VALUE self, VALUE str)
Definition: strscan.c:338
S_PBEG
#define S_PBEG(s)
Definition: strscan.c:50
strscanner::regs
struct re_registers regs
Definition: strscan.c:40
rb_str_length
VALUE rb_str_length(VALUE)
Definition: string.c:1298
_
static VALUE infect _((VALUE str, struct strscanner *p))
rb_enc_copy
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:916
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1015
strlen
size_t strlen(const char *)
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1288
strscan_eos_p
static VALUE strscan_eos_p(VALUE self)
Definition: strscan.c:887
strscan_matched_p
static VALUE strscan_matched_p(VALUE self)
Definition: strscan.c:933
ONIG_OPTION_NONE
#define ONIG_OPTION_NONE
Definition: oniguruma.h:352
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:630
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1655
ruby.h
strscan_getbyte
static VALUE strscan_getbyte(VALUE self)
Definition: strscan.c:784
strscan_clear
static VALUE strscan_clear(VALUE self)
Definition: strscan.c:313
str_new
static VALUE str_new(struct strscanner *p, const char *ptr, long len)
Definition: strscan.c:136
CURPTR
#define CURPTR(s)
Definition: strscan.c:53
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2140
Qtrue
#define Qtrue
Definition: ruby.h:426
strscan_get_charpos
static VALUE strscan_get_charpos(VALUE self)
Definition: strscan.c:411
TypedData_Wrap_Struct
#define TypedData_Wrap_Struct(klass, data_type, sval)
Definition: ruby.h:1027
re_registers::end
OnigPosition * end
Definition: oniguruma.h:616
strscan_post_match
static VALUE strscan_post_match(VALUE self)
Definition: strscan.c:1087
S_RESTLEN
#define S_RESTLEN(s)
Definition: strscan.c:54
onig_region_copy
void onig_region_copy(OnigRegion *to, OnigRegion *from)
Definition: regexec.c:331
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1500
CLEAR_MATCH_STATUS
#define CLEAR_MATCH_STATUS(s)
Definition: strscan.c:48
UNREACHABLE
#define UNREACHABLE
Definition: ruby.h:42
strscan_mark
static void strscan_mark(void *ptr)
Definition: strscan.c:166
strscanner_type
static const rb_data_type_t strscanner_type
Definition: strscan.c:191
SYM2ID
#define SYM2ID(x)
Definition: ruby.h:356
strscan_rest
static VALUE strscan_rest(VALUE self)
Definition: strscan.c:1101
strscan_get_byte
static VALUE strscan_get_byte(VALUE self)
Definition: strscan.c:762
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:775
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:676
Check_Type
#define Check_Type(v, t)
Definition: ruby.h:532
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
onig_region_clear
void onig_region_clear(OnigRegion *region)
Definition: regexec.c:209
strscanner
Definition: strscan.c:26
EOS_P
#define EOS_P(s)
Definition: strscan.c:56
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_const_defined
int rb_const_defined(VALUE, ID)
Definition: variable.c:2124
rb_enc_mbclen
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:946
check_strscan
static struct strscanner * check_strscan(VALUE obj)
Definition: strscan.c:231
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:3604
re_pattern_buffer
Definition: oniguruma.h:658
strscan_matched_size
static VALUE strscan_matched_size(VALUE self)
Definition: strscan.c:970
strscan_bol_p
static VALUE strscan_bol_p(VALUE self)
Definition: strscan.c:866
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:552
strscan_inspect
static VALUE strscan_inspect(VALUE self)
Definition: strscan.c:1155
re_registers
Definition: oniguruma.h:612
strscan_scan
static VALUE strscan_scan(VALUE self, VALUE re)
Definition: strscan.c:526
strscan_restsize
static VALUE strscan_restsize(VALUE self)
Definition: strscan.c:1134
strscan_check_until
static VALUE strscan_check_until(VALUE self, VALUE re)
Definition: strscan.c:681
MEMZERO
#define MEMZERO(p, type, n)
Definition: ruby.h:1351
onig_region_set
int onig_region_set(OnigRegion *region, int at, int beg, int end)
Definition: regexec.c:279
onig_region_init
void onig_region_init(OnigRegion *region)
Definition: regexec.c:294
strscanner::curr
long curr
Definition: strscan.c:37
strscanner::regex
VALUE regex
Definition: strscan.c:43
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1553
strscan_scan_full
static VALUE strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f)
Definition: strscan.c:603
strscan_check
static VALUE strscan_check(VALUE self, VALUE re)
Definition: strscan.c:587
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:2159
infect
static VALUE infect(VALUE str, struct strscanner *p)
Definition: strscan.c:129
MATCHED
#define MATCHED(s)
Definition: strscan.c:47
name_to_backref_number
static int name_to_backref_number(struct re_registers *regs, VALUE regexp, const char *name, const char *name_end)
Definition: strscan.c:980
NIL_P
#define NIL_P(v)
Definition: ruby.h:438
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:630
onig_name_to_backref_number
int onig_name_to_backref_number(regex_t *reg, const UChar *name, const UChar *name_end, OnigRegion *region)
Definition: regparse.c:870
strscanner::str
VALUE str
Definition: strscan.c:33
strscan_get_pos
static VALUE strscan_get_pos(VALUE self)
Definition: strscan.c:389
onig_region_free
void onig_region_free(OnigRegion *r, int free_self)
Definition: regexec.c:315
TYPE
#define TYPE(x)
Definition: ruby.h:505
argc
int argc
Definition: ruby.c:131
Qfalse
#define Qfalse
Definition: ruby.h:425
inspect2
static VALUE inspect2(struct strscanner *p)
Definition: strscan.c:1206
onig_region_memsize
size_t onig_region_memsize(const OnigRegion *regs)
Definition: regcomp.c:5611
rb_str_new2
#define rb_str_new2
Definition: intern.h:840
strscan_terminate
static VALUE strscan_terminate(VALUE self)
Definition: strscan.c:298
rb_eIndexError
VALUE rb_eIndexError
Definition: error.c:550
strscan_matched
static VALUE strscan_matched(VALUE self)
Definition: strscan.c:949
encoding.h
ALLOC
#define ALLOC(type)
Definition: ruby.h:1334
strscan_reset
static VALUE strscan_reset(VALUE self)
Definition: strscan.c:280
strscan_getch
static VALUE strscan_getch(VALUE self)
Definition: strscan.c:723
strscan_unscan
static VALUE strscan_unscan(VALUE self)
Definition: strscan.c:841
strscan_concat
static VALUE strscan_concat(VALUE self, VALUE str)
Definition: strscan.c:364
extract_range
static VALUE extract_range(struct strscanner *p, long beg_i, long end_i)
Definition: strscan.c:144
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
ScanError
static VALUE ScanError
Definition: strscan.c:23
strscan_init_copy
static VALUE strscan_init_copy(VALUE vself, VALUE vorig)
Definition: strscan.c:244
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:6242
id_byteslice
static ID id_byteslice
Definition: strscan.c:24
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
strscanner::flags
unsigned long flags
Definition: strscan.c:29
strscan_exist_p
static VALUE strscan_exist_p(VALUE self, VALUE re)
Definition: strscan.c:640
strscan_rest_p
static VALUE strscan_rest_p(VALUE self)
Definition: strscan.c:915
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:137
ID
unsigned long ID
Definition: ruby.h:89
Qnil
#define Qnil
Definition: ruby.h:427
rb_const_set
void rb_const_set(VALUE, ID, VALUE)
Definition: variable.c:2160
VALUE
unsigned long VALUE
Definition: ruby.h:88
MATCHED_P
#define MATCHED_P(s)
Definition: strscan.c:46
strscan_peek
static VALUE strscan_peek(VALUE self, VALUE vlen)
Definition: strscan.c:802
strscan_s_allocate
static VALUE strscan_s_allocate(VALUE klass)
Definition: strscan.c:198
rb_alias
void rb_alias(VALUE, ID, ID)
Definition: vm_method.c:1244
strscan_aref
static VALUE strscan_aref(VALUE self, VALUE idx)
Definition: strscan.c:1025
re_registers::beg
OnigPosition * beg
Definition: oniguruma.h:615
rb_str_new_cstr
VALUE rb_str_new_cstr(const char *)
Definition: string.c:560
rb_str_dump
VALUE rb_str_dump(VALUE)
Definition: string.c:4899
Init_strscan
void Init_strscan()
Definition: strscan.c:1331
re.h
GET_SCANNER
#define GET_SCANNER(obj, var)
Definition: strscan.c:58
S_PEND
#define S_PEND(s)
Definition: strscan.c:52
UChar
#define UChar
Definition: oniguruma.h:108
extract_beg_len
static VALUE extract_beg_len(struct strscanner *p, long beg_i, long len)
Definition: strscan.c:153
rb_enc_get
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:832
size
int size
Definition: encoding.c:49
adjust_registers_to_matched
static void adjust_registers_to_matched(struct strscanner *p)
Definition: strscan.c:702
f
#define f
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:231
onig_search
OnigPosition onig_search(regex_t *reg, const UChar *str, const UChar *end, const UChar *start, const UChar *range, OnigRegion *region, OnigOptionType option)
Definition: regexec.c:3902
rb_check_typeddata
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:520
strscan_scan_until
static VALUE strscan_scan_until(VALUE self, VALUE re)
Definition: strscan.c:621
onig_match
OnigPosition onig_match(regex_t *reg, const UChar *str, const UChar *end, const UChar *at, OnigRegion *region, OnigOptionType option)
Definition: regexec.c:3599
strscan_get_string
static VALUE strscan_get_string(VALUE self)
Definition: strscan.c:323
re_registers::num_regs
int num_regs
Definition: oniguruma.h:614
rb_data_type_struct
Definition: ruby.h:966
strscan_free
static void strscan_free(void *ptr)
Definition: strscan.c:173
strscan_pre_match
static VALUE strscan_pre_match(VALUE self)
Definition: strscan.c:1068
inspect1
static VALUE inspect1(struct strscanner *p)
Definition: strscan.c:1187
RTEST
#define RTEST(v)
Definition: ruby.h:437
T_STRING
#define T_STRING
Definition: ruby.h:482
rb_reg_prepare_re
regex_t * rb_reg_prepare_re(VALUE re, VALUE str)
Definition: re.c:1307
OBJ_INFECT
#define OBJ_INFECT(x, s)
Definition: ruby.h:1180
RREGEXP
#define RREGEXP(obj)
Definition: ruby.h:1122
STRSCAN_VERSION
#define STRSCAN_VERSION
Definition: strscan.c:16
name
const char * name
Definition: nkf.c:208
strscan_search_full
static VALUE strscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f)
Definition: strscan.c:696
rb_id2name
const char * rb_id2name(ID id)
Definition: ripper.c:17230
StringValuePtr
#define StringValuePtr(v)
Definition: ruby.h:540
strscanner::prev
long prev
Definition: strscan.c:36
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:236
regint.h
strscan_peep
static VALUE strscan_peep(VALUE self, VALUE vlen)
Definition: strscan.c:823
strscan_do_scan
static VALUE strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
Definition: strscan.c:448
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Definition: object.c:1076
strscan_empty_p
static VALUE strscan_empty_p(VALUE self)
Definition: strscan.c:900
StringScanner
static VALUE StringScanner
Definition: strscan.c:22
rb_intern
#define rb_intern(str)
NULL
#define NULL
Definition: _sdbm.c:103
onig_free
void onig_free(regex_t *reg)
Definition: regcomp.c:5587
strscan_skip
static VALUE strscan_skip(VALUE self, VALUE re)
Definition: strscan.c:566
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2298
S_LEN
#define S_LEN(s)
Definition: strscan.c:51
strscan_initialize
static VALUE strscan_initialize(int argc, VALUE *argv, VALUE self)
Definition: strscan.c:217
T_REGEXP
#define T_REGEXP
Definition: ruby.h:483
NUM2LONG
#define NUM2LONG(x)
Definition: ruby.h:600
INSPECT_LENGTH
#define INSPECT_LENGTH
Definition: strscan.c:1140
argv
char ** argv
Definition: ruby.c:132
strscan_s_mustc
static VALUE strscan_s_mustc(VALUE self)
Definition: strscan.c:271
StringValue
#define StringValue(v)
Definition: ruby.h:539
strscan_skip_until
static VALUE strscan_skip_until(VALUE self, VALUE re)
Definition: strscan.c:662
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:226
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:534