strscan 3.1.1 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45d46129cae1a1b9273f5500d6d15279e592946173312c034fb54387faef9d0d
4
- data.tar.gz: fc2d15f94f2e597d57dc89c44dddce16aa0096f02a6d268c22e1595ab9c5a00f
3
+ metadata.gz: 721eeedd937d05ca382b444254fba9a33c4b5c31851e50c4dbdd577bf6500cbc
4
+ data.tar.gz: 60b383fe5478479a7888f1c11da32abbcbc98e223697b4255b9bff88f97adb55
5
5
  SHA512:
6
- metadata.gz: 295727ce636512083608565f16c7675509143708abce6896da39fb0b3bad4d8e69538b6574a0ed6c6d7e0f85c14569c79cdc5901b55c7c5320c3d5a7af0cc61d
7
- data.tar.gz: 4bba01c59eb8e3062fb498d6e8468ed6def6fa36d7c5ef9a0bb24806f7d500def565e9598eb5b7958589b3145653b57991a270963d066486b4e1ba915cb3030f
6
+ metadata.gz: af10ae102cc3b960eec9bad084d434a436a847effbc265c03e63aeafbcfae537a45c902af4a05499f424a9a050053cc630477eca652b5a1e031548228e796ae8
7
+ data.tar.gz: 101a27af7c1f3d9eb46a2ee3e6e62b279d934d02f2e0e89d756c36699205ab66d3316e49692a19a2a872ac4c34810d9f11c58e8314d8546f4c4b69614c0db240
@@ -10,7 +10,7 @@ Display scanner's situation:
10
10
  - Character position (`#charpos`)
11
11
  - Target string (`#rest`) and size (`#rest_size`).
12
12
 
13
- ```
13
+ ```rb
14
14
  scanner = StringScanner.new('foobarbaz')
15
15
  scanner.scan(/foo/)
16
16
  put_situation(scanner)
@@ -25,7 +25,7 @@ put_situation(scanner)
25
25
 
26
26
  Display the scanner's match values:
27
27
 
28
- ```
28
+ ```rb
29
29
  scanner = StringScanner.new('Fri Dec 12 1975 14:39')
30
30
  pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) /
31
31
  scanner.match?(pattern)
@@ -53,7 +53,7 @@ put_match_values(scanner)
53
53
 
54
54
  Returns whether the scanner's match values are all properly cleared:
55
55
 
56
- ```
56
+ ```rb
57
57
  scanner = StringScanner.new('foobarbaz')
58
58
  match_values_cleared?(scanner) # => true
59
59
  put_match_values(scanner)
@@ -75,7 +75,7 @@ match_values_cleared?(scanner) # => false
75
75
 
76
76
  ## The Code
77
77
 
78
- ```
78
+ ```rb
79
79
  def put_situation(scanner)
80
80
  puts '# Situation:'
81
81
  puts "# pos: #{scanner.pos}"
@@ -83,9 +83,7 @@ def put_situation(scanner)
83
83
  puts "# rest: #{scanner.rest.inspect}"
84
84
  puts "# rest_size: #{scanner.rest_size}"
85
85
  end
86
- ```
87
86
 
88
- ```
89
87
  def put_match_values(scanner)
90
88
  puts '# Basic match values:'
91
89
  puts "# matched?: #{scanner.matched?}"
@@ -109,9 +107,7 @@ def put_match_values(scanner)
109
107
  end
110
108
  end
111
109
  end
112
- ```
113
110
 
114
- ```
115
111
  def match_values_cleared?(scanner)
116
112
  scanner.matched? == false &&
117
113
  scanner.matched_size.nil? &&
@@ -10,7 +10,7 @@ Returns the next byte, if available:
10
10
  - Increments the [byte position][2].
11
11
  - Adjusts the [character position][7].
12
12
 
13
- ```
13
+ ```rb
14
14
  scanner = StringScanner.new(HIRAGANA_TEXT)
15
15
  # => #<StringScanner 0/15 @ "\xE3\x81\x93\xE3\x82...">
16
16
  scanner.string # => "こんにちは"
@@ -24,7 +24,7 @@ Returns the next byte, if available:
24
24
 
25
25
  - Otherwise, returns `nil`, and does not change the positions.
26
26
 
27
- ```
27
+ ```rb
28
28
  scanner.terminate
29
29
  [scanner.get_byte, scanner.pos, scanner.charpos] # => [nil, 15, 5]
