35void PrepareLib(TString name);
 
   37void SetNames(TString& plusPath,
 
   45void PrepareMonitor(TString name, TString type1, TString type2);
 
   49void MakeLinkDef(TString name, std::vector<TString> sources);
 
   51std::vector<TString> ParseHeader(TString sourceName);
 
   53void PrepareCutClass(TString type, TString name);
 
   55int main(
int argc, 
char* argv[]) {
 
   57    std::cout << 
"not enough params, type --help" << std::endl;
 
   60  auto args = Hal::Std::ConvertMainArgs(argc, argv);
 
   61  if (args[0].first == 
"help") {  
 
   62    std::cout << 
"options" << std::endl;
 
   63    std::cout << 
"--dir=[LIBRARYNAME] prepare cmake template for this directory" << std::endl;
 
   64    std::cout << 
"--updatedir update cmake SRC list and linkdef" << std::endl;
 
   65    std::cout << 
"--template=[TYPE] --name=[NAME] prepares template for class" << std::endl;
 
   66    std::cout << 
"\t TYPE = event-cut, track-cut, twotrack-cut for cuts" << std::endl;
 
   67    std::cout << 
"\t TYPE = event-monx, event-mony, event-monz, for x, xy, xyz, property monitors for events" << std::endl;
 
   68    std::cout << 
"\t TYPE = track-monx, track-mony, track-monz, for x, xy, xyz, property monitors for tracks" << std::endl;
 
   69    std::cout << 
"\t TYPE = twotrack-monx, twotrack-mony, twotrack-monz, for x, xy, xyz, property monitors for pairs" 
   71    std::cout << 
"\tName = name of class e.g. hal_cmake --type=event-cut --name=Multiplicity " << std::endl;
 
   73  if (args[0].first == 
"dir") {
 
   74    PrepareLib(args[0].second);
 
   77  if (args[0].first == 
"updatedir") {
 
   81  if (args[0].first == 
"template") {
 
   82    auto vec = Hal::Std::ExplodeString(args[0].second, 
'-');
 
   83    if (vec.size() <= 1) 
return 0;
 
   84    if (vec[1].EqualTo(
"cut")) { PrepareCutClass(args[0].second, args[1].second); }
 
   85    if (vec[1].EqualTo(
"monx")) { PrepareMonitor(args[1].second, vec[0], 
"x"); }
 
   86    if (vec[1].EqualTo(
"mony")) { PrepareMonitor(args[1].second, vec[0], 
"y"); }
 
   87    if (vec[1].EqualTo(
"monz")) { PrepareMonitor(args[1].second, vec[0], 
"z"); }
 
   94void PrepareLib(TString name) {
 
   95  TString plusPath    = Hal::Std::GetHalrootPlus();
 
   96  TString toCopy      = plusPath + 
"templates/CMakeLists.txt";
 
   97  TString tempFile[2] = {
"temp.txt", 
"temp2.txt"};
 
   98  gSystem->CopyFile(toCopy, tempFile[0], kTRUE);
 
  100  Hal::Std::ReplaceInFile(tempFile[0], tempFile[1], 
"__HAL_NAME_OF_LINKDEF__", Form(
"%sLinkDef.h", name.Data()));
 
  101  Hal::Std::ReplaceInFile(tempFile[1], tempFile[0], 
"__HAL_NAME_OF_LIBRARY__", name);
 
  102  auto list  = Hal::Std::GetListOfFiles(
"", 
"cxx", kFALSE, 3);
 
  103  auto list2 = Hal::Std::GetListOfFiles(
"", 
"cpp", kFALSE, 3);
 
  108  TString sources = 
"";
 
  109  for (
auto i : list) {
 
  110    sources = sources + 
" " + i + 
"\n";
 
  113  Hal::Std::ReplaceInFile(tempFile[0], tempFile[1], 
"__HAL_NAME_OF_CXX_FILES__", sources);
 
  114  gSystem->CopyFile(tempFile[1], 
"CMakeLists.txt", kTRUE);
 
  115  gSystem->Exec(
"rm temp.txt temp2.txt");
 
  116  MakeLinkDef(Form(
"%sLinkDef.h", name.Data()), list);
 
  121  cmake.open(
"CMakeLists.txt");
 
  124    std::cout << 
"Cannto find CMakeLists.txt here" << std::endl;
 
  129  other.open(
"CMakeLists.temp");
 
  130  Bool_t listOpen = kFALSE;
 
  131  auto cppFiles   = Hal::Std::GetListOfFiles(
"", 
"cxx", kFALSE, 3);
 
  132  auto list2      = Hal::Std::GetListOfFiles(
"", 
"cpp", kFALSE, 3);
 
  135    cppFiles.push_back(i);
 
  136  while (!temp.ReadLine(cmake, kFALSE).eof()) {
 
  137    if (temp.Contains(
"SRCS")) {
 
  138      other << temp << std::endl;
 
  140      for (
auto file : cppFiles) {
 
  141        other << file << std::endl;
 
  144    if (listOpen && temp.Contains(
")")) listOpen = kFALSE;
 
  145    if (!listOpen) other << temp << std::endl;
 
  147  gSystem->Exec(
"mv CMakeLists.temp CMakeLists.txt");
 
  148  auto headers = Hal::Std::GetListOfFiles(
"", 
"h", kFALSE, 1);
 
  150  for (
auto header : headers) {
 
  151    if (header.EndsWith(
"LinkDef.h")) {
 
  156  if (linkdef.Length() == 0) {
 
  157    std::cout << 
"Cannot find linkdef !" << std::endl;
 
  160  MakeLinkDef(linkdef, cppFiles);
 
  163void SetNames(TString& plusPath,
 
  166              TString& headerGuard,
 
  171  toCopy      = plusPath + 
"templates/" + inputName;
 
  172  headerGuard = 
"TEMPLATES_" + inputName;
 
  173  headerGuard.ToUpper();
 
  178void PrepareCutClass(TString type, TString name) {
 
  179  TString plusPath = Hal::Std::GetHalrootPlus();
 
  186  if (type.EqualTo(
"event-cut", TString::ECaseCompare::kIgnoreCase)) {
 
  187    SetNames(plusPath, pattern, toCopy, headerGuard, newGuard, name, 
"EventCutTemplate");
 
  189  if (type.EqualTo(
"track-cut", TString::ECaseCompare::kIgnoreCase)) {
 
  190    SetNames(plusPath, pattern, toCopy, headerGuard, newGuard, name, 
"TrackCutTemplate");
 
  192  if (type.EqualTo(
"twotrack-cut", TString::ECaseCompare::kIgnoreCase)) {
 
  193    SetNames(plusPath, pattern, toCopy, headerGuard, newGuard, name, 
"TwoTrackCutTemplate");
 
  195  if (toCopy.Length() == 0) {
 
  196    std::cout << 
"Wrong flag in template type" << std::endl;
 
  199  TString tempFile[2] = {
"temp.txt", 
"temp2.txt"};
 
  200  gSystem->CopyFile(Form(
"%s.cxx", toCopy.Data()), tempFile[0]);
 
  201  Hal::Std::ReplaceInFile(tempFile[0], Form(
"%s.cxx", name.Data()), pattern, name);
 
  202  gSystem->CopyFile(Form(
"%s.h", toCopy.Data()), tempFile[0], kTRUE);
 
  203  Hal::Std::ReplaceInFile(tempFile[0], tempFile[1], pattern, name);  
 
  204  Hal::Std::ReplaceInFile(tempFile[1], Form(
"%s.h", name.Data()), headerGuard, newGuard);
 
  205  gSystem->Exec(
"rm temp.txt temp2.txt");
 
  208std::vector<TString> ParseHeader(TString sourceName) {
 
  209  TString header = sourceName.ReplaceAll(
".cpp", 
".h");
 
  210  header         = sourceName.ReplaceAll(
".cxx", 
".h");
 
  213  std::vector<TString> res;
 
  219  auto replaceEverything = [](TString& str, std::initializer_list<TString> list) {
 
  220    for (
auto i : list) {
 
  221      str = str.ReplaceAll(i, 
"");
 
  225  std::vector<std::pair<TString, int>> namespaceArray;
 
  227  while (!temp.ReadLine(file).eof()) {
 
  229    Int_t bra      = line.CountChar(
'{');
 
  230    Int_t ket      = line.CountChar(
'}');
 
  231    Int_t dBracket = bra - ket;
 
  232    TString curNamespace;
 
  233    if (line.Contains(
"namespace") && !line.Contains(
"using")) {
 
  237      Int_t npos  = line.First(
'n');
 
  239      if (line.Contains(
"/*") || line.Contains(
"*/") || line.Contains(
"//")) { nLast = line.First(
'/'); }
 
  247      replaceEverything(curNamespace, {
"namespace", 
"}", 
" ", 
"\t", 
"{"});
 
  248      if (curNamespace.Length()) {
 
  249        std::pair<TString, int> name(curNamespace, bracket + dBracket);
 
  250        Bool_t replaced = kFALSE;
 
  251        for (
auto& i : namespaceArray) {
 
  252          if (i.second == name.second) {
 
  258        if (!replaced) { namespaceArray.push_back(name); }
 
  263    if (line.Contains(
"ClassDef")) {  
 
  264      replaceEverything(line, {
"ClassDef(", 
")", 
";", 
" "});
 
  265      line                = line(0, line.Last(
','));
 
  266      TString myNamespace = 
"";
 
  267      Int_t realBracket   = bracket - 1;  
 
  268      for (
auto i : namespaceArray) {
 
  269        if (realBracket >= i.second) { myNamespace = myNamespace + 
"::" + i.first; }
 
  271      if (myNamespace.BeginsWith(
"::")) { myNamespace = Hal::Std::RemoveNChars(myNamespace, 2, 
'b'); }
 
  272      if (myNamespace.Length() > 0 && !myNamespace.EndsWith(
"::")) { myNamespace = myNamespace + 
"::"; }
 
  273      res.push_back(myNamespace + line);
 
  279void MakeLinkDef(TString name, std::vector<TString> sources) {
 
  280  std::ofstream linkdef;
 
  282  linkdef << 
"#ifdef __CINT__" << std::endl;
 
  283  linkdef << 
"" << std::endl;
 
  284  linkdef << 
"#pragma link off all globals;" << std::endl;
 
  285  linkdef << 
"#pragma link off all classes;" << std::endl;
 
  286  linkdef << 
"#pragma link off all functions;" << std::endl;
 
  287  linkdef << 
"" << std::endl;
 
  288  for (
auto cppFIle : sources) {
 
  289    auto cppClasses = ParseHeader(cppFIle);
 
  290    for (
auto singleClass : cppClasses) {
 
  291      linkdef << 
"#pragma link C++ class ";
 
  292      linkdef << singleClass << 
"+;" << std::endl;  
 
  295  linkdef << 
"" << std::endl;
 
  296  linkdef << 
"#endif" << std::endl;
 
  300void PrepareMonitor(TString name, TString type1, TString type2) {
 
  301  TString baseClassName;
 
  303    baseClassName = 
"PropertyMonitorTemplateX";
 
  304  } 
else if (type2 == 
"y") {
 
  305    baseClassName = 
"PropertyMonitorTemplateXY";
 
  306  } 
else if (type2 == 
"z") {
 
  307    baseClassName = 
"PropertyMonitorTemplateXYZ";
 
  312  TString updateMethod;
 
  313  if (type1 == 
"event") {
 
  314    cutUpdate    = 
"Hal::ECutUpdate::kEvent";
 
  315    updateMethod = 
"  Hal::Event *event = (Hal::Event*)obj;";
 
  316  } 
else if (type1 == 
"track") {
 
  317    cutUpdate    = 
"Hal::ECutUpdate::kTrack";
 
  318    updateMethod = 
"  Hal::Track *track = (Hal::Track*)obj; ";
 
  319  } 
else if (type1 == 
"twotrack") {
 
  320    cutUpdate    = 
"Hal::ECutUpdate::kTwoTrack";
 
  321    updateMethod = 
"  Hal::TwoTrack *pair = (Hal::TwoTrack*)obj; ";
 
  325  TString plusPath = Hal::Std::GetHalrootPlus();
 
  330  SetNames(plusPath, pattern, toCopy, headerGuard, newGuard, name, baseClassName);
 
  331  gSystem->CopyFile(Form(
"%s.cxx", toCopy.Data()), Form(
"%s.cxx", name.Data()));
 
  332  gSystem->CopyFile(Form(
"%s.h", toCopy.Data()), Form(
"%s.h", name.Data()));
 
  333  Hal::Std::ReplaceInFile(Form(
"%s.h", name.Data()), Form(
"%s.h", name.Data()), {headerGuard, baseClassName}, {newGuard, name});
 
  335  Hal::Std::ReplaceInFile(Form(
"%s.cxx", name.Data()),
 
  336                          Form(
"%s.cxx", name.Data()),
 
  337                          {TString(
"__UPDATE_METHOD__"), TString(
"__UPDATE__"), baseClassName},
 
  338                          {updateMethod, cutUpdate, name});