Home || Visual Search || Applications || Architecture || Important Messages || OGL || Src

CmdOptions.h

Go to the documentation of this file.
00001 #ifndef Impala_Basis_CmdOptions_h
00002 #define Impala_Basis_CmdOptions_h
00003 
00004 #include <vector>
00005 #include <iterator>
00006 
00007 #include "Basis/FileName.h"
00008 #include "Basis/FileReadString.h"
00009 #include "Basis/FileExists.h"
00010 #include "Basis/LogSystem.h"
00011 #include "Basis/ILog.h"
00012 
00013 namespace Impala
00014 {
00015 
00016 class CmdOptions
00017 {
00018 public:
00019 
00020     static CmdOptions&
00021     GetInstance()
00022     {
00023         static CmdOptions theCmdOptions;
00024         return theCmdOptions;
00025     }
00026 
00027     void
00028     Initialise(bool stdVideoOptions = false, bool stdGaussOptions = false,
00029                bool stdDatabaseOptions = false)
00030     {
00031         if (stdVideoOptions)
00032         {
00033             AddOption(0, "wndWidth",  "size",    "-1");
00034             AddOption(0, "wndHeight", "size",    "-1");
00035             AddOption(0, "viewScale", "scale",   "1.0");
00036             AddOption('s', "src",     "type",    "",
00037               "dx|avi|lavc|lavcnoidx|lavcwithidx|lavcwriteidx");
00038             AddOption(0, "srcWindow", "type",    "",
00039               "size;3;copyreal|size;5;rgb2ooo|size;5;gauss;0.75;0;0;3.0");
00040             AddOption(0, "step",      "",        "0");
00041             AddOption(0, "loop",      "",        "0");
00042             AddOption(0, "startFrame","nr",      "0");
00043             AddOption(0, "stepSize",  "nr",      "1");
00044             AddOption(0, "numberFrames", "nr",   "-1");
00045             AddOption(0, "delay",     "nrFrames","0");
00046             AddOption(0, "jmp","type","pos","pos|pts");
00047             AddOption(0, "fixIdx", "Fix Broken indexes for LAVC", "1");
00048         }
00049         if (stdGaussOptions)
00050         {
00051             AddOption(0, "sigma",     "val",     "1.0");
00052             AddOption(0, "precision", "val",     "3.0");
00053             AddOption(0, "recGauss",  "",        "0");
00054             AddOption(0, "disp",      "mode",    "LogMagnitude");
00055             AddOption(0, "logScale",  "val",     "32.0");
00056         }
00057         if (stdDatabaseOptions)
00058         {
00059             AddOption(0, "data",          "path", ".", 0, true);
00060             AddOption(0, "dataServer",    "machine:port", "", 0, true);
00061             AddOption(0, "mapi",          "machine:port[:db]", "", 0, true);
00062             AddOption(0, "config",        "directory", "${IMPALAROOT}/src",
00063                       0, true);
00064             AddOption(0, "passwordFile",  "filename", ".passwords", 0, true);
00065             AddOption(0, "videoSet",      "filename", "", 0, true);
00066 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00067             AddOption(0, "videoSetRepository", "filename", "../videosets.txt",
00068                       0, true);
00069 #endif // REPOSITORY_USED
00070             AddOption(0, "videoSetsRepository", "filename", "videosets.txt",
00071                       0, true);
00072             AddOption(0, "imageSet",      "filename", "", 0, true);
00073 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00074             AddOption(0, "imageSetRepository", "filename", "../imagesets.txt",
00075                       0, true);
00076 #endif // REPOSITORY_USED
00077             AddOption(0, "imageSetsRepository", "filename", "imagesets.txt",
00078                       0, true);
00079             AddOption(0, "override",      "",     "0");
00080         }
00081         AddOption(0, "tmpPath",           "folder",     "");
00082         AddOption(0, "cudaDevice",        "index", "0");
00083         AddOption(0, "noFeatureCache",    "",      "0");
00084     }
00085 
00086     void
00087     AddOption(char optNameS, const char* optNameL, const char* parName,
00088               const char* defVal, const char* alternatives = 0,
00089               bool defaultFromEnv = false)
00090     {
00091         mOptNameS.push_back(optNameS);
00092         mOptNameL.push_back(String(optNameL));
00093         mOptParName.push_back(parName);
00094         String stringDef(defVal);
00095         if (defaultFromEnv)
00096         {
00097             String optS(optNameL);
00098             char* str;
00099             str = getenv(optS.c_str());
00100             if (str != 0)
00101             {
00102                 stringDef = str;
00103             }
00104             else
00105             {
00106                 StringToUpper(optS);
00107                 str = getenv(optS.c_str());
00108                 if (str != 0)
00109                     stringDef = str;
00110             }
00111         }
00112         mOptDefVal.push_back(stringDef);
00113         mOptVal.push_back(stringDef);
00114         if (alternatives)
00115             mOptAlt.push_back(alternatives);
00116         else
00117             mOptAlt.push_back("");
00118         mOptHideUsage.push_back(false);
00119     }
00120 
00121     void
00122     SetDefault(char* optNameL, char* defVal)
00123     {
00124         int i = GetOptIdx(String(optNameL));
00125         if (i < 0)
00126             return;
00127         mOptVal[i] = String(defVal);
00128     }
00129 
00130     bool
00131     ParseArgs(int argc, char* argv[], CString usageStr, int nrReqArgs = 0)
00132     {
00133         if ((argc > 1) && (String(argv[1]) == "--version"))
00134         {
00135             std::cout << "Impala version " << IMPALA_VERSION_STR
00136                       << ", svnversion " << SVN_VERSION_STR
00137                       << ", build on " << __DATE__ << " at " << __TIME__
00138                       << std::endl;
00139             return false;
00140         }
00141 
00142         String parseError = DoParseArgs(argc, argv, usageStr, nrReqArgs);
00143         ConfigureLogSystem(); // we assume this will not fail
00144         if (parseError.empty())
00145             return true;
00146 
00147         ILOG_ERROR(parseError);
00148         ShowUsage(argv[0], usageStr);
00149         return false;
00150     }
00151 
00152     int
00153     GetNrArg()
00154     {
00155         return mArg.size();
00156     }
00157 
00158     String
00159     GetArg(int i)
00160     {
00161         if ((i<0) || (i>=mArg.size()))
00162         {
00163             std::cout << "CmdOptions: no argument " << i << std::endl;
00164             return String("");
00165         }
00166         if ((mArg[i] == "nil") || (mArg[i] == "empty"))
00167             return "";
00168         return mArg[i];
00169     }
00170 
00171     String
00172     GetString(String optL, String defVal = "")
00173     {
00174         int i = GetOptIdx(optL);
00175         if (i < 0)
00176             return defVal;// String("");
00177         return mOptVal[i];
00178     }
00179 
00180     int
00181     GetInt(String optL, int defVal = -1)
00182     {
00183         int i = GetOptIdx(optL);
00184         if (i < 0)
00185             return defVal;
00186         String s = mOptVal[i];
00187         return atoi(s);
00188     }
00189 
00190     double
00191     GetDouble(String optL, double defVal = -1)
00192     {
00193         int i = GetOptIdx(optL);
00194         if (i < 0)
00195             return defVal;
00196         String s = mOptVal[i];
00197         return atof(s);
00198     }
00199 
00200     bool
00201     GetBool(String optL, bool defVal = false)
00202     {
00203         int i = GetOptIdx(optL);
00204         if (i < 0)
00205             return defVal;
00206         String s = mOptVal[i];
00207         if (atoi(s) != 0)
00208             return true;
00209         if (s == "yes"  ||  s == "true")
00210             return true;
00211         return false;
00212     }
00213 
00214     void
00215     PrintArgs(std::ostream& os)
00216     {
00217         for (int i = 0 ; i < mOptNameL.size() ; ++i)
00218             os << mOptNameL[i] << " => " << mOptVal[i] << "\n";
00219         os << std::endl;
00220     }
00221 
00222     void
00223     HideUsageFor(String parameter)
00224     {
00225         int idx = GetOptIdx(parameter);
00226         if (idx < 0) 
00227             return;
00228         mOptHideUsage[idx] = true;
00229     }
00230 
00231 private:
00232 
00233     CmdOptions()
00234     {
00235         AddOption('v', "verb", "level", "0");
00236         AddOption(0, "debug", "", "0");
00237         AddOption(0, "debugCat", "categories separated with ';' or ':'", "");
00238         AddOption(0, "logProperties", "fileName", "./log4cpp.properties");
00239         AddOption(0, "logFile", "fileName", "");
00240         AddOption(0, "logLayout", "layoutPattern",
00241                   "%d{%a%d %H:%M:%S,%l} %-5p [%c %x] %m%n");
00242         AddOption(0, "noErrorLog", "", "0");
00243         AddOption(0, "jobErrorLog", "fileName", "");
00244         AddOption(0, "exitOnErrorLogged", "", "0");
00245         AddOption(0, "logFlushOutput", "flag", "0");
00246         AddOption(0, "showProgress", "flag", "1");
00247         AddOption(0, "ini", "filename", "");
00248     }
00249 
00250     CmdOptions(const CmdOptions&)
00251     {
00252     }
00253 
00254     CmdOptions&
00255     operator=(const CmdOptions&)
00256     {
00257     }
00258 
00259     virtual
00260     ~CmdOptions()
00261     {
00262     }
00263 
00264     int
00265     NrOpt()
00266     {
00267         return mOptNameL.size();
00268     }
00269 
00270     int
00271     GetOptIdx(String s)
00272     {
00273         for (int i=0 ; i<NrOpt() ; i++)
00274         {
00275             if ((s.size() == 1) && (s[0] == mOptNameS[i]))
00276                 return i;
00277             if (s.compare(mOptNameL[i]) == 0)
00278                 return i;
00279         }
00280         return -1;
00281     }
00282 
00283     bool
00284     IsOpt(String s)
00285     {
00286         return (s[0] == '-');
00287     }
00288 
00289     bool
00290     IsOptS(String s)
00291     {
00292         return ((s[0] == '-') && (s[1] != '-'));
00293     }
00294 
00295     bool
00296     IsOptL(String s)
00297     {
00298         return ((s[0] == '-') && (s[1] == '-'));
00299     }
00300 
00301     void
00302     CheckDynamicOption(String s)
00303     {
00304         if (StringStartsWith(s, "data::"))
00305         {
00306             AddOption(0, s.c_str(), "prefixPath", "");
00307         }
00308         if (StringStartsWith(s, "dataServer::"))
00309         {
00310             AddOption(0, s.c_str(), "otherServer", "");
00311         }
00312     }
00313 
00314     String
00315     DoParseArgs(int argc, char* argv[], CString usageStr, int nrReqArgs)
00316     {
00317         if (argc < nrReqArgs + 1)
00318         {
00319             for(int i=0 ; i<argc ; i++)
00320                 std::cout << argv[i] << std::endl;
00321             return "Need more arguments: " + MakeString(argc-1) + " found, "
00322                 + MakeString(nrReqArgs) + " expected";
00323         }
00324         
00325         // search for ini file name in the arguments
00326         String fileName(argv[0]);
00327         bool sawIniOption = false;
00328         fileName = FileNameBase(fileName) + ".ini";
00329         int i = 1;
00330         while (i < argc)
00331         {
00332             String s = String(argv[i]);
00333             if (s == "--ini")
00334             {
00335                 if (i+1 >= argc)
00336                     return "Missing value for --ini";
00337 
00338                 if (argv[i+1][0] == '-')
00339                     return "Missing value for --ini";
00340 
00341                 sawIniOption = true;
00342                 fileName = String(argv[i+1]);
00343                 break;
00344             }
00345             i++;
00346         }
00347         if (sawIniOption && !FileExists(fileName))
00348             return "Couldn't open ini file " + fileName;
00349 
00350         ReadIniFile(fileName);
00351 
00352         i = 1;
00353         while (i < argc)
00354         {
00355             String s = String(argv[i]);
00356             if ((s == "-h") || (s == "--help"))
00357                 return "help";
00358 
00359             if (IsOpt(s))
00360             {
00361                 s = s.substr(s.rfind('-',2)+1); // remove --
00362                 CheckDynamicOption(s); // add data::something like options
00363                 int idx = GetOptIdx(s);
00364                 if (idx < 0)
00365                 {
00366                     if (s != "ini")
00367                         return "Unknown option --" + s;
00368 
00369                 }
00370                 else if (mOptParName[idx] != "")
00371                 {
00372                     if (i+1 >= argc)
00373                         return "Missing value for --" + s;
00374 
00375                     if (argv[i+1][0] == '-')
00376                         return "Missing value for --" + s;
00377 
00378                     String tmp(argv[i+1]);
00379                     if (tmp[0] == '"')
00380                     {   // follow embedding quotes
00381                         while (tmp[tmp.size()-1] != '"')
00382                         {
00383                             i++;
00384                             if (i + 1 >= argc)
00385                                 return "Quoted string not terminated";
00386 
00387                             tmp = tmp + " " + String(argv[i+1]);
00388                         }
00389                         tmp = tmp.substr(1, tmp.size()-2);
00390                         if (tmp[0] == '"') // mpi programs still get these
00391                             tmp = tmp.substr(1, tmp.size()-2);
00392                     }
00393                     mOptVal[idx] = tmp;
00394                     i++;
00395                 }
00396                 else
00397                 {
00398                     mOptVal[idx] = "1";
00399                 }
00400             }
00401             else
00402             {
00403                 if (s[0] == '"') // mpi programs still get these
00404                     s = s.substr(1, s.size()-2);
00405                 mArg.push_back(s);
00406             }
00407             i++;
00408         }
00409 
00410         if (mArg.size() < nrReqArgs)
00411             return "Need more arguments";
00412 
00413         return String();
00414     }
00415 
00416     void
00417     ShowUsage(const char* progName, CString usageStr)
00418     {
00419         std::cout << std::endl;
00420         std::cout << "Usage : " << progName << " " << usageStr << std::endl;
00421         std::cout << std::endl;
00422         std::cout << "  Options:" << std::endl;
00423         std::cout << "    -h  --help" << std::endl;
00424         std::cout << "        --version" << std::endl;
00425         for (int i=0 ; i<NrOpt() ; i++)
00426         {
00427             if (mOptParName[i] == "read from ini file")
00428                 continue;
00429             if (mOptHideUsage[i])
00430                 continue;
00431             if (mOptNameS[i])
00432                 std::cout << "    -" << mOptNameS[i];
00433             else
00434                 std::cout << "      ";
00435             std::cout << "  --" << mOptNameL[i] << " " << mOptParName[i];
00436             if (! mOptDefVal[i].empty())
00437                 std::cout << " [default: " << mOptDefVal[i] <<"]";
00438             if (! mOptAlt[i].empty())
00439                 std::cout << " [" << mOptParName[i] << " in " << mOptAlt[i]
00440                           << "]";
00441             std::cout << std::endl;
00442         }
00443     }
00444     
00445     void
00446     ReadIniFile(String fileName)
00447     {
00448         std::vector<String> lines;
00449         std::back_insert_iterator<std::vector<String> > bi(lines);
00450         FileReadString(bi, fileName, true, false);
00451         for (int i=0 ; i<lines.size() ; i++)
00452         {
00453             String& s = lines[i];
00454             if (s[0] == '#')
00455                 continue;
00456             String::size_type pos = 0;
00457             while (s[pos] == ' ')
00458                 pos++;
00459             String::size_type end = s.find(' ', pos);
00460             String name = s.substr(pos, end - pos);
00461             if (end == String::npos)
00462                 continue;
00463 
00464             pos = end;
00465             while (s[pos] == ' ')
00466                 pos++;
00467             char delim = (s[pos] == '"') ? '"' : ' ';
00468             if (delim == '"')
00469                 pos++;
00470             end = s.find(delim, pos);
00471             String value = s.substr(pos, end - pos);
00472 
00473             int index = GetOptIdx(name);
00474             if (index == -1)
00475                 AddOption(0, name.c_str(), "read from ini file", value.c_str());
00476             else
00477                 mOptVal[index] = value;
00478         }
00479     }
00480 
00481     void
00482     ConfigureLogSystem()
00483     {
00484         LogSystem::LogSystemConfig logConfig;
00485         logConfig.mLogProperties = GetString("logProperties");
00486         logConfig.mLogLayout = GetString("logLayout");
00487         logConfig.mLogFile = GetString("logFile");
00488         logConfig.mLogFlushOutput = GetBool("logFlushOutput");
00489         logConfig.mLogLevel = GetInt("logLevel");
00490         logConfig.mDebug = GetBool("debug");
00491         logConfig.mDebugCat = StringReplaceAll(GetString("debugCat"), ":", ";", false);
00492         logConfig.mNoErrorLog = GetBool("noErrorLog");
00493         logConfig.mJobErrorLog = GetString("jobErrorLog");
00494         logConfig.mExitOnError = GetBool("exitOnErrorLogged");
00495         LogSystem::GetInstance().Configure(logConfig);
00496     }
00497 
00498     std::vector<char>   mOptNameS;
00499     std::vector<String> mOptNameL;
00500     std::vector<String> mOptDefVal;
00501     /* note that the default value is only stored in order to display it, it is
00502        already stored in the value upon creation of the option. see AddOption()*/
00503     std::vector<String> mOptVal;
00504     std::vector<String> mOptParName;
00505     std::vector<String> mOptAlt;
00506     std::vector<bool>   mOptHideUsage;
00507     std::vector<String> mArg;
00508 
00509     ILOG_VAR_DECL;
00510 };
00511 
00512 ILOG_VAR_INIT(CmdOptions, Impala);
00513 
00514 } // namespace Impala
00515 
00516 #endif

Generated on Thu Jan 13 09:03:57 2011 for ImpalaSrc by  doxygen 1.5.1