30
30
  ```
@@ -5,7 +5,7 @@ Returns the [character position][7] (initially zero),
5
5
  which may be different from the [byte position][2]
6
6
  given by method #pos:
7
7
 
8
- ```
8
+ ```rb
9
9
  scanner = StringScanner.new(HIRAGANA_TEXT)
10
10
  scanner.string # => "こんにちは"
11
11
  scanner.getch # => "こ" # 3-byte character.
@@ -4,7 +4,7 @@ call-seq:
4
4
  Returns the integer [byte position][2],
5
5
  which may be different from the [character position][7]:
6
6
 
7
- ```
7
+ ```rb
8
8
  scanner = StringScanner.new(HIRAGANA_TEXT)
9
9
  scanner.string # => "こんにちは"
10
10
  scanner.pos # => 0
@@ -12,7 +12,7 @@ if available:
12
12
  - Increments the [byte position][2]
13
13
  by the size (in bytes) of the character.
14
14
 
15
- ```
15
+ ```rb
16
16
  scanner = StringScanner.new(HIRAGANA_TEXT)
17
17
  scanner.string # => "こんにちは"
18
18
  [scanner.getch, scanner.pos, scanner.charpos] # => ["こ", 3, 1]
@@ -27,7 +27,7 @@ if available:
27
27
  (that is, not at its beginning),
28
28
  behaves like #get_byte (returns a 1-byte character):
29
29
 
30
- ```
30
+ ```rb
31
31
  scanner.pos = 1
32
32
  [scanner.getch, scanner.pos, scanner.charpos] # => ["\x81", 2, 2]
33
33
  [scanner.getch, scanner.pos, scanner.charpos] # => ["\x93", 3, 1]
@@ -37,7 +37,7 @@ if available:
37
37
  - If the [position][2] is at the end of the [stored string][1],
38
38
  returns `nil` and does not modify the positions:
39
39
 
40
- ```
40
+ ```rb
41
41
  scanner.terminate
42
42
  [scanner.getch, scanner.pos, scanner.charpos] # => [nil, 15, 5]
43
43
  ```
@@ -11,7 +11,7 @@ If the match succeeds:
11
11
  and may increment the [character position][7].
12
12
  - Sets [match values][9].
13
13
 
14
- ```
14
+ ```rb
15
15
  scanner = StringScanner.new(HIRAGANA_TEXT)
16
16
  scanner.string # => "こんにちは"
17
17
  scanner.pos = 6
@@ -45,7 +45,7 @@ If the match fails:
45
45
  - Does not increment byte and character positions.
46
46
  - Clears match values.
47
47
 
48
- ```
48
+ ```rb
49
49
  scanner.scan(/nope/) # => nil
50
50
  match_values_cleared?(scanner) # => true
51
51
  ```
@@ -12,7 +12,7 @@ If the match attempt succeeds:
12
12
  - Returns the matched substring.
13
13
 
14
14
 
15
- ```
15
+ ```rb
16
16
  scanner = StringScanner.new(HIRAGANA_TEXT)
17
17
  scanner.string # => "こんにちは"
18
18
  scanner.pos = 6
@@ -46,7 +46,7 @@ If the match attempt fails:
46
46
  - Returns `nil`.
47
47
  - Does not update positions.
48
48
 
49
- ```
49
+ ```rb
50
50
  scanner.scan_until(/nope/) # => nil
51
51
  match_values_cleared?(scanner) # => true
52
52
  ```
@@ -9,7 +9,7 @@ Does not affect [match values][9].
9
9
 
10
10
  For non-negative `n`, sets the position to `n`:
11
11
 
12
- ```
12
+ ```rb
13
13
  scanner = StringScanner.new(HIRAGANA_TEXT)
14
14
  scanner.string # => "こんにちは"
15
15
  scanner.pos = 3 # => 3
@@ -19,7 +19,7 @@ scanner.charpos # => 1
19
19
 
20
20
  For negative `n`, counts from the end of the [stored string][1]:
21
21
 
22
- ```
22
+ ```rb
23
23
  scanner.pos = -9 # => -9
24
24
  scanner.pos # => 6
25
25
  scanner.rest # => "にちは"
@@ -11,7 +11,7 @@ If the match succeeds:
11
11
  - Sets [match values][9].
12
12
  - Returns the size (bytes) of the matched substring.
13
13
 
14
- ```
14
+ ```rb
15
15
  scanner = StringScanner.new(HIRAGANA_TEXT)
16
16
  scanner.string # => "こんにちは"
17
17
  scanner.pos = 6
@@ -10,7 +10,7 @@ If the match attempt succeeds:
10
10
  - Sets [match values][9].
11
11
  - Returns the size of the matched substring.
12
12
 
13
- ```
13
+ ```rb
14
14
  scanner = StringScanner.new(HIRAGANA_TEXT)
15
15
  scanner.string # => "こんにちは"
16
16
  scanner.pos = 6
@@ -43,7 +43,7 @@ If the match attempt fails:
43
43
  - Clears match values.
44
44
  - Returns `nil`.
45
45
 
46
- ```
46
+ ```rb
47
47
  scanner.skip_until(/nope/) # => nil
48
48
  match_values_cleared?(scanner) # => true
49
49
  ```
@@ -7,7 +7,7 @@ returns +self+:
7
7
  - Sets both [positions][11] to end-of-stream.
8
8
  - Clears [match values][9].
9
9
 
10
- ```
10
+ ```rb
11
11
  scanner = StringScanner.new(HIRAGANA_TEXT)
12
12
  scanner.string # => "こんにちは"
13
13
  scanner.scan_until(/に/)
@@ -1,7 +1,7 @@
1
1
  \Class `StringScanner` supports processing a stored string as a stream;
2
2
  this code creates a new `StringScanner` object with string `'foobarbaz'`:
3
3
 
4
- ```
4
+ ```rb
5
5
  require 'strscan'
6
6
  scanner = StringScanner.new('foobarbaz')
7
7
  ```
