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 OptionParser::parse(int argc, char **argv) const {
ParseResult result; ParseResult result;
bool scriptConsumed = false; std::vector<std::string> operands;
bool endOfOptions = false;
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
std::string arg = argv[i] == nullptr ? "" : argv[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. // --help and --version are terminal actions: no scripts or files are read.
if (arg == "--help") { if (arg == "--help") {
printHelp(true, true); printHelp(true, true);
@@ -63,7 +79,7 @@ ParseResult OptionParser::parse(int argc, char **argv) const {
return result; 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 // Long options either toggle state or add a script source while preserving
// the original source order in scriptSpecs. // the original source order in scriptSpecs.
if (arg == "--quiet" || arg == "--silent") { if (arg == "--quiet" || arg == "--silent") {
@@ -190,15 +206,21 @@ ParseResult OptionParser::parse(int argc, char **argv) const {
continue; continue;
} }
if (result.options.scripts.empty() && result.options.scriptFiles.empty() && operands.push_back(arg);
!scriptConsumed) { }
// With no -e/-f, the first non-option argument is the script; the rest are
// input files. if (result.options.scripts.empty() && result.options.scriptFiles.empty() &&
result.options.scripts.push_back(arg); !operands.empty()) {
result.options.scriptSpecs.push_back({false, arg}); // GNU-style option permutation means later -e/-f options still prevent the
scriptConsumed = true; // first operand from becoming an implicit script. Decide only after every
} else { // argv entry has been scanned.
result.options.inputFiles.push_back(arg); 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);
} }
} }