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