@@ -10,13 +10,13 @@ scanner = StringScanner.new('foobarbaz')
10
10
 
11
11
  All examples here assume that `StringScanner` has been required:
12
12
 
13
- ```
13
+ ```rb
14
14
  require 'strscan'
15
15
  ```
16
16
 
17
17
  Some examples here assume that these constants are defined:
18
18
 
19
- ```
19
+ ```rb
20
20
  MULTILINE_TEXT = <<~EOT
21
21
  Go placidly amid the noise and haste,
22
22
  and remember what peace there may be in silence.
@@ -45,7 +45,7 @@ This code creates a `StringScanner` object
45
45
  (we'll call it simply a _scanner_),
46
46
  and shows some of its basic properties:
47
47
 
48
- ```
48
+ ```rb
49
49
  scanner = StringScanner.new('foobarbaz')
50
50
  scanner.string # => "foobarbaz"
51
51
  put_situation(scanner)
@@ -112,11 +112,11 @@ and a zero-based <i>character position</i>.
112
112
 
113
113
  Each of these methods explicitly sets positions:
114
114
 
115
- | Method | Effect |
116
- |--------------------------|----------------------------------------------------------|
117
- | #reset | Sets both positions to zero (begining of stored string). |
118
- | #terminate | Sets both positions to the end of the stored string. |
119
- | #pos=(new_byte_position) | Sets byte position; adjusts character position. |
115
+ | Method | Effect |
116
+ |--------------------------|-----------------------------------------------------------|
117
+ | #reset | Sets both positions to zero (beginning of stored string). |
118
+ | #terminate | Sets both positions to the end of the stored string. |
119
+ | #pos=(new_byte_position) | Sets byte position; adjusts character position. |
120
120
 
121
121
  ### Byte Position (Position)
122
122
 
@@ -138,7 +138,7 @@ To get or set the byte position:
138
138
  Many methods use the byte position as the basis for finding matches;
139
139
  many others set, increment, or decrement the byte position:
140
140
 
141
- ```
141
+ ```rb
142
142
  scanner = StringScanner.new('foobar')
143
143
  scanner.pos # => 0
144
144
  scanner.scan(/foo/) # => "foo" # Match found.
@@ -176,7 +176,7 @@ see:
176
176
 
177
177
  Example (string includes multi-byte characters):
178
178
 
179
- ```
179
+ ```rb
180
180
  scanner = StringScanner.new(ENGLISH_TEXT) # Five 1-byte characters.
181
181
  scanner.concat(HIRAGANA_TEXT) # Five 3-byte characters
182
182
  scanner.string # => "Helloこんにちは" # Twenty bytes in all.
@@ -216,7 +216,7 @@ and its size is returned by method #rest_size.
216
216
 
217
217
  Examples:
218
218
 
219
- ```
219
+ ```rb
220
220
  scanner = StringScanner.new('foobarbaz')
221
221
  put_situation(scanner)
222
222
  # Situation:
@@ -430,7 +430,7 @@ See examples below.
430
430
 
431
431
  Successful basic match attempt (no captures):
432
432
 
433
- ```
433
+ ```rb
434
434
  scanner = StringScanner.new('foobarbaz')
435
435
  scanner.exist?(/bar/)
436
436
  put_match_values(scanner)
@@ -452,7 +452,7 @@ put_match_values(scanner)
452
452
 
453
453
  Failed basic match attempt (no captures);
454
454
 
455
- ```
455
+ ```rb
456
456
  scanner = StringScanner.new('foobarbaz')
457
457
  scanner.exist?(/nope/)
458
458
  match_values_cleared?(scanner) # => true
@@ -460,7 +460,7 @@ match_values_cleared?(scanner) # => true
460
460
 
461
461
  Successful unnamed capture match attempt:
462
462
 
463
- ```
463
+ ```rb
464
464
  scanner = StringScanner.new('foobarbazbatbam')
465
465
  scanner.exist?(/(foo)bar(baz)bat(bam)/)
466
466
  put_match_values(scanner)
@@ -486,7 +486,7 @@ put_match_values(scanner)
486
486
  Successful named capture match attempt;
487
487
  same as unnamed above, except for #named_captures:
488
488
 
489
- ```
489
+ ```rb
490
490
  scanner = StringScanner.new('foobarbazbatbam')
491
491
  scanner.exist?(/(?<x>foo)bar(?<y>baz)bat(?<z>bam)/)
492
492
  scanner.named_captures # => {"x"=>"foo", "y"=>"baz", "z"=>"bam"}
@@ -494,7 +494,7 @@ scanner.named_captures # => {"x"=>"foo", "y"=>"baz", "z"=>"bam"}
494
494
 
495
495
  Failed unnamed capture match attempt:
496
496
 
497
- ```
497
+ ```rb
498
498
  scanner = StringScanner.new('somestring')
499
499
  scanner.exist?(/(foo)bar(baz)bat(bam)/)
500
500
  match_values_cleared?(scanner) # => true
@@ -503,7 +503,7 @@ match_values_cleared?(scanner) # => true
503
503
  Failed named capture match attempt;
504
504
  same as unnamed above, except for #named_captures:
505
505
 
506
- ```
506
+ ```rb
507
507
  scanner = StringScanner.new('somestring')
508
508
  scanner.exist?(/(?<x>foo)bar(?<y>baz)bat(?<z>bam)/)
509
509
  match_values_cleared?(scanner) # => false
@@ -518,7 +518,7 @@ which determines the meaning of `'\A'`:
518
518
 
519
519
  * `false` (the default): matches the current byte position.
520
520
 
521
- ```
521
+ ```rb
522
522
  scanner = StringScanner.new('foobar')
523
523
  scanner.scan(/\A./) # => "f"
524
524
  scanner.scan(/\A./) # => "o"
@@ -529,7 +529,7 @@ which determines the meaning of `'\A'`:
529
529
  * `true`: matches the beginning of the target substring;
530
530
  never matches unless the byte position is zero:
531
531
 
532
- ```
532
+ ```rb
533
533
  scanner = StringScanner.new('foobar', fixed_anchor: true)
534
534
  scanner.scan(/\A./) # => "f"
535
535
  scanner.scan(/\A./) # => nil
@@ -22,7 +22,7 @@ extern size_t onig_region_memsize(const struct re_registers *regs);
22
22
 
23
23
  #include <stdbool.h>
24
24
 
25
- #define STRSCAN_VERSION "3.1.1"
25
+ #define STRSCAN_VERSION "3.1.3"
26
26
 
27
27
  /* =======================================================================
28
28
  Data Type Definitions
@@ -58,8 +58,13 @@ struct strscanner
58
58
  };
59
59
 
60
60
  #define MATCHED_P(s) ((s)->flags & FLAG_MATCHED)
61
- #define MATCHED(s) (s)->flags |= FLAG_MATCHED
62
- #define CLEAR_MATCH_STATUS(s) (s)->flags &= ~FLAG_MATCHED
61
+ #define MATCHED(s) ((s)->flags |= FLAG_MATCHED)
62
+ #define CLEAR_MATCHED(s) ((s)->flags &= ~FLAG_MATCHED)
63
+ #define CLEAR_NAMED_CAPTURES(s) ((s)->regex = Qnil)
64
+ #define CLEAR_MATCH_STATUS(s) do {\
65
+ CLEAR_MATCHED(s);\
66
+ CLEAR_NAMED_CAPTURES(s);\
67
+ } while (0)
63
68
 
64
69
  #define S_PBEG(s) (RSTRING_PTR((s)->str))
65
70
  #define S_LEN(s) (RSTRING_LEN((s)->str))
@@ -216,7 +221,6 @@ strscan_s_allocate(VALUE klass)
216
221
  CLEAR_MATCH_STATUS(p);
217
222
  onig_region_init(&(p->regs));
218
223
  p->str = Qnil;
219
- p->regex = Qnil;
220
224
  return obj;
221
225
  }
222
226
 
@@ -231,7 +235,7 @@ strscan_s_allocate(VALUE klass)
231
235
  * is the given `string`;
232
236
  * sets the [fixed-anchor property][10]:
233
237
  *
234
- * ```
238
+ * ```rb
235
239
  * scanner = StringScanner.new('foobarbaz')
236
240
  * scanner.string # => "foobarbaz"
237
241
  * scanner.fixed_anchor? # => false
@@ -339,7 +343,7 @@ strscan_s_mustc(VALUE self)
339
343
  * and clears [match values][9];
340
344
  * returns +self+:
341
345
  *
342
- * ```
346
+ * ```rb
343
347
  * scanner = StringScanner.new('foobarbaz')
344
348
  * scanner.exist?(/bar/) # => 6
345
349
  * scanner.reset # => #<StringScanner 0/9 @ "fooba...">
@@ -405,7 +409,7 @@ strscan_clear(VALUE self)
405
409
  *
406
410
  * Returns the [stored string][1]:
407
411
  *
408
- * ```
412
+ * ```rb
409
413
  * scanner = StringScanner.new('foobar')
410
414
  * scanner.string # => "foobar"
411
415
  * scanner.concat('baz')
@@ -435,7 +439,7 @@ strscan_get_string(VALUE self)
435
439
  * - Clears [match values][9].
436
440
  * - Returns `other_string`.
437
441
  *
438
- * ```
442
+ * ```rb
439
443
  * scanner = StringScanner.new('foobar')
440
444
  * scanner.scan(/foo/)
441
445
  * put_situation(scanner)
@@ -483,7 +487,7 @@ strscan_set_string(VALUE self, VALUE str)
483
487
  * or [match values][9].
484
488
  *
485
489
  *
486
- * ```
490
+ * ```rb
487
491
  * scanner = StringScanner.new('foo')
488
492
  * scanner.string # => "foo"
489
493
  * scanner.terminate
@@ -520,7 +524,7 @@ strscan_get_pos(VALUE self)
520
524
  struct strscanner *p;
521
525
 
522
526
  GET_SCANNER(self, p);
523
- return INT2FIX(p->curr);
527
+ return LONG2NUM(p->curr);
524
528
  }
525
529
 
526
530
  /*
@@ -550,7 +554,7 @@ strscan_set_pos(VALUE self, VALUE v)
550
554
  long i;
551
555
 
552
556
  GET_SCANNER(self, p);
553
- i = NUM2INT(v);
557
+ i = NUM2LONG(v);
554
558
  if (i < 0) i += S_LEN(p);
555
559
  if (i < 0) rb_raise(rb_eRangeError, "index out of range");
556
560
  if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range");
@@ -571,19 +575,20 @@ match_target(struct strscanner *p)
571
575
  }
572
576
 
573
577
  static inline void
574
- set_registers(struct strscanner *p, size_t length)
578
+ set_registers(struct strscanner *p, size_t pos, size_t length)
575
579
  {
576
580
  const int at = 0;
577
581
  OnigRegion *regs = &(p->regs);
578
582
  onig_region_clear(regs);
579
583
  if (onig_region_set(regs, at, 0, 0)) return;
580
584
  if (p->fixed_anchor_p) {
581
- regs->beg[at] = p->curr;
582
- regs->end[at] = p->curr + length;
585
+ regs->beg[at] = pos + p->curr;
586
+ regs->end[at] = pos + p->curr + length;
583
587
  }
584
588
  else
585
589
  {
586
- regs->end[at] = length;
590
+ regs->beg[at] = pos;
591
+ regs->end[at] = pos + length;
587
592
  }
588
593
  }
589
594
 
@@ -731,7 +736,7 @@ strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly
731
736
  if (memcmp(CURPTR(p), RSTRING_PTR(pattern), RSTRING_LEN(pattern)) != 0) {
732
737
  return Qnil;
733
738
  }
734
- set_registers(p, RSTRING_LEN(pattern));
739
+ set_registers(p, 0, RSTRING_LEN(pattern));
735
740
  }
736
741
  else {
737
742
  rb_encoding *enc = rb_enc_check(p->str, pattern);
@@ -740,7 +745,7 @@ strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly
740
745
  if (pos == -1) {
741
746
  return Qnil;
742
747
  }
743
- set_registers(p, RSTRING_LEN(pattern) + pos);
748
+ set_registers(p, pos, RSTRING_LEN(pattern));
744
749
  }
745
750
  }
746
751
 
@@ -789,7 +794,7 @@ strscan_scan(VALUE self, VALUE re)
789
794
  * - Returns the size in bytes of the matched substring.
790
795
  *
791
796
  *
792
- * ```
797
+ * ```rb
793
798
  * scanner = StringScanner.new('foobarbaz')
794
799
  * scanner.pos = 3
795
800
  * scanner.match?(/bar/) => 3
@@ -822,7 +827,7 @@ strscan_scan(VALUE self, VALUE re)
822
827
  * - Returns `nil`.
823
828
  * - Does not increment positions.
824
829
  *
825
- * ```
830
+ * ```rb
826
831
  * scanner.match?(/nope/) # => nil
827
832
  * match_values_cleared?(scanner) # => true
828
833
  * ```
