There is no CLI syntax to disable a switch. A switch enabled in a YAML file cannot be overridden off on the command line, contradicting the documented "command line options overwrite YAML file(s)" precedence.
Affected files
gemc/goptions/goptions.cc:163-172 (CLI switch handling — only turnOn())
gemc/goptions/goptions.cc:332-334 (YAML switch handling — only turnOn())
gemc/goptions/goptions.cc:513 (documented precedence: "command line options overwrite YAML file(s)")
gemc/goptions/gswitch.h:60-69 (turnOn() / turnOff() both exist)
Details
On the CLI, a switch is only recognized in the no-= branch, where it is unconditionally turned on:
else {
// Treat as a switch: -gui, -i, etc.
const string& possibleSwitch = argStr;
if (switches.find(possibleSwitch) != switches.end()) {
switches[possibleSwitch].turnOn();
}
else {
cerr << "The switch " << possibleSwitch << " is not known to this system." << endl;
exit(EC__NOOPTIONFOUND);
}
}
Anything containing = is routed to the option path (line 128 eqPos != string::npos). So -gui=false is parsed as option gui, doesOptionExist("gui") is false (it is a switch, not an option), and the program exits with "The option gui is not known to this system." (line 158).
GSwitch already provides turnOff() (gswitch.h:69), but it is unreachable from parsing. Consequently a YAML gui: true (handled at line 333 switches[name].turnOn()) can never be overridden off from the CLI, directly contradicting the precedence note printed at line 513.
Impact
Users cannot disable a YAML-enabled switch (e.g. turn off gui for a batch run) without editing the YAML file. The stated CLI-over-YAML precedence is false for switches.
Proposed fix
Before the eqPos != string::npos option branch, intercept -<switch>=<bool> tokens whose key is a known switch and route to turnOn()/turnOff(). This adds an explicit off syntax (-gui=false / -gui=true) while leaving option parsing untouched.
if (eqPos != string::npos) {
string keyPart = argStr.substr(0, eqPos);
string valuePart = argStr.substr(eqPos + 1);
+ // Switch with explicit boolean value: -gui=false / -gui=true
+ if (switches.find(keyPart) != switches.end()) {
+ if (valuePart == "true" || valuePart == "1") switches[keyPart].turnOn();
+ else if (valuePart == "false" || valuePart == "0") switches[keyPart].turnOff();
+ else {
+ cerr << "The switch " << keyPart << " accepts only true/false." << endl;
+ exit(EC__NOOPTIONFOUND);
+ }
+ continue;
+ }
+
// Strip outer quotes if present (e.g., -gstreamer="[...]")
if (!valuePart.empty() && valuePart.front() == '"' && valuePart.back() == '"') {
turnOff() already exists in gswitch.h, so no change to GSwitch is required. The bare -gui form continues to work via the existing no-= branch.
Split out from #102 (one issue per bug). Found via an AI-assisted code review with manual verification against commit 5f8ce875.
There is no CLI syntax to disable a switch. A switch enabled in a YAML file cannot be overridden off on the command line, contradicting the documented "command line options overwrite YAML file(s)" precedence.
Affected files
gemc/goptions/goptions.cc:163-172(CLI switch handling — onlyturnOn())gemc/goptions/goptions.cc:332-334(YAML switch handling — onlyturnOn())gemc/goptions/goptions.cc:513(documented precedence: "command line options overwrite YAML file(s)")gemc/goptions/gswitch.h:60-69(turnOn()/turnOff()both exist)Details
On the CLI, a switch is only recognized in the no-
=branch, where it is unconditionally turned on:Anything containing
=is routed to the option path (line 128eqPos != string::npos). So-gui=falseis parsed as optiongui,doesOptionExist("gui")is false (it is a switch, not an option), and the program exits with "The option gui is not known to this system." (line 158).GSwitchalready providesturnOff()(gswitch.h:69), but it is unreachable from parsing. Consequently a YAMLgui: true(handled at line 333switches[name].turnOn()) can never be overridden off from the CLI, directly contradicting the precedence note printed at line 513.Impact
Users cannot disable a YAML-enabled switch (e.g. turn off
guifor a batch run) without editing the YAML file. The stated CLI-over-YAML precedence is false for switches.Proposed fix
Before the
eqPos != string::nposoption branch, intercept-<switch>=<bool>tokens whose key is a known switch and route toturnOn()/turnOff(). This adds an explicit off syntax (-gui=false/-gui=true) while leaving option parsing untouched.if (eqPos != string::npos) { string keyPart = argStr.substr(0, eqPos); string valuePart = argStr.substr(eqPos + 1); + // Switch with explicit boolean value: -gui=false / -gui=true + if (switches.find(keyPart) != switches.end()) { + if (valuePart == "true" || valuePart == "1") switches[keyPart].turnOn(); + else if (valuePart == "false" || valuePart == "0") switches[keyPart].turnOff(); + else { + cerr << "The switch " << keyPart << " accepts only true/false." << endl; + exit(EC__NOOPTIONFOUND); + } + continue; + } + // Strip outer quotes if present (e.g., -gstreamer="[...]") if (!valuePart.empty() && valuePart.front() == '"' && valuePart.back() == '"') {turnOff()already exists ingswitch.h, so no change toGSwitchis required. The bare-guiform continues to work via the existing no-=branch.Split out from #102 (one issue per bug). Found via an AI-assisted code review with manual verification against commit
5f8ce875.