Ruby  2.1.10p492(2016-04-01revision54464)
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 
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 */
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) */
41 
42  /* regexp used for last scan */
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));
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
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
167 {
168  struct strscanner *p = ptr;
169  rb_gc_mark(p->str);
170 }
171 
172 static void
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 
192  "StringScanner",
195 };
196 
197 static VALUE
199 {
200  struct strscanner *p;
201 
202  p = ALLOC(struct strscanner);
203  MEMZERO(p, struct strscanner, 1);
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
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 *
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
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
272 {
273  return self;
274 }
275 
276 /*
277  * Reset the scan pointer (index 0) and clear matching data.
278  */
279 static VALUE
281 {
282  struct strscanner *p;
283 
284  GET_SCANNER(self, p);
285  p->curr = 0;
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
299 {
300  struct strscanner *p;
301 
302  GET_SCANNER(self, p);
303  p->curr = S_LEN(p);
305  return self;
306 }
307 
308 /*
309  * Equivalent to #terminate.
310  * This method is obsolete; use #terminate instead.
311  */
312 static VALUE
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
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
339 {
340  struct strscanner *p = check_strscan(self);
341 
342  StringValue(str);
343  p->str = str;
344  p->curr = 0;
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
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
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
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
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 {
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 
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
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
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
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
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
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
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
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
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
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
697 {
698  return strscan_do_scan(self, re, RTEST(s), RTEST(f), 0);
699 }
700 
701 static void
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
724 {
725  struct strscanner *p;
726  long len;
727 
728  GET_SCANNER(self, 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);
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
763 {
764  struct strscanner *p;
765 
766  GET_SCANNER(self, p);
768  if (EOS_P(p))
769  return Qnil;
770 
771  p->prev = p->curr;
772  p->curr++;
773  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
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
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
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
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;
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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);
1340  if (!rb_const_defined(rb_cObject, id_scanerr)) {
1341  rb_const_set(rb_cObject, id_scanerr, ScanError);
1342  }
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 
1366 
1372 
1378 
1384 
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?"));
1392 
1399 
1403 
1405 }
static VALUE strscan_match_p(VALUE self, VALUE re)
Definition: strscan.c:543
static VALUE strscan_set_pos(VALUE self, VALUE v)
Definition: strscan.c:433
#define ALLOC(type)
VALUE rb_eStandardError
Definition: error.c:546
static size_t strscan_memsize(const void *ptr)
Definition: strscan.c:181
static VALUE strscan_rest_size(VALUE self)
Definition: strscan.c:1116
static VALUE strscan_set_string(VALUE self, VALUE str)
Definition: strscan.c:338
#define S_PBEG(s)
Definition: strscan.c:50
struct re_registers regs
Definition: strscan.c:40
#define ONIG_OPTION_NONE
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:916
size_t strlen(const char *)
#define OBJ_INFECT(x, s)
static VALUE strscan_eos_p(VALUE self)
Definition: strscan.c:887
static VALUE strscan_matched_p(VALUE self)
Definition: strscan.c:933
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1646
static VALUE strscan_getbyte(VALUE self)
Definition: strscan.c:784
static VALUE strscan_clear(VALUE self)
Definition: strscan.c:313
static VALUE str_new(struct strscanner *p, const char *ptr, long len)
Definition: strscan.c:136
#define CURPTR(s)
Definition: strscan.c:53
rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts))
static VALUE strscan_get_charpos(VALUE self)
Definition: strscan.c:411
#define UChar
static VALUE strscan_post_match(VALUE self)
Definition: strscan.c:1087
#define S_RESTLEN(s)
Definition: strscan.c:54
void onig_region_copy(OnigRegion *to, OnigRegion *from)
Definition: regexec.c:331
VALUE rb_str_new_cstr(const char *)
Definition: string.c:560
int ret
Definition: tcltklib.c:285
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1491
Real * a
Definition: bigdecimal.c:1198
VALUE rb_obj_freeze(VALUE)
Definition: object.c:1070
#define CLEAR_MATCH_STATUS(s)
Definition: strscan.c:48
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
#define UNREACHABLE
Definition: ruby.h:42
static void strscan_mark(void *ptr)
Definition: strscan.c:166
static const rb_data_type_t strscanner_type
Definition: strscan.c:191
#define TYPE(x)
static VALUE strscan_rest(VALUE self)
Definition: strscan.c:1101
rb_str_append(str, i)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4056
static VALUE strscan_get_byte(VALUE self)
Definition: strscan.c:762
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:657
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
return Qtrue
Definition: tcltklib.c:9618
VALUE rb_obj_class(VALUE)
Definition: object.c:226
void onig_region_clear(OnigRegion *region)
Definition: regexec.c:209
#define EOS_P(s)
Definition: strscan.c:56
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:946
static struct strscanner * check_strscan(VALUE obj)
Definition: strscan.c:231
tmp
Definition: enum.c:447
#define rb_str_new2
static VALUE strscan_matched_size(VALUE self)
Definition: strscan.c:970
int size
Definition: encoding.c:49
static VALUE strscan_bol_p(VALUE self)
Definition: strscan.c:866
VALUE rb_eRangeError
Definition: error.c:552
i
Definition: enum.c:446
static VALUE strscan_inspect(VALUE self)
Definition: strscan.c:1155
#define MEMZERO(p, type, n)
static VALUE strscan_scan(VALUE self, VALUE re)
Definition: strscan.c:526
static VALUE strscan_restsize(VALUE self)
Definition: strscan.c:1134
static VALUE strscan_check_until(VALUE self, VALUE re)
Definition: strscan.c:681
VALUE rb_str_dump(VALUE)
Definition: string.c:4902
int onig_region_set(OnigRegion *region, int at, int beg, int end)
Definition: regexec.c:279
void onig_region_init(OnigRegion *region)
Definition: regexec.c:294
long curr
Definition: strscan.c:37
OnigPosition * end
Definition: ripper.y:617
return Qfalse
Definition: tcltklib.c:6790
VALUE regex
Definition: strscan.c:43
#define Qnil
Definition: enum.c:67
#define StringValuePtr(v)
static VALUE strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f)
Definition: strscan.c:603
static VALUE strscan_check(VALUE self, VALUE re)
Definition: strscan.c:587
static VALUE char * str
Definition: tcltklib.c:3539
static VALUE infect(VALUE str, struct strscanner *p)
Definition: strscan.c:129
unsigned long ID
Definition: ripper.y:89
#define MATCHED(s)
Definition: strscan.c:47
static int name_to_backref_number(struct re_registers *regs, VALUE regexp, const char *name, const char *name_end)
Definition: strscan.c:980
void rb_gc_mark(VALUE)
Definition: gc.c:3607
Check_Type(i, T_ARRAY)
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:2158
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:611
int onig_name_to_backref_number(regex_t *reg, const UChar *name, const UChar *name_end, OnigRegion *region)
Definition: regparse.c:870
static VALUE VALUE obj
Definition: tcltklib.c:3150
#define INT2FIX(i)
VALUE str
Definition: strscan.c:33
#define T_STRING
static VALUE strscan_get_pos(VALUE self)
Definition: strscan.c:389
void onig_region_free(OnigRegion *r, int free_self)
Definition: regexec.c:315
static VALUE inspect2(struct strscanner *p)
Definition: strscan.c:1206
size_t onig_region_memsize(const OnigRegion *regs)
Definition: regcomp.c:5611
#define TypedData_Wrap_Struct(klass, data_type, sval)
static VALUE strscan_terminate(VALUE self)
Definition: strscan.c:298
VALUE rb_eIndexError
Definition: error.c:550
int len
Definition: enumerator.c:1332
static VALUE strscan_matched(VALUE self)
Definition: strscan.c:949
VALUE * argv
Definition: tcltklib.c:1969
static VALUE strscan_reset(VALUE self)
Definition: strscan.c:280
static VALUE strscan_getch(VALUE self)
Definition: strscan.c:723
#define RTEST(v)
static VALUE strscan_unscan(VALUE self)
Definition: strscan.c:841
static VALUE strscan_concat(VALUE self, VALUE str)
Definition: strscan.c:364
static VALUE extract_range(struct strscanner *p, long beg_i, long end_i)
Definition: strscan.c:144
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
#define StringValue(v)
int rb_const_defined(VALUE, ID)
Definition: variable.c:2127
VALUE v
Definition: enum.c:845
#define RUBY_TYPED_FREE_IMMEDIATELY
#define T_REGEXP
register char * s
Definition: os2.c:56
static VALUE ScanError
Definition: strscan.c:23
static VALUE strscan_init_copy(VALUE vself, VALUE vorig)
Definition: strscan.c:244
void ruby_xfree(void *x)
Definition: gc.c:6245
static ID id_byteslice
Definition: strscan.c:24
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
unsigned long flags
Definition: strscan.c:29
static VALUE strscan_exist_p(VALUE self, VALUE re)
Definition: strscan.c:640
static VALUE strscan_rest_p(VALUE self)
Definition: strscan.c:915
OnigPosition * beg
Definition: ripper.y:616
void rb_const_set(VALUE, ID, VALUE)
Definition: variable.c:2163
int argc
Definition: tcltklib.c:1968
void rb_alias(VALUE, ID, ID)
Definition: vm_method.c:1255
#define MATCHED_P(s)
Definition: strscan.c:46
static VALUE strscan_peek(VALUE self, VALUE vlen)
Definition: strscan.c:802
static VALUE strscan_s_allocate(VALUE klass)
Definition: strscan.c:198
static VALUE strscan_aref(VALUE self, VALUE idx)
Definition: strscan.c:1025
void Init_strscan()
Definition: strscan.c:1331
#define GET_SCANNER(obj, var)
Definition: strscan.c:58
VALUE idx
Definition: enumerator.c:499
Real * b
Definition: bigdecimal.c:1198
return ptr
Definition: tcltklib.c:789
#define S_PEND(s)
Definition: strscan.c:52
#define _(args)
Definition: dln.h:28
static VALUE extract_beg_len(struct strscanner *p, long beg_i, long len)
Definition: strscan.c:153
#define T_SYMBOL
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2139
VALUE rb_str_length(VALUE)
Definition: string.c:1298
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:832
static void adjust_registers_to_matched(struct strscanner *p)
Definition: strscan.c:702
#define f
#define NUM2LONG(x)
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
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:520
static VALUE strscan_scan_until(VALUE self, VALUE re)
Definition: strscan.c:621
OnigPosition onig_match(regex_t *reg, const UChar *str, const UChar *end, const UChar *at, OnigRegion *region, OnigOptionType option)
Definition: regexec.c:3599
VALUE name
Definition: enum.c:572
static VALUE strscan_get_string(VALUE self)
Definition: strscan.c:323
int num_regs
Definition: ripper.y:615
static void strscan_free(void *ptr)
Definition: strscan.c:173
static VALUE strscan_pre_match(VALUE self)
Definition: strscan.c:1068
static VALUE inspect1(struct strscanner *p)
Definition: strscan.c:1187
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1561
klass
Definition: tcltklib.c:3496
regex_t * rb_reg_prepare_re(VALUE re, VALUE str)
Definition: re.c:1339
#define INT2NUM(x)
#define STRSCAN_VERSION
Definition: strscan.c:16
register C_block * p
Definition: crypt.c:309
VALUE rb_str_new(const char *, long)
Definition: string.c:534
static VALUE strscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f)
Definition: strscan.c:696
#define NUM2INT(x)
const char * rb_id2name(ID id)
Definition: ripper.c:17271
static struct tcltkip *VALUE self
Definition: tcltklib.c:774
#define PRIsVALUE
long prev
Definition: strscan.c:36
unsigned long VALUE
Definition: ripper.y:88
void rb_warning(const char *fmt,...)
Definition: error.c:236
#define RREGEXP(obj)
static VALUE strscan_peep(VALUE self, VALUE vlen)
Definition: strscan.c:823
static VALUE strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
Definition: strscan.c:448
static VALUE strscan_empty_p(VALUE self)
Definition: strscan.c:900
static VALUE StringScanner
Definition: strscan.c:22
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
void onig_free(regex_t *reg)
Definition: regcomp.c:5587
static VALUE strscan_skip(VALUE self, VALUE re)
Definition: strscan.c:566
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1479
#define S_LEN(s)
Definition: strscan.c:51
static VALUE strscan_initialize(int argc, VALUE *argv, VALUE self)
Definition: strscan.c:217
#define SYM2ID(x)
#define INSPECT_LENGTH
Definition: strscan.c:1140
static VALUE strscan_s_mustc(VALUE self)
Definition: strscan.c:271
static VALUE strscan_skip_until(VALUE self, VALUE re)
Definition: strscan.c:662