28 #pragma warning (disable: 4786)
29 #define strcasecmp _stricmp
42 const char const_usage[] =
43 " --SBMLSchema schema The Schema of the SBML file to export.\n"
44 " --configdir dir The configuration directory for copasi. The\n"
45 " default is .copasi in the home directory.\n"
46 " --configfile file The configuration file for copasi. The\n"
47 " default is copasi in the ConfigDir.\n"
48 " --exportBerkeleyMadonna file The Berkeley Madonna file to export.\n"
49 " --exportC file The C code file to export.\n"
50 " --exportXPPAUT file The XPPAUT file to export.\n"
51 " --home dir Your home directory.\n"
52 " --license Display the license.\n"
53 " --maxTime seconds The maximal time CopasiSE may run in\n"
55 " --nologo Surpresses the startup message.\n"
56 " --validate Only validate the given input file (COPASI,\n"
57 " Gepasi, or SBML) without performing any\n"
59 " --verbose Enable output of messages during runtime to\n"
61 " -c, --copasidir dir The COPASI installation directory.\n"
62 " -e, --exportSBML file The SBML file to export.\n"
63 " -i, --importSBML file A SBML file to import.\n"
64 " -s, --save file The file the model is saved to after work.\n"
65 " -t, --tmp dir The temp directory used for autosave.\n";
67 const char const_help_comment[] =
68 "use the -h option for help";
70 const char* expand_long_name(
const std::string &name);
75 : state_(state_option)
88 std::string tmp(argv[1]);
90 if (!tmp.compare(0, 4,
"-psn")) i = 2;
95 for (; i < argc; ++i) parse_element(argv[i], i, source_cl);
97 if (call_finalize) finalize();
106 std::string::size_type pos;
107 std::ifstream File(fileName);
111 std::ostringstream error;
112 error <<
"error opening file: '" << fileName <<
"'";
122 std::getline(File, Line);
125 if (File.eof())
break;
129 std::ostringstream error;
130 error <<
"unknown problem";
139 (pos < 1) ? 0 : pos--;
141 if (Line[pos] == 0xd) Line.erase(pos);
146 Line.erase(0, Line.find_first_not_of(
' '));
149 if (Line.length() == 0 || Line[0] ==
'#')
continue;
152 pos = Line.find_first_of(
":=");
154 Option =
"--" + Line.substr(0, pos);
155 Option.erase(Option.find_last_not_of(
' ') + 1);
157 parse_element(Option.c_str(), 0, source_cf);
159 if (pos != std::string::npos)
161 Value = Line.substr(pos + 1);
162 Value.erase(0, Value.find_first_not_of(
' '));
163 Value.erase(Value.find_last_not_of(
' ') + 1);
165 if (Value.length()) parse_element(Value.c_str(), 0, source_cf);
173 std::ostringstream error;
174 error <<
"error reading file: '" << fileName <<
"(" << LineCounter
175 <<
")': " << e.what();
187 if (state_ == state_value)
191 case option_ConfigDir:
192 throw option_error(
"missing value for 'configdir' option");
193 case option_ConfigFile:
194 throw option_error(
"missing value for 'configfile' option");
195 case option_CopasiDir:
196 throw option_error(
"missing value for 'copasidir' option");
197 case option_ExportBerkeleyMadonna:
198 throw option_error(
"missing value for 'exportBerkeleyMadonna' option");
200 throw option_error(
"missing value for 'exportC' option");
201 case option_ExportSBML:
202 throw option_error(
"missing value for 'exportSBML' option");
203 case option_ExportXPPAUT:
204 throw option_error(
"missing value for 'exportXPPAUT' option");
207 case option_ImportSBML:
208 throw option_error(
"missing value for 'importSBML' option");
210 throw option_error(
"missing value for 'license' option");
212 throw option_error(
"missing value for 'maxTime' option");
214 throw option_error(
"missing value for 'nologo' option");
215 case option_SBMLSchema:
216 throw option_error(
"missing value for 'SBMLSchema' option");
221 case option_Validate:
222 throw option_error(
"missing value for 'validate' option");
224 throw option_error(
"missing value for 'verbose' option");
231 size_t length = strlen(element);
236 non_options_.push_back(element);
240 if (length >= 2 && element[0] ==
'-' && element[1] ==
'-')
242 if (length == 2) {state_ = state_consume;
return;}
245 const char *value = element;
247 while (*value != 0 && *value !=
'=') ++value;
251 std::string selement(element, value - element), svalue(++value);
253 parse_long_option(selement.c_str(), position, source);
255 if (state_ != state_value)
257 std::string error(
"the '"); error += element; error +=
"' option does not take a value";
261 parse_value(svalue.c_str());
262 state_ = state_option;
266 parse_long_option(element, position, source);
269 else if (length >= 2 && element[0] ==
'-')
275 while (*element != 0)
277 parse_short_option(*element, position, source);
280 if (state_ == state_value && *element ==
'=')
282 parse_value(++element);
283 state_ = state_option;
286 else if (state_ == state_value) finalize();
291 parse_short_option(*element, position, source);
296 non_options_.push_back(element);
301 parse_value(element);
302 state_ = state_option;
313 if (source != source_cl)
throw option_error(
"the 'copasidir' option can only be used on the command line");
315 if (locations_.CopasiDir)
317 throw option_error(
"the 'copasidir' option is only allowed once");
320 openum_ = option_CopasiDir;
321 state_ = state_value;
322 locations_.CopasiDir = position;
326 if (source != source_cl)
throw option_error(
"the 'exportSBML' option can only be used on the command line");
328 if (locations_.ExportSBML)
330 throw option_error(
"the 'exportSBML' option is only allowed once");
333 openum_ = option_ExportSBML;
334 state_ = state_value;
335 locations_.ExportSBML = position;
339 if (source != source_cl)
throw option_error(
"the 'importSBML' option can only be used on the command line");
341 if (locations_.ImportSBML)
343 throw option_error(
"the 'importSBML' option is only allowed once");
346 openum_ = option_ImportSBML;
347 state_ = state_value;
348 locations_.ImportSBML = position;
355 throw option_error(
"the 'save' option is only allowed once");
358 openum_ = option_Save;
359 state_ = state_value;
360 locations_.Save = position;
367 throw option_error(
"the 'tmp' option is only allowed once");
370 openum_ = option_Tmp;
371 state_ = state_value;
372 locations_.Tmp = position;
376 if (source != source_cl)
break;
381 if (source != source_cl)
break;
386 std::string error(
"unknown option: '"); error += option; error +=
"'";
392 option = expand_long_name(option);
394 if (strcmp(option,
"SBMLSchema") == 0)
396 if (source != source_cl)
throw option_error(
"the 'SBMLSchema' option is only allowed on the command line");
398 if (locations_.SBMLSchema)
400 throw option_error(
"the 'SBMLSchema' option is only allowed once");
403 openum_ = option_SBMLSchema;
404 locations_.SBMLSchema = position;
405 state_ = state_value;
408 else if (strcmp(option,
"configdir") == 0)
410 if (source != source_cl)
throw option_error(
"the 'configdir' option is only allowed on the command line");
412 if (locations_.ConfigDir)
414 throw option_error(
"the 'configdir' option is only allowed once");
417 openum_ = option_ConfigDir;
418 locations_.ConfigDir = position;
419 state_ = state_value;
422 else if (strcmp(option,
"configfile") == 0)
424 if (source != source_cl)
throw option_error(
"the 'configfile' option is only allowed on the command line");
426 if (locations_.ConfigFile)
428 throw option_error(
"the 'configfile' option is only allowed once");
431 openum_ = option_ConfigFile;
432 locations_.ConfigFile = position;
433 state_ = state_value;
436 else if (strcmp(option,
"copasidir") == 0)
438 if (source != source_cl)
throw option_error(
"the 'copasidir' option is only allowed on the command line");
440 if (locations_.CopasiDir)
442 throw option_error(
"the 'copasidir' option is only allowed once");
445 openum_ = option_CopasiDir;
446 locations_.CopasiDir = position;
447 state_ = state_value;
450 else if (strcmp(option,
"exportBerkeleyMadonna") == 0)
452 if (source != source_cl)
throw option_error(
"the 'exportBerkeleyMadonna' option is only allowed on the command line");
454 if (locations_.ExportBerkeleyMadonna)
456 throw option_error(
"the 'exportBerkeleyMadonna' option is only allowed once");
459 openum_ = option_ExportBerkeleyMadonna;
460 locations_.ExportBerkeleyMadonna = position;
461 state_ = state_value;
464 else if (strcmp(option,
"exportC") == 0)
466 if (source != source_cl)
throw option_error(
"the 'exportC' option is only allowed on the command line");
468 if (locations_.ExportC)
470 throw option_error(
"the 'exportC' option is only allowed once");
473 openum_ = option_ExportC;
474 locations_.ExportC = position;
475 state_ = state_value;
478 else if (strcmp(option,
"exportSBML") == 0)
480 if (source != source_cl)
throw option_error(
"the 'exportSBML' option is only allowed on the command line");
482 if (locations_.ExportSBML)
484 throw option_error(
"the 'exportSBML' option is only allowed once");
487 openum_ = option_ExportSBML;
488 locations_.ExportSBML = position;
489 state_ = state_value;
492 else if (strcmp(option,
"exportXPPAUT") == 0)
494 if (source != source_cl)
throw option_error(
"the 'exportXPPAUT' option is only allowed on the command line");
496 if (locations_.ExportXPPAUT)
498 throw option_error(
"the 'exportXPPAUT' option is only allowed once");
501 openum_ = option_ExportXPPAUT;
502 locations_.ExportXPPAUT = position;
503 state_ = state_value;
506 else if (strcmp(option,
"home") == 0)
508 if (source != source_cl)
throw option_error(
"the 'home' option is only allowed on the command line");
512 throw option_error(
"the 'home' option is only allowed once");
515 openum_ = option_Home;
516 locations_.Home = position;
517 state_ = state_value;
520 else if (strcmp(option,
"importSBML") == 0)
522 if (source != source_cl)
throw option_error(
"the 'importSBML' option is only allowed on the command line");
524 if (locations_.ImportSBML)
526 throw option_error(
"the 'importSBML' option is only allowed once");
529 openum_ = option_ImportSBML;
530 locations_.ImportSBML = position;
531 state_ = state_value;
534 else if (strcmp(option,
"license") == 0)
536 if (source != source_cl)
throw option_error(
"the 'license' option is only allowed on the command line");
538 if (locations_.License)
540 throw option_error(
"the 'license' option is only allowed once");
543 openum_ = option_License;
544 locations_.License = position;
545 options_.License = !options_.License;
548 else if (strcmp(option,
"maxTime") == 0)
550 if (source != source_cl)
throw option_error(
"the 'maxTime' option is only allowed on the command line");
552 if (locations_.MaxTime)
554 throw option_error(
"the 'maxTime' option is only allowed once");
557 openum_ = option_MaxTime;
558 locations_.MaxTime = position;
559 state_ = state_value;
562 else if (strcmp(option,
"nologo") == 0)
566 if (locations_.NoLogo)
568 throw option_error(
"the 'nologo' option is only allowed once");
571 openum_ = option_NoLogo;
572 locations_.NoLogo = position;
573 options_.NoLogo = !options_.NoLogo;
576 else if (strcmp(option,
"save") == 0)
582 throw option_error(
"the 'save' option is only allowed once");
585 openum_ = option_Save;
586 locations_.Save = position;
587 state_ = state_value;
590 else if (strcmp(option,
"tmp") == 0)
596 throw option_error(
"the 'tmp' option is only allowed once");
599 openum_ = option_Tmp;
600 locations_.Tmp = position;
601 state_ = state_value;
604 else if (strcmp(option,
"validate") == 0)
608 if (locations_.Validate)
610 throw option_error(
"the 'validate' option is only allowed once");
613 openum_ = option_Validate;
614 locations_.Validate = position;
615 options_.Validate = !options_.Validate;
618 else if (strcmp(option,
"verbose") == 0)
622 if (locations_.Verbose)
624 throw option_error(
"the 'verbose' option is only allowed once");
627 openum_ = option_Verbose;
628 locations_.Verbose = position;
629 options_.Verbose = !options_.Verbose;
632 else if (source == source_cl && strcmp(option,
"help") == 0)
637 std::string error(
"unknown option '"); error += option; error +=
"'";
645 case option_ConfigDir:
647 options_.ConfigDir = value;
650 case option_ConfigFile:
652 options_.ConfigFile = value;
655 case option_CopasiDir:
657 options_.CopasiDir = value;
660 case option_ExportBerkeleyMadonna:
662 options_.ExportBerkeleyMadonna = value;
667 options_.ExportC = value;
670 case option_ExportSBML:
672 options_.ExportSBML = value;
675 case option_ExportXPPAUT:
677 options_.ExportXPPAUT = value;
682 options_.Home = value;
685 case option_ImportSBML:
687 options_.ImportSBML = value;
694 char *endptr;
int tmp = std::strtol(value, &endptr, 0);
696 while (*endptr != 0 && std::isspace(*endptr)) ++endptr;
700 std::string error(
"invalid integer value '"); error += value; error +=
"'";
706 throw option_error(
"integer value out of range, 'maxTime' min is 0");
709 options_.MaxTime = tmp;
714 case option_SBMLSchema:
718 if (strcmp(value,
"L1V1") == 0)
722 else if (strcmp(value,
"L1V2") == 0)
726 else if (strcmp(value,
"L2V1") == 0)
730 else if (strcmp(value,
"L2V2") == 0)
734 else if (strcmp(value,
"L2V3") == 0)
738 else if (strcmp(value,
"L2V4") == 0)
742 else if (strcmp(value,
"L3V1") == 0)
748 std::string error(
"'"); error += value; error +=
"' is an invalid value for the 'SBMLSchema' option";
752 options_.SBMLSchema = evalue;
757 options_.Save = value;
762 options_.Tmp = value;
765 case option_Validate:
774 return const_help_comment;
779 const char* expand_long_name(
const std::string &name)
781 std::string::size_type name_size = name.size();
782 std::vector<const char*> matches;
784 if (name_size <= 10 && name.compare(
"SBMLSchema") == 0)
785 matches.push_back(
"SBMLSchema");
787 if (name_size <= 9 && name.compare(
"configdir") == 0)
788 matches.push_back(
"configdir");
790 if (name_size <= 10 && name.compare(
"configfile") == 0)
791 matches.push_back(
"configfile");
793 if (name_size <= 9 && name.compare(
"copasidir") == 0)
794 matches.push_back(
"copasidir");
796 if (name_size <= 21 && name.compare(
"exportBerkeleyMadonna") == 0)
797 matches.push_back(
"exportBerkeleyMadonna");
799 if (name_size <= 7 && name.compare(
"exportC") == 0)
800 matches.push_back(
"exportC");
802 if (name_size <= 10 && name.compare(
"exportSBML") == 0)
803 matches.push_back(
"exportSBML");
805 if (name_size <= 12 && name.compare(
"exportXPPAUT") == 0)
806 matches.push_back(
"exportXPPAUT");
808 if (name_size <= 4 && name.compare(
"home") == 0)
809 matches.push_back(
"home");
811 if (name_size <= 10 && name.compare(
"importSBML") == 0)
812 matches.push_back(
"importSBML");
814 if (name_size <= 7 && name.compare(
"license") == 0)
815 matches.push_back(
"license");
817 if (name_size <= 7 && name.compare(
"maxTime") == 0)
818 matches.push_back(
"maxTime");
820 if (name_size <= 6 && name.compare(
"nologo") == 0)
821 matches.push_back(
"nologo");
823 if (name_size <= 4 && name.compare(
"save") == 0)
824 matches.push_back(
"save");
826 if (name_size <= 3 && name.compare(
"tmp") == 0)
827 matches.push_back(
"tmp");
829 if (name_size <= 8 && name.compare(
"validate") == 0)
830 matches.push_back(
"validate");
832 if (name_size <= 7 && name.compare(
"verbose") == 0)
833 matches.push_back(
"verbose");
835 if (name_size <= 4 && name.compare(
"help") == 0)
836 matches.push_back(
"help");
840 std::string error(
"unknown option '"); error += name; error +=
"'";
844 if (matches.size() == 1)
849 std::string error(
"the option name '"); error += name; error +=
"' is ambiguous";
void parse_short_option(char option, int position, opsource source)
void parse_element(const char *element, int position, opsource source)
const char * get_help_comment(void) const
option_locations locations_
void parse_long_option(const char *option, int position, opsource source)
void parse_value(const char *value)
void parse(int argc, char *argv[], bool call_finalize=true)
parse the command line
COptionParser(void)
default constructor
void finalize(void)
finalize all parsing (eg. check for mandatory options)