re2 2.25.0 → 2.26.1

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: 477c8a61880d0b90859d119d21612ccaa439fd6e7a5d06946b5044a6520b2fab
4
- data.tar.gz: '0973c566418525946e61a99d1d317bd708a52dc395053064261c6d581ebb797c'
3
+ metadata.gz: 32598d3c71b90c6646ca084271c0c3cc07a4b0a0d5ca60e9e50f5007fd335adc
4
+ data.tar.gz: 4415cd8091165f5ed1a9361f92dc1f8d1ee7db86c905c2987331d404a50b6a3c
5
5
  SHA512:
6
- metadata.gz: 9e18ab14bd16e37917b988483dd432b7469da78113c1f67dcaefaf5102771c635dfde842779b6b325ffd857d0203acc9c32cd88c5f1cb7017fdf05f93f89adf1
7
- data.tar.gz: 20081d9a25c5789a2c585b0c33049c8431ab0f5abc29b2bc0c4e4baa6a1bc6b3da24fd609fe7f05e65a4d5eb4759c20ba3c481f31bc85c25d3cbf2f8efb56d18
6
+ metadata.gz: 26cc651d02984bfb0bdf2b3ca2d9dff1e4a32710c589cf186cf04a05cfcf82048a1994624ed5cec47a28b81c768844e8a9eaa5f2a3aa35621c50928f0a1ee151
7
+ data.tar.gz: 55b85a59ab0f4c6a59f07dad5ae109ddd1134b763d2b857c3cb071847962665ba71052cb1f9095982ae5975eaacab130dd1cf64ef7fe061bb721ed14ecc833a2
data/README.md CHANGED
@@ -6,7 +6,7 @@ Python".
6
6
 
