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