diff options
| author | Feoramund <161657516+Feoramund@users.noreply.github.com> | 2024-07-24 15:59:59 -0400 |
|---|---|---|
| committer | Feoramund <161657516+Feoramund@users.noreply.github.com> | 2024-07-24 16:27:08 -0400 |
| commit | c52a8a5f86707eeb71bcb44e2f691c67c9383500 (patch) | |
| tree | 347731501d635b3a0bb9c755aad09a83857c8e74 | |
| parent | 16b644ad79ca80227c67c4a7a2234dcd47800161 (diff) | |
Allow configuring of `MAX_CAPTURE_GROUPS` for `n` > 10
| -rw-r--r-- | core/text/regex/common/common.odin | 2 | ||||
| -rw-r--r-- | tests/core/text/regex/test_core_text_regex.odin | 70 |
2 files changed, 65 insertions, 7 deletions
diff --git a/core/text/regex/common/common.odin b/core/text/regex/common/common.odin index f53f043a1..f401658cb 100644 --- a/core/text/regex/common/common.odin +++ b/core/text/regex/common/common.odin @@ -2,7 +2,7 @@ package regex_common // VM limitations -MAX_CAPTURE_GROUPS :: 10 +MAX_CAPTURE_GROUPS :: max(#config(ODIN_REGEX_MAX_CAPTURE_GROUPS, 10), 10) MAX_PROGRAM_SIZE :: int(max(i16)) MAX_CLASSES :: int(max(u8)) diff --git a/tests/core/text/regex/test_core_text_regex.odin b/tests/core/text/regex/test_core_text_regex.odin index 0bd1ff288..74a0b8cf7 100644 --- a/tests/core/text/regex/test_core_text_regex.odin +++ b/tests/core/text/regex/test_core_text_regex.odin @@ -276,9 +276,58 @@ test_optional_capture_group :: proc(t: ^testing.T) { @test test_max_capture_groups :: proc(t: ^testing.T) { - EXPR :: "(1)(2)(3)(4)(5)(6)(7)(8)(9)" - check_expression(t, EXPR, "123456789", "123456789", - "1", "2", "3", "4", "5", "6", "7", "8", "9") + sb_pattern := strings.builder_make() + sb_haystack := strings.builder_make() + expected_captures: [dynamic]string + defer { + strings.builder_destroy(&sb_pattern) + strings.builder_destroy(&sb_haystack) + delete(expected_captures) + } + + w_pattern := strings.to_writer(&sb_pattern) + w_haystack := strings.to_writer(&sb_haystack) + + // The full expression capture, capture 0: + for i in 1..<common.MAX_CAPTURE_GROUPS { + io.write_int(w_pattern, i) + } + append(&expected_captures, fmt.tprint(strings.to_string(sb_pattern))) + strings.builder_reset(&sb_pattern) + + // The individual captures: + for i in 1..<common.MAX_CAPTURE_GROUPS { + io.write_byte(w_pattern, '(') + io.write_int(w_pattern, i) + io.write_byte(w_pattern, ')') + + io.write_int(w_haystack, i) + + append(&expected_captures, fmt.tprint(i)) + } + + pattern := strings.to_string(sb_pattern) + haystack := strings.to_string(sb_haystack) + + rex, err := regex.create(pattern) + defer regex.destroy(rex) + if !testing.expect_value(t, err, nil) { + return + } + + capture, ok := regex.match(rex, haystack) + defer regex.destroy(capture) + if !testing.expectf(t, ok, "expected %q to match %q", pattern, haystack) { + return + } + + if !testing.expect_value(t, len(capture.groups), common.MAX_CAPTURE_GROUPS) { + return + } + + for g, i in capture.groups { + testing.expect_value(t, g, expected_captures[i]) + } } @test @@ -692,9 +741,18 @@ test_error_invalid_unicode_in_string :: proc(t: ^testing.T) { @test test_error_too_many_capture_groups :: proc(t: ^testing.T) { - // NOTE: There are 1 + 9 + 1 capture groups in this pattern. - // Remember the implicit capture group 0. - expect_error(t, "(1)(2)(3)(4)(5)(6)(7)(8)(9) (A)", parser.Too_Many_Capture_Groups) + sb := strings.builder_make() + defer strings.builder_destroy(&sb) + w := strings.to_writer(&sb) + + for i in 1..<common.MAX_CAPTURE_GROUPS+1 { + io.write_byte(w, '(') + io.write_int(w, i) + io.write_byte(w, ')') + } + + pattern := strings.to_string(sb) + expect_error(t, pattern, parser.Too_Many_Capture_Groups) } @test |