new "getopt" style parsing (but as a "get argv" type loop).

This commit is contained in:
Jonathan Campbell 2015-01-18 02:16:32 -08:00
parent a945c8ca57
commit 88b1b44cb4
3 changed files with 161 additions and 57 deletions

View File

@ -39,8 +39,15 @@
class CommandLine {
public:
CommandLine(int argc,char const * const argv[]);
CommandLine(char const * const name,char const * const cmdline);
enum opt_style {
dos=0, // MS-DOS style /switches
gnu, // GNU style --switches or -switches, switch parsing stops at --
gnu_getopt, // GNU style --long or -a -b -c -d or -abcd (short as single char), switch parsing stops at --
either // both dos and gnu, switch parsing stops at --
};
public:
CommandLine(int argc,char const * const argv[],enum opt_style opt=CommandLine::either);
CommandLine(char const * const name,char const * const cmdline,enum opt_style opt=CommandLine::either);
const char * GetFileName(){ return file_name.c_str();}
bool FindExist(char const * const name,bool remove=false);
@ -58,10 +65,17 @@ public:
void Shift(unsigned int amount=1);
Bit16u Get_arglength();
bool BeginOpt(bool eat_argv=true);
bool GetOpt(std::string &name);
bool NextOptArgv(std::string &argv);
void EndOpt();
private:
typedef std::list<std::string>::iterator cmd_it;
cmd_it opt_scan;
bool opt_eat_argv;
std::list<std::string> cmds;
std::string file_name;
enum opt_style opt_style;
bool FindEntry(char const * const name,cmd_it & it,bool neednext=false);
};

View File

@ -3099,7 +3099,7 @@ static void show_warning(char const * const message) {
SDL_Delay(12000);
}
static void launcheditor() {
static void launcheditor(std::string edit) {
std::string path,file;
Cross::CreatePlatformConfigDir(path);
Cross::GetPlatformConfigName(file);
@ -3110,13 +3110,9 @@ static void launcheditor() {
exit(1);
}
if(f) fclose(f);
/* if(edit.empty()) {
printf("no editor specified.\n");
exit(1);
}*/
std::string edit;
while(control->cmdline->FindString("-editconf",edit,true)) //Loop until one succeeds
execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0);
execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0);
//if you get here the launching failed!
printf("can't find editor(s) specified at the command line.\n");
exit(1);
@ -3346,41 +3342,78 @@ int main(int argc, char* argv[]) {
/* NTS: Warning, do NOT move the Config myconf() object out of this scope.
* The destructor relies on executing section destruction code as part of
* DOSBox shutdown. */
std::string config_file,config_path;
std::string opt_editconf;
bool opt_eraseconf = false;
bool opt_resetconf = false;
bool opt_printconf = false;
bool opt_erasemapper = false;
bool opt_resetmapper = false;
std::string opt_opensaves,opt_opencaptures;
std::string config_file,config_path,optname,optarg;
CommandLine com_line(argc,argv);
Config myconf(&com_line);
control=&myconf;
if (control->cmdline->FindExist("-version")) {
printf("\nDOSBox version %s, copyright 2002-2013 DOSBox Team.\n\n",VERSION);
printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n");
printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
printf("and you are welcome to redistribute it under certain conditions;\n");
printf("please read the COPYING file thoroughly before doing so.\n\n");
return 0;
}
if (control->cmdline->FindExist("-help") || control->cmdline->FindExist("-h")) {
printf("\ndosbox [options]\n");
printf("\nDOSBox version %s, copyright 2002-2013 DOSBox Team.\n\n",VERSION);
printf(" -h -help Show this help\n");
printf(" -editconf Launch editor\n");
printf(" -opencaptures <param> Launch captures\n");
printf(" -opensaves <param> Launch saves\n");
printf(" -eraseconf Erase config file\n");
printf(" -resetconf Erase config file\n");
printf(" -printconf Print config file location\n");
printf(" -erasemapper Erase mapper file\n");
printf(" -resetmapper Erase mapper file\n");
printf(" -noconsole Don't show console (debug+win32 only)\n");
printf(" -nogui Don't show gui (win32 only)\n");
printf(" -nomenu Don't show menu (win32 only)\n");
printf(" -userconf Create user level config file\n");
printf(" -conf <param> Use config file <param>\n");
printf(" -startui Start DOSBox-X with UI\n");
printf(" -startmapper Start DOSBox-X with mapper\n");
printf(" -showcycles Show cycles count\n");
printf(" -fullscreen Start in fullscreen\n");
return 0;
control->cmdline->BeginOpt(/*eat argv=*/false); // TODO: When the rest of DOSBox has been weaned off of FindExist/etc change to true
while (control->cmdline->GetOpt(optname)) {
if (optname == "version") {
printf("\nDOSBox version %s, copyright 2002-2015 DOSBox Team.\n\n",VERSION);
printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n");
printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
printf("and you are welcome to redistribute it under certain conditions;\n");
printf("please read the COPYING file thoroughly before doing so.\n\n");
return 0;
}
else if (optname == "h" || optname == "help") {
printf("\ndosbox [options]\n");
printf("\nDOSBox version %s, copyright 2002-2015 DOSBox Team.\n\n",VERSION);
printf(" -h -help Show this help\n");
printf(" -editconf Launch editor\n");
printf(" -opencaptures <param> Launch captures\n");
printf(" -opensaves <param> Launch saves\n");
printf(" -eraseconf Erase config file\n");
printf(" -resetconf Erase config file\n");
printf(" -printconf Print config file location\n");
printf(" -erasemapper Erase mapper file\n");
printf(" -resetmapper Erase mapper file\n");
printf(" -noconsole Don't show console (debug+win32 only)\n");
printf(" -nogui Don't show gui (win32 only)\n");
printf(" -nomenu Don't show menu (win32 only)\n");
printf(" -userconf Create user level config file\n");
printf(" -conf <param> Use config file <param>\n");
printf(" -startui Start DOSBox-X with UI\n");
printf(" -startmapper Start DOSBox-X with mapper\n");
printf(" -showcycles Show cycles count\n");
printf(" -fullscreen Start in fullscreen\n");
return 0;
}
else if (optname == "editconf") {
if (!control->cmdline->NextOptArgv(opt_editconf)) return 1;
}
else if (optname == "opencaptures") {
if (!control->cmdline->NextOptArgv(opt_opencaptures)) return 1;
}
else if (optname == "opensaves") {
if (!control->cmdline->NextOptArgv(opt_opensaves)) return 1;
}
else if (optname == "eraseconf") {
opt_eraseconf = true;
}
else if (optname == "resetconf") {
opt_resetconf = true;
}
else if (optname == "printconf") {
opt_printconf = true;
}
else if (optname == "erasemapper") {
opt_erasemapper = true;
}
else if (optname == "resetmapper") {
opt_resetmapper = true;
}
else {
printf("WARNING: Unknown option %s (first parsing stage)\n",optname.c_str());
}
}
/* Init the configuration system and add default values */
@ -3388,20 +3421,18 @@ int main(int argc, char* argv[]) {
Config_Add_SDL();
DOSBOX_Init();
{
std::string editor;
if (control->cmdline->FindString("-editconf",editor,false)) launcheditor();
if (control->cmdline->FindString("-opencaptures",editor,true)) launchcaptures(editor);
if (control->cmdline->FindString("-opensaves",editor,true)) launchsaves(editor);
}
if (control->cmdline->FindExist("-eraseconf")) eraseconfigfile();
if (control->cmdline->FindExist("-resetconf")) eraseconfigfile();
if (control->cmdline->FindExist("-printconf")) printconfiglocation();
if (control->cmdline->FindExist("-erasemapper")) erasemapperfile();
if (control->cmdline->FindExist("-resetmapper")) erasemapperfile();
if (opt_editconf.length() != 0)
launcheditor(opt_editconf);
if (opt_opencaptures.length() != 0)
launchcaptures(opt_opencaptures);
if (opt_opensaves.length() != 0)
launchsaves(opt_opensaves);
if (opt_eraseconf || opt_resetconf)
eraseconfigfile();
if (opt_printconf)
printconfiglocation();
if (opt_erasemapper || opt_resetmapper)
erasemapperfile();
#if C_DEBUG
# if defined(WIN32)

View File

@ -1021,6 +1021,63 @@ unsigned int CommandLine::GetCount(void) {
return (unsigned int)cmds.size();
}
bool CommandLine::NextOptArgv(std::string &argv) {
argv.clear();
if (opt_scan == cmds.end()) return false;
argv = *opt_scan;
if (opt_eat_argv) opt_scan = cmds.erase(opt_scan);
else opt_scan++;
return true;
}
bool CommandLine::BeginOpt(bool eat_argv) {
opt_scan = cmds.begin();
if (opt_scan == cmds.end()) return false;
opt_eat_argv = eat_argv;
return true;
}
bool CommandLine::GetOpt(std::string &name) {
name.clear();
while (opt_scan != cmds.end()) {
std::string &argv = *opt_scan;
const char *str = argv.c_str();
if ((opt_style == CommandLine::either || opt_style == CommandLine::dos) && *str == '/') {
/* MS-DOS style /option. Example: /A /OPT /HAX /BLAH */
name = str+1; /* copy to caller minus leaking slash, then erase/skip */
if (opt_eat_argv) opt_scan = cmds.erase(opt_scan);
else opt_scan++;
return true;
}
else if ((opt_style == CommandLine::either || opt_style == CommandLine::gnu || opt_style == CommandLine::gnu_getopt) && *str == '-') {
str++; /* step past '-' */
if (str[0] == '-' && str[1] == 0) { /* '--' means to stop parsing */
opt_scan = cmds.end();
if (opt_eat_argv) opt_scan = cmds.erase(opt_scan);
break;
}
/* TODO: getopt single-char switches like -a -b or to represent -q -r -s as -qrs */
if (opt_style != CommandLine::gnu_getopt && *str == '-') str++;
name = str; /* copy to caller, then erase/skip */
if (opt_eat_argv) opt_scan = cmds.erase(opt_scan);
else opt_scan++;
return true;
}
else {
opt_scan++;
}
}
return false;
}
void CommandLine::EndOpt() {
opt_scan = cmds.end();
}
void CommandLine::FillVector(std::vector<std::string> & vector) {
for(cmd_it it=cmds.begin(); it != cmds.end(); it++) {
vector.push_back((*it));
@ -1086,11 +1143,12 @@ int CommandLine::GetParameterFromList(const char* const params[], std::vector<st
}
CommandLine::CommandLine(int argc,char const * const argv[]) {
CommandLine::CommandLine(int argc,char const * const argv[],enum opt_style opt) {
if (argc>0) {
file_name=argv[0];
}
int i=1;
opt_style = opt;
while (i<argc) {
cmds.push_back(argv[i]);
i++;
@ -1106,13 +1164,14 @@ Bit16u CommandLine::Get_arglength() {
}
CommandLine::CommandLine(char const * const name,char const * const cmdline) {
CommandLine::CommandLine(char const * const name,char const * const cmdline,enum opt_style opt) {
if (name) file_name=name;
/* Parse the cmds and put them in the list */
bool inword,inquote;char c;
inword=false;inquote=false;
std::string str;
const char * c_cmdline=cmdline;
opt_style = opt;
while ((c=*c_cmdline)!=0) {
if (inquote) {
if (c!='"') str+=c;