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