|
// // Command line option manager // // // $Id: BrAppOptionManager.cxx,v 1.8 2002/04/23 15:18:30 hagel Exp $ // $Author: hagel $ // $Date: 2002/04/23 15:18:30 $ // $Copyright: BRAHMS Collaboration 2000 // #include <cstring> #include <cstdlib> #include <BrIostream.h> #include <TString.h> #include <TObject.h> #include <TObjArray.h> #include <THashTable.h> #include <THashList.h> #include <TSystem.h> #include <BrAppOption.h> #include <BrAppOptionManager.h> #ifdef BR_USE_EXCEPTIONS #undef BR_USE_EXCEPTIONS #endif #ifdef BR_USE_EXCEPTIONS #include <BrException.h> #endif //_____________________________________________________________________ ClassImp(BrAppOptionManager); // Options class BrAppOptionManager* BrAppOptionManager::fgInstance = 0; //_____________________________________________________________________ BrAppOptionManager::BrAppOptionManager() { // Constructor. // First two arguments are the major and version of this // application. third is the version string, and fourth is the help // string. // Set the default values SetHelp(); SetVersion(); fArgv = 0; fArgc = 0; fIsOk = kTRUE; fHasParsed = kFALSE; // initialize internal table fTable = new THashList(10); // AddOption(fHelpOption); // AddOption(fVersionOption); } //_____________________________________________________________________ BrAppOptionManager* BrAppOptionManager::Instance() { if (!fgInstance) { fgInstance = new BrAppOptionManager; fgInstance->AddHelpVersion(); } return fgInstance; } //_____________________________________________________________________ void BrAppOptionManager::AddHelpVersion() { // Set the two default otptions fHelpOption = new BrAppBoolOption('h', "help", "Show this help",kFALSE); fVersionOption = new BrAppBoolOption('V', "version", "Version number",kFALSE); } //_____________________________________________________________________ void BrAppOptionManager::AddOption(BrAppOption* option, Bool_t internal) { // Add an option to the manager if (!internal) { Warning("AddOption", "options now add them selves to the manager, " "please remove the message BrAppOptionManager::AddOption " "from your script or program. This method will soon " "become private, and should not be used."); return; } fTable->Add(option); } //_____________________________________________________________________ void BrAppOptionManager::SetCommandLine(Int_t& argc, Char_t** argv) { // if (fArgv) { Error("SetCommandLine", "you can only set the command line once"); return; } fArgc = &argc; fArgv = argv; } //_____________________________________________________________________ void BrAppOptionManager::SetHelp(const Char_t* helpString) { // Set the help string // Set help string if (!helpString) fHelpString = "n"; else fHelpString = helpString; } //_____________________________________________________________________ void BrAppOptionManager::SetVersion(Int_t major, Int_t minor, const Char_t* versionString) { // Set the help string fMajorVersion = major; fMinorVersion = minor; if (versionString) fVersionString = versionString; else fVersionString = ""; } //_____________________________________________________________________ BrAppOption* BrAppOptionManager::GetOption(Char_t option) { // Get the BrAppOption with short name 'option' TIter next(fTable); BrAppOption* opt; while ((opt = (BrAppOption*)next())) { if (opt->GetShortName() == option) return opt; } return 0; } //_____________________________________________________________________ BrAppOption* BrAppOptionManager::GetOption(Char_t* option) { // Get the BrAppOption with long name "option" // TIter next(fTable); // BrAppOption* opt; // while ((opt = (BrAppOption*)next())) { // if (strcmp(opt->GetLongName(),option) == 0) // return opt; // } return (BrAppOption*)fTable->FindObject(option); } //_____________________________________________________________________ void BrAppOptionManager::SetOptionValue(Char_t option, Char_t* value) { // Set the value of the option with short name 'option' BrAppOption* opt = GetOption(option); if (!opt) { #ifdef BR_USE_EXCEPTIONS throw new BrError("BrAppOptionManager::SetOptionValue", "No such option: -%c", option); #else Error("SetOptionValue", "No such option: -%c", option); return; #endif } opt->SetValue(value); } //_____________________________________________________________________ void BrAppOptionManager::SetOptionValue(Char_t* option, Char_t* value) { // Set the value of the option with long name "option" BrAppOption* opt = GetOption(option); if (!opt) { #ifdef BR_USE_EXCEPTIONS throw new BrError("BrAppOptionManager::SetOptionValue", "No such option: --%s", option); #else Error("SetOptionValue", "No such option: -%c", option); return; #endif } opt->SetValue(value); } //_____________________________________________________________________ Bool_t BrAppOptionManager::ProcessCommandLine() { // Process command line parameters. If this class was compiled with // exceptions enabled, then a BrException is thrown in case of // errors. If it wasn't compiled with exceptions enabled, it returns // kFALSE in case of errors. if (!fArgc) { Error("ProcessCommandLine", "command line not set"); return kFALSE; } fProgName = gSystem->BaseName(fArgv[0]); // Sort hash list fTable->Sort(); // Assume success fIsOk = kTRUE; // Flag the manager as having done it's stuff fHasParsed = kFALSE; // Needed for Micros**t Visual C++ non-ANSI behaviour - God that is // soooo annoying Int_t i = 0; Int_t j = 0; for (i = 1; i < *fArgc; i++) { // See if we got an option if (fArgv[i][0] == '-') { // See if we got a long option Bool_t killNext = kFALSE; if (!fArgv[i][1] || fArgv[i][1] == '0') continue; if (fArgv[i][1] == '-') { if (!ProcessLongOption(fArgv[i]+2)) fIsOk = kFALSE; } else { Int_t len = strlen(fArgv[i]); for (Int_t j = 1; j < len; j++) { // if we got a short option, get the option if (!ProcessShortOption(fArgv[i][j],killNext, fArgv[i+1])) { fIsOk = kFALSE; break; } if (killNext) { if (fArgv[i][j+1] != '0') { #ifdef BR_USE_EXCEPTIONS throw new BrError("BrAppOptionManager::ProcessCommandLine", "Option -%c need an argument. Try\n\t%s --help", fArgv[i][j],fProgName.Data()); #else Error("ProcessCommandLine", "short options can not follow option -%c that " "need an argument.", fArgv[i][j]); fIsOk = kFALSE; break; #endif } // if (fArgv[i][j+1] != '\0') break; } // if (killNext) } // for (j = 1; j < len; j++) } // if (fArgv[i][1] == '-') ... else // Set the command line argument to zero, so that it's ignored // hereafter fArgv[i] = 0; if (killNext) fArgv[++i] = 0; } // if (fArgv[i][0] == '-') if (!fIsOk) break; } // for (i = 1; i < *fArgc; i++) for (i = 0; i < *fArgc; i++) { if (fArgv[i]) fArgv[j++] = fArgv[i]; } *fArgc = j; fArgv[*fArgc] = 0; return fIsOk; } //_____________________________________________________________________ Bool_t BrAppOptionManager::ProcessLongOption(Char_t* argument) { // Deal with long options of the form "--<option>=<value>". For // Boolean typed options, the form is "--<option>" // Put the full long argument into a string object. TString* arg = new TString(argument); if (!arg) { #ifdef BR_USE_EXCEPTIONS throw new BrError("BrAppOptionManager::ProcessLongOption", "Unknown option --%s. Try\n\t%s --help", argument, fProgName.Data()); #else Error("ProcessLongOption", "Unknown option --%s. Try\n\t%s --help", argument, fProgName.Data()); return kFALSE; #endif } // Find the equal sign Ssiz_t eqPos = arg->Index("="); // Get the option name TString* opt = 0; if (eqPos == kNPOS) opt = arg; else opt = new TString(arg->Data(),eqPos); if (!opt || opt->IsNull()) { #ifdef BR_USE_EXCEPTIONS throw new BrError("BrAppOptionManager::ProcessLongOption", "Invalid option --%s. Try\n\t%s --help", arg->Data(), fProgName.Data()); #else Error("ProcessLongOption", "Invalid option --%s. Try\n\t%s --help", arg->Data(), fProgName.Data()); return kFALSE; #endif } // Get the option BrAppOption* option = GetOption((Char_t*)opt->Data()); if (!option) { #ifdef BR_USE_EXCEPTIONS throw new BrError("BrAppOptionManager::ProcessLongOption", "Unknown option --%s. Try\n\t%s --help", opt->Data(), fProgName.Data()); #else Error("ProcessLongOption", "Unknown option --%s. Try\n\t%s --help", arg->Data(), fProgName.Data()); return kFALSE; #endif } // Figure out the value passed if (option->NeedValue() && eqPos == kNPOS) { #ifdef BR_USE_EXCEPTIONS throw new BrError("BrAppOptionManager::ProcessLongOption", "Option --%s need an argument. Try\n\t%s --help", opt->Data(), fProgName.Data()); #else Error("ProcessLongOption", "Option --%s need an argument. Try\n\t%s --help", opt->Data(), fProgName.Data()); return kFALSE; #endif } TString* val = new TString((*arg)(eqPos+1,256)); // Finally, set the option to value. return option->SetValue((Char_t*)val->Data()); } //_____________________________________________________________________ Bool_t BrAppOptionManager::ProcessShortOption(Char_t option, Bool_t& killNext, Char_t* value) { // Process short options. These are of the form "-<option> <val>" or // in the case of boolean flags "-<option>" // Get the option BrAppOption* opt = GetOption(option); if (!opt) { #ifdef BR_USE_EXCEPTIONS throw new BrWarning("BrAppOptionManager::ProcessShortOption", "Unknown option %c. Try\n\t%s --help", option, fProgName.Data()); #else Error("ProcessShortOption", "Unknown option %c. Try\n\t%s --help", option, fProgName.Data()); return kFALSE; #endif } if (!opt->SetValue(value)) return kFALSE; if (opt->NeedValue()) { // We need to remove the next argument killNext = kTRUE; } return kTRUE; } //_____________________________________________________________________ void BrAppOptionManager::Print(Option_t* option="") const { // Print the list of options TIter next(fTable); BrAppOption* opt; while ((opt = (BrAppOption*)next())) opt->Print(); } //_____________________________________________________________________ Bool_t BrAppOptionManager::ShowHelp(void) { // Show the help screen if either "-h" or "--help" was on the // command line. Return true if so, otherwise false if (!fHelpOption->operator Bool_t()) return kFALSE; cout << "Usage: " << fProgName.Data() << " [options] " << fHelpString.Data() << endl << "Options:" << endl; TIter next(fTable); BrAppOption* opt; cout.setf(ios::left); while ((opt = (BrAppOption*)next())) opt->Print(); return kTRUE; } //_____________________________________________________________________ Bool_t BrAppOptionManager::ShowVersion(void) { // Show the version screen if either "-V" or "--version" was on the // command line. Return true if so, otherwise false if (!fVersionOption->operator Bool_t()) return kFALSE; cout << fProgName.Data() << " Version " << fMajorVersion << "." << fMinorVersion << " " << fVersionString.Data() << endl; return kTRUE; } // $Log: BrAppOptionManager.cxx,v $ // Revision 1.8 2002/04/23 15:18:30 hagel // Add return to BrAppStringOption::SetValue // // Revision 1.7 2001/12/14 15:28:19 cholm // BrAppOption sublcasses now adds them selves to BrAppOptionManager // automatically. Also, the int, float, and string option class can now // hold multiple values. It's all fairly well documented in 'The Guide'. // // Revision 1.6 2001/08/21 14:25:24 cholm // Added member fHasParsed, so that we can check if we've parsed the // commandline. Not really needed now, but I left it in anyway. No real // harm in that. // // Revision 1.5 2001/07/30 19:28:29 cholm // Made a fix that allows scripts using no options to perform anyway. // // Revision 1.4 2001/07/29 15:08:00 cholm // Fixed problem with negative numbers parsed to a short option. // // Revision 1.3 2001/07/29 14:39:40 cholm // Removed Djamel's "fix" which made it impossible to use long options. // That was very VERY bad, since the CRS software ONLY uses the long form // of command line options. I'm looking into the problem he reported // now. In the mean time, do not use BRAT-2-0-16 on the farm since it'll // not work! // // Revision 1.2 2001/07/27 10:20:23 ouerdane // Added a check in ProcessCommandLine in the case you want to pass negative // numbers (eg. -p -4.5) since so far, it was confused with an option because // of the negative sign. // // Revision 1.1.1.1 2001/06/21 14:55:15 hagel // Initial revision of brat2 // // Revision 1.4 2001/03/07 12:15:41 cholm // * Defined standard BrModule methods in BrIOModule. // * Add the (simple) class BrHistIOModule. // * BrAppOptionManager and BrAppOption classes changed to not use // BrExceptions. // * Added the method Int_t BrMainModule::Main() to do EVERYTHING. // * Made the method BrModule::Info() const obsolete in favour of // BrModule::Print(Option_t* option="B") const. Impact on other classes. // // Revision 1.3 2000/09/04 13:38:33 videbaek // Use BrIostream.h to facilitate different iostream conventions. // // Revision 1.2 2000/06/13 17:12:21 alv // ProcessCommandLine // Added argv[argc]=0 // // Revision 1.1 2000/04/06 20:17:43 cholm // Added the classes BrAppOption, BrAppOptionManager, and // BrDetectorList. The first two are for command line processing, // the third for easy detector list, can be used for many purposes. // // |
||||||
This page automatically generated by script docBrat by Christian Holm |
Copyright ; 2002 BRAHMS Collaboration
<brahmlib@rcf.rhic.bnl.gov>
|