@@ -861,7 +866,7 @@ strscan_skip(VALUE self, VALUE re)
861
866
  * - Returns the matched substring.
862
867
  * - Sets all [match values][9].
863
868
  *
864
- * ```
869
+ * ```rb
865
870
  * scanner = StringScanner.new('foobarbaz')
866
871
  * scanner.pos = 3
867
872
  * scanner.check('bar') # => "bar"
@@ -894,7 +899,7 @@ strscan_skip(VALUE self, VALUE re)
894
899
  * - Returns `nil`.
895
900
  * - Clears all [match values][9].
896
901
  *
897
- * ```
902
+ * ```rb
898
903
  * scanner.check(/nope/) # => nil
899
904
  * match_values_cleared?(scanner) # => true
900
905
  * ```
@@ -961,7 +966,7 @@ strscan_scan_until(VALUE self, VALUE re)
961
966
  * and the end of the matched substring.
962
967
  * - Sets all [match values][9].
963
968
  *
964
- * ```
969
+ * ```rb
965
970
  * scanner = StringScanner.new('foobarbazbatbam')
966
971
  * scanner.pos = 6
967
972
  * scanner.exist?(/bat/) # => 6
@@ -993,7 +998,7 @@ strscan_scan_until(VALUE self, VALUE re)
993
998
  * - Returns `nil`.
994
999
  * - Clears all [match values][9].
995
1000
  *
996
- * ```
1001
+ * ```rb
997
1002
  * scanner.exist?(/nope/) # => nil
998
1003
  * match_values_cleared?(scanner) # => true
999
1004
  * ```
@@ -1035,7 +1040,7 @@ strscan_skip_until(VALUE self, VALUE re)
1035
1040
  * which extends from the current [position][2]
1036
1041
  * to the end of the matched substring.
1037
1042
  *
1038
- * ```
1043
+ * ```rb
1039
1044
  * scanner = StringScanner.new('foobarbazbatbam')
1040
1045
  * scanner.pos = 6
1041
1046
  * scanner.check_until(/bat/) # => "bazbat"
@@ -1067,7 +1072,7 @@ strscan_skip_until(VALUE self, VALUE re)
1067
1072
  * - Clears all [match values][9].
1068
1073
  * - Returns `nil`.
1069
1074
  *
1070
- * ```
1075
+ * ```rb
1071
1076
  * scanner.check_until(/nope/) # => nil
1072
1077
  * match_values_cleared?(scanner) # => true
1073
1078
  * ```
@@ -1239,7 +1244,7 @@ strscan_getbyte(VALUE self)
1239
1244
  * Returns the substring `string[pos, length]`;
1240
1245
  * does not update [match values][9] or [positions][11]:
1241
1246
  *
1242
- * ```
1247
+ * ```rb
1243
1248
  * scanner = StringScanner.new('foobarbaz')
1244
1249
  * scanner.pos = 3
1245
1250
  * scanner.peek(3) # => "bar"
@@ -1292,6 +1297,10 @@ strscan_parse_integer(struct strscanner *p, int base, long len)
1292
1297
  integer = rb_cstr2inum(buffer, base);
1293
1298
  RB_ALLOCV_END(buffer_v);
1294
1299
  p->curr += len;
1300
+
1301
+ MATCHED(p);
1302
+ adjust_registers_to_matched(p);
1303
+
1295
1304
  return integer;
1296
1305
  }
1297
1306
 
@@ -1341,7 +1350,6 @@ strscan_scan_base10_integer(VALUE self)
1341
1350
  return Qnil;
1342
1351
  }
1343
1352
 
1344
- MATCHED(p);
1345
1353
  p->prev = p->curr;
1346
1354
 
1347
1355
  while (len < remaining_len && rb_isdigit(ptr[len])) {
@@ -1375,7 +1383,7 @@ strscan_scan_base16_integer(VALUE self)
1375
1383
  len++;
1376
1384
  }
1377
1385
 
1378
- if ((remaining_len >= (len + 2)) && ptr[len] == '0' && ptr[len + 1] == 'x') {
1386
+ if ((remaining_len >= (len + 3)) && ptr[len] == '0' && ptr[len + 1] == 'x' && rb_isxdigit(ptr[len + 2])) {
1379
1387
  len += 2;
1380
1388
  }
1381
1389
 
@@ -1383,7 +1391,6 @@ strscan_scan_base16_integer(VALUE self)
1383
1391
  return Qnil;
1384
1392
  }
1385
1393
 
1386
- MATCHED(p);
1387
1394
  p->prev = p->curr;
1388
1395
 
1389
1396
  while (len < remaining_len && rb_isxdigit(ptr[len])) {
@@ -1403,7 +1410,7 @@ strscan_scan_base16_integer(VALUE self)
1403
1410
  * Sets the [position][2] to its value previous to the recent successful
1404
1411
  * [match][17] attempt:
1405
1412
  *
1406
- * ```
1413
+ * ```rb
1407
1414
  * scanner = StringScanner.new('foobarbaz')
1408
1415
  * scanner.scan(/foo/)
1409
1416
  * put_situation(scanner)
@@ -1424,7 +1431,7 @@ strscan_scan_base16_integer(VALUE self)
1424
1431
  *
1425
1432
  * Raises an exception if match values are clear:
1426
1433
  *
1427
- * ```
1434
+ * ```rb
1428
1435
  * scanner.scan(/nope/) # => nil
1429
1436
  * match_values_cleared?(scanner) # => true
1430
1437
  * scanner.unscan # Raises StringScanner::Error.
@@ -1498,7 +1505,7 @@ strscan_bol_p(VALUE self)
1498
1505
  * Returns whether the [position][2]
1499
1506
  * is at the end of the [stored string][1]:
1500
1507
  *
1501
- * ```
1508
+ * ```rb
1502
1509
  * scanner = StringScanner.new('foobarbaz')
1503
1510
  * scanner.eos? # => false
1504
1511
  * pos = 3
@@ -1567,7 +1574,7 @@ strscan_rest_p(VALUE self)
1567
1574
  * `false` otherwise;
1568
1575
  * see [Basic Matched Values][18]:
1569
1576
  *
1570
- * ```
1577
+ * ```rb
1571
1578
  * scanner = StringScanner.new('foobarbaz')
1572
1579
  * scanner.matched? # => false
1573
1580
  * scanner.pos = 3
@@ -1599,7 +1606,7 @@ strscan_matched_p(VALUE self)
1599
1606
  * or `nil` otherwise;
1600
1607
  * see [Basic Matched Values][18]:
1601
1608
  *
1602
- * ```
1609
+ * ```rb
1603
1610
  * scanner = StringScanner.new('foobarbaz')
1604
1611
  * scanner.matched # => nil
1605
1612
  * scanner.pos = 3
@@ -1634,7 +1641,7 @@ strscan_matched(VALUE self)
1634
1641
  * or `nil` otherwise;
1635
1642
  * see [Basic Matched Values][18]:
1636
1643
  *
1637
- * ```
1644
+ * ```rb
1638
1645
  * scanner = StringScanner.new('foobarbaz')
1639
1646
  * scanner.matched_size # => nil
1640
1647
  *
@@ -1660,19 +1667,17 @@ strscan_matched_size(VALUE self)
1660
1667
  static int
1661
1668
  name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name, const char* name_end, rb_encoding *enc)
1662
1669
  {
1663
- int num;
1664
-
1665
- num = onig_name_to_backref_number(RREGEXP_PTR(regexp),
1666
- (const unsigned char* )name, (const unsigned char* )name_end, regs);
1667
- if (num >= 1) {
1668
- return num;
1669
- }
1670
- else {
1671
- rb_enc_raise(enc, rb_eIndexError, "undefined group name reference: %.*s",
1672
- rb_long2int(name_end - name), name);
1670
+ if (RTEST(regexp)) {
1671
+ int num = onig_name_to_backref_number(RREGEXP_PTR(regexp),
1672
+ (const unsigned char* )name,
1673
+ (const unsigned char* )name_end,
1674
+ regs);
1675
+ if (num >= 1) {
1676
+ return num;
1677
+ }
1673
1678
  }
1674
-
1675
- UNREACHABLE;
1679
+ rb_enc_raise(enc, rb_eIndexError, "undefined group name reference: %.*s",
1680
+ rb_long2int(name_end - name), name);
1676
1681
  }
1677
1682
 
1678
1683
  /*
@@ -1688,14 +1693,14 @@ name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name
1688
1693
  *
1689
1694
  * When there are captures:
1690
1695
  *
1691
- * ```
1696
+ * ```rb
1692
1697
  * scanner = StringScanner.new('Fri Dec 12 1975 14:39')
1693
1698
  * scanner.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /)
1694
1699
  * ```
