///|
async fn run(args : ArrayView[String]) -> Int32 {
let parsed = @cli.parse(args, [
@cli.flag("quiet", short='n'),
@cli.flag("silent"),
@cli.flag("regexp-extended", short='E'),
@cli.flag("extended", short='r'),
@cli.option("expression", short='e'),
@cli.option("file", short='f'),
@cli.flag("help"),
@cli.flag("version"),
])
if parsed.contains("help") {
@stdio.stdout.write(
"Usage: sed [-nE] [-e SCRIPT] [-f SCRIPTFILE] [SCRIPT] [FILE...]\n --help display this help and exit\n --version display version and exit\nStream editor: p/d/q/=, s/RE/REPLACEMENT/[gNp], h/H/g/G/x, :/b/t/T, groups, n/N/P/D/a/i/c.\nAddresses: line number, $, /RE/, ranges and !. BRE default; -E enables ERE.\nBRE/ERE supports pattern backreferences and word assertions.\nIn-place editing and locale-aware matching are not supported.\n",
)
return 0
}
if parsed.contains("version") {
@stdio.stdout.write("sed 0.2.0\n")
return 0
}
let scripts : Array[String] = []
let expressions = parsed.values("expression")
let script_files = parsed.values("file")
let mut e = 0
let mut f = 0
for option in parsed.order {
if option == "expression" {
scripts.push(@bytere.argument(expressions[e]))
e += 1
}
if option == "file" {
scripts.push(@bytere.text(@fs.read_file(script_files[f]).binary()))
f += 1
}
}
let files = parsed.operands
if scripts.is_empty() {
guard !files.is_empty() else { fail("missing script") }
scripts.push(@bytere.argument(files.remove(0)))
}
let source = scripts.join("\n")
let commands = compile(
source,
parsed.contains("regexp-extended") || parsed.contains("extended"),
)
let quiet = parsed.contains("quiet") ||
parsed.contains("silent") ||
source.has_prefix("#n")
if files.is_empty() {
files.push("-")
}
let input : Input = {
paths: files,
index: 0,
path: "",
file: None,
reader: None,
buffer: b"",
position: 0,
number: 0,
status: 0,
}
defer input.close()
let runtime : Runtime = { previous: None, missing_newline: false, }
execute(commands, input, quiet, runtime)
input.status
}
///|
async fn main {
let status = run(@env.args()[1:]) catch {
SedLabelError(message) => {
@stdio.stderr.write("sed: \{message}\n")
4
}
SedError(message) | @bytere.PatternError(message) => {
@stdio.stderr.write("sed: \{message}\n")
1
}
err => {
@stdio.stderr.write("sed: \{err}\n")
1
}
}
if status != 0 {
@sys.exit(status)
}
}