openMSX
CommandLineParser.cc
Go to the documentation of this file.
1 #include "CommandLineParser.hh"
2 #include "CLIOption.hh"
4 #include "Interpreter.hh"
5 #include "SettingsConfig.hh"
6 #include "File.hh"
7 #include "FileContext.hh"
8 #include "FileOperations.hh"
9 #include "GlobalCliComm.hh"
10 #include "StdioMessages.hh"
11 #include "Version.hh"
12 #include "MSXRomCLI.hh"
13 #include "CliExtension.hh"
14 #include "CliConnection.hh"
15 #include "ReplayCLI.hh"
16 #include "SaveStateCLI.hh"
17 #include "CassettePlayerCLI.hh"
18 #include "DiskImageCLI.hh"
19 #include "HDImageCLI.hh"
20 #include "CDImageCLI.hh"
21 #include "ConfigException.hh"
22 #include "FileException.hh"
23 #include "EnumSetting.hh"
24 #include "XMLException.hh"
25 #include "StringOp.hh"
26 #include "xrange.hh"
27 #include "GLUtil.hh"
28 #include "Reactor.hh"
29 #include "RomInfo.hh"
30 #include "StringMap.hh"
31 #include "memory.hh"
32 #include "stl.hh"
33 #include "build-info.hh"
34 #include "components.hh"
35 
36 #if COMPONENT_LASERDISC
37 #include "LaserdiscPlayerCLI.hh"
38 #endif
39 
40 #include <cassert>
41 #include <iostream>
42 
43 using std::cout;
44 using std::endl;
45 using std::string;
46 using std::vector;
47 
48 namespace openmsx {
49 
50 class HelpOption final : public CLIOption
51 {
52 public:
53  explicit HelpOption(CommandLineParser& parser);
54  void parseOption(const string& option, array_ref<string>& cmdLine) override;
55  string_ref optionHelp() const override;
56 private:
57  CommandLineParser& parser;
58 };
59 
60 class VersionOption final : public CLIOption
61 {
62 public:
63  explicit VersionOption(CommandLineParser& parser);
64  void parseOption(const string& option, array_ref<string>& cmdLine) override;
65  string_ref optionHelp() const override;
66 private:
67  CommandLineParser& parser;
68 };
69 
70 class ControlOption final : public CLIOption
71 {
72 public:
73  explicit ControlOption(CommandLineParser& parser);
74  void parseOption(const string& option, array_ref<string>& cmdLine) override;
75  string_ref optionHelp() const override;
76 private:
77  CommandLineParser& parser;
78 };
79 
80 class ScriptOption final : public CLIOption, public CLIFileType
81 {
82 public:
84  void parseOption(const string& option, array_ref<string>& cmdLine) override;
85  string_ref optionHelp() const override;
86  void parseFileType(const std::string& filename,
87  array_ref<std::string>& cmdLine) override;
88  string_ref fileTypeHelp() const override;
89 
90 private:
92 };
93 
94 class MachineOption final : public CLIOption
95 {
96 public:
97  explicit MachineOption(CommandLineParser& parser);
98  void parseOption(const string& option, array_ref<string>& cmdLine) override;
99  string_ref optionHelp() const override;
100 private:
101  CommandLineParser& parser;
102 };
103 
104 class SettingOption final : public CLIOption
105 {
106 public:
107  explicit SettingOption(CommandLineParser& parser);
108  void parseOption(const string& option, array_ref<string>& cmdLine) override;
109  string_ref optionHelp() const override;
110 private:
111  CommandLineParser& parser;
112 };
113 
114 class NoPBOOption final : public CLIOption {
115 public:
116  void parseOption(const string& option, array_ref<string>& cmdLine) override;
117  string_ref optionHelp() const override;
118 };
119 
120 class TestConfigOption final : public CLIOption
121 {
122 public:
123  explicit TestConfigOption(CommandLineParser& parser);
124  void parseOption(const string& option, array_ref<string>& cmdLine) override;
125  string_ref optionHelp() const override;
126 private:
127  CommandLineParser& parser;
128 };
129 
130 class BashOption final : public CLIOption
131 {
132 public:
133  explicit BashOption(CommandLineParser& parser);
134  void parseOption(const string& option, array_ref<string>& cmdLine) override;
135  string_ref optionHelp() const override;
136 private:
137  CommandLineParser& parser;
138 };
139 
140 
141 // class CommandLineParser
142 
145 
147  : reactor(reactor_)
148  , helpOption(make_unique<HelpOption>(*this))
149  , versionOption(make_unique<VersionOption>(*this))
150  , controlOption(make_unique<ControlOption>(*this))
151  , scriptOption(make_unique<ScriptOption>())
152  , machineOption(make_unique<MachineOption>(*this))
153  , settingOption(make_unique<SettingOption>(*this))
154  , noPBOOption(make_unique<NoPBOOption>())
155  , testConfigOption(make_unique<TestConfigOption>(*this))
156  , bashOption(make_unique<BashOption>(*this))
157  , msxRomCLI(make_unique<MSXRomCLI>(*this))
158  , cliExtension(make_unique<CliExtension>(*this))
159  , replayCLI(make_unique<ReplayCLI>(*this))
160  , saveStateCLI(make_unique<SaveStateCLI>(*this))
161  , cassettePlayerCLI(make_unique<CassettePlayerCLI>(*this))
163  , laserdiscPlayerCLI(make_unique<LaserdiscPlayerCLI>(*this))
164 #endif
165  , diskImageCLI(make_unique<DiskImageCLI>(*this))
166  , hdImageCLI(make_unique<HDImageCLI>(*this))
167  , cdImageCLI(make_unique<CDImageCLI>(*this))
168  , parseStatus(UNPARSED)
169 {
170  haveConfig = false;
171  haveSettings = false;
172 
173  registerOption("-h", *helpOption, PHASE_BEFORE_INIT, 1);
174  registerOption("--help", *helpOption, PHASE_BEFORE_INIT, 1);
175  registerOption("-v", *versionOption, PHASE_BEFORE_INIT, 1);
176  registerOption("--version", *versionOption, PHASE_BEFORE_INIT, 1);
177  registerOption("-bash", *bashOption, PHASE_BEFORE_INIT, 1);
178 
179  registerOption("-setting", *settingOption, PHASE_BEFORE_SETTINGS);
180  registerOption("-control", *controlOption, PHASE_BEFORE_SETTINGS, 1);
181  registerOption("-script", *scriptOption, PHASE_BEFORE_SETTINGS, 1); // correct phase?
182  #if COMPONENT_GL
183  registerOption("-nopbo", *noPBOOption, PHASE_BEFORE_SETTINGS, 1);
184  #endif
185  registerOption("-testconfig", *testConfigOption, PHASE_BEFORE_SETTINGS, 1);
186 
187  registerOption("-machine", *machineOption, PHASE_BEFORE_MACHINE);
188 
189  registerFileType("tcl", *scriptOption);
190 
191  // At this point all options and file-types must be registered
192  sort(begin(options), end(options), CmpOptions());
193  sort(begin(fileTypes), end(fileTypes), CmpFileTypes());
194 }
195 
197 {
198 }
199 
201  const char* str, CLIOption& cliOption, ParsePhase phase, unsigned length)
202 {
203  options.emplace_back(str, OptionData{&cliOption, phase, length});
204 }
205 
207  string_ref extensions, CLIFileType& cliFileType)
208 {
209  for (auto& ext: StringOp::split(extensions, ',')) {
210  fileTypes.emplace_back(ext, &cliFileType);
211  }
212 }
213 
214 bool CommandLineParser::parseOption(
215  const string& arg, array_ref<string>& cmdLine, ParsePhase phase)
216 {
217  auto it = lower_bound(begin(options), end(options), arg, CmpOptions());
218  if ((it != end(options)) && (it->first == arg)) {
219  // parse option
220  if (it->second.phase <= phase) {
221  try {
222  it->second.option->parseOption(arg, cmdLine);
223  return true;
224  } catch (MSXException& e) {
225  throw FatalError(e.getMessage());
226  }
227  }
228  }
229  return false; // unknown
230 }
231 
232 bool CommandLineParser::parseFileName(const string& arg, array_ref<string>& cmdLine)
233 {
234  // First try the fileName as we get it from the commandline. This may
235  // be more interesting than the original fileName of a (g)zipped file:
236  // in case of an OMR file for instance, we want to select on the
237  // original extension, and not on the extension inside the gzipped
238  // file.
239  bool processed = parseFileNameInner(arg, arg, cmdLine);
240  if (!processed) {
241  try {
242  File file(UserFileContext().resolve(arg));
243  string originalName = file.getOriginalName();
244  processed = parseFileNameInner(originalName, arg, cmdLine);
245  } catch (FileException&) {
246  // ignore
247  }
248  }
249  return processed;
250 }
251 
252 bool CommandLineParser::parseFileNameInner(const string& name, const string& originalPath, array_ref<string>& cmdLine)
253 {
254  string_ref extension = FileOperations::getExtension(name);
255  if (extension.empty()) {
256  return false; // no extension
257  }
258 
259  auto it = lower_bound(begin(fileTypes), end(fileTypes), extension,
260  CmpFileTypes());
261  StringOp::casecmp cmp;
262  if ((it == end(fileTypes)) || !cmp(it->first, extension)) {
263  return false; // unknown extension
264  }
265 
266  try {
267  // parse filetype
268  it->second->parseFileType(originalPath, cmdLine);
269  return true; // file processed
270  } catch (MSXException& e) {
271  throw FatalError(e.getMessage());
272  }
273 }
274 
275 void CommandLineParser::parse(int argc, char** argv)
276 {
277  parseStatus = RUN;
278 
279  vector<string> cmdLineBuf;
280  for (auto i : xrange(1, argc)) {
281  cmdLineBuf.push_back(FileOperations::getConventionalPath(argv[i]));
282  }
283  array_ref<string> cmdLine(cmdLineBuf);
284  vector<string> backupCmdLine;
285 
286  for (ParsePhase phase = PHASE_BEFORE_INIT;
287  (phase <= PHASE_LAST) && (parseStatus != EXIT);
288  phase = static_cast<ParsePhase>(phase + 1)) {
289  switch (phase) {
290  case PHASE_INIT:
291  reactor.init();
292  getInterpreter().init(argv[0]);
293  break;
294  case PHASE_LOAD_SETTINGS:
295  // after -control and -setting has been parsed
296  if (parseStatus != CONTROL) {
297  // if there already is a XML-StdioConnection, we
298  // can't also show plain messages on stdout
299  auto& cliComm = reactor.getGlobalCliComm();
300  cliComm.addListener(new StdioMessages());
301  }
302  if (!haveSettings) {
303  auto& settingsConfig =
305  // Load default settings file in case the user
306  // didn't specify one.
308  string filename = "settings.xml";
309  try {
310  settingsConfig.loadSetting(context, filename);
311  } catch (XMLException& e) {
312  reactor.getCliComm().printWarning(
313  "Loading of settings failed: " +
314  e.getMessage() + "\n"
315  "Reverting to default settings.");
316  } catch (FileException&) {
317  // settings.xml not found
318  } catch (ConfigException& e) {
319  throw FatalError("Error in default settings: "
320  + e.getMessage());
321  }
322  // Consider an attempt to load the settings good enough.
323  haveSettings = true;
324  // Even if parsing failed, use this file for saving,
325  // this forces overwriting a non-setting file.
326  settingsConfig.setSaveFilename(context, filename);
327  }
328  break;
329  case PHASE_LOAD_MACHINE: {
330  if (!haveConfig) {
331  // load default config file in case the user didn't specify one
332  const auto& machine =
333  reactor.getMachineSetting().getString();
334  try {
335  reactor.switchMachine(machine);
336  } catch (MSXException& e) {
337  reactor.getCliComm().printInfo(
338  "Failed to initialize default machine: " + e.getMessage());
339  // Default machine is broken; fall back to C-BIOS config.
340  const auto& fallbackMachine =
342  reactor.getCliComm().printInfo("Using fallback machine: " + fallbackMachine);
343  try {
344  reactor.switchMachine(fallbackMachine);
345  } catch (MSXException& e2) {
346  // Fallback machine failed as well; we're out of options.
347  throw FatalError(e2.getMessage());
348  }
349  }
350  haveConfig = true;
351  }
352  break;
353  }
354  default:
355  // iterate over all arguments
356  while (!cmdLine.empty()) {
357  string arg = std::move(cmdLine.front());
358  cmdLine.pop_front();
359  // first try options
360  if (!parseOption(arg, cmdLine, phase)) {
361  // next try the registered filetypes (xml)
362  if ((phase != PHASE_LAST) ||
363  !parseFileName(arg, cmdLine)) {
364  // no option or known file
365  backupCmdLine.push_back(arg);
366  auto it = lower_bound(begin(options), end(options), arg, CmpOptions());
367  if ((it != end(options)) && (it->first == arg)) {
368  for (unsigned i = 0; i < it->second.length - 1; ++i) {
369  if (!cmdLine.empty()) {
370  backupCmdLine.push_back(std::move(cmdLine.front()));
371  cmdLine.pop_front();
372  }
373  }
374  }
375  }
376  }
377  }
378  std::swap(backupCmdLine, cmdLineBuf);
379  backupCmdLine.clear();
380  cmdLine = cmdLineBuf;
381  break;
382  }
383  }
384  if (!cmdLine.empty() && (parseStatus != EXIT)) {
385  throw FatalError(
386  "Error parsing command line: " + cmdLine.front() + "\n" +
387  "Use \"openmsx -h\" to see a list of available options" );
388  }
389 }
390 
392 {
393  return (parseStatus == CONTROL) || (parseStatus == TEST);
394 }
395 
397 {
398  assert(parseStatus != UNPARSED);
399  return parseStatus;
400 }
401 
403 {
404  return scriptOption->getScripts();
405 }
406 
408 {
409  return reactor.getMotherBoard();
410 }
411 
413 {
414  return reactor.getGlobalCommandController();
415 }
416 
418 {
419  return reactor.getInterpreter();
420 }
421 
422 
423 // Control option
424 
426  : parser(parser_)
427 {
428 }
429 
430 void ControlOption::parseOption(const string& option, array_ref<string>& cmdLine)
431 {
432  const auto& fullType = getArgument(option, cmdLine);
433  string_ref type, arguments;
434  StringOp::splitOnFirst(fullType, ':', type, arguments);
435 
436  auto& controller = parser.getGlobalCommandController();
437  auto& distributor = parser.reactor.getEventDistributor();
438  auto& cliComm = parser.reactor.getGlobalCliComm();
439  std::unique_ptr<CliListener> connection;
440  if (type == "stdio") {
441  connection = make_unique<StdioConnection>(
442  controller, distributor);
443 #ifdef _WIN32
444  } else if (type == "pipe") {
445  OSVERSIONINFO info;
446  info.dwOSVersionInfoSize = sizeof(info);
447  GetVersionEx(&info);
448  if (info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
449  connection = make_unique<PipeConnection>(
450  controller, distributor, arguments);
451  } else {
452  throw FatalError("Pipes are not supported on this "
453  "version of Windows");
454  }
455 #endif
456  } else {
457  throw FatalError("Unknown control type: '" + type + '\'');
458  }
459  cliComm.addListener(connection.release());
460 
461  parser.parseStatus = CommandLineParser::CONTROL;
462 }
463 
465 {
466  return "Enable external control of openMSX process";
467 }
468 
469 
470 // Script option
471 
473 {
474  return scripts;
475 }
476 
477 void ScriptOption::parseOption(const string& option, array_ref<string>& cmdLine)
478 {
479  parseFileType(getArgument(option, cmdLine), cmdLine);
480 }
481 
483 {
484  return "Run extra startup script";
485 }
486 
487 void ScriptOption::parseFileType(const string& filename,
488  array_ref<std::string>& /*cmdLine*/)
489 {
490  scripts.push_back(filename);
491 }
492 
494 {
495  return "Extra Tcl script to run at startup";
496 }
497 
498 // Help option
499 
500 static string formatSet(const vector<string_ref>& inputSet, string::size_type columns)
501 {
502  StringOp::Builder outString;
503  string::size_type totalLength = 0; // ignore the starting spaces for now
504  for (auto& temp : inputSet) {
505  if (totalLength == 0) {
506  // first element ?
507  outString << " " << temp;
508  totalLength = temp.size();
509  } else {
510  outString << ", ";
511  if ((totalLength + temp.size()) > columns) {
512  outString << "\n " << temp;
513  totalLength = temp.size();
514  } else {
515  outString << temp;
516  totalLength += 2 + temp.size();
517  }
518  }
519  }
520  if (totalLength < columns) {
521  outString << string(columns - totalLength, ' ');
522  }
523  return outString;
524 }
525 
526 static string formatHelptext(string_ref helpText,
527  unsigned maxLength, unsigned indent)
528 {
529  string outText;
530  string_ref::size_type index = 0;
531  while (helpText.substr(index).size() > maxLength) {
532  auto pos = helpText.substr(index, maxLength).rfind(' ');
533  if (pos == string_ref::npos) {
534  pos = helpText.substr(maxLength).find(' ');
535  if (pos == string_ref::npos) {
536  pos = helpText.substr(index).size();
537  }
538  }
539  outText += helpText.substr(index, index + pos) + '\n' +
540  string(indent, ' ');
541  index = pos + 1;
542  }
543  string_ref t = helpText.substr(index);
544  outText.append(t.data(), t.size());
545  return outText;
546 }
547 
548 static void printItemMap(const StringMap<vector<string_ref>>& itemMap)
549 {
550  vector<string> printSet;
551  for (auto& p : itemMap) {
552  printSet.push_back(formatSet(p.second, 15) + ' ' +
553  formatHelptext(p.first(), 50, 20));
554  }
555  sort(begin(printSet), end(printSet));
556  for (auto& s : printSet) {
557  cout << s << endl;
558  }
559 }
560 
562  : parser(parser_)
563 {
564 }
565 
566 void HelpOption::parseOption(const string& /*option*/,
567  array_ref<string>& /*cmdLine*/)
568 {
569  const auto& fullVersion = Version::full();
570  cout << fullVersion << endl;
571  cout << string(fullVersion.size(), '=') << endl;
572  cout << endl;
573  cout << "usage: openmsx [arguments]" << endl;
574  cout << " an argument is either an option or a filename" << endl;
575  cout << endl;
576  cout << " this is the list of supported options:" << endl;
577 
578  StringMap<vector<string_ref>> optionMap;
579  for (auto& p : parser.options) {
580  const auto& helpText = p.second.option->optionHelp();
581  if (!helpText.empty()) {
582  optionMap[helpText].push_back(p.first);
583  }
584  }
585  printItemMap(optionMap);
586 
587  cout << endl;
588  cout << " this is the list of supported file types:" << endl;
589 
591  for (auto& p : parser.fileTypes) {
592  extMap[p.second->fileTypeHelp()].push_back(p.first);
593  }
594  printItemMap(extMap);
595 
596  parser.parseStatus = CommandLineParser::EXIT;
597 }
598 
600 {
601  return "Shows this text";
602 }
603 
604 
605 // class VersionOption
606 
608  : parser(parser_)
609 {
610 }
611 
612 void VersionOption::parseOption(const string& /*option*/,
613  array_ref<string>& /*cmdLine*/)
614 {
615  cout << Version::full() << endl;
616  cout << "flavour: " << BUILD_FLAVOUR << endl;
617  cout << "components: " << BUILD_COMPONENTS << endl;
618  parser.parseStatus = CommandLineParser::EXIT;
619 }
620 
622 {
623  return "Prints openMSX version and exits";
624 }
625 
626 
627 // Machine option
628 
630  : parser(parser_)
631 {
632 }
633 
634 void MachineOption::parseOption(const string& option, array_ref<string>& cmdLine)
635 {
636  if (parser.haveConfig) {
637  throw FatalError("Only one machine option allowed");
638  }
639  try {
640  parser.reactor.switchMachine(getArgument(option, cmdLine));
641  } catch (MSXException& e) {
642  throw FatalError(e.getMessage());
643  }
644  parser.haveConfig = true;
645 }
647 {
648  return "Use machine specified in argument";
649 }
650 
651 
652 // Setting Option
653 
655  : parser(parser_)
656 {
657 }
658 
659 void SettingOption::parseOption(const string& option, array_ref<string>& cmdLine)
660 {
661  if (parser.haveSettings) {
662  throw FatalError("Only one setting option allowed");
663  }
664  try {
665  auto& settingsConfig = parser.reactor.getGlobalCommandController().getSettingsConfig();
666  settingsConfig.loadSetting(
667  CurrentDirFileContext(), getArgument(option, cmdLine));
668  parser.haveSettings = true;
669  } catch (FileException& e) {
670  throw FatalError(e.getMessage());
671  } catch (ConfigException& e) {
672  throw FatalError(e.getMessage());
673  }
674 }
675 
677 {
678  return "Load an alternative settings file";
679 }
680 
681 
682 // class NoPBOOption
683 
684 void NoPBOOption::parseOption(const string& /*option*/,
685  array_ref<string>& /*cmdLine*/)
686 {
687  #if COMPONENT_GL
688  cout << "Disabling PBO" << endl;
690  #endif
691 }
692 
694 {
695  return "Disables usage of openGL PBO (for debugging)";
696 }
697 
698 
699 // class TestConfigOption
700 
702  : parser(parser_)
703 {
704 }
705 
706 void TestConfigOption::parseOption(const string& /*option*/,
707  array_ref<string>& /*cmdLine*/)
708 {
709  parser.parseStatus = CommandLineParser::TEST;
710 }
711 
713 {
714  return "Test if the specified config works and exit";
715 }
716 
717 // class BashOption
718 
720  : parser(parser_)
721 {
722 }
723 
724 void BashOption::parseOption(const string& /*option*/,
725  array_ref<string>& cmdLine)
726 {
727  string last = cmdLine.empty() ? "" : cmdLine.front();
728  cmdLine.clear(); // eat all remaining parameters
729 
730  if (last == "-machine") {
731  for (auto& s : Reactor::getHwConfigs("machines")) {
732  cout << s << '\n';
733  }
734  } else if (StringOp::startsWith(last, "-ext")) {
735  for (auto& s : Reactor::getHwConfigs("extensions")) {
736  cout << s << '\n';
737  }
738  } else if (last == "-romtype") {
739  for (auto& s : RomInfo::getAllRomTypes()) {
740  cout << s << '\n';
741  }
742  } else {
743  for (auto& p : parser.options) {
744  cout << p.first << '\n';
745  }
746  }
747  parser.parseStatus = CommandLineParser::EXIT;
748 }
749 
751 {
752  return ""; // don't include this option in --help
753 }
754 
755 } // namespace openmsx
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:281
CmpTupleElement< 0, StringOp::caseless > CmpFileTypes
Contains the main loop of openMSX.
Definition: Reactor.hh:62
string_ref optionHelp() const override
void pop_front()
Definition: array_ref.hh:91
string_ref::const_iterator end(const string_ref &x)
Definition: string_ref.hh:135
std::string getString() const finaloverride
Get the current value of this setting in a string format that can be presented to the user...
Definition: Setting.cc:176
GlobalCommandController & getGlobalCommandController()
Definition: Reactor.hh:80
void parseOption(const string &option, array_ref< string > &cmdLine) override
HelpOption(CommandLineParser &parser)
MSXMotherBoard * getMotherBoard() const
const Scripts & getStartupScripts() const
bool isHiddenStartup() const
Need to suppress renderer window on startup?
SettingOption(CommandLineParser &parser)
static std::vector< std::string > getHwConfigs(string_ref type)
Definition: Reactor.cc:288
void parseFileType(const std::string &filename, array_ref< std::string > &cmdLine) override
string getConventionalPath(string_ref path)
Returns the path in conventional path-delimiter.
void splitOnFirst(string_ref str, string_ref chars, string_ref &first, string_ref &last)
Definition: StringOp.cc:311
BashOption(CommandLineParser &parser)
void init(const char *programName)
Definition: Interpreter.cc:70
std::string getRestoreValue() const finaloverride
Get the value that will be set after a Tcl 'unset' command.
Definition: Setting.cc:186
void parseOption(const string &option, array_ref< string > &cmdLine) override
void printWarning(string_ref message)
Definition: CliComm.cc:28
const CommandLineParser::Scripts & getScripts() const
TestConfigOption(CommandLineParser &parser)
size_type find(string_ref s) const
Definition: string_ref.cc:58
This class implements a subset of the proposal for std::string_ref (proposed for the next c++ standar...
Definition: string_ref.hh:18
void parseOption(const string &option, array_ref< string > &cmdLine) override
void parseOption(const string &option, array_ref< string > &cmdLine) override
void parseOption(const string &option, array_ref< string > &cmdLine) override
static std::vector< string_ref > getAllRomTypes()
Definition: RomInfo.cc:195
CommandLineParser(Reactor &reactor)
const T & front() const
Definition: array_ref.hh:69
size_type size() const
Definition: string_ref.hh:55
EventDistributor & getEventDistributor()
Definition: Reactor.hh:78
EnumSetting< int > & getMachineSetting()
Definition: Reactor.hh:86
const char * data() const
Definition: string_ref.hh:68
size_t size_type
Definition: string_ref.hh:21
size_type rfind(string_ref s) const
Definition: string_ref.cc:85
std::string getArgument(const std::string &option, array_ref< std::string > &cmdLine) const
Definition: CLIOption.cc:11
#define COMPONENT_LASERDISC
Definition: components.hh:8
string_ref optionHelp() const override
MachineOption(CommandLineParser &parser)
void clear()
Definition: array_ref.hh:74
bool startsWith(string_ref total, string_ref part)
Definition: StringOp.cc:241
This class implements a subset of the proposal for std::array_ref (proposed for the next c++ standard...
Definition: array_ref.hh:19
std::unique_ptr< Context > context
Definition: GLContext.cc:9
bool empty() const
Definition: array_ref.hh:62
MSXMotherBoard * getMotherBoard() const
Definition: Reactor.cc:331
string_ref optionHelp() const override
void registerOption(const char *str, CLIOption &cliOption, ParsePhase phase=PHASE_LAST, unsigned length=2)
const std::string & getMessage() const
Definition: MSXException.hh:14
void loadSetting(const FileContext &context, string_ref filename)
static const size_type npos
Definition: string_ref.hh:26
GlobalCliComm & getGlobalCliComm()
Definition: Reactor.hh:79
string_ref optionHelp() const override
void registerFileType(string_ref extensions, CLIFileType &cliFileType)
void parseOption(const string &option, array_ref< string > &cmdLine) override
ControlOption(CommandLineParser &parser)
static bool enabled
Global switch to disable pixel buffers using the "-nopbo" option.
Definition: GLUtil.hh:162
vector< string_ref > split(string_ref str, char chars)
Definition: StringOp.cc:357
string_ref optionHelp() const override
GlobalCommandController & getGlobalCommandController() const
VersionOption(CommandLineParser &parser)
string_ref getExtension(string_ref path)
Returns the extension portion of a path.
void parse(int argc, char **argv)
void parseOption(const string &option, array_ref< string > &cmdLine) override
std::vector< std::string > Scripts
void parseOption(const string &option, array_ref< string > &cmdLine) override
string_ref optionHelp() const override
static std::string full()
Definition: Version.cc:7
void printInfo(string_ref message)
Definition: CliComm.cc:23
ParseStatus getParseStatus() const
CliComm & getCliComm()
Definition: Reactor.cc:268
string_ref optionHelp() const override
string_ref fileTypeHelp() const override
Interpreter & getInterpreter() const
string_ref substr(size_type pos, size_type n=npos) const
Definition: string_ref.cc:52
void switchMachine(const std::string &machine)
Definition: Reactor.cc:393
string_ref optionHelp() const override
LessTupleElement< 0 > CmpOptions
void parseOption(const string &option, array_ref< string > &cmdLine) override
string_ref::const_iterator begin(const string_ref &x)
Definition: string_ref.hh:134
string_ref optionHelp() const override
std::unique_ptr< T > make_unique()
Definition: memory.hh:27
bool empty() const
Definition: string_ref.hh:56
XRange< T > xrange(T e)
Definition: xrange.hh:98
Interpreter & getInterpreter()
Definition: Reactor.cc:273
void addListener(CliListener *listener)