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});