1695
1700
  *
1696
1701
  * - `specifier` zero: returns the entire matched substring:
1697
1702
  *
1698
- * ```
1703
+ * ```rb
1699
1704
  * scanner[0] # => "Fri Dec 12 "
1700
1705
  * scanner.pre_match # => ""
1701
1706
  * scanner.post_match # => "1975 14:39"
@@ -1703,7 +1708,7 @@ name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name
1703
1708
  *
1704
1709
  * - `specifier` positive integer. returns the `n`th capture, or `nil` if out of range:
1705
1710
  *
1706
- * ```
1711
+ * ```rb
1707
1712
  * scanner[1] # => "Fri"
1708
1713
  * scanner[2] # => "Dec"
1709
1714
  * scanner[3] # => "12"
@@ -1712,7 +1717,7 @@ name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name
1712
1717
  *
1713
1718
  * - `specifier` negative integer. counts backward from the last subgroup:
1714
1719
  *
1715
- * ```
1720
+ * ```rb
1716
1721
  * scanner[-1] # => "12"
1717
1722
  * scanner[-4] # => "Fri Dec 12 "
1718
1723
  * scanner[-5] # => nil
@@ -1720,7 +1725,7 @@ name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name
1720
1725
  *
1721
1726
  * - `specifier` symbol or string. returns the named subgroup, or `nil` if no such:
