diff --git a/tools/obabel.cpp b/tools/obabel.cpp index 0989ca267..6f5d6e2ff 100644 --- a/tools/obabel.cpp +++ b/tools/obabel.cpp @@ -25,15 +25,15 @@ GNU General Public License for more details. #include -#include #include +#include #include #if HAVE_CONIO_H - #include +#include #endif #if !HAVE_STRNCASECMP -extern "C" int strncasecmp(const char *s1, const char *s2, size_t n); +extern "C" int strncasecmp(const char* s1, const char* s2, size_t n); #endif #include @@ -43,18 +43,17 @@ using namespace std; using namespace OpenBabel; void DoOption(const char* p, OBConversion& Conv, OBConversion::Option_type typ, - int& arg, int argc, char *argv[]); + int& arg, int argc, char* argv[]); void usage(); void help(); // There isn't a great way to do this -- we need to save argv[0] for usage() namespace { -char *program_name; +char* program_name; } -int main(int argc,char *argv[]) -{ - OBConversion Conv{&cin, &cout}; //default input and output are console +int main(int argc, char* argv[]) { + OBConversion Conv{&cin, &cout}; // default input and output are console OBFormat* pInFormat = nullptr; OBFormat* pOutFormat = nullptr; @@ -64,422 +63,415 @@ int main(int argc,char *argv[]) // Parse commandline bool gotInType = false, gotOutType = false; - bool SplitOrBatch=false; + bool SplitOrBatch = false; - char *oext = nullptr; + char* oext = nullptr; - //Save name of program without its path (and .exe) + // Save name of program without its path (and .exe) string pn{argv[0]}; string::size_type pos; #ifdef _WIN32 pos = pn.find(".exe"); - if(pos!=string::npos) - argv[0][pos]='\0'; + if (pos != string::npos) argv[0][pos] = '\0'; #endif pos = pn.find_last_of("/\\"); - if(pos==string::npos) - program_name=argv[0]; + if (pos == string::npos) + program_name = argv[0]; else - program_name=argv[0]+pos+1; + program_name = argv[0] + pos + 1; const char* p; - for (int arg = 1; arg < argc; ++arg) - { - if (!argv[arg]) - continue; - if (argv[arg][0] != '-') - { - FileList.push_back(argv[arg]); - continue; + for (int arg = 1; arg < argc; ++arg) { + if (!argv[arg]) continue; + if (argv[arg][0] != '-') { + FileList.push_back(argv[arg]); + continue; + } + + char opchar[2] = "?"; + opchar[0] = argv[arg][1]; + switch (opchar[0]) { + case 'V': { + cout << "Open Babel " << BABEL_VERSION << " -- " << __DATE__ << " -- " + << __TIME__ << endl; + return 0; + } + + case 'i': { + // Parameter is the input format which overrides any file extensions + gotInType = true; + char* iext = argv[arg] + 2; + if (!*iext) + iext = argv[++arg]; // space left after -i: use next argument + + if (iext && strncasecmp(iext, "MIME", 4) == 0) { + // get the MIME type from the next argument + iext = argv[++arg]; + pInFormat = Conv.FormatFromMIME(iext); + } else { + pInFormat = Conv.FindFormat(iext); + } + if (pInFormat == nullptr) { + cerr << program_name << ": cannot read input format!" << endl; + usage(); + return 1; + } + break; + } + + case 'o': + // Parameter is the output format which overrides any file extension + gotOutType = true; + oext = argv[arg] + 2; + if (!*oext) + oext = argv[++arg]; // space left after -i: use next argument + + if (oext && strncasecmp(oext, "MIME", 4) == 0) { + // get the MIME type from the next argument + oext = argv[++arg]; + pOutFormat = Conv.FormatFromMIME(oext); + } else { + pOutFormat = Conv.FindFormat(oext); + } + + if (pOutFormat == nullptr) { + cerr << program_name << ": cannot write output format!" << endl; + usage(); + return 1; + } + break; + + case 'O': + OutputFileName = argv[arg] + 2; + if (OutputFileName.empty()) + OutputFileName = + argv[++arg]; // space left after -O: use next argument + break; + + case 'L': { // display a list of plugin type or classes + const char* param = nullptr; + if (argc > arg + 1) param = argv[arg + 2]; + + // First assume first arg is a plugin type and + // param is a subtype, like babel -L ops gen3D + // or first arg is a plugin ID, like babel -L cml + OBPlugin* plugin; + if ((OBPlugin::GetPlugin("plugins", argv[arg + 1]) && + (plugin = OBPlugin::GetPlugin(argv[arg + 1], param))) || + (plugin = OBPlugin::GetPlugin(nullptr, argv[arg + 1]))) { + // Output details of subtype + string txt; + plugin->Display(txt, "verbose", argv[arg + 1]); + cout << "One of the " << plugin->TypeID() << '\n' << txt << endl; + return 0; + } + //...otherwise assume it is a plugin type, like babel -L forcefields + // Output list of subtypes + OBPlugin::List(argv[arg + 1], param); + return 0; + } + + case '?': + case 'H': + if (isalnum(argv[arg][2]) || arg == argc - 2) { + if (strncasecmp(argv[arg] + 2, "all", 3)) { + OBFormat* pFormat = (arg == argc - 2) + ? Conv.FindFormat(argv[arg + 1]) + : Conv.FindFormat(argv[arg] + 2); + if (pFormat) { + cout << argv[arg] + 2 << " " << pFormat->Description() << endl; + if (pFormat->Flags() & NOTWRITABLE) + cout << " This format is Read-only" << endl; + if (pFormat->Flags() & NOTREADABLE) + cout << " This format is Write-only" << endl; + + if (strlen(pFormat->SpecificationURL())) + cout << "Specification at: " << pFormat->SpecificationURL() + << endl; + } else { + cout << "Format type: " << argv[arg] + 2 << " was not recognized" + << endl; } + } else { + OBPlugin::List("formats", "verbose"); + } + } else { + help(); + } + return 0; - char opchar[2]="?"; - opchar[0]=argv[arg][1]; - switch (opchar[0]) - { - - case 'V': - { - cout << "Open Babel " << BABEL_VERSION << " -- " - << __DATE__ << " -- " << __TIME__ << endl; - return 0; - } - - case 'i': - { - //Parameter is the input format which overrides any file extensions - gotInType = true; - char *iext = argv[arg] + 2; - if(!*iext) - iext = argv[++arg]; //space left after -i: use next argument - - if (iext && strncasecmp(iext, "MIME", 4) == 0) - { - // get the MIME type from the next argument - iext = argv[++arg]; - pInFormat = Conv.FormatFromMIME(iext); - } - else - { - pInFormat = Conv.FindFormat(iext); - } - if (pInFormat == nullptr) - { - cerr << program_name << ": cannot read input format!" << endl; - usage(); - return 1; - } - break; - } - - case 'o': - //Parameter is the output format which overrides any file extension - gotOutType = true; - oext = argv[arg] + 2; - if(!*oext) - oext = argv[++arg]; //space left after -i: use next argument - - if (oext && strncasecmp(oext, "MIME", 4) == 0) - { - // get the MIME type from the next argument - oext = argv[++arg]; - pOutFormat = Conv.FormatFromMIME(oext); - } - else - { - pOutFormat = Conv.FindFormat(oext); - } - - if (pOutFormat == nullptr) - { - cerr << program_name << ": cannot write output format!" << endl; - usage(); - return 1; - } - break; - - case 'O': - OutputFileName = argv[arg] + 2; - if(OutputFileName.empty()) - OutputFileName = argv[++arg]; //space left after -O: use next argument - break; - - case 'L': //display a list of plugin type or classes - { - const char* param = nullptr; - if(argc>arg+1) - param = argv[arg+2]; - - // First assume first arg is a plugin type and - // param is a subtype, like babel -L ops gen3D - // or first arg is a plugin ID, like babel -L cml - OBPlugin* plugin; - if ((OBPlugin::GetPlugin("plugins", argv[arg+1]) && - (plugin = OBPlugin::GetPlugin(argv[arg+1], param))) || - (plugin = OBPlugin::GetPlugin(nullptr, argv[arg+1]))) - { - //Output details of subtype - string txt; - plugin->Display(txt, "verbose", argv[arg+1]); - cout << "One of the " << plugin->TypeID() << '\n' << txt << endl; - return 0; - } - //...otherwise assume it is a plugin type, like babel -L forcefields - //Output list of subtypes - OBPlugin::List(argv[arg+1], param); - return 0; - } - - case '?': - case 'H': - if(isalnum(argv[arg][2]) || arg==argc-2) - { - if(strncasecmp(argv[arg]+2,"all",3)) - { - OBFormat* pFormat - = (arg==argc-2) ? Conv.FindFormat(argv[arg+1]) : Conv.FindFormat(argv[arg]+2); - if(pFormat) - { - cout << argv[arg]+2 << " " << pFormat->Description() << endl; - if(pFormat->Flags() & NOTWRITABLE) - cout << " This format is Read-only" << endl; - if(pFormat->Flags() & NOTREADABLE) - cout << " This format is Write-only" << endl; - - if(strlen(pFormat->SpecificationURL())) - cout << "Specification at: " << pFormat->SpecificationURL() << endl; - } - else - { - cout << "Format type: " << argv[arg]+2 << " was not recognized" < tempFileList{FileList}; FileList.clear(); - for(const auto& f : tempFileList) - { - if(f[0]=='-') + for (const auto& f : tempFileList) { + if (f[0] == '-') FileList.push_back(f); else - DLHandler::findFiles (FileList, f); + DLHandler::findFiles(FileList, f); } #endif - if (!gotInType && FileList.empty()) - { - cerr << "No input file or format spec or possibly a misplaced option.\n" - "Most options must come after the input files. (-i -o -O -m can be anywhwere.)\n" <1) - { - clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] < 1) { + clog << OutputFileList.size() << " files output. The first is " + << OutputFileList[0] << endl; + } - //std::string messageSummary = obErrorLog.GetMessageSummary(); - //if (messageSummary.size()) + // std::string messageSummary = obErrorLog.GetMessageSummary(); + // if (messageSummary.size()) // { // clog << messageSummary << endl; // } #ifdef _DEBUG - //CM keep window open - cout << "Press any key to finish" <] [-o] -O [Options]" << endl; + cout << "Usage:\n" + << program_name + << " [-i] [-o] -O " + "[Options]" + << endl; cout << "Try -H option for more information." << endl; #ifdef _DEBUG - //CM keep window open - cout << "Press any key to finish" <] [-o] -O [Options]" << endl; - cout << "The extension of a file decides the format, unless it is overridden" <] [-o] -O " + "[Options]" + << endl; + cout << "The extension of a file decides the format, unless it is overridden" + << endl; cout << " by -i or -o options, e.g. -icml, or -o smi" << endl; - cout << "See below for available format-types, which are the same as the " << endl; + cout << "See below for available format-types, which are the same as the " + << endl; cout << "file extensions and are case independent." << endl; - cout << "If no input or output file is given stdin or stdout are used instead." << endl << endl; - cout << "More than one input file can be specified and their names can contain" < Lists plugin classes of this category, e.g. " << endl; + cout << "-Hxxx (xxx is file format ID e.g. -Hcml) gives format info" << endl; + cout << "-Hall Outputs details of all formats" << endl; + cout << "-V Outputs version number" << endl; + cout << "-L Lists plugin classes of this category, e.g. " + << endl; cout << " Use just -L for a list of plugin categories." << endl; - cout << " Use -L e.g. -L sdf for details of a format or other plugin." << endl; - cout << "-m Produces multiple output files, to allow:" < e.g. -L sdf for details of a format or other plugin." + << endl; + cout << "-m Produces multiple output files, to allow:" << endl; + cout << " Splitting: e.g. " << program_name + << " infile.mol -O new.smi -m" << endl; + cout << " puts each molecule into new1.smi new2.smi etc" << endl; + cout << " Batch conversion: e.g. " << program_name << " *.mol -osmi -m" + << endl; cout << " converts each input file to a .smi file" << endl; #ifdef _WIN32 - cout << " In Windows these can also be done using the forms" <TargetClassDescription();// some more options probably for OBMol + if (pDefault) + // some more options probably for OBMol + cout << pDefault->TargetClassDescription(); - OBFormat* pAPI= OBConversion::FindFormat("obapi"); - if(pAPI) - cout << pAPI->Description(); + OBFormat* pAPI = OBConversion::FindFormat("obapi"); + if (pAPI) cout << pAPI->Description(); - cout << "To see a list of recognized file formats use\n obabel -L formats [read] [write]\n" - << "To see details and specific options for a particular format, e.g CML, use\n obabel -L cml\n" + cout << "To see a list of recognized file formats use\n" + " obabel -L formats [read] [write]\n" + << "To see details and specific options for a particular format, e.g " + "CML, use\n obabel -L cml\n" << endl; - //cout << "The following file formats are recognized:" << endl; - //OBPlugin::List("formats"); - //cout << "\nSee further specific info and options using -H, e.g. -Hcml" << endl; + // cout << "The following file formats are recognized:" << endl; + // OBPlugin::List("formats"); + // cout << "\nSee further specific info and options using -H, " + // "e.g. -Hcml" << endl; } /* OpenBabel man page*/