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

Generated on Fri Mar 19 09:30:41 2010 for ImpalaSrc by  doxygen 1.5.1