Repository: SerenityOS/serenity
File: Userland/Utilities/sed.cpp (C++)

Code before:
        if (input.has_next()) {
            pattern_space.clear();
            pattern_space.append(TRY(input.next()));
        }
        break;
    case 'p':
        TRY(write_pattern_space(stdout, pattern_space));
        break;
    case 'P': {
        auto pattern_sv = pattern_space.string_view();
        auto newline_position = pattern_sv.find('\n').value_or(pattern_sv.length() - 1);
        TRY(stdout.write_until_depleted(pattern_sv.substring_view(0, newline_position + 1).bytes()));
        break;
    }
    case 'q':
        cycle_decision = CycleDecision::Quit;
        break;
    case 's': {
        auto pattern_space_sv = pattern_space.string_view();
        auto const& s_args = command.arguments->get<SArguments>();
        ByteString result;
        if (s_args.regex.has<Regex<PosixExtended>>()) {
            result = s_args.regex.get<Regex<PosixExtended>>().replace(pattern_space_sv, s_args.replacement, s_args.options);
        } else {
            result = s_args.regex.get<Regex<PosixBasic>>().replace(pattern_space_sv, s_args.replacement, s_args.options);
        }
        auto replacement_made = result != pattern_space_sv;
        pattern_space.clear();
        pattern_space.append(result);
        if (replacement_made && s_args.output_filepath.has_value()) {
            auto output_file = TRY(Core::File::open(s_args.output_filepath.value(), Core::File::OpenMode::Write | Core::File::OpenMode::Append));
            TRY(output_file->write_until_depleted(TRY(pattern_space.to_byte_buffer())));
            TRY(output_file->write_value('\n'));
        }
        if (replacement_made && s_args.print)
            TRY(write_pattern_space(stdout, pattern_space));
        TRY(write_pattern_space(input, pattern_space));
        break;
    }
    case 'y': {
        // FIXME: Escaping in the transform strings doesn't work properly
        auto pattern_space_sv = pattern_space.string_view();
        auto const& y_args = command.arguments->get<YArguments>();
        VERIFY(y_args.characters.length() == y_args.replacements.length());

        HashMap<char, char> replacement;
        for (size_t i = 0; i < y_args.characters.length(); i++) {
            TRY(replacement.try_set(y_args.characters[i], y_args.replacements[i]));
        }

        StringBuilder new_string;

Review comment (suggestion):
```suggestion
        auto result = s_args.regex.visit([&](auto& re) { return re.replace(pattern_space_sv, s_args.replacement, s_args.options); });
```

Code after:
            pattern_space.clear();
            pattern_space.append(TRY(input.next()));
        }
        break;
    case 'p':
        TRY(write_pattern_space(stdout, pattern_space));
        break;
    case 'P': {
        auto pattern_sv = pattern_space.string_view();
        auto newline_position = pattern_sv.find('\n').value_or(pattern_sv.length() - 1);
        TRY(stdout.write_until_depleted(pattern_sv.substring_view(0, newline_position + 1).bytes()));
        break;
    }
    case 'q':
        cycle_decision = CycleDecision::Quit;
        break;
    case 's': {
        auto pattern_space_sv = pattern_space.string_view();
        auto const& s_args = command.arguments->get<SArguments>();
        auto result = s_args.regex.visit([&](auto& re) { return re.replace(pattern_space_sv, s_args.replacement, s_args.options); });
        auto replacement_made = result != pattern_space_sv;
        pattern_space.clear();
        pattern_space.append(result);
        if (replacement_made && s_args.output_filepath.has_value()) {
            auto output_file = TRY(Core::File::open(s_args.output_filepath.value(), Core::File::OpenMode::Write | Core::File::OpenMode::Append));
            TRY(output_file->write_until_depleted(TRY(pattern_space.to_byte_buffer())));
            TRY(output_file->write_value('\n'));
        }
        if (replacement_made && s_args.print)
            TRY(write_pattern_space(stdout, pattern_space));
        TRY(write_pattern_space(input, pattern_space));
        break;
    }
    case 'y': {
        // FIXME: Escaping in the transform strings doesn't work properly
        auto pattern_space_sv = pattern_space.string_view();
        auto const& y_args = command.arguments->get<YArguments>();
        VERIFY(y_args.characters.length() == y_args.replacements.length());

        HashMap<char, char> replacement;
        for (size_t i = 0; i < y_args.characters.length(); i++) {
            TRY(replacement.try_set(y_args.characters[i], y_args.replacements[i]));
        }

        StringBuilder new_string;
        for (size_t i = 0; i < pattern_space.length(); i++) {
            if (replacement.contains(pattern_space_sv[i]))
                new_string.append(replacement.get(pattern_space_sv[i]).value());
            else
                new_string.append(pattern_space_sv[i]);
        }