int main(int argc,char *argv[]) { OBConversion Conv(&cin, &cout); //default input and output are console OBFormat* pInFormat = NULL; OBFormat* pOutFormat = NULL; vector<string> FileList, OutputFileList; string OutputFileName; // Parse commandline bool gotInType = false, gotOutType = false; bool SplitOrBatch=false; char *oext = NULL; char *iext = NULL; //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'; #endif pos = pn.find_last_of("/\\"); if(pos==string::npos) program_name=argv[0]; else program_name=argv[0]+pos+1; const char* p; int arg; for (arg = 1; arg < argc; ++arg) { if (argv[arg]) { if (argv[arg][0] == '-') { char opchar[2]="?"; opchar[0]=argv[arg][1]; switch (opchar[0]) { case 'V': { cout << "Open Babel " << BABEL_VERSION << " -- " << __DATE__ << " -- " << __TIME__ << endl; exit(0); } case 'i': //Parameter is the input format which overrides any file extensions gotInType = true; iext = argv[arg] + 2; if(!*iext) iext = argv[++arg]; //space left after -i: use next argument if (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==NULL) { cerr << program_name << ": cannot read input format!" << endl; usage(); } 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 (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==NULL) { cerr << program_name << ": cannot write output format!" << endl; usage(); } break; case 'O': OutputFileName = argv[arg] + 2; if(OutputFileName.size()<3) OutputFileName = argv[++arg]; //space left after -O: use next argument break; case 'L': //display a list of plugin type or classes { const char* param=NULL; 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(NULL, 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; case '-': //long option --name text { //Option's text is in the next and subsequent args, until one starts with - char* nam = argv[arg]+2; if(!strcasecmp(nam, "help")) //special case handled here { help(); return 0; } if(*nam != '\0') //Do nothing if name is empty { string txt; while(arg<argc-1 && *argv[arg+1]!='-') { //use text from subsequent args if(!txt.empty())txt += ' '; //..space separated if more than one txt += argv[++arg]; } // If a API directive, e.g.---errorlevel // send to the pseudoformat "obapi" (without any leading -) if(*nam=='-') { OBConversion apiConv; OBFormat* pAPI= OBConversion::FindFormat("obapi"); if(pAPI) { apiConv.SetOutFormat(pAPI); apiConv.AddOption(nam+1, OBConversion::GENOPTIONS, txt.c_str()); apiConv.Write(NULL, &std::cout); } } else // Is a normal long option name, e.g --addtotitle Conv.AddOption(nam,OBConversion::GENOPTIONS,txt.c_str()); } } break; case 'm': //multiple output files SplitOrBatch=true; break; case 'a': //single character input option p = argv[arg]+2; DoOption(p,Conv,OBConversion::INOPTIONS,arg,argc,argv); break; case 'x': //single character output option p = argv[arg]+2; DoOption(p,Conv,OBConversion::OUTOPTIONS,arg,argc,argv); break; //Not essential, but allows these options to be before input filenames //since we know they take one parameter, and are the most likely options to be misplaced case 'f': case 'l': p = argv[arg] + 2; if(!*p) p = argv[++arg]; //space left after -f: use next argument Conv.AddOption(opchar, OBConversion::GENOPTIONS, p); break; case ':': //e.g. -:c1ccccc1. SMILES passed as a file name and handled in OBConversion FileList.push_back(argv[arg]); break; default: //single character general option p = argv[arg]+1; DoOption(p,Conv,OBConversion::GENOPTIONS,arg,argc,argv); break; } } else //filenames FileList.push_back(argv[arg]); } } #ifdef _WIN32 //Expand wildcards in input filenames and add to FileList vector<string> tempFileList(FileList); FileList.clear(); vector<string>::iterator itr; for(itr=tempFileList.begin();itr!=tempFileList.end();++itr) { if((*itr)[0]=='-') FileList.push_back(*itr); else DLHandler::findFiles (FileList, *itr); } #endif if (!gotInType) { if(FileList.empty()) { cerr << "No input file or format spec or possibly a misplaced option.\n" "Options, other than -i -o -O -m, must come after the input files.\n" <<endl; usage(); } } if (!gotOutType) { //check there is a valid output format, but the extension will be re-interpreted in OBConversion pOutFormat = Conv.FormatFromExt(OutputFileName.c_str()); if(OutputFileName.empty() || pOutFormat==NULL) { cerr << "Missing or unknown output file or format spec or possibly a misplaced option.\n" "Options, other than -i -o -O -m, must come after the input files.\n" <<endl; usage(); } } if(!Conv.SetInFormat(pInFormat)) { cerr << "Invalid input format" << endl; usage(); } if(!Conv.SetOutFormat(pOutFormat)) { cerr << "Invalid output format" << endl; usage(); } if(SplitOrBatch) { //Put * into output file name before extension (or ext.gz) if(OutputFileName.empty()) { OutputFileName = "*."; OutputFileName += oext; } else { string::size_type pos = OutputFileName.rfind(".gz"); if(pos==string::npos) pos = OutputFileName.rfind('.'); else pos = OutputFileName.rfind('.',pos-1); if(pos==string::npos) OutputFileName += '*'; else OutputFileName.insert(pos,"*"); } } int count = Conv.FullConvert(FileList, OutputFileName, OutputFileList); Conv.ReportNumberConverted(count); if(OutputFileList.size()>1) { clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl; } //std::string messageSummary = obErrorLog.GetMessageSummary(); //if (messageSummary.size()) // { // clog << messageSummary << endl; // } #ifdef _DEBUG //CM keep window open cout << "Press any key to finish" <<endl; getch(); #endif return 0; }
int main(int argc,char *argv[]) { OBConversion Conv(&cin, &cout); //default input and output are console OBFormat* pInFormat = NULL; OBFormat* pOutFormat = NULL; bool inGzip = false; bool outGzip = false; vector<string> FileList, OutputFileList; string OutputFileName; // Parse commandline bool gotInType = false, gotOutType = false; bool SplitOrBatch=false; char *oext = NULL; char *iext = NULL; //load plugs to fully initialize option parameters OBPlugin::LoadAllPlugins(); //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'; #endif pos = pn.find_last_of("/\\"); if(pos==string::npos) program_name=argv[0]; else program_name=argv[0]+pos+1; const char* p; int arg; for (arg = 1; arg < argc; ++arg) { if (argv[arg]) { if (argv[arg][0] == '-') { switch (argv[arg][1]) { case 'V': { cout << "Open Babel " << BABEL_VERSION << " -- " << __DATE__ << " -- " << __TIME__ << endl; exit(0); } case 'i': gotInType = true; iext = argv[arg] + 2; if(!*iext) iext = argv[++arg]; //space left after -i: use next argument if (strncasecmp(iext, "MIME", 4) == 0) { // get the MIME type from the next argument iext = argv[++arg]; pInFormat = Conv.FormatFromMIME(iext); } else { //The ID provided by the OBFormat class is used as the identifying file extension pInFormat = Conv.FindFormat(iext); } if(pInFormat==NULL) { cerr << program_name << ": cannot read input format!" << endl; usage(); } break; case 'o': gotOutType = true; oext = argv[arg] + 2; if(!*oext) oext = argv[++arg]; //space left after -i: use next argument if (arg >= argc) usage(); // error in parsing command-line if (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==NULL) { cerr << program_name << ": cannot write output format!" << endl; usage(); } break; case 'L': //display a list of plugin type or classes { const char* param=NULL; 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(NULL, 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)) { const char* pID= (arg==argc-2) ? argv[arg+1] : argv[arg]+2; OBFormat* pFormat = Conv.FindFormat(pID); if(pFormat) { cout << pID << " " << 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: " << pID << " was not recognized" <<endl; } else { OBPlugin::List("formats","verbose"); } } else help(); return 0; case '-': //long option --name text { //Do nothing if name is empty //Option's text is the next arg provided it doesn't start with - char* nam = argv[arg]+2; if(*nam != '\0') { string txt; int i; for(i=0; i<Conv.GetOptionParams(nam, OBConversion::GENOPTIONS) && arg<argc-1 && argv[arg+1];++i) //removed && *argv[arg+1]!='-' { if(!txt.empty()) txt+=' '; txt += argv[++arg]; } if(*nam=='-') { // Is a API directive, e.g.---errorlevel //Send to the pseudoformat "obapi" (without any leading -) OBConversion apiConv; OBFormat* pAPI= OBConversion::FindFormat("obapi"); if(pAPI) { apiConv.SetOutFormat(pAPI); apiConv.AddOption(nam+1, OBConversion::GENOPTIONS, txt.c_str()); apiConv.Write(NULL, &std::cout); } } else // Is a long option name, e.g --addtotitle Conv.AddOption(nam,OBConversion::GENOPTIONS,txt.c_str()); } } break; case 'm': //multiple output files SplitOrBatch=true; break; case 'a': //single character input option p = argv[arg]+2; DoOption(p,Conv,OBConversion::INOPTIONS,arg,argc,argv); break; case 'x': //single character output option p = argv[arg]+2; DoOption(p,Conv,OBConversion::OUTOPTIONS,arg,argc,argv); break; default: //single character general option p = argv[arg]+1; DoOption(p,Conv,OBConversion::GENOPTIONS,arg,argc,argv); break; } } else { //filenames if(!gotOutType) FileList.push_back(argv[arg]); else OutputFileName = argv[arg]; } } } if(!gotOutType) //the last file is the output { if(FileList.empty()) { cerr << "No output file or format spec!" << endl; usage(); } OutputFileName = FileList.back(); FileList.pop_back(); } #if defined(_WIN32) && defined(USING_DYNAMIC_LIBS) //Expand wildcards in input filenames and add to FileList vector<string> tempFileList(FileList); FileList.clear(); vector<string>::iterator itr; for(itr=tempFileList.begin();itr!=tempFileList.end();++itr) DLHandler::findFiles (FileList, *itr); #endif if (!gotInType) { if(FileList.empty()) { cerr << "No input file or format spec!" <<endl; usage(); } } if (!gotOutType) { pOutFormat = Conv.FormatFromExt(OutputFileName.c_str(), outGzip); if(pOutFormat==NULL) { cerr << program_name << ": cannot write output format!" << endl; usage(); } } if(!Conv.SetInFormat(pInFormat)) { cerr << "Invalid input format" << endl; usage(); } if(!Conv.SetOutFormat(pOutFormat, outGzip)) { cerr << "Invalid output format" << endl; usage(); } if(SplitOrBatch) { //Put * into output file name before extension (or ext.gz) if(OutputFileName.empty()) { OutputFileName = "*."; if (oext != NULL) OutputFileName += oext; } else { string::size_type pos = OutputFileName.rfind(".gz"); if(pos==string::npos) pos = OutputFileName.rfind('.'); else pos = OutputFileName.rfind('.',pos-1); if(pos==string::npos) OutputFileName += '*'; else OutputFileName.insert(pos,"*"); } } int count = Conv.FullConvert(FileList, OutputFileName, OutputFileList); Conv.ReportNumberConverted(count); if(OutputFileList.size()>1) { clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl; } std::string messageSummary = obErrorLog.GetMessageSummary(); if (messageSummary.size()) { clog << messageSummary << endl; } #ifdef _DEBUG //CM keep window open cout << "Press any key to finish" <<endl; getch(); #endif return 0; }