1722
1727
  *
1723
- * ```
1728
+ * ```rb
1724
1729
  * scanner[:wday] # => "Fri"
1725
1730
  * scanner['wday'] # => "Fri"
1726
1731
  * scanner[:month] # => "Dec"
@@ -1730,7 +1735,7 @@ name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name
1730
1735
  *
1731
1736
  * When there are no captures, only `[0]` returns non-`nil`:
1732
1737
  *
1733
- * ```
1738
+ * ```rb
1734
1739
  * scanner = StringScanner.new('foobarbaz')
1735
1740
  * scanner.exist?(/bar/)
1736
1741
  * scanner[0] # => "bar"
@@ -1739,7 +1744,7 @@ name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name
1739
1744
  *
1740
1745
  * For a failed match, even `[0]` returns `nil`:
1741
1746
  *
1742
- * ```
1747
+ * ```rb
1743
1748
  * scanner.scan(/nope/) # => nil
1744
1749
  * scanner[0] # => nil
1745
1750
  * scanner[1] # => nil
@@ -1761,7 +1766,6 @@ strscan_aref(VALUE self, VALUE idx)
1761
1766
  idx = rb_sym2str(idx);
1762
1767
  /* fall through */
1763
1768
  case T_STRING:
1764
- if (!RTEST(p->regex)) return Qnil;
1765
1769
  RSTRING_GETMEM(idx, name, i);
1766
1770
  i = name_to_backref_number(&(p->regs), p->regex, name, name + i, rb_enc_get(idx));
1767
1771
  break;
@@ -1790,7 +1794,7 @@ strscan_aref(VALUE self, VALUE idx)
1790
1794
  * Returns the count of captures if the most recent match attempt succeeded, `nil` otherwise;
1791
1795
  * see [Captures Match Values][13]:
1792
1796
  *
1793
- * ```
1797
+ * ```rb
1794
1798
  * scanner = StringScanner.new('Fri Dec 12 1975 14:39')
1795
1799
  * scanner.size # => nil
1796
1800
  *
@@ -1824,7 +1828,7 @@ strscan_size(VALUE self)
1824
1828
  * Returns the array of [captured match values][13] at indexes `(1..)`
1825
1829
  * if the most recent match attempt succeeded, or `nil` otherwise:
1826
1830
  *
1827
- * ```
1831
+ * ```rb
1828
1832
  * scanner = StringScanner.new('Fri Dec 12 1975 14:39')
1829
1833
  * scanner.captures # => nil
1830
1834
  *
@@ -1879,7 +1883,7 @@ strscan_captures(VALUE self)
1879
1883
  * For each `specifier`, the returned substring is `[specifier]`;
1880
1884
  * see #[].
1881
1885
  *
1882
- * ```
1886
+ * ```rb
1883
1887
  * scanner = StringScanner.new('Fri Dec 12 1975 14:39')
1884
1888
  * pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) /
1885
1889
  * scanner.match?(pattern)
@@ -1919,7 +1923,7 @@ strscan_values_at(int argc, VALUE *argv, VALUE self)
1919
1923
  * or `nil` otherwise;
1920
1924
  * see [Basic Match Values][18]:
1921
1925
  *
1922
- * ```
1926
+ * ```rb
1923
1927
  * scanner = StringScanner.new('foobarbaz')
1924
1928
  * scanner.pre_match # => nil
1925
1929
  *
@@ -1956,7 +1960,7 @@ strscan_pre_match(VALUE self)
1956
1960
  * or `nil` otherwise;
1957
1961
  * see [Basic Match Values][18]:
1958
1962
  *
1959
- * ```
1963
+ * ```rb
1960
1964
  * scanner = StringScanner.new('foobarbaz')
1961
1965
  * scanner.post_match # => nil
1962
1966
  *
@@ -1991,7 +1995,7 @@ strscan_post_match(VALUE self)
1991
1995
  * Returns the 'rest' of the [stored string][1] (all after the current [position][2]),
1992
1996
  * which is the [target substring][3]:
1993
1997
  *
1994
- * ```
1998
+ * ```rb
1995
1999
  * scanner = StringScanner.new('foobarbaz')
1996
2000
  * scanner.rest # => "foobarbaz"
1997
2001
  * scanner.pos = 3
@@ -2022,7 +2026,7 @@ strscan_rest(VALUE self)
2022
2026
  *
2023
2027
  * Returns the size (in bytes) of the #rest of the [stored string][1]:
2024
2028
  *
2025
- * ```
2029
+ * ```rb
2026
2030
  * scanner = StringScanner.new('foobarbaz')
2027
2031
  * scanner.rest # => "foobarbaz"
2028
2032
  * scanner.rest_size # => 9
@@ -2081,7 +2085,7 @@ strscan_restsize(VALUE self)
2081
2085
  * 3. The substring preceding the current position.
2082
2086
  * 4. The substring following the current position (which is also the [target substring][3]).
2083
2087
  *
2084
- * ```
2088
+ * ```rb
2085
2089
  * scanner = StringScanner.new("Fri Dec 12 1975 14:39")
2086
2090
  * scanner.pos = 11
2087
2091
  * scanner.inspect # => "#<StringScanner 11/21 \"...c 12 \" @ \"1975 ...\">"
@@ -2089,14 +2093,14 @@ strscan_restsize(VALUE self)
2089
2093
  *
2090
2094
  * If at beginning-of-string, item 4 above (following substring) is omitted:
2091
2095
  *
2092
- * ```
2096
+ * ```rb
2093
2097
  * scanner.reset
2094
2098
  * scanner.inspect # => "#<StringScanner 0/21 @ \"Fri D...\">"
2095
2099
  * ```
2096
2100
  *
2097
2101
  * If at end-of-string, all items above are omitted:
2098
2102
  *
2099
- * ```
2103
+ * ```rb
2100
2104
  * scanner.terminate
2101
2105
  * scanner.inspect # => "#<StringScanner fin>"
2102
2106
  * ```
@@ -2224,7 +2228,7 @@ named_captures_iter(const OnigUChar *name,
2224
2228
  * if the most recent match attempt succeeded, or nil otherwise;
2225
2229
  * see [Captured Match Values][13]:
2226
2230
  *
2227
- * ```
2231
+ * ```rb
2228
2232
  * scanner = StringScanner.new('Fri Dec 12 1975 14:39')
2229
2233
  * scanner.named_captures # => {}
2230
2234
  *
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strscan
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Minero Aoki
8
8
  - Sutou Kouhei
9
9
  - Charles Oliver Nutter
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2024-12-12 00:00:00.000000000 Z
12
+ date: 2025-04-13 00:00:00.000000000 Z
14
13
  dependencies: []
15
14
  description: Provides lexical scanning operations on a String.
16
15
  email:
@@ -60,7 +59,6 @@ licenses:
60
59
  - Ruby
61
60
  - BSD-2-Clause
62
61
  metadata: {}
63
- post_install_message:
64
62
  rdoc_options:
65
63
  - "-idoc"
66
64
  require_paths:
@@ -76,8 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
74
  - !ruby/object:Gem::Version
77
75
  version: '0'
78
76
  requirements: []
79
- rubygems_version: 3.5.22
80
- signing_key:
77
+ rubygems_version: 3.6.2
81
78
  specification_version: 4
82
79
  summary: Provides lexical scanning operations on a String.
83
80
  test_files: []