Handle sed options after operands

This commit is contained in:
2026-06-13 23:04:01 -05:00
parent 0ae8830b04
commit 0aa10adb4f
+33 -11
View File
@@ -44,11 +44,27 @@ void OptionParser::printHelp(bool includeEmail, bool toStdout) {
ParseResult OptionParser::parse(int argc, char **argv) const {
ParseResult result;
bool scriptConsumed = false;
std::vector<std::string> operands;
bool endOfOptions = false;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i] == nullptr ? "" : argv[i];
if (endOfOptions) {
operands.push_back(arg);
continue;
}
if (arg == "--") {
endOfOptions = true;
continue;
}
if (arg == "-") {
operands.push_back(arg);
continue;
}
// --help and --version are terminal actions: no scripts or files are read.
if (arg == "--help") {
printHelp(true, true);
@@ -63,7 +79,7 @@ ParseResult OptionParser::parse(int argc, char **argv) const {
return result;
}
if (!scriptConsumed && !arg.empty() && arg[0] == '-') {
if (!arg.empty() && arg[0] == '-') {
// Long options either toggle state or add a script source while preserving
// the original source order in scriptSpecs.
if (arg == "--quiet" || arg == "--silent") {
@@ -190,15 +206,21 @@ ParseResult OptionParser::parse(int argc, char **argv) const {
continue;
}
if (result.options.scripts.empty() && result.options.scriptFiles.empty() &&
!scriptConsumed) {
// With no -e/-f, the first non-option argument is the script; the rest are
// input files.
result.options.scripts.push_back(arg);
result.options.scriptSpecs.push_back({false, arg});
scriptConsumed = true;
} else {
result.options.inputFiles.push_back(arg);
operands.push_back(arg);
}
if (result.options.scripts.empty() && result.options.scriptFiles.empty() &&
!operands.empty()) {
// GNU-style option permutation means later -e/-f options still prevent the
// first operand from becoming an implicit script. Decide only after every
// argv entry has been scanned.
result.options.scripts.push_back(operands.front());
result.options.scriptSpecs.push_back({false, operands.front()});
result.options.inputFiles.insert(result.options.inputFiles.end(),
operands.begin() + 1, operands.end());
} else {
for (const std::string &operand : operands) {
result.options.inputFiles.push_back(operand);
}
}