Ruby
1.9.3p448(2013-06-27revision41675)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
strscan
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
21
static
VALUE
StringScanner
;
22
static
VALUE
ScanError
;
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 */
31
VALUE
str
;
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) */
38
struct
re_registers
regs
;
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
160
strscan_mark
(
struct
strscanner
*
p
)
161
{
162
rb_gc_mark
(p->
str
);
163
}
164
165
static
void
166
strscan_free
(
struct
strscanner
*
p
)
167
{
168
onig_region_free
(&(p->
regs
), 0);
169
ruby_xfree
(p);
170
}
171
172
static
VALUE
173
strscan_s_allocate
(
VALUE
klass)
174
{
175
struct
strscanner
*
p
;
176
177
p =
ALLOC
(
struct
strscanner
);
178
MEMZERO
(p,
struct
strscanner
, 1);
179
CLEAR_MATCH_STATUS
(p);
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
192
strscan_initialize
(
int
argc
,
VALUE
*
argv
,
VALUE
self
)
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
206
check_strscan
(
VALUE
obj)
207
{
208
if
(
TYPE
(obj) !=
T_DATA
||
RDATA
(obj)->dmark != (
RUBY_DATA_FUNC
)
strscan_mark
) {
209
rb_raise
(
rb_eTypeError
,
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
223
strscan_init_copy
(
VALUE
vself,
VALUE
vorig)
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
251
strscan_s_mustc
(
VALUE
self
)
252
{
253
return
self
;
254
}
255
256
/*
257
* Reset the scan pointer (index 0) and clear matching data.
258
*/
259
static
VALUE
260
strscan_reset
(
VALUE
self
)
261
{
262
struct
strscanner
*
p
;
263
264
GET_SCANNER
(
self
, p);
265
p->
curr
= 0;
266
CLEAR_MATCH_STATUS
(p);
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
278
strscan_terminate
(
VALUE
self
)
279
{
280
struct
strscanner
*
p
;
281
282
GET_SCANNER
(
self
, p);
283
p->
curr
=
S_LEN
(p);
284
CLEAR_MATCH_STATUS
(p);
285
return
self
;
286
}
287
288
/*
289
* Equivalent to #terminate.
290
* This method is obsolete; use #terminate instead.
291
*/
292
static
VALUE
293
strscan_clear
(
VALUE
self
)
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
303
strscan_get_string
(
VALUE
self
)
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
318
strscan_set_string
(
VALUE
self
,
VALUE
str
)
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;
326
CLEAR_MATCH_STATUS
(p);
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
345
strscan_concat
(
VALUE
self
,
VALUE
str
)
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
370
strscan_get_pos
(
VALUE
self
)
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
388
strscan_set_pos
(
VALUE
self
,
VALUE
v
)
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
{
405
regex_t
*
rb_reg_prepare_re
(
VALUE
re,
VALUE
str
);
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
414
CLEAR_MATCH_STATUS
(p);
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
479
strscan_scan
(
VALUE
self
,
VALUE
re)
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
496
strscan_match_p
(
VALUE
self
,
VALUE
re)
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
519
strscan_skip
(
VALUE
self
,
VALUE
re)
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
540
strscan_check
(
VALUE
self
,
VALUE
re)
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
556
strscan_scan_full
(
VALUE
self
,
VALUE
re,
VALUE
s,
VALUE
f)
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
574
strscan_scan_until
(
VALUE
self
,
VALUE
re)
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
593
strscan_exist_p
(
VALUE
self
,
VALUE
re)
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
615
strscan_skip_until
(
VALUE
self
,
VALUE
re)
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
634
strscan_check_until
(
VALUE
self
,
VALUE
re)
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
649
strscan_search_full
(
VALUE
self
,
VALUE
re,
VALUE
s,
VALUE
f)
650
{
651
return
strscan_do_scan
(
self
, re,
RTEST
(s),
RTEST
(f), 0);
652
}
653
654
static
void
655
adjust_registers_to_matched
(
struct
strscanner
*
p
)
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
676
strscan_getch
(
VALUE
self
)
677
{
678
struct
strscanner
*
p
;
679
long
len
;
680
681
GET_SCANNER
(
self
, p);
682
CLEAR_MATCH_STATUS
(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);
693
adjust_registers_to_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
715
strscan_get_byte
(
VALUE
self
)
716
{
717
struct
strscanner
*
p
;
718
719
GET_SCANNER
(
self
, p);
720
CLEAR_MATCH_STATUS
(p);
721
if
(
EOS_P
(p))
722
return
Qnil
;
723
724
p->
prev
= p->
curr
;
725
p->
curr
++;
726
MATCHED
(p);
727
adjust_registers_to_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
737
strscan_getbyte
(
VALUE
self
)
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
755
strscan_peek
(
VALUE
self
,
VALUE
vlen)
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
776
strscan_peep
(
VALUE
self
,
VALUE
vlen)
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
794
strscan_unscan
(
VALUE
self
)
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
;
802
CLEAR_MATCH_STATUS
(p);
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
819
strscan_bol_p
(
VALUE
self
)
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
840
strscan_eos_p
(
VALUE
self
)
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
853
strscan_empty_p
(
VALUE
self
)
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
868
strscan_rest_p
(
VALUE
self
)
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
886
strscan_matched_p
(
VALUE
self
)
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
902
strscan_matched
(
VALUE
self
)
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
923
strscan_matched_size
(
VALUE
self
)
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
947
strscan_aref
(
VALUE
self
,
VALUE
idx)
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
976
strscan_pre_match
(
VALUE
self
)
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
995
strscan_post_match
(
VALUE
self
)
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
1009
strscan_rest
(
VALUE
self
)
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
1024
strscan_rest_size
(
VALUE
self
)
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
1042
strscan_restsize
(
VALUE
self
)
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
1063
strscan_inspect
(
VALUE
self
)
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
1100
inspect1
(
struct
strscanner
*
p
)
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
1119
inspect2
(
struct
strscanner
*
p
)
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
1246
Init_strscan
()
1247
{
1248
ID
id_scanerr =
rb_intern
(
"ScanError"
);
1249
VALUE
tmp;
1250
1251
StringScanner
=
rb_define_class
(
"StringScanner"
,
rb_cObject
);
1252
ScanError
=
rb_define_class_under
(
StringScanner
,
"Error"
,
rb_eStandardError
);
1253
if
(!
rb_const_defined
(
rb_cObject
, id_scanerr)) {
1254
rb_const_set
(
rb_cObject
, id_scanerr,
ScanError
);
1255
}
1256
tmp =
rb_str_new2
(
STRSCAN_VERSION
);
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
1263
rb_define_alloc_func
(
StringScanner
,
strscan_s_allocate
);
1264
rb_define_private_method
(
StringScanner
,
"initialize"
,
strscan_initialize
, -1);
1265
rb_define_private_method
(
StringScanner
,
"initialize_copy"
,
strscan_init_copy
, 1);
1266
rb_define_singleton_method
(
StringScanner
,
"must_C_version"
,
strscan_s_mustc
, 0);
1267
rb_define_method
(
StringScanner
,
"reset"
,
strscan_reset
, 0);
1268
rb_define_method
(
StringScanner
,
"terminate"
,
strscan_terminate
, 0);
1269
rb_define_method
(
StringScanner
,
"clear"
,
strscan_clear
, 0);
1270
rb_define_method
(
StringScanner
,
"string"
,
strscan_get_string
, 0);
1271
rb_define_method
(
StringScanner
,
"string="
,
strscan_set_string
, 1);
1272
rb_define_method
(
StringScanner
,
"concat"
,
strscan_concat
, 1);
1273
rb_define_method
(
StringScanner
,
"<<"
,
strscan_concat
, 1);
1274
rb_define_method
(
StringScanner
,
"pos"
,
strscan_get_pos
, 0);
1275
rb_define_method
(
StringScanner
,
"pos="
,
strscan_set_pos
, 1);
1276
rb_define_method
(
StringScanner
,
"pointer"
,
strscan_get_pos
, 0);
1277
rb_define_method
(
StringScanner
,
"pointer="
,
strscan_set_pos
, 1);
1278
1279
rb_define_method
(
StringScanner
,
"scan"
,
strscan_scan
, 1);
1280
rb_define_method
(
StringScanner
,
"skip"
,
strscan_skip
, 1);
1281
rb_define_method
(
StringScanner
,
"match?"
,
strscan_match_p
, 1);
1282
rb_define_method
(
StringScanner
,
"check"
,
strscan_check
, 1);
1283
rb_define_method
(
StringScanner
,
"scan_full"
,
strscan_scan_full
, 3);
1284
1285
rb_define_method
(
StringScanner
,
"scan_until"
,
strscan_scan_until
, 1);
1286
rb_define_method
(
StringScanner
,
"skip_until"
,
strscan_skip_until
, 1);
1287
rb_define_method
(
StringScanner
,
"exist?"
,
strscan_exist_p
, 1);
1288
rb_define_method
(
StringScanner
,
"check_until"
,
strscan_check_until
, 1);
1289
rb_define_method
(
StringScanner
,
"search_full"
,
strscan_search_full
, 3);
1290
1291
rb_define_method
(
StringScanner
,
"getch"
,
strscan_getch
, 0);
1292
rb_define_method
(
StringScanner
,
"get_byte"
,
strscan_get_byte
, 0);
1293
rb_define_method
(
StringScanner
,
"getbyte"
,
strscan_getbyte
, 0);
1294
rb_define_method
(
StringScanner
,
"peek"
,
strscan_peek
, 1);
1295
rb_define_method
(
StringScanner
,
"peep"
,
strscan_peep
, 1);
1296
1297
rb_define_method
(
StringScanner
,
"unscan"
,
strscan_unscan
, 0);
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?"
));
1301
rb_define_method
(
StringScanner
,
"eos?"
,
strscan_eos_p
, 0);
1302
rb_define_method
(
StringScanner
,
"empty?"
,
strscan_empty_p
, 0);
1303
rb_define_method
(
StringScanner
,
"rest?"
,
strscan_rest_p
, 0);
1304
1305
rb_define_method
(
StringScanner
,
"matched?"
,
strscan_matched_p
, 0);
1306
rb_define_method
(
StringScanner
,
"matched"
,
strscan_matched
, 0);
1307
rb_define_method
(
StringScanner
,
"matched_size"
,
strscan_matched_size
, 0);
1308
rb_define_method
(
StringScanner
,
"[]"
,
strscan_aref
, 1);
1309
rb_define_method
(
StringScanner
,
"pre_match"
,
strscan_pre_match
, 0);
1310
rb_define_method
(
StringScanner
,
"post_match"
,
strscan_post_match
, 0);
1311
1312
rb_define_method
(
StringScanner
,
"rest"
,
strscan_rest
, 0);
1313
rb_define_method
(
StringScanner
,
"rest_size"
,
strscan_rest_size
, 0);
1314
rb_define_method
(
StringScanner
,
"restsize"
,
strscan_restsize
, 0);
1315
1316
rb_define_method
(
StringScanner
,
"inspect"
,
strscan_inspect
, 0);
1317
}
1318
Generated on Fri Jun 28 2013 02:34:38 for Ruby by
1.8.3