00001
00002
00003
00004
00005
00006
00007
00009 #include <iostream>
00010 #include <iomanip>
00011 #include <fstream>
00012 #include <string>
00013 #include <vector>
00014 #include "Util/UtilString.h"
00015
00017
00018
00019 class ConfigParam {
00020 public:
00021 ConfigParam() : fName(""), fType(""), fValue("") { }
00022 public:
00023 std::string fName;
00024 std::string fType;
00025 std::string fValue;
00026 };
00027 typedef std::vector<ConfigParam> ModuleConfig;
00028
00029
00031
00032
00033 class ModuleOptions {
00034 public:
00035 ModuleOptions() :
00036 fPackageName(""), fClassName(""), fModuleName(""),
00037 fDescription(""), fEmailAddr(""),
00038 fNeedAna(false), fNeedReco(false), fNeedBeginJob(false),
00039 fNeedEndJob(false), fNeedBeginFile(false), fNeedEndFile(false),
00040 fNeedBeginRun(false), fNeedEndRun(false), fNeedGet(false),
00041 fNeedPut(false), fNeedConfig(false), fNeedHelp(false),
00042 fNeedReport(false), fNeedReset(false), fNeedHandleCommand(false),
00043 fNeedMsg(false), fPackagePrefix("")
00044 { }
00045 public:
00046 std::string fPackageName;
00047 std::string fClassName;
00048 std::string fModuleName;
00049 std::string fDescription;
00050 std::string fEmailAddr;
00051
00052 bool fNeedAna;
00053 bool fNeedReco;
00054 bool fNeedBeginJob;
00055 bool fNeedEndJob;
00056 bool fNeedBeginFile;
00057 bool fNeedEndFile;
00058 bool fNeedBeginRun;
00059 bool fNeedEndRun;
00060 bool fNeedGet;
00061 bool fNeedPut;
00062
00063 bool fNeedConfig;
00064
00065 bool fNeedHelp;
00066 bool fNeedReport;
00067 bool fNeedReset;
00068 bool fNeedHandleCommand;
00069
00070 bool fNeedMsg;
00071 std::string fPackagePrefix;
00072 };
00073
00074
00075
00076 static bool yn_querry(const char* t, bool deflt)
00077 {
00078
00079
00080
00081
00082 if (deflt) std::cout << t << "[y] : " << std::flush;
00083 else std::cout << t << "[n] : " << std::flush;
00084
00085 std::string s;
00086 getline(std::cin,s);
00087
00088 if (s=="y" || s=="Y" || s=="yes" || s=="YES") return true;
00089 if (s=="n" || s=="N" || s=="no" || s=="NO") return false;
00090
00091 return deflt;
00092 }
00093
00094
00095
00096 static std::string str_querry(const char* t, const char* deflt)
00097 {
00098
00099
00100
00101
00102 if (deflt==0 || deflt=="") std::cout << t << " : ";
00103 else std::cout << t << "[" << deflt << "] :";
00104 std::cout << std::flush;
00105
00106 std::string s;
00107 getline(std::cin, s);
00108
00109 return s;
00110 }
00111
00112
00113
00114 static void setupNames(ModuleOptions& m)
00115 {
00116
00117
00118
00119 m.fClassName =str_querry("Class name",0);
00120 m.fPackageName=str_querry("Package name",0);
00121 m.fModuleName =str_querry("Human readable name of the module",0);
00122 m.fDescription=str_querry("Short description of what the module does",0);
00123 m.fEmailAddr =str_querry("Your e-mail address",0);
00124 }
00125
00126
00127
00128 static void setupMethods(ModuleOptions& m)
00129 {
00130
00131
00132
00133 std::cout << "Which methods do you need? (Select [y/n])"<<std::endl;
00134 m.fNeedAna = yn_querry(" Ana() ? ", true);
00135 m.fNeedReco = yn_querry(" Reco() ? ", true);
00136 m.fNeedBeginJob = yn_querry(" BeginJob() ? ", true);
00137 m.fNeedEndJob = yn_querry(" EndJob() ? ", false);
00138 m.fNeedBeginFile = yn_querry(" BeginFile() ? ", false);
00139 m.fNeedEndFile = yn_querry(" EndFile() ? ", false);
00140 m.fNeedBeginRun = yn_querry(" BeginRun() ? ", false);
00141 m.fNeedEndRun = yn_querry(" EndRun() ? ", false);
00142 m.fNeedGet = yn_querry(" Get() ? ", false);
00143 m.fNeedPut = yn_querry(" Put() ? ", false);
00144 m.fNeedHelp = yn_querry(" Help() ? ", false);
00145 m.fNeedReport = yn_querry(" Report() ? ", false);
00146 m.fNeedReset = yn_querry(" Reset() ? ", false);
00147 m.fNeedHandleCommand = yn_querry(" HandleCommand() ? ", false);
00148 }
00149
00150
00151
00152 static void setupServices(ModuleOptions& m)
00153 {
00154
00155
00156
00157 m.fNeedMsg = yn_querry("Do you plan to use the MessageService? ",true);
00158 if (m.fNeedMsg) {
00159 m.fPackagePrefix = str_querry(" What's the package prefix? ",0);
00160 }
00161 }
00162
00163
00164
00165 static void parseCfg(std::string str, ConfigParam& p)
00166 {
00167
00168
00169
00170
00171 std::string name;
00172 std::string value;
00173 const char* s = str.c_str();
00174 const char* c;
00175
00176 name = "";
00177 value = "";
00178 bool passedEqual = false;
00179 for (c=s; *c!='\0'; ++c) {
00180 switch (*c) {
00181 case '=': passedEqual = true; break;
00182 case ' ': continue; break;
00183 default:
00184 if (passedEqual) value += *c;
00185 else name += *c;
00186 }
00187 }
00188 p.fName = name;
00189 p.fValue = value;
00190
00191
00192 s = p.fValue.c_str();
00193 p.fType = "string";
00194 if (UtilString::IsBool(s)) { p.fType = "bool"; }
00195 if (UtilString::IsFloat(s)) { p.fType = "float"; }
00196 if (UtilString::IsInt(s)) { p.fType = "int"; }
00197 }
00198
00199
00200
00201 static void setupConfig(ModuleOptions& m, ModuleConfig& cfg)
00202 {
00203
00204
00205
00206 m.fNeedConfig =
00207 yn_querry("Do you want to set up the module's configuration parameters? ",
00208 true);
00209 if (m.fNeedConfig == false) {
00210 return;
00211 }
00212
00213 std::cout << " Enter parameter list following these examples:"<<std::endl;
00214 std::cout << " bool parameter: > DoTest = true"<<std::endl;
00215 std::cout << " int parameter: > NhitMax = 20"<<std::endl;
00216 std::cout << " real parameter: > ChiSqrCut = 10.0"<<std::endl;
00217 std::cout << " string parameter: > UseStream = DaqSnarl"<<std::endl;
00218 std::cout << " Enter 'q' to end\n";
00219
00220 bool more = true;
00221 std::string s;
00222 while (more) {
00223 s = str_querry("[name = default_value] ",0);
00224 if (s == "q" || s == "Q" || s=="" || s==" ") {
00225 more = false;
00226 }
00227 else {
00228 ConfigParam p;
00229 parseCfg(s,p);
00230 cfg.push_back(p);
00231 }
00232 }
00233 }
00234
00235
00236
00237 static const char* gsDocComment =
00238 "
00239
00240 static const char* gsSlashDivider =
00241 "
00242
00243 static const char* gsEqualsDivider =
00244 "
00245
00246 static const char* gsDotDivider =
00247 "
00248
00249
00250
00251 static void write_h(const ModuleOptions& m,ModuleConfig& cfg)
00252 {
00253
00254
00255
00256 std::string filename = m.fClassName;
00257 filename += ".h";
00258 std::ofstream ofs(filename.c_str());
00259
00260 std::string inc_tag = UtilString::ToUpper(m.fClassName);
00261 inc_tag += "_H";
00262
00263
00264
00265 ofs << gsSlashDivider << std::endl;
00266 ofs << "
00267 ofs << "
00268 ofs << gsDocComment << std::endl;
00269 ofs << "
00270 ofs << "
00271 ofs << gsSlashDivider << std::endl;
00272 ofs << "#ifndef " << inc_tag << std::endl;
00273 ofs << "#define " << inc_tag << std::endl;
00274 ofs << "#include \"JobControl/JobCModule.h\"" << std::endl;
00275 ofs << std::endl;
00276 ofs << "class "<<m.fClassName<<" : public JobCModule"<<std::endl;
00277 ofs << "{" << std::endl;
00278 ofs << "public:" << std::endl;
00279 ofs << " " << m.fClassName << "();" << std::endl;
00280 ofs << " ~" << m.fClassName << "();" << std::endl;
00281 ofs << std::endl;
00282 ofs << "public:" << std::endl;
00283 if (m.fNeedBeginJob || m.fNeedEndJob ||
00284 m.fNeedBeginFile || m.fNeedEndFile ||
00285 m.fNeedBeginRun || m.fNeedEndRun) {
00286 ofs << " // Handle job status changes" << std::endl;
00287 if (m.fNeedBeginJob) ofs << " void BeginJob();" << std::endl;
00288 if (m.fNeedEndJob) ofs << " void EndJob();" << std::endl;
00289 if (m.fNeedBeginFile) ofs << " void BeginFile();" << std::endl;
00290 if (m.fNeedEndFile) ofs << " void EndFile();" << std::endl;
00291 if (m.fNeedBeginRun) ofs << " void BeginRun();" << std::endl;
00292 if (m.fNeedEndRun) ofs << " void EndRun();" << std::endl;
00293 ofs << std::endl;
00294 }
00295 if (m.fNeedAna || m.fNeedReco) {
00296 ofs << " // Analysis and Reconstruction methods" << std::endl;
00297 if (m.fNeedAna)
00298 ofs << " JobCResult Ana(const MomNavigator* mom);" << std::endl;
00299 if (m.fNeedReco)
00300 ofs << " JobCResult Reco(MomNavigator* mom);" << std::endl;
00301 ofs << std::endl;
00302 }
00303 if (m.fNeedGet || m.fNeedPut) {
00304 ofs << " // I/O methods" << std::endl;
00305 if (m.fNeedGet)
00306 ofs << " JobCResult Get(MomNavigator* mom);" << std::endl;
00307 if (m.fNeedPut)
00308 ofs << " JobCResult Put(const MomNavigator* mom);" << std::endl;
00309 ofs << std::endl;
00310 }
00311 if (m.fNeedConfig) {
00312 ofs << " // Module configuration" << std::endl;
00313 ofs << " const Registry& DefaultConfig() const;" << std::endl;
00314 ofs << " void Config(const Registry& r);" << std::endl;
00315 ofs << std::endl;
00316 }
00317 if (m.fNeedHelp || m.fNeedReport ||
00318 m.fNeedReset || m.fNeedHandleCommand) {
00319 ofs << " // User interface methods" << std::endl;
00320 if (m.fNeedHelp)
00321 ofs << " void Help();" << std::endl;
00322 if (m.fNeedReport)
00323 ofs << " void Report();" << std::endl;
00324 if (m.fNeedReset)
00325 ofs << " void Reset();" << std::endl;
00326 if (m.fNeedHandleCommand)
00327 ofs << " void HandleCommand(JobCommand* c);" << std::endl;
00328 ofs << std::endl;
00329 }
00330 ofs << std::endl;
00331 ofs << "private:" << std::endl;
00332 ofs << " // Module configuration" << std::endl;
00333 if(m.fNeedConfig) {
00334 ModuleConfig::const_iterator itr(cfg.begin());
00335 ModuleConfig::const_iterator itrEnd(cfg.end());
00336 for (itr=cfg.begin(); itr!=itrEnd; ++itr) {
00337 if (itr->fType == "bool") { ofs << " Bool_t "; }
00338 if (itr->fType == "int") { ofs << " Int_t "; }
00339 if (itr->fType == "float") { ofs << " Double_t "; }
00340 if (itr->fType == "string") { ofs << " std::string "; }
00341 ofs << "f" << itr->fName << ";" << std::endl;
00342 }
00343 }
00344 ofs << std::endl;
00345 ofs << " // Module member data" << std::endl;
00346 ofs << std::endl;
00347 ofs << "};" << std::endl;
00348 ofs << "#endif // " << inc_tag << std::endl;
00349 ofs << gsSlashDivider << std::endl;
00350 }
00351
00352
00353
00354 static void write_method(const char* type_s,
00355 const char* meth,
00356 const char* return_s,
00357 const ModuleOptions& m, std::ofstream& ofs)
00358 {
00359
00360
00361
00362
00363
00364
00365
00366
00367 ofs << gsDotDivider << std::endl;
00368 ofs << std::endl;
00369 if (type_s!=0 && type_s!="")
00370 ofs << type_s << " " << m.fClassName << "::" << meth << std::endl;
00371 else
00372 ofs << m.fClassName << "::" << meth << std::endl;
00373 ofs << "{" << std::endl;
00374 ofs << " " << gsEqualsDivider << std::endl;
00375 ofs << " " << gsDocComment << std::endl;
00376 ofs << " " << gsEqualsDivider << std::endl;
00377 if (return_s!=0 && return_s != "")
00378 ofs << " return " << return_s << std::endl;
00379 ofs << "}" << std::endl;
00380 ofs << std::endl;
00381 }
00382
00383
00384
00385 static void write_constructor(const ModuleOptions& m,
00386 const ModuleConfig& cfg,
00387 std::ofstream& ofs)
00388 {
00389 ofs << gsDotDivider << std::endl;
00390 ofs << std::endl;
00391 ofs << m.fClassName << "::" << m.fClassName << "()";
00392 if(m.fNeedConfig) {
00393 ofs << " : ";
00394 ModuleConfig::const_iterator itr(cfg.begin());
00395 ModuleConfig::const_iterator itrEnd(cfg.end());
00396 for (itr=cfg.begin(); itr!=itrEnd; ++itr) {
00397 ofs << std::endl;
00398 ofs << " f" << itr->fName << "(";
00399 if (itr->fType == "bool") { ofs << "false"; }
00400 if (itr->fType == "int") { ofs << "0"; }
00401 if (itr->fType == "float") { ofs << "0.0"; }
00402 if (itr->fType == "string") { ofs << "\"\""; }
00403 ofs << ")";
00404 if(itr+1 != itrEnd) ofs << ",";
00405 }
00406 }
00407 ofs << std::endl;
00408 ofs << "{" << std::endl;
00409 ofs << " " << gsEqualsDivider << std::endl;
00410 ofs << " " << gsDocComment << std::endl;
00411 ofs << " " << gsEqualsDivider << std::endl;
00412 ofs << "}" << std::endl;
00413
00414
00415 }
00416
00417
00418 static void write_default_config_method(const ModuleOptions& m,
00419 const ModuleConfig& cfg,
00420 std::ofstream& ofs)
00421 {
00422
00423
00424
00425 ofs << gsDotDivider << std::endl;
00426 ofs << std::endl;
00427 ofs << "const Registry& " << m.fClassName << "::DefaultConfig() const"
00428 << std::endl;
00429 ofs << "{" << std::endl;
00430 ofs << " " << gsEqualsDivider << std::endl;
00431 ofs << " /// Supply the default configuration for the module" << std::endl;
00432 ofs << " " << gsEqualsDivider << std::endl;
00433 ofs << " static Registry r; // Default configuration for module"
00434 << std::endl;
00435 ofs << std::endl;
00436 ofs << " // Set name of config" << std::endl;
00437 ofs << " std::string name = this->GetName();" << std::endl;
00438 ofs << " name += \".config.default\";" << std::endl;
00439 ofs << " r.SetName(name.c_str());" << std::endl;
00440 ofs << std::endl;
00441 ofs << " // Set values in configuration" << std::endl;
00442 ofs << " r.UnLockValues();" << std::endl;
00443 ModuleConfig::const_iterator itr(cfg.begin());
00444 ModuleConfig::const_iterator itrEnd(cfg.end());
00445 unsigned int w = 0;
00446 for (; itr!=itrEnd; ++itr) {
00447 if (itr->fName.size() > w) w = itr->fName.size();
00448 }
00449 for (itr = cfg.begin(); itr!=itrEnd; ++itr) {
00450 ofs << " r.Set(\"" << itr->fName << "\",";
00451 for (unsigned int i=itr->fName.size(); i<w; ++i) ofs << " ";
00452 if (itr->fType == "string") {
00453 ofs << "\"" << itr->fValue << "\");" << std::endl;
00454 }
00455 else if (itr->fType == "bool") {
00456 if (UtilString::atob(itr->fValue.c_str()))
00457 ofs << " true);" << std::endl;
00458 else
00459 ofs << " false);" << std::endl;
00460 }
00461 else {
00462 ofs << " " << itr->fValue << ");" << std::endl;
00463 }
00464 }
00465 ofs << " r.LockValues();" << std::endl;
00466 ofs << std::endl;
00467 ofs << " return r;" << std::endl;
00468 ofs << "}" << std::endl;
00469 ofs << std::endl;
00470 }
00471
00472
00473
00474 static void write_config_method(const ModuleOptions& m,
00475 const ModuleConfig& cfg,
00476 std::ofstream& ofs)
00477 {
00478
00479
00480
00481 ofs << gsDotDivider << std::endl;
00482 ofs << std::endl;
00483 ofs << "void " << m.fClassName << "::Config(const Registry& r)"
00484 << std::endl;
00485 ofs << "{" << std::endl;
00486 ofs << " " << gsEqualsDivider << std::endl;
00487 ofs << " /// Configure the module given the Registry r" << std::endl;
00488 ofs << " " << gsEqualsDivider << std::endl;
00489
00490 ModuleConfig::const_iterator itr(cfg.begin());
00491 ModuleConfig::const_iterator itrEnd(cfg.end());
00492 for (; itr!=itrEnd; ++itr) {
00493 ofs << " f" << itr->fName << " = ";
00494 if (itr->fType == "bool") ofs << "r.GetInt";
00495 if (itr->fType == "int") ofs << "r.GetInt";
00496 if (itr->fType == "float") ofs << "r.GetDouble";
00497 if (itr->fType == "string") ofs << "r.GetCharString";
00498 ofs << "(\"" << itr->fName << "\");" << std::endl;
00499 }
00500 ofs << "}" << std::endl;
00501 ofs << std::endl;
00502
00503 return;
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 }
00553
00554
00555
00556 static void write_config_methods(const ModuleOptions& m,
00557 const ModuleConfig& cfg,
00558 std::ofstream& ofs)
00559 {
00560
00561
00562
00563 write_default_config_method(m,cfg,ofs);
00564 write_config_method(m,cfg,ofs);
00565 }
00566
00567
00568
00569
00570 static void write_cxx(const ModuleOptions& m, const ModuleConfig& cfg)
00571 {
00572
00573
00574
00575 std::string filename = m.fClassName;
00576 filename += ".cxx";
00577 std::ofstream ofs(filename.c_str());
00578
00579 ofs << gsSlashDivider << std::endl;
00580 ofs << "
00581 ofs << "
00582 ofs << gsDocComment << std::endl;
00583 ofs << "
00584 ofs << "
00585 ofs << gsSlashDivider << std::endl;
00586
00587
00588 ofs <<
00589 "#include \""<<m.fClassName<<".h\""<<std::endl;
00590 if (m.fNeedMsg) {
00591 ofs << "#include \"MessageService/MsgService.h\"" << std::endl;
00592 }
00593 ofs << "#include \"MinosObjectMap/MomNavigator.h\"" << std::endl;
00594 ofs << "#include \"JobControl/JobCModuleRegistry.h\" // For JOBMODULE macro"
00595 << std::endl;
00596 ofs << std::endl;
00597
00598
00599 ofs << "JOBMODULE(" << m.fClassName << ", \"" << m.fModuleName << "\",\n"
00600 << " \"" << m.fDescription << "\");" << std::endl;
00601 if (m.fNeedMsg) {
00602 ofs << "CVSID(\"$Id: gen_module.cc,v 1.3 2005/05/26 11:47:30 tagg Exp $\");" << std::endl;
00603 }
00604
00605
00606 write_constructor(m,cfg,ofs);
00607
00608
00609
00610
00611 std::string s = "~"; s += m.fClassName; s+= "()";
00612 write_method("", s.c_str(), "", m, ofs);
00613
00614
00615 if (m.fNeedBeginJob) write_method("void", "BeginJob()", "", m, ofs);
00616 if (m.fNeedEndJob) write_method("void", "EndJob()", "", m, ofs);
00617 if (m.fNeedBeginFile) write_method("void", "BeginFile()", "", m, ofs);
00618 if (m.fNeedEndFile) write_method("void", "EndFile()", "", m, ofs);
00619 if (m.fNeedBeginRun) write_method("void", "BeginRun()", "", m, ofs);
00620 if (m.fNeedEndRun) write_method("void", "EndRun()", "", m, ofs);
00621
00622 if (m.fNeedAna)
00623 write_method("JobCResult",
00624 "Ana(const MomNavigator* mom)",
00625 "JobCResult::kPassed; // kNoDecision, kFailed, etc.",
00626 m, ofs);
00627 if (m.fNeedReco)
00628 write_method("JobCResult",
00629 "Reco(MomNavigator* mom)",
00630 "JobCResult::kPassed; // kNoDecision, kFailed, etc.",
00631 m, ofs);
00632 if (m.fNeedGet)
00633 write_method("JobCResult",
00634 "Get(MomNavigator* mom)",
00635 "JobCResult::kPassed; // kNoDecision, kFailed, etc.",
00636 m, ofs);
00637 if (m.fNeedPut)
00638 write_method("JobCResult",
00639 "Put(const MomNavigator* mom)",
00640 "JobCResult::kPassed; // kNoDecision, kFailed, etc.",
00641 m, ofs);
00642 if (m.fNeedConfig) write_config_methods(m,cfg,ofs);
00643 if (m.fNeedHelp) write_method("void","Help()", "",m,ofs);
00644 if (m.fNeedReport) write_method("void","Report()","",m,ofs);
00645 if (m.fNeedReset) write_method("void","Reset()", "",m,ofs);
00646 if (m.fNeedHandleCommand)
00647 write_method("void","HandleCommand(JobCommand* c)", "",m,ofs);
00648 ofs << gsSlashDivider << std::endl;
00649 }
00650
00651
00652
00653 static void getSetup(ModuleOptions& m, ModuleConfig& cfg) {
00654 setupNames(m);
00655 setupMethods(m);
00656 setupServices(m);
00657 setupConfig(m,cfg);
00658 }
00659
00660
00661
00662 static void doWrite(ModuleOptions& m, ModuleConfig& cfg) {
00663 write_h(m,cfg);
00664 write_cxx(m,cfg);
00665 }
00666
00667
00668
00669 int main(void) {
00670 ModuleOptions m;
00671 ModuleConfig cfg;
00672
00673 getSetup(m,cfg);
00674 doWrite(m,cfg);
00675 }
00676