Skip to content

Commit

Permalink
Merge pull request #1701 from eileencodes/implement-regex-flags
Browse files Browse the repository at this point in the history
Ensure last encoding flag wins
  • Loading branch information
kddnewton authored Oct 17, 2023
2 parents fbd101d + 4182c98 commit b28bb19
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,18 +779,21 @@ parse_decimal_number(pm_parser_t *parser, const uint8_t *start, const uint8_t *e
static inline pm_node_flags_t
pm_regular_expression_flags_create(const pm_token_t *closing) {
pm_node_flags_t flags = 0;
pm_node_flags_t mask = (uint16_t) 0xFF0F;

if (closing->type == PM_TOKEN_REGEXP_END) {
for (const uint8_t *flag = closing->start + 1; flag < closing->end; flag++) {
switch (*flag) {
case 'i': flags |= PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE; break;
case 'm': flags |= PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE; break;
case 'x': flags |= PM_REGULAR_EXPRESSION_FLAGS_EXTENDED; break;
case 'e': flags |= PM_REGULAR_EXPRESSION_FLAGS_EUC_JP; break;
case 'n': flags |= PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT; break;
case 's': flags |= PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J; break;
case 'u': flags |= PM_REGULAR_EXPRESSION_FLAGS_UTF_8; break;
case 'o': flags |= PM_REGULAR_EXPRESSION_FLAGS_ONCE; break;

case 'e': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_EUC_JP; break;
case 'n': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT; break;
case 's': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J; break;
case 'u': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_UTF_8; break;

default: assert(false && "unreachable");
}
}
Expand Down
12 changes: 12 additions & 0 deletions test/prism/regexp_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ def test_flag_combined
assert_equal(value, options("mix"))
end

def test_last_encoding_option_wins
regex = "/foo/nu"
option = Prism.parse(regex).value.statements.body.first.options

assert_equal Regexp::FIXEDENCODING, option

regex = "/foo/un"
option = Prism.parse(regex).value.statements.body.first.options

assert_equal Regexp::NOENCODING, option
end

private

def named_captures(source)
Expand Down

0 comments on commit b28bb19

Please sign in to comment.