7
7
  [![Build Status](https://github.com/mudge/re2/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/mudge/re2/actions)
8
8
 
9
- **Current version:** 2.25.0
9
+ **Current version:** 2.26.1
10
10
  **Bundled RE2 version:** libre2.11 (2025-11-05)
11
11
 
12
12
  ```ruby
data/Rakefile CHANGED
@@ -24,10 +24,6 @@ cross_platforms = %w[
24
24
  arm-linux-musl
25
25
  arm64-darwin
26
26
  x64-mingw-ucrt
27
- x64-mingw32
28
- x86-linux-gnu
29
- x86-linux-musl
30
- x86-mingw32
31
27
  x86_64-darwin
32
28
  x86_64-linux-gnu
33
29
  x86_64-linux-musl
data/ext/re2/extconf.rb CHANGED
@@ -139,7 +139,6 @@ module RE2
139
139
  compile_options = +"-x c++"
140
140
 
141
141
  have_library("stdc++")
142
- have_header("stdint.h")
143
142
 
144
143
  minimal_program = <<~SRC
145
144
  #include <re2/re2.h>
@@ -153,7 +152,7 @@ module RE2
153
152
  if re2_requires_version_flag
154
153
  # Recent versions of RE2 depend directly on Abseil, which requires a
155
154
  # compiler with C++17 support.
156
- abort "Cannot compile re2 with your compiler: recent versions require C++17 support." unless %w[c++20 c++17 c++11 c++0x].any? do |std|
155
+ abort "Cannot compile re2 with your compiler: recent versions require C++17 support." unless %w[c++20 c++17 c++11].any? do |std|
157
156
  checking_for("re2 that compiles with #{std} standard") do
158
157
  if try_compile(minimal_program, compile_options + " -std=#{std}")
159
158
  compile_options << " -std=#{std}"
@@ -268,8 +267,8 @@ module RE2
268
267
  message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
269
268
 
270
269
  recipe.host = target_host
271
- # Ensure x64-mingw-ucrt and x64-mingw32 use different library paths since the host
272
- # is the same (x86_64-w64-mingw32).
270
+ # Ensure x64-mingw-ucrt uses different library paths since the host is
271
+ # the same (x86_64-w64-mingw32).
273
272
  recipe.target = File.join(recipe.target, target_arch) if cross_build_p
274
273
 
275
274
  yield recipe
data/ext/re2/re2.cc CHANGED
@@ -8,7 +8,7 @@
8
8
  * Released under the BSD Licence, please see LICENSE.txt
9
9
  */
10
10
 
11
- #include <stdint.h>
11
+ #include <cstdint>
12
12
 
13
13
  #include <map>
14
14
  #include <sstream>
@@ -296,12 +296,12 @@ static re2_scanner *unwrap_re2_scanner(VALUE self) {
296
296
  static VALUE re2_regexp_names(const VALUE self) {
297
297
  re2_pattern *p = unwrap_re2_regexp(self);
298
298
 
299
- const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
299
+ const auto& groups = p->pattern->NamedCapturingGroups();
300
300
  VALUE names = rb_ary_new2(groups.size());
301
301
 
302
- for (std::map<std::string, int>::const_iterator it = groups.begin(); it != groups.end(); ++it) {
302
+ for (const auto& group : groups) {
303
303
  rb_ary_push(names,
304
- encoded_str_new(it->first.data(), it->first.size(),
304
+ encoded_str_new(group.first.data(), group.first.size(),
305
305
  p->pattern->options().encoding()));
306
306
  }
307
307
 
@@ -385,7 +385,7 @@ static VALUE re2_scanner_rewind(VALUE self) {
385
385
  delete c->input;
386
386
  c->input = new(std::nothrow) re2::StringPiece(
387
387
  RSTRING_PTR(c->text), RSTRING_LEN(c->text));
388
- if (c->input == 0) {
388
+ if (c->input == nullptr) {
389
389
  rb_raise(rb_eNoMemError,
390
390
  "not enough memory to allocate StringPiece for input");
391
391
  }
@@ -412,12 +412,12 @@ static VALUE re2_scanner_initialize_copy(VALUE self, VALUE other) {
412
412
 
413
413
  if (other_c->input) {
414
414
  self_c->input = new(std::nothrow) re2::StringPiece(*other_c->input);
415
- if (self_c->input == 0) {
415
+ if (self_c->input == nullptr) {
416
416
  rb_raise(rb_eNoMemError,
417
417
  "not enough memory to allocate StringPiece for input");
418
418
  }
419
419
  } else {
420
- self_c->input = NULL;
420
+ self_c->input = nullptr;
421
421
  }
422
422
 
423
423
  return self;
@@ -469,7 +469,7 @@ static VALUE re2_scanner_scan(VALUE self) {
469
469
  VALUE result = rb_ary_new2(c->number_of_capturing_groups);
470
470
 
471
471
  for (int i = 0; i < c->number_of_capturing_groups; ++i) {
472
- if (matches[i].empty()) {
472
+ if (matches[i].data() == nullptr) {
473
473
  rb_ary_push(result, Qnil);
474
474
  } else {
475
475
  rb_ary_push(result, encoded_str_new(matches[i].data(),
@@ -501,36 +501,36 @@ static re2::StringPiece *re2_matchdata_find_match(VALUE idx, const VALUE self) {
501
501
  if (RB_INTEGER_TYPE_P(idx)) {
502
502
  id = NUM2INT(idx);
503
503
  } else if (SYMBOL_P(idx)) {
504
- const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
505
- std::map<std::string, int>::const_iterator search = groups.find(rb_id2name(SYM2ID(idx)));
504
+ const auto& groups = p->pattern->NamedCapturingGroups();
505
+ auto search = groups.find(rb_id2name(SYM2ID(idx)));
506
506
 
507
507
  if (search != groups.end()) {
508
508
  id = search->second;
509
509
  } else {
510
- return NULL;
510
+ return nullptr;
511
511
  }
512
512
  } else {
513
513
  StringValue(idx);
514
514
 
515
- const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
516
- std::map<std::string, int>::const_iterator search = groups.find(std::string(RSTRING_PTR(idx), RSTRING_LEN(idx)));
515
+ const auto& groups = p->pattern->NamedCapturingGroups();
516
+ auto search = groups.find(std::string(RSTRING_PTR(idx), RSTRING_LEN(idx)));
517
517
 
518
518
  if (search != groups.end()) {
519
519
  id = search->second;
520
520
  } else {
521
- return NULL;
521
+ return nullptr;
522
522
  }
523
523
  }
524
524
 
525
525
  if (id >= 0 && id < m->number_of_matches) {
526
526
  re2::StringPiece *match = &m->matches[id];
527
527
 
528
- if (!match->empty()) {
528
+ if (match->data() != nullptr) {
529
529
  return match;
530
530
  }
531
531
  }
532
532
 
533
- return NULL;
533
+ return nullptr;
534
534
  }
535
535
 
536
536
  /*
@@ -564,7 +564,7 @@ static VALUE re2_matchdata_begin(const VALUE self, VALUE n) {
564
564
  re2_matchdata *m = unwrap_re2_matchdata(self);
565
565
 
566
566
  re2::StringPiece *match = re2_matchdata_find_match(n, self);
567
- if (match == NULL) {
567
+ if (match == nullptr) {
568
568
  return Qnil;
569
569
  } else {
570
570
  long offset = match->data() - RSTRING_PTR(m->text);
@@ -589,7 +589,7 @@ static VALUE re2_matchdata_end(const VALUE self, VALUE n) {
589
589
  re2_matchdata *m = unwrap_re2_matchdata(self);
590
590
 
591
591
  re2::StringPiece *match = re2_matchdata_find_match(n, self);
592
- if (match == NULL) {
592
+ if (match == nullptr) {
593
593
  return Qnil;
594
594
  } else {
595
595
  long offset = (match->data() - RSTRING_PTR(m->text)) + match->size();
@@ -615,7 +615,7 @@ static VALUE re2_matchdata_pre_match(const VALUE self) {
615
615
  re2_pattern *p = unwrap_re2_regexp(m->regexp);
616
616
 
617
617
  re2::StringPiece *match = &m->matches[0];
618
- if (match->empty()) {
618
+ if (match->data() == nullptr) {
619
619
  return Qnil;
620
620
  }
621
621
 
@@ -642,7 +642,7 @@ static VALUE re2_matchdata_post_match(const VALUE self) {
642
642
  re2_pattern *p = unwrap_re2_regexp(m->regexp);
643
643
 
644
644
  re2::StringPiece *match = &m->matches[0];
645
- if (match->empty()) {
645
+ if (match->data() == nullptr) {
646
646
  return Qnil;
647
647
  }
648
648
 
@@ -669,7 +669,7 @@ static VALUE re2_matchdata_offset(const VALUE self, VALUE n) {
669
669
  re2_matchdata *m = unwrap_re2_matchdata(self);
670
670
 
671
671
  re2::StringPiece *match = re2_matchdata_find_match(n, self);
672
- if (match == NULL) {
672
+ if (match == nullptr) {
673
673
  return Qnil;
674
674
  }
675
675
 
@@ -700,7 +700,7 @@ static VALUE re2_matchdata_match_length(const VALUE self, VALUE n) {
700
700
  re2_matchdata *m = unwrap_re2_matchdata(self);
701
701
 
702
702
  re2::StringPiece *match = re2_matchdata_find_match(n, self);
703
- if (match == NULL) {
703
+ if (match == nullptr) {
704
704
  return Qnil;
705
705
  }
706
706
 
@@ -766,7 +766,7 @@ static VALUE re2_matchdata_to_a(const VALUE self) {
766
766
  for (int i = 0; i < m->number_of_matches; ++i) {
767
767
  re2::StringPiece *match = &m->matches[i];
768
768
 
769
- if (match->empty()) {
769
+ if (match->data() == nullptr) {
770
770
  rb_ary_push(array, Qnil);
771
771
  } else {
772
772
  rb_ary_push(array, encoded_str_new(match->data(), match->size(),
@@ -786,7 +786,7 @@ static VALUE re2_matchdata_nth_match(int nth, const VALUE self) {
786
786
  } else {
787
787
  re2::StringPiece *match = &m->matches[nth];
788
788
 
789
- if (match->empty()) {
789
+ if (match->data() == nullptr) {
790
790
  return Qnil;
791
791
  } else {
792
792
  return encoded_str_new(match->data(), match->size(),
@@ -799,8 +799,8 @@ static VALUE re2_matchdata_named_match(const std::string &name, const VALUE self
799
799
  re2_matchdata *m = unwrap_re2_matchdata(self);
800
800
  re2_pattern *p = unwrap_re2_regexp(m->regexp);
801
801
 
802
- const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
803
- std::map<std::string, int>::const_iterator search = groups.find(name);
802
+ const auto& groups = p->pattern->NamedCapturingGroups();
803
+ auto search = groups.find(name);
804
804
 
805
805
  if (search != groups.end()) {
806
806
  return re2_matchdata_nth_match(search->second, self);
@@ -955,7 +955,7 @@ static VALUE re2_matchdata_deconstruct(const VALUE self) {
955
955
  for (int i = 1; i < m->number_of_matches; ++i) {
956
956
  re2::StringPiece *match = &m->matches[i];
957
957
 
958
- if (match->empty()) {
958
+ if (match->data() == nullptr) {
959
959
  rb_ary_push(array, Qnil);
960
960
  } else {
961
961
  rb_ary_push(array, encoded_str_new(match->data(), match->size(),
@@ -999,14 +999,14 @@ static VALUE re2_matchdata_deconstruct_keys(const VALUE self, const VALUE keys)
999
999
  re2_matchdata *m = unwrap_re2_matchdata(self);
1000
1000
  re2_pattern *p = unwrap_re2_regexp(m->regexp);
1001
1001
 
1002
- const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
1002
+ const auto& groups = p->pattern->NamedCapturingGroups();
1003
1003
  VALUE capturing_groups = rb_hash_new();
1004
1004
 
1005
1005
  if (NIL_P(keys)) {
1006
- for (std::map<std::string, int>::const_iterator it = groups.begin(); it != groups.end(); ++it) {
1006
+ for (const auto& group : groups) {
1007
1007
  rb_hash_aset(capturing_groups,
1008
- ID2SYM(rb_intern2(it->first.data(), it->first.size())),
1009
- re2_matchdata_nth_match(it->second, self));
1008
+ ID2SYM(rb_intern2(group.first.data(), group.first.size())),
1009
+ re2_matchdata_nth_match(group.second, self));
1010
1010
  }
1011
1011
  } else {
1012
1012
  Check_Type(keys, T_ARRAY);
@@ -1016,7 +1016,7 @@ static VALUE re2_matchdata_deconstruct_keys(const VALUE self, const VALUE keys)
1016
1016
  VALUE key = rb_ary_entry(keys, i);
1017
1017
  Check_Type(key, T_SYMBOL);
1018
1018
  const char *name = rb_id2name(SYM2ID(key));
1019
- std::map<std::string, int>::const_iterator search = groups.find(name);
1019
+ auto search = groups.find(name);
1020
1020
 
1021
1021
  if (search != groups.end()) {
1022
1022
  rb_hash_aset(capturing_groups, key, re2_matchdata_nth_match(search->second, self));
@@ -1069,18 +1069,18 @@ static VALUE re2_matchdata_named_captures(int argc, VALUE *argv, const VALUE sel
1069
1069
  re2_matchdata *m = unwrap_re2_matchdata(self);
1070
1070
  re2_pattern *p = unwrap_re2_regexp(m->regexp);
1071
1071
 
1072
- const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
1072
+ const auto& groups = p->pattern->NamedCapturingGroups();
1073
1073
  VALUE result = rb_hash_new();
1074
1074
 
1075
- for (std::map<std::string, int>::const_iterator it = groups.begin(); it != groups.end(); ++it) {
1075
+ for (const auto& group : groups) {
1076
1076
  VALUE key;
1077
1077
  if (symbolize) {
1078
- key = ID2SYM(rb_intern2(it->first.data(), it->first.size()));
1078
+ key = ID2SYM(rb_intern2(group.first.data(), group.first.size()));
1079
1079
  } else {
1080
- key = encoded_str_new(it->first.data(), it->first.size(),
1080
+ key = encoded_str_new(group.first.data(), group.first.size(),
1081
1081
  p->pattern->options().encoding());
1082
1082
  }
1083
- rb_hash_aset(result, key, re2_matchdata_nth_match(it->second, self));
1083
+ rb_hash_aset(result, key, re2_matchdata_nth_match(group.second, self));
1084
1084
  }
1085
1085
 
1086
1086
  return result;
@@ -1160,7 +1160,7 @@ static VALUE re2_matchdata_initialize_copy(VALUE self, VALUE other) {
1160
1160
 
1161
1161
  if (other_m->matches) {
1162
1162
  self_m->matches = new(std::nothrow) re2::StringPiece[other_m->number_of_matches];
1163
- if (self_m->matches == 0) {
1163
+ if (self_m->matches == nullptr) {
1164
1164
  rb_raise(rb_eNoMemError,
1165
1165
  "not enough memory to allocate StringPiece for matches");
1166
1166
  }
@@ -1168,7 +1168,7 @@ static VALUE re2_matchdata_initialize_copy(VALUE self, VALUE other) {
1168
1168
  self_m->matches[i] = other_m->matches[i];
1169
1169
  }
1170
1170
  } else {
1171
- self_m->matches = NULL;
1171
+ self_m->matches = nullptr;
1172
1172
  }
1173
1173
 
1174
1174
  return self;
@@ -1244,7 +1244,7 @@ static VALUE re2_regexp_initialize(int argc, VALUE *argv, VALUE self) {
1244
1244
  re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)));
1245
1245
  }
1246
1246
 
1247
- if (p->pattern == 0) {
1247
+ if (p->pattern == nullptr) {
1248
1248
  rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object");
1249
1249
  }
1250
1250
 
@@ -1263,7 +1263,7 @@ static VALUE re2_regexp_initialize_copy(VALUE self, VALUE other) {
1263
1263
 
1264
1264
  self_p->pattern = new(std::nothrow) RE2(other_p->pattern->pattern(),
1265
1265
  other_p->pattern->options());
1266
- if (self_p->pattern == 0) {
1266
+ if (self_p->pattern == nullptr) {
1267
1267
  rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object");
1268
1268
  }
1269
1269
 
@@ -1629,14 +1629,14 @@ static VALUE re2_regexp_number_of_capturing_groups(const VALUE self) {
1629
1629
  */
1630
1630
  static VALUE re2_regexp_named_capturing_groups(const VALUE self) {
1631
1631
  re2_pattern *p = unwrap_re2_regexp(self);
1632
- const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
1632
+ const auto& groups = p->pattern->NamedCapturingGroups();
1633
1633
  VALUE capturing_groups = rb_hash_new();
1634
1634
 
1635
- for (std::map<std::string, int>::const_iterator it = groups.begin(); it != groups.end(); ++it) {
1635
+ for (const auto& group : groups) {
1636
1636
  rb_hash_aset(capturing_groups,
1637
- encoded_str_new(it->first.data(), it->first.size(),
1637
+ encoded_str_new(group.first.data(), group.first.size(),
1638
1638
  p->pattern->options().encoding()),
1639
- INT2FIX(it->second));
1639
+ INT2FIX(group.second));
1640
1640
  }
1641
1641
 
1642
1642
  return capturing_groups;
@@ -1737,8 +1737,8 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
1737
1737
  p = unwrap_re2_regexp(self);
1738
1738
 
1739
1739
  int n;
1740
- int startpos = 0;
1741
- int endpos = RSTRING_LEN(text);
1740
+ size_t startpos = 0;
1741
+ size_t endpos = RSTRING_LEN(text);
1742
1742
  RE2::Anchor anchor = RE2::UNANCHORED;
1743
1743
 
1744
1744
  if (RTEST(options)) {
@@ -1756,11 +1756,13 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
1756
1756
  VALUE endpos_option = rb_hash_aref(options, ID2SYM(id_endpos));
1757
1757
  if (!NIL_P(endpos_option)) {
1758
1758
  #ifdef HAVE_ENDPOS_ARGUMENT
1759
- endpos = NUM2INT(endpos_option);
1759
+ ssize_t endpos_value = NUM2SSIZET(endpos_option);
1760
1760
 
1761
- if (endpos < 0) {
1761
+ if (endpos_value < 0) {
1762
1762
  rb_raise(rb_eArgError, "endpos should be >= 0");
1763
1763
  }
1764
+
1765
+ endpos = static_cast<size_t>(endpos_value);
1764
1766
  #else
1765
1767
  rb_raise(re2_eRegexpUnsupportedError, "current version of RE2::Match() does not support endpos argument");
1766
1768
  #endif
@@ -1799,11 +1801,13 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
1799
1801
 
1800
1802
  VALUE startpos_option = rb_hash_aref(options, ID2SYM(id_startpos));
1801
1803
  if (!NIL_P(startpos_option)) {
1802
- startpos = NUM2INT(startpos_option);
1804
+ ssize_t startpos_value = NUM2SSIZET(startpos_option);
1803
1805
 
1804
- if (startpos < 0) {
1806
+ if (startpos_value < 0) {
1805
1807
  rb_raise(rb_eArgError, "startpos should be >= 0");
1806
1808
  }
1809
+
1810
+ startpos = static_cast<size_t>(startpos_value);
1807
1811
  }
1808
1812
  }
1809
1813
  } else {
@@ -1838,7 +1842,7 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
1838
1842
  n += 1;
1839
1843
 
1840
1844
  re2::StringPiece *matches = new(std::nothrow) re2::StringPiece[n];
1841
- if (matches == 0) {
1845
+ if (matches == nullptr) {
1842
1846
  rb_raise(rb_eNoMemError,
1843
1847
  "not enough memory to allocate StringPieces for matches");
1844
1848
  }
@@ -1935,7 +1939,7 @@ static VALUE re2_regexp_scan(const VALUE self, VALUE text) {
1935
1939
  RB_OBJ_WRITE(scanner, &c->text, rb_str_new_frozen(text));
1936
1940
  c->input = new(std::nothrow) re2::StringPiece(
1937
1941
  RSTRING_PTR(c->text), RSTRING_LEN(c->text));
1938
- if (c->input == 0) {
1942
+ if (c->input == nullptr) {
1939
1943
  rb_raise(rb_eNoMemError,
1940
1944
  "not enough memory to allocate StringPiece for input");
1941
1945
  }
@@ -2293,7 +2297,7 @@ static VALUE re2_set_initialize(int argc, VALUE *argv, VALUE self) {
2293
2297
  }
2294
2298
 
2295
2299
  s->set = new(std::nothrow) RE2::Set(re2_options, re2_anchor);
2296
- if (s->set == 0) {
2300
+ if (s->set == nullptr) {
2297
2301
  rb_raise(rb_eNoMemError, "not enough memory to allocate RE2::Set object");
2298
2302
  }
2299
2303
 
@@ -2480,8 +2484,8 @@ static VALUE re2_set_match(int argc, VALUE *argv, const VALUE self) {
2480
2484
  rb_raise(re2_eSetMatchError, "Unknown RE2::Set::ErrorKind: %d", e.kind);
2481
2485
  }
2482
2486
  } else {
2483
- for (std::vector<int>::size_type i = 0; i < v.size(); ++i) {
2484
- rb_ary_push(result, INT2FIX(v[i]));
2487
+ for (int index : v) {
2488
+ rb_ary_push(result, INT2FIX(index));
2485
2489
  }
2486
2490
  }
2487
2491
 
@@ -2495,8 +2499,8 @@ static VALUE re2_set_match(int argc, VALUE *argv, const VALUE self) {
2495
2499
  VALUE result = rb_ary_new2(v.size());
2496
2500
 
2497
2501
  if (matched) {
2498
- for (std::vector<int>::size_type i = 0; i < v.size(); ++i) {
2499
- rb_ary_push(result, INT2FIX(v[i]));
2502
+ for (int index : v) {
2503
+ rb_ary_push(result, INT2FIX(index));
2500
2504
  }
2501
2505
  }
2502
2506
 
data/lib/re2/version.rb CHANGED
@@ -10,5 +10,5 @@
10
10
 
11
11
 
12
12
  module RE2
13
- VERSION = "2.25.0"
13
+ VERSION = "2.26.1"
14
14
  end
@@ -66,10 +66,16 @@ RSpec.describe RE2::MatchData do
66
66
  expect(a).to eq(["woo", "o", "o"])
67
67
  end
68
68
 
69
- it "populates optional capturing groups with nil if they are missing" do
69
+ it "populates optional capturing groups with empty strings if they match zero characters" do
70
70
  a = RE2::Regexp.new('(\d?)(a)(b)').match('ab').to_a
71
71
 
72
- expect(a).to eq(["ab", nil, "a", "b"])
72
+ expect(a).to eq(["ab", "", "a", "b"])
73
+ end
74
+
75
+ it "distinguishes between zero-length matches and unmatched groups" do
76
+ a = RE2::Regexp.new('()(a)?').match('b').to_a
77
+
78
+ expect(a).to eq(["", "", nil])
73
79
  end
74
80
 
75
81
  it "returns UTF-8 strings if the pattern is UTF-8" do
@@ -158,6 +164,12 @@ RSpec.describe RE2::MatchData do
158
164
  expect(md[:numbers]).to eq("123")
159
165
  end
160
166
 
167
+ it "returns an empty string for a zero-length capturing group" do
168
+ md = RE2::Regexp.new('()').match("bob")
169
+
170
+ expect(md[1]).to eq("")
171
+ end
172
+
161
173
  it "returns nil if no such named group exists", :aggregate_failures do
162
174
  md = RE2::Regexp.new('(\d+)').match("bob 123")
163
175
 
@@ -281,6 +293,12 @@ RSpec.describe RE2::MatchData do
281
293
  expect(md.inspect).to eq('#<RE2::MatchData "1234 " 1:"1234" 2:nil>')
282
294
  end
283
295
 
296
+ it "represents zero-length capturing groups as empty strings" do
297
+ md = RE2::Regexp.new('()').match("bob")
298
+
299
+ expect(md.inspect).to eq('#<RE2::MatchData "" 1:"">')
300
+ end
301
+
284
302
  it "supports matches with null bytes" do
285
303
  md = RE2::Regexp.new("(\\w\0\\w) (\\w\0\\w)").match("a\0b c\0d")
286
304
 
@@ -299,6 +317,12 @@ RSpec.describe RE2::MatchData do
299
317
  expect(md.to_s).to eq("23456")
300
318
  end
301
319
 
320
+ it "returns an empty string for a zero-length match" do
321
+ md = RE2::Regexp.new('()').match("bob")
322
+
323
+ expect(md.to_s).to eq("")
324
+ end
325
+
302
326
  it "raises an error when called on an uninitialized object" do
303
327
  expect { described_class.allocate.to_s }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
304
328
  end
@@ -346,6 +370,12 @@ RSpec.describe RE2::MatchData do
346
370
  expect(md.string[md.begin(0)..-1]).to eq('Ruby')
347
371
  end
348
372
 
373
+ it "returns the offset for a zero-length capturing group" do
374
+ md = RE2::Regexp.new('()').match("bob")
375
+
376
+ expect(md.begin(1)).to eq(0)
377
+ end
378
+
349
379
  it "returns nil for non-existent numerical matches" do
350
380
  md = RE2::Regexp.new('(\d)').match('123')
351
381
 
@@ -419,6 +449,12 @@ RSpec.describe RE2::MatchData do
419
449
  expect(md.string[0...md.end(0)]).to eq('I ♥ Ruby')
420
450
  end
421
451
 
452
+ it "returns the offset for a zero-length capturing group" do
453
+ md = RE2::Regexp.new('()').match("bob")
454
+
455
+ expect(md.end(1)).to eq(0)
456
+ end
457
+
422
458
  it "returns nil for non-existent numerical matches" do
423
459
  md = RE2::Regexp.new('(\d)').match('123')
424
460
 
@@ -492,6 +528,12 @@ RSpec.describe RE2::MatchData do
492
528
  expect(md.pre_match.encoding).to eq(Encoding::ISO_8859_1)
493
529
  end
494
530
 
531
+ it "returns the text before a zero-length match" do
532
+ md = RE2::Regexp.new('()').match("bob")
533
+
534
+ expect(md.pre_match).to eq("")
535
+ end
536
+
495
537
  it "raises an error when called on an uninitialized object" do
496
538
  expect { described_class.allocate.pre_match }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
497
539
  end
@@ -528,6 +570,12 @@ RSpec.describe RE2::MatchData do
528
570
  expect(md.post_match.encoding).to eq(Encoding::ISO_8859_1)
529
571
  end
530
572
 
573
+ it "returns the text after a zero-length match" do
574
+ md = RE2::Regexp.new('()').match("bob")
575
+
576
+ expect(md.post_match).to eq("bob")
577
+ end
578
+
531
579
  it "raises an error when called on an uninitialized object" do
532
580
  expect { described_class.allocate.post_match }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
533
581
  end
@@ -564,6 +612,12 @@ RSpec.describe RE2::MatchData do
564
612
  expect(md.offset(0)).to eq([4, 8])
565
613
  end
566
614
 
615
+ it "returns identical offsets for a zero-length capturing group" do
616
+ md = RE2::Regexp.new('()').match("bob")
617
+
618
+ expect(md.offset(1)).to eq([0, 0])
619
+ end
620
+
567
621
  it "returns nil for non-existent numerical matches" do
568
622
  md = RE2::Regexp.new('(\d)').match("123")
569
623
 
@@ -618,6 +672,12 @@ RSpec.describe RE2::MatchData do
618
672
  expect(md.match_length(0)).to eq(6)
619
673
  end
620
674
 
675
+ it "returns zero for a zero-length capturing group" do
676
+ md = RE2::Regexp.new('()').match("bob")
677
+
678
+ expect(md.match_length(1)).to eq(0)
679
+ end
680
+
621
681
  it "returns nil for non-existent numerical matches" do
622
682
  md = RE2::Regexp.new('(\d)').match("123")
623
683
 
@@ -672,6 +732,12 @@ RSpec.describe RE2::MatchData do
672
732
  expect(md.values_at(:a, :z)).to eq(["123", nil])
673
733
  end
674
734
 
735
+ it "returns an empty string for a zero-length capturing group" do
736
+ md = RE2::Regexp.new('()(b)').match("bob")
737
+
738
+ expect(md.values_at(1, 2)).to eq(["", "b"])
739
+ end
740
+
675
741
  it "returns the full match when given index 0" do
676
742
  md = RE2::Regexp.new('(\d+) (\d+)').match("123 456")
677
743
 
@@ -702,6 +768,12 @@ RSpec.describe RE2::MatchData do
702
768
  expect(md.deconstruct).to eq(['o', 'o', nil])
703
769
  end
704
770
 
771
+ it "includes zero-length capturing groups as empty strings" do
772
+ md = RE2::Regexp.new('()').match("bob")
773
+
774
+ expect(md.deconstruct).to eq([""])
775
+ end
776
+
705
777
  it "raises an error when called on an uninitialized object" do
706
778
  expect { described_class.allocate.deconstruct }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
707
779
  end
@@ -744,6 +816,12 @@ RSpec.describe RE2::MatchData do
744
816
  expect(md.named_captures).to eq("a" => "123", "b" => nil)
745
817
  end
746
818
 
819
+ it "returns an empty string for a zero-length named capturing group" do
820
+ md = RE2::Regexp.new('(?P<empty>)(?P<word>\w+)').match("bob")
821
+
822
+ expect(md.named_captures).to eq("empty" => "", "word" => "bob")
823
+ end
824
+
747
825
  it "returns symbol keys when symbolize_names: true" do
748
826
  md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
749
827
 
@@ -822,6 +900,12 @@ RSpec.describe RE2::MatchData do
822
900
  expect(md.deconstruct_keys(nil)).to eq({})
823
901
  end
824
902
 
903
+ it "returns an empty string for a zero-length named capturing group" do
904
+ md = RE2::Regexp.new('(?P<empty>)(?P<word>\w+)').match("bob")
905
+
906
+ expect(md.deconstruct_keys(nil)).to eq(empty: "", word: "bob")
907
+ end
908
+
825
909
  it "raises an error if given a non-array of keys" do
826
910
  md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
827
911
 
@@ -590,6 +590,24 @@ RSpec.describe RE2::Regexp do
590
590
  expect { re.match("one two three", endpos: 3) }.to raise_error(RE2::Regexp::UnsupportedError)
591
591
  end
592
592
 
593
+ it "does not truncate startpos to 32 bits" do
594
+ skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
595
+ skip "size_t is not larger than a 32-bit int" if RbConfig::SIZEOF.fetch("size_t") <= (32 / 8)
596
+
597
+ re = RE2::Regexp.new('(\w+)', log_errors: false)
598
+
599
+ expect(re.match("one two three", startpos: 2_147_483_648, endpos: 2_147_483_649)).to be_nil
600
+ end
601
+
602
+ it "does not truncate endpos to 32 bits" do
603
+ skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
604
+ skip "size_t is not larger than a 32-bit int" if RbConfig::SIZEOF.fetch("size_t") <= (32 / 8)
605
+
606
+ re = RE2::Regexp.new('(\w+)', log_errors: false)
607
+
608
+ expect(re.match("one two three", endpos: 2_147_483_648)).to be_nil
609
+ end
610
+
593
611
  it "does not anchor matches by default when extracting submatches" do
594
612
  re = RE2::Regexp.new('(two)')
595
613
 
@@ -185,11 +185,11 @@ RSpec.describe RE2::Scanner do
185
185
  expect(scanner.scan).to be_nil
186
186
  end
187
187
 
188
- it "returns an array of nil with an empty input and capture", :aggregate_failures do
188
+ it "returns an array of empty strings with an empty input and capture", :aggregate_failures do
189
189
  r = RE2::Regexp.new("()")
190
190
  scanner = r.scan("")
191
191
 
192
- expect(scanner.scan).to eq([nil])
192
+ expect(scanner.scan).to eq([""])
193
193
  expect(scanner.scan).to be_nil
194
194
  end
195
195
 
@@ -204,25 +204,34 @@ RSpec.describe RE2::Scanner do
204
204
  expect(scanner.scan).to be_nil
205
205
  end
206
206
 
207
- it "returns an array of nil if the pattern is an empty capturing group", :aggregate_failures do
207
+ it "returns an array of empty strings if the pattern is an empty capturing group", :aggregate_failures do
208
208
  r = RE2::Regexp.new("()")
209
209
  scanner = r.scan("Foo")
210
210
 
211
- expect(scanner.scan).to eq([nil])
212
- expect(scanner.scan).to eq([nil])
213
- expect(scanner.scan).to eq([nil])
214
- expect(scanner.scan).to eq([nil])
211
+ expect(scanner.scan).to eq([""])
212
+ expect(scanner.scan).to eq([""])
213
+ expect(scanner.scan).to eq([""])
214
+ expect(scanner.scan).to eq([""])
215
215
  expect(scanner.scan).to be_nil
216
216
  end
217
217
 
218
- it "returns array of nils with multiple empty capturing groups", :aggregate_failures do
218
+ it "returns array of empty strings with multiple empty capturing groups", :aggregate_failures do
219
219
  r = RE2::Regexp.new("()()()")
220
220
  scanner = r.scan("Foo")
221
221
 
222
- expect(scanner.scan).to eq([nil, nil, nil])
223
- expect(scanner.scan).to eq([nil, nil, nil])
224
- expect(scanner.scan).to eq([nil, nil, nil])
225
- expect(scanner.scan).to eq([nil, nil, nil])
222
+ expect(scanner.scan).to eq(["", "", ""])
223
+ expect(scanner.scan).to eq(["", "", ""])
224
+ expect(scanner.scan).to eq(["", "", ""])
225
+ expect(scanner.scan).to eq(["", "", ""])
226
+ expect(scanner.scan).to be_nil
227
+ end
228
+
229
+ it "distinguishes zero-length matches from unmatched groups", :aggregate_failures do
230
+ r = RE2::Regexp.new("()(a)?")
231
+ scanner = r.scan("b")
232
+
233
+ expect(scanner.scan).to eq(["", nil])
234
+ expect(scanner.scan).to eq(["", nil])
226
235
  expect(scanner.scan).to be_nil
227
236
  end
228
237
 
@@ -230,7 +239,7 @@ RSpec.describe RE2::Scanner do
230
239
  r = RE2::Regexp.new("()€")
231
240
  scanner = r.scan("€")
232
241
 
233
- expect(scanner.scan).to eq([nil])
242
+ expect(scanner.scan).to eq([""])
234
243
  expect(scanner.scan).to be_nil
235
244
  end
236
245
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: re2
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.25.0
4
+ version: 2.26.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Mucur