Skip to content

Add m/M multiline substitute flag #399

@sylvestre

Description

@sylvestre

Bug

The m / M substitute flag (multiline mode — make ^ and $
match at embedded newlines inside the pattern space) is not
implemented.

Reproduction

$ printf "foo\nbar\n" | /usr/bin/sed 'N;s/^./X/gm'
Xoo
Xar

$ printf "foo\nbar\n" | ./target/release/sed 'N;s/^./X/gm'
sed: <script argument 1>:1:11: error: invalid substitute flag: 'm'

Without the m flag, ^ only matches the start of the pattern space,
so only the first line gets X:

$ printf "foo\nbar\n" | /usr/bin/sed 'N;s/^./X/g'
Xoo
bar

What it should do

GNU sed manual:

M m This is a GNU extension. If specified, it causes ^ and
$ to match respectively (in addition to the normal behavior) the
empty string after a newline, and the empty string before a newline.

In the underlying regex engine (fancy-regex), this corresponds to
turning on the (?m) (multiline) inline flag for the compiled regex.

Suspected place to add it

src/sed/compiler.rs:854compile_subst_flags. Around the existing
'i' | 'I' branch (line 891), add:

'm' | 'M' => {
    subst.multiline = true;     // new field on Subst
    line.advance();
}

Then in src/sed/fast_regex.rs (or wherever the regex is compiled
from the substitution command), prepend (?m) to the pattern when
subst.multiline is true — analogous to how subst.ignore_case adds
(?i).

Rejected under --posix (handled by issue #11 once that lands).

Affected GNU testsuite tests

subst-options, posix-mode-s.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions