From: Alex Schmidt Date: Thu, 23 May 2013 11:51:05 +0000 (+0200) Subject: improved argument handling. X-Git-Url: http://git.treefish.org/~alex/phys/latlib.git/commitdiff_plain/7a385d92335a4707d5b0aae66e4850d137c1fe7d improved argument handling. --- diff --git a/o815/o815.cpp b/o815/o815.cpp index 9b0fff8..4c2b28d 100644 --- a/o815/o815.cpp +++ b/o815/o815.cpp @@ -1,12 +1,15 @@ #include "o815.h" #include +#include #include "latlib/progress.h" +using namespace std; + extern int opterr; -o815::o815(int argc, char **argv, const string& _programid) { +o815::o815(int argc, char **argv, const string& _programid, comoption specOps[], void (*helpHeader)()) { long timestamp; programid = _programid; @@ -28,7 +31,64 @@ o815::o815(int argc, char **argv, const string& _programid) { paraQ = new paraq(numprocs, rank); - parseArgs(argc, argv); + addComOption("lsize", required_argument, NULL, 'L', "define lattice size", "xsize:tsize"); + addComOption("nmeas", required_argument, NULL, 'N', "set number of measurements", "nmeas"); + addComOption("skip", required_argument, NULL, 'S', "set number of skips between configs", "nskip"); + addComOption("nequi", required_argument, NULL, 'E', "set number of equilibrations", "nequi"); + addComOption("oro", required_argument, NULL, 'o', "read-only observable-store directory", "dir"); + addComOption("orw", required_argument, NULL, 'O', "read-write observable-store directory", "dir"); + addComOption("cro", required_argument, NULL, 'c', "read-only config-store directory", "dir"); + addComOption("crw", required_argument, NULL, 'C', "read-write config-store directory", "dir"); + addComOption("write", required_argument, NULL, 'w', "data writeout directory", "dir"); + addComOption("idonly", no_argument, &comargs.idonly, 'i', "show output-id only", ""); + addComOption("jobnum", no_argument, &comargs.showjobnum, 'j', "show jobnumber only", ""); + + if (specOps != NULL) + for (int ispecop = 0; specOps[ispecop].name != ""; ispecop++) + comOptions.push_back(specOps[ispecop]); + + if (argc > 1) + parseArgs(argc, argv, specOps); + else { + int longestCombinedLong=0; + + if (helpHeader != NULL) + helpHeader(); + + cout << "Options:" << endl; + + for (vector::iterator opit = comOptions.begin(); opit != comOptions.end(); ++opit) { + stringstream combinedLong; + + combinedLong << opit->name; + if (opit->has_arg == required_argument) + combinedLong << "=" << opit->argdesc; + else if (opit->has_arg == optional_argument) + combinedLong << "[=" << opit->argdesc << "]"; + + if (longestCombinedLong < combinedLong.str().size()) + longestCombinedLong = combinedLong.str().size(); + } + + for (vector::iterator opit = comOptions.begin(); opit != comOptions.end(); ++opit) { + stringstream combinedLong; + + cout << " -" << char(opit->val) << ", --"; + + combinedLong << opit->name; + if (opit->has_arg == required_argument) + combinedLong << "=" << opit->argdesc; + else if (opit->has_arg == optional_argument) + combinedLong << "[=" << opit->argdesc << "]"; + + cout << setw(longestCombinedLong) << setiosflags(ios::left) << combinedLong.str(); + + cout << "\t" << opit->optdesc; + + cout << endl; + } + exit(0); + } if(comargs.idonly) { cout << programid << headMaster() << endl << flush; @@ -97,12 +157,37 @@ void o815::mainLoop() { } } -void o815::parseArgs(int argc, char **argv) { - int opt = 0; - - opterr = 0; +void o815::addComOption(const char* name, int has_arg, int *flag, int val, const char* optdesc, const char* argdesc) { + comoption newop = { name, has_arg, flag, val, optdesc, argdesc }; + comOptions.push_back(newop); +} + +void o815::parseArgs(int argc, char **argv, comoption specOps[]) { + int opt; + int indexptr=0; + stringstream optargstr; + option allOptions[comOptions.size()+1]; + + for (int iop=0; iop < comOptions.size(); iop++) { + allOptions[iop].name = comOptions[iop].name.c_str(); + allOptions[iop].has_arg = comOptions[iop].has_arg; + //allOptions[iop].flag = NULL; + allOptions[iop].flag = comOptions[iop].flag; + allOptions[iop].val = comOptions[iop].val; + + optargstr << char(allOptions[iop].val); + if (allOptions[iop].has_arg == required_argument) + optargstr << ":"; + else if (allOptions[iop].has_arg == optional_argument) + optargstr << "::"; + } - while( (opt = getopt(argc, argv, "L:N:S:E:o:O:c:C:w:i:j:")) != -1 ) + allOptions[comOptions.size()].name = 0; + allOptions[comOptions.size()].has_arg = 0; + allOptions[comOptions.size()].flag = 0; + allOptions[comOptions.size()].val = 0; + + while((opt = getopt_long( argc, argv, optargstr.str().c_str(), allOptions, &indexptr )) != -1) switch(opt) { case 'L': listArg(comargs.lsize, 2, optarg); @@ -135,13 +220,26 @@ void o815::parseArgs(int argc, char **argv) { case 'w': comargs.outdir = optarg; break; - case 'i': - comargs.idonly = atoi(optarg); - break; - case 'j': - comargs.showjobnum = atoi(optarg); + default: + if ( opt != 0) { + comoption* thisop = getOptionByVal(opt); + if (thisop->flag != 0) + *thisop->flag = thisop->val; + else + parsedSpecOps.push_back( pair(thisop->val, optarg) ); + } break; } + + for (int ilon=0; optind+ilon < argc; ilon++) + lonelyArgs.push_back(argv[optind+ilon]); +} + +o815::comoption* o815::getOptionByVal(int val) { + for (vector::iterator opit = comOptions.begin(); opit != comOptions.end(); ++opit) + if ( opit->val == val ) + return &(*opit); + return NULL; } void o815::listArg(int *target, int tlen, char *listarg) { diff --git a/o815/o815.h b/o815/o815.h index 510e799..8b00437 100644 --- a/o815/o815.h +++ b/o815/o815.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "latlib/paraq.h" #include "latlib/writeout.h" @@ -62,11 +63,20 @@ class o815 { pair obscache; pair confcache; string outdir; - bool idonly; - bool showjobnum; + int idonly; + int showjobnum; } comargs; - o815(int argc, char **argv, const string& programid); + struct comoption { + string name; + int has_arg; + int *flag; + int val; + string optdesc; + string argdesc; + }; + + o815(int argc, char **argv, const string& _programid, comoption specOps[]=NULL, void (*helpHeader)()=NULL); ~o815(); paraq *paraQ; writeout *out; @@ -75,14 +85,19 @@ class o815 { void mainLoop(); string headMaster(); void addPara(const string& paraid, const double& paraDefault); + void addComOption(const char* name, int has_arg, int *flag, int val, const char* optdesc, const char* argdesc); + vector< pair > parsedSpecOps; + vector lonelyArgs; private: + vector comOptions; MPI_Status mpiStatus; int numprocs, rank; static void listArg(int *target, int tlen, char *listarg); - void parseArgs(int argc, char **argv); + void parseArgs(int argc, char **argv, comoption specOps[]); string programid; int nextParas(); + comoption* getOptionByVal(int val); }; #endif