Ruby
1.9.3p551(2014-11-13revision48407)
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 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
30
static
VALUE
StringScanner
;
31
static
VALUE
ScanError
;
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 */
40
VALUE
str
;
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) */
47
struct
re_registers
regs
;
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
));
78
static
VALUE
strscan_s_allocate
_
((
VALUE
klass));
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
132
infect
(
VALUE
str,
struct
strscanner
*
p
)
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
169
strscan_mark
(
struct
strscanner
*
p
)
170
{
171
rb_gc_mark
(p->
str
);
172
}
173
174
static
void
175
strscan_free
(
struct
strscanner
*
p
)
176
{
177
onig_region_free
(&(p->
regs
), 0);
178
ruby_xfree
(p);
179
}
180
181
static
VALUE
182
strscan_s_allocate
(
VALUE
klass)
183
{
184
struct
strscanner
*
p
;
185
186
p =
ALLOC
(
struct
strscanner
);
187
MEMZERO
(p,
struct
strscanner
, 1);
188
CLEAR_MATCH_STATUS
(p);
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
201
strscan_initialize
(
int
argc
,
VALUE
*
argv
,
VALUE
self
)
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
215
check_strscan
(
VALUE
obj)
216
{
217
if
(
TYPE
(obj) !=
T_DATA
||
RDATA
(obj)->dmark != (
RUBY_DATA_FUNC
)
strscan_mark
) {
218
rb_raise
(
rb_eTypeError
,
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
232
strscan_init_copy
(
VALUE
vself,
VALUE
vorig)
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
260
strscan_s_mustc
(
VALUE
self
)
261
{
262
return
self
;
263
}
264
265
/*
266
* Reset the scan pointer (index 0) and clear matching data.
267
*/
268
static
VALUE
269
strscan_reset
(
VALUE
self
)
270
{
271
struct
strscanner
*
p
;
272
273
GET_SCANNER
(
self
, p);
274
p->
curr
= 0;
275
CLEAR_MATCH_STATUS
(p);
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
287
strscan_terminate
(
VALUE
self
)
288
{
289
struct
strscanner
*
p
;
290
291
GET_SCANNER
(
self
, p);
292
p->
curr
=
S_LEN
(p);
293
CLEAR_MATCH_STATUS
(p);
294
return
self
;
295
}
296
297
/*
298
* Equivalent to #terminate.
299
* This method is obsolete; use #terminate instead.
300
*/
301
static
VALUE
302
strscan_clear
(
VALUE
self
)
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
312
strscan_get_string
(
VALUE
self
)
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
327
strscan_set_string
(
VALUE
self
,
VALUE
str
)
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;
335
CLEAR_MATCH_STATUS
(p);
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
354
strscan_concat
(
VALUE
self
,
VALUE
str
)
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
379
strscan_get_pos
(
VALUE
self
)
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
397
strscan_set_pos
(
VALUE
self
,
VALUE
v
)
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
{
414
regex_t
*
rb_reg_prepare_re
(
VALUE
re,
VALUE
str
);
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
423
CLEAR_MATCH_STATUS
(p);
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
488
strscan_scan
(
VALUE
self
,
VALUE
re)
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
505
strscan_match_p
(
VALUE
self
,
VALUE
re)
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
528
strscan_skip
(
VALUE
self
,
VALUE
re)
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
549
strscan_check
(
VALUE
self
,
VALUE
re)
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
565
strscan_scan_full
(
VALUE
self
,
VALUE
re,
VALUE
s,
VALUE
f)
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
583
strscan_scan_until
(
VALUE
self
,
VALUE
re)
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
602
strscan_exist_p
(
VALUE
self
,
VALUE
re)
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
624
strscan_skip_until
(
VALUE
self
,
VALUE
re)
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
643
strscan_check_until
(
VALUE
self
,
VALUE
re)
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
658
strscan_search_full
(
VALUE
self
,
VALUE
re,
VALUE
s,
VALUE
f)
659
{
660
return
strscan_do_scan
(
self
, re,
RTEST
(s),
RTEST
(f), 0);
661
}
662
663
static
void
664
adjust_registers_to_matched
(
struct
strscanner
*
p
)
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
685
strscan_getch
(
VALUE
self
)
686
{
687
struct
strscanner
*
p
;
688
long
len
;
689
690
GET_SCANNER
(
self
, p);
691
CLEAR_MATCH_STATUS
(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);
702
adjust_registers_to_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
724
strscan_get_byte
(
VALUE
self
)
725
{
726
struct
strscanner
*
p
;
727
728
GET_SCANNER
(
self
, p);
729
CLEAR_MATCH_STATUS
(p);
730
if
(
EOS_P
(p))
731
return
Qnil
;
732
733
p->
prev
= p->
curr
;
734
p->
curr
++;
735
MATCHED
(p);
736
adjust_registers_to_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
746
strscan_getbyte
(
VALUE
self
)
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
764
strscan_peek
(
VALUE
self
,
VALUE
vlen)
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
785
strscan_peep
(
VALUE
self
,
VALUE
vlen)
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
803
strscan_unscan
(
VALUE
self
)
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
;
811
CLEAR_MATCH_STATUS
(p);
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
828
strscan_bol_p
(
VALUE
self
)
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
849
strscan_eos_p
(
VALUE
self
)
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
862
strscan_empty_p
(
VALUE
self
)
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
877
strscan_rest_p
(
VALUE
self
)
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
895
strscan_matched_p
(
VALUE
self
)
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
911
strscan_matched
(
VALUE
self
)
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
932
strscan_matched_size
(
VALUE
self
)
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
956
strscan_aref
(
VALUE
self
,
VALUE
idx)
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
985
strscan_pre_match
(
VALUE
self
)
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
1004
strscan_post_match
(
VALUE
self
)
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
1018
strscan_rest
(
VALUE
self
)
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
1033
strscan_rest_size
(
VALUE
self
)
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
1051
strscan_restsize
(
VALUE
self
)
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
1072
strscan_inspect
(
VALUE
self
)
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
1104
inspect1
(
struct
strscanner
*
p
)
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
1123
inspect2
(
struct
strscanner
*
p
)
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
1248
Init_strscan
()
1249
{
1250
ID
id_scanerr =
rb_intern
(
"ScanError"
);
1251
VALUE
tmp;
1252
1253
StringScanner
=
rb_define_class
(
"StringScanner"
,
rb_cObject
);
1254
ScanError
=
rb_define_class_under
(
StringScanner
,
"Error"
,
rb_eStandardError
);
1255
if
(!
rb_const_defined
(
rb_cObject
, id_scanerr)) {
1256
rb_const_set
(
rb_cObject
, id_scanerr,
ScanError
);
1257
}
1258
tmp =
rb_str_new2
(
STRSCAN_VERSION
);
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
1265
rb_define_alloc_func
(
StringScanner
,
strscan_s_allocate
);
1266
rb_define_private_method
(
StringScanner
,
"initialize"
,
strscan_initialize
, -1);
1267
rb_define_private_method
(
StringScanner
,
"initialize_copy"
,
strscan_init_copy
, 1);
1268
rb_define_singleton_method
(
StringScanner
,
"must_C_version"
,
strscan_s_mustc
, 0);
1269
rb_define_method
(
StringScanner
,
"reset"
,
strscan_reset
, 0);
1270
rb_define_method
(
StringScanner
,
"terminate"
,
strscan_terminate
, 0);
1271
rb_define_method
(
StringScanner
,
"clear"
,
strscan_clear
, 0);
1272
rb_define_method
(
StringScanner
,
"string"
,
strscan_get_string
, 0);
1273
rb_define_method
(
StringScanner
,
"string="
,
strscan_set_string
, 1);
1274
rb_define_method
(
StringScanner
,
"concat"
,
strscan_concat
, 1);
1275
rb_define_method
(
StringScanner
,
"<<"
,
strscan_concat
, 1);
1276
rb_define_method
(
StringScanner
,
"pos"
,
strscan_get_pos
, 0);
1277
rb_define_method
(
StringScanner
,
"pos="
,
strscan_set_pos
, 1);
1278
rb_define_method
(
StringScanner
,
"pointer"
,
strscan_get_pos
, 0);
1279
rb_define_method
(
StringScanner
,
"pointer="
,
strscan_set_pos
, 1);
1280
1281
rb_define_method
(
StringScanner
,
"scan"
,
strscan_scan
, 1);
1282
rb_define_method
(
StringScanner
,
"skip"
,
strscan_skip
, 1);
1283
rb_define_method
(
StringScanner
,
"match?"
,
strscan_match_p
, 1);
1284
rb_define_method
(
StringScanner
,
"check"
,
strscan_check
, 1);
1285
rb_define_method
(
StringScanner
,
"scan_full"
,
strscan_scan_full
, 3);
1286
1287
rb_define_method
(
StringScanner
,
"scan_until"
,
strscan_scan_until
, 1);
1288
rb_define_method
(
StringScanner
,
"skip_until"
,
strscan_skip_until
, 1);
1289
rb_define_method
(
StringScanner
,
"exist?"
,
strscan_exist_p
, 1);
1290
rb_define_method
(
StringScanner
,
"check_until"
,
strscan_check_until
, 1);
1291
rb_define_method
(
StringScanner
,
"search_full"
,
strscan_search_full
, 3);
1292
1293
rb_define_method
(
StringScanner
,
"getch"
,
strscan_getch
, 0);
1294
rb_define_method
(
StringScanner
,
"get_byte"
,
strscan_get_byte
, 0);
1295
rb_define_method
(
StringScanner
,
"getbyte"
,
strscan_getbyte
, 0);
1296
rb_define_method
(
StringScanner
,
"peek"
,
strscan_peek
, 1);
1297
rb_define_method
(
StringScanner
,
"peep"
,
strscan_peep
, 1);
1298
1299
rb_define_method
(
StringScanner
,
"unscan"
,
strscan_unscan
, 0);
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?"
));
1303
rb_define_method
(
StringScanner
,
"eos?"
,
strscan_eos_p
, 0);
1304
rb_define_method
(
StringScanner
,
"empty?"
,
strscan_empty_p
, 0);
1305
rb_define_method
(
StringScanner
,
"rest?"
,
strscan_rest_p
, 0);
1306
1307
rb_define_method
(
StringScanner
,
"matched?"
,
strscan_matched_p
, 0);
1308
rb_define_method
(
StringScanner
,
"matched"
,
strscan_matched
, 0);
1309
rb_define_method
(
StringScanner
,
"matched_size"
,
strscan_matched_size
, 0);
1310
rb_define_method
(
StringScanner
,
"[]"
,
strscan_aref
, 1);
1311
rb_define_method
(
StringScanner
,
"pre_match"
,
strscan_pre_match
, 0);
1312
rb_define_method
(
StringScanner
,
"post_match"
,
strscan_post_match
, 0);
1313
1314
rb_define_method
(
StringScanner
,
"rest"
,
strscan_rest
, 0);
1315
rb_define_method
(
StringScanner
,
"rest_size"
,
strscan_rest_size
, 0);
1316
rb_define_method
(
StringScanner
,
"restsize"
,
strscan_restsize
, 0);
1317
1318
rb_define_method
(
StringScanner
,
"inspect"
,
strscan_inspect
, 0);
1319
}
1320
Generated on Fri Nov 14 2014 16:04:04 for Ruby by
1.8.3