KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
KVClassFactory.cpp
1/*
2$Id: KVClassFactory.cpp,v 1.19 2009/01/21 08:04:20 franklan Exp $
3$Revision: 1.19 $
4$Date: 2009/01/21 08:04:20 $
5*/
6
7#include "KVClassFactory.h"
8#include "TSystem.h"
9#include "TSystemDirectory.h"
10#include "KVBase.h"
11#include "TObjString.h"
12#include "KVHashList.h"
13#include "TClass.h"
14#include "TMethod.h"
15#include "TMethodArg.h"
16
17using namespace std;
18
20
21
22
23
24KVString __add_indented_line(const KVString& line, const KVString& indent, Bool_t newline = kTRUE)
25{
26 KVString output;
27 line.Begin("\n");
28 while (!line.End()) {
29 KVString _line = line.Next();
30 output += (indent + _line);
31 output += "\n";
32 }
33 if (!newline) output.Remove(output.Length() - 1);
34 return output;
35}
36
37
38
41
43 : fBaseClass(nullptr), fHasBaseClass(kFALSE), fBaseClassTObject(kFALSE), fInlineAllMethods(kFALSE), fInlineAllCtors(kFALSE),
44 fInheritAllCtors(kTRUE)
45{
46 // Default ctor
47}
48
49
50
80
82 const Char_t* classdesc,
83 const Char_t* base_class,
84 Bool_t withTemplate,
85 const Char_t* templateFile)
86 : fBaseClass(nullptr), fHasBaseClass(kFALSE), fBaseClassTObject(kFALSE), fInlineAllMethods(kFALSE), fInlineAllCtors(kFALSE),
87 fInheritAllCtors(kTRUE)
88{
89 //Create a new class with the following characteristics:
90 //
91 // classname = name of new class
92 // classdesc = short (one line) description of class
93 // base_class = name of base class(es)* (if creating a derived class)
94 // withTemplate = kTRUE if template files for the '.h' and '.cpp' are to be used
95 // templateFile = base name of template files
96 //
97 // *(if the class has several base classes, give a comma-separated list)
98 //
99 //Only classname and classdesc have to be given.
100 //By default we create a new base class without use of template files.
101 //
102 //If withTemplate=kTRUE, the base name for the template files must be given.
103 //We check that the template files exist. If they do not, an error message is
104 //printed and this object will be made a zombie (test IsZombie() after constructor).
105 //The template for the class structure is defined in a '.h' and a '.cpp' file,
106 //as follows:
107 //
108 // if templateFile="" (default), we expect base_class!="", and template files with names base_classTemplate.h and base_classTemplate.cpp
109 // must be present in either $TEMPLATEDIR, $HOME or $PWD directories.
110 // the dummy classname "base_classTemplate" will be replaced everywhere by 'classname'
111 //
112 // if templateFile="/absolute/path/classTemplate" we use classTemplate.h & classTemplate.cpp in the given directory.
113 // the dummy classname "classTemplate" will be replaced everywhere by 'classname'
114 //
115 // if templateFile="classTemplate" we look for classTemplate.h & classTemplate.cpp in $TEMPLATEDIR, $HOME or $PWD directories.
116 // the dummy classname "classTemplate" will be replaced everywhere by 'classname'
117
118 fBaseClass = NULL;
119 SetClassName(classname);
120 SetClassDesc(classdesc);
121 SetBaseClass(base_class);
122 SetTemplate(withTemplate, templateFile);
123 SetWhoWhen();
124
125 if (!withTemplate) {
126 // for untemplated classes we add default ctor & dtor straight away
129 }
130}
131
132
133
134
150
151void KVClassFactory::SetTemplate(Bool_t temp, const Char_t* templateFile)
152{
153 //If the class uses template files (temp=kTRUE), 'templateFile' is the base name used to find these files.
154 //The template for the class structure is defined in a '.h' and a '.cpp' file,
155 //as follows:
156 //
157 // if templateFile="" (default), we expect a base class to have been given,
158 // and template files with names base_classTemplate.h and base_classTemplate.cpp
159 // must be present in either $TEMPLATEDIR, $HOME or $PWD directories.
160 // the dummy classname "base_classTemplate" will be replaced everywhere by 'classname'
161 //
162 // if templateFile="/absolute/path/classTemplate" we use classTemplate.h & classTemplate.cpp in the given directory.
163 // the dummy classname "classTemplate" will be replaced everywhere by 'classname'
164 //
165 // if templateFile="classTemplate" we look for classTemplate.h & classTemplate.cpp in $TEMPLATEDIR, $HOME or $PWD directories.
166 // the dummy classname "classTemplate" will be replaced everywhere by 'classname'
167
168 fWithTemplate = temp;
169 fTemplateBase = templateFile;
170
171 if (temp) {
172 //if we want to use template files for the new class,
173 //we have to make sure they exist;
174 if (!CheckTemplateFiles(GetBaseClass(), templateFile)) {
175 //template files not found - cannot proceed
176 Error("SetTemplate", "Cannot find template files %s. Object made a zombie.", templateFile);
178 }
179 }
180}
181
182
183
184#if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
185
188
190#else
192#endif
193{
194 //Copy the state of this KVClassFactory to the one referenced by 'obj'
195 TObject::Copy(obj);
196 ((KVClassFactory&)obj).SetClassName(GetClassName());
197 ((KVClassFactory&)obj).SetClassDesc(GetClassDesc());
198 ((KVClassFactory&)obj).SetBaseClass(GetBaseClass());
199 ((KVClassFactory&)obj).SetTemplate(WithTemplate(), GetTemplateBase());
200 ((KVClassFactory&)obj).SetWhoWhen();
201 if (fMethods.GetEntries()) {
202 TIter next(&fMethods);
203 KVClassMethod* meth;
204 while ((meth = (KVClassMethod*)next()))((KVClassFactory&)obj).AddMethod(*meth);
205 }
206 if (fHeadInc.GetEntries()) fHeadInc.Copy(((KVClassFactory&)obj).fHeadInc);
207 if (fImpInc.GetEntries()) fImpInc.Copy(((KVClassFactory&)obj).fImpInc);
208 ((KVClassFactory&)obj).SetOutputPath(GetOutputPath());
209}
210
211
212
215
217{
218 //ctor par copie
219 fBaseClass = NULL;
220#if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
221 obj.Copy(*this);
222#else
223 ((KVClassFactory&)obj).Copy(*this);
224#endif
225}
226
227
228
233
235{
236 // Write a stub doxygen comment block to be used to document the file
237 // This will include
238 // class name, brief description, author name and date
239
240 file << "/**\n \\class " << GetClassName() << "\n \\brief " << GetClassDesc() << "\n\n ";
241 file << "Write a detailed documentation for your class here, see doxygen manual for help.\n\n ";
242 file << "\\author " << fAuthor.Data() << "\n \\date " << fNow.AsString() << "\n*/\n\n";
243}
244
245
246
252
254{
255 //Write pre-processor directives in file
256 //i.e. '#ifndef __TOTO_H' etc.
257 //If this class has inheritance, we add '#include "base_class.h"' for each of the base classes.
258 //and any other include files added using AddHeaderIncludeFile
259
260 TString tmp = fClassName;
261 tmp.ToUpper();
262 tmp.Prepend("__");
263 tmp.Append("_H");
264 file << "#ifndef " << tmp.Data() << endl;
265 file << "#define " << tmp.Data() << "\n" << endl;
266 //base class(es) ?
267 if (fHasBaseClass) {
270 while (!fBaseClassName.End())
271 file << "#include \"" << fBaseClassName.Next(kTRUE) << ".h\"" << endl;
272 file << endl;
273 }
274 else
275 file << "#include \"" << fBaseClassName.Data() << ".h\"\n" << endl;
276 }
277 if (fHeadInc.GetSize()) {
278 TIter next(&fHeadInc);
279 TObjString* str;
280 while ((str = (TObjString*)next())) {
281 file << "#include \"" << str->String().Data() << "\"\n" << endl;
282 }
283 }
284}
285
286
287
293
295{
296 // Write the class declaration in the header file
297 // This will include a default constructor & destructor and
298 // any methods added using AddMethod, sorted according to
299 // their access type.
300
301 file << "class " << fClassName.Data();
302 if (fHasBaseClass) {
303 file << " : ";
306 file << "public " << fBaseClassName.Next(kTRUE);
307 while (!fBaseClassName.End()) file << ", public " << fBaseClassName.Next(kTRUE);
308 }
309 else
310 file << "public " << fBaseClassName.Data();
311 }
312 file << "\n{" << endl;
313
314 // private members
315 unique_ptr<KVSeqCollection> prem(fMembers.GetSubListWithMethod("private", "GetAccess"));
316 if (prem->GetEntries()) {
317 file << "\n" << endl;
319 TIter next(prem.get());
320 KVClassMember* meth;
321 while ((meth = (KVClassMember*)next())) {
322 meth->WriteDeclaration(line);
323 file << " " << line.Data() << endl;
324 }
325 }
326
327 // private methods + constructors + destructor (if private)
328 unique_ptr<KVSeqCollection> priv(fMethods.GetSubListWithMethod("private", "GetAccess"));
329 unique_ptr<KVSeqCollection> ctor(priv->GetSubListWithMethod("1", "IsConstructor"));
330 if (ctor->GetEntries()) {
331 file << endl;
333 TIter next(ctor.get());
334 KVClassMethod* meth;
335 while ((meth = (KVClassMethod*)next())) {
336 meth->WriteDeclaration(line);
337 file << " " << line.Data() << endl;
338 }
339 }
340 if (priv->GetEntries()) {
341 file << endl;
343 TIter next(priv.get());
344 KVClassMethod* meth;
345 while ((meth = (KVClassMethod*)next())) {
346 if (meth->IsNormalMethod()) {
347 meth->WriteDeclaration(line);
348 file << " " << line.Data() << endl;
349 }
350 }
351 }
352 // private destructor
353 if (GetDestructor()->IsPrivate()) {
356 file << " " << line.Data() << endl;
357 }
358
359 bool protected_written = kFALSE;
360
361 // protected members
362 prem.reset(fMembers.GetSubListWithMethod("protected", "GetAccess"));
363 if (prem->GetEntries()) {
364 file << "\nprotected:" << endl;
365 protected_written = kTRUE;
367 TIter next(prem.get());
368 KVClassMember* meth;
369 while ((meth = (KVClassMember*)next())) {
370 meth->WriteDeclaration(line);
371 file << " " << line.Data() << endl;
372 }
373 }
374
375 // protected methods + ctors + dtor (if protected)
376 unique_ptr<KVSeqCollection> prot(fMethods.GetSubListWithMethod("protected", "GetAccess"));
377 ctor.reset(prot->GetSubListWithMethod("1", "IsConstructor"));
378 if (ctor->GetEntries()) {
379 if (!protected_written) {
380 file << "\nprotected:" << endl;
381 protected_written = kTRUE;
382 }
383 else
384 file << endl;
386 TIter next(ctor.get());
387 KVClassMethod* meth;
388 while ((meth = (KVClassMethod*)next())) {
389 meth->WriteDeclaration(line);
390 file << " " << line.Data() << endl;
391 }
392 }
393 if (prot->GetEntries()) {
394 if (!protected_written) {
395 file << "\nprotected:" << endl;
396 protected_written = kTRUE;
397 }
398 else
399 file << endl;
401 TIter next(prot.get());
402 KVClassMethod* meth;
403 while ((meth = (KVClassMethod*)next())) {
404 if (meth->IsNormalMethod()) {
405 meth->WriteDeclaration(line);
406 file << " " << line.Data() << endl;
407 }
408 }
409 }
410 // protected destructor
411 if (GetDestructor()->IsProtected()) {
412 if (!protected_written) {
413 file << "\nprotected:" << endl;
414 protected_written = kTRUE;
415 }
416 else
417 file << endl;
420 file << " " << line.Data() << endl;
421 }
422
423 //public methods
424 file << "public:" << endl;
425 //list of public ctors
426 unique_ptr<KVSeqCollection> pub(fMethods.GetSubListWithMethod("public", "GetAccess"));
427 ctor.reset(pub->GetSubListWithMethod("1", "IsConstructor"));
428 unique_ptr<KVSeqCollection> pubnor(pub->GetSubListWithMethod("1", "IsNormalMethod"));
429 if (ctor->GetEntries()) {
431 TIter next(ctor.get());
432 KVClassMethod* meth;
433 while ((meth = (KVClassMethod*)next())) {
434 meth->WriteDeclaration(line);
435 file << line.Data() << endl;
436 }
437 }
438 // public destructor
439 if (GetDestructor()->IsPublic()) {
440 file << endl;
443 file << line.Data() << endl;
444 if (pubnor->GetEntries()) file << endl;
445 }
446
447 // public methods
448 if (pubnor->GetEntries()) {
450 TIter next(pubnor.get());
451 KVClassMethod* meth;
452 while ((meth = (KVClassMethod*)next())) {
453 meth->WriteDeclaration(line);
454 file << line.Data() << endl;
455 }
456 }
457
458 file << "\n ClassDef(" << fClassName.Data() << ",1)//";
459 file << fClassDesc.Data() << endl;
460 file << "};\n\n#endif" << endl; //don't forget to close the preprocessor #if !!!
461}
462
463
464
468
470{
471 //Write the class implementation file
472 //This includes a class description in pure HTML
473
474 ofstream file_cpp;
475
476 // make sure any required directories exist
478 file_cpp.open(GetImpFileName());
479
480 file_cpp << "#include \"" << fClassName.Data() << ".h\"" << endl;
481 if (fImpInc.GetSize()) {
482 TIter next(&fImpInc);
483 TObjString* str;
484 while ((str = (TObjString*)next())) {
485 file_cpp << "#include \"" << str->String().Data() << "\"" << endl;
486 }
487 }
488 file_cpp << endl << "ClassImp(" << fClassName.Data() << ")\n" << endl << endl;
489
490 // list of constructors
491 unique_ptr<KVSeqCollection> ctor(fMethods.GetSubListWithMethod("1", "IsConstructor"));
492 if (ctor->GetEntries()) {
494 TIter next(ctor.get());
495 KVClassMethod* meth;
496 while ((meth = (KVClassMethod*)next())) {
497 if (!meth->IsInline()) {
499 file_cpp << line.Data() << endl;
500 }
501 }
502 }
503
504 // write destructor
505 if (!GetDestructor()->IsInline()) {
508 file_cpp << line.Data() << endl;
509 }
510
511 //write implementations of added methods
512 unique_ptr<KVSeqCollection> normeth(fMethods.GetSubListWithMethod("1", "IsNormalMethod"));
513 if (normeth->GetEntries()) {
515 TIter next(normeth.get());
516 KVClassMethod* meth;
517 while ((meth = (KVClassMethod*)next())) {
518 if (!meth->IsInline()) {
520 file_cpp << line.Data() << endl << endl;
521 }
522 }
523 }
524
525 file_cpp.close();
526
527 cout << "<KVClassFactory::WriteClassImp> : File " << GetImpFileName() << " generated." << endl;
528}
529
530
531
534
536{
537 //Write the class header file
538
539 ofstream file_h;
540
541 // make sure any required directories exist
543 file_h.open(GetHeaderFileName());
544
545 WritePreProc(file_h);
546 WriteWhoWhen(file_h);
547 WriteClassDec(file_h);
548
549 file_h.close();
550
551 cout << "<KVClassFactory::WriteClassHeader> : File " << GetHeaderFileName() << " generated." << endl;
552}
553
554
555
630
631void KVClassFactory::MakeClass(const Char_t* classname,
632 const Char_t* classdesc,
633 const Char_t* base_class,
634 Bool_t withTemplate,
635 const Char_t* templateFile)
636{
637 //Static method for generating skeleton header and implementation files for a new class.
638 //
639 //Give a name for the class and a short description, used for HTML doc.
640 //
641 //The optional string 'base_class' gives the name(s) of the parent class(es)*, in case of inheritance;
642 //if not given, the new class will be a base class.
643 // *(in case of several base classes, give a comma-separated list)
644 //
645 //if withTemplate=kTRUE, we use a template for the class structure, defined in a '.h' and a '.cpp' file,
646 //as follows:
647 //
648 // - if templateFile="" (default), we expect base_class!="", and template files with names base_classTemplate.h and base_classTemplate.cpp
649 // must be present in either $KVROOT/KVFiles, $HOME or $PWD directories.
650 // the dummy classname "base_classTemplate" will be replaced everywhere by 'classname'
651 //
652 // - if templateFile="/absolute/path/classTemplate" we use classTemplate.h & classTemplate.cpp in the given directory.
653 // the dummy classname "classTemplate" will be replaced everywhere by 'classname'
654 //
655 // - if templateFile="classTemplate" we look for classTemplate.h & classTemplate.cpp in $KVROOT/KVFiles, $HOME or $PWD directories.
656 // the dummy classname "classTemplate" will be replaced everywhere by 'classname'
657 //
658 //Example of use:
659 //~~~~~{.cpp}
660 // KVClassFactory::MakeClass("MyClass", "A brand new class", "TObject")
661 //~~~~~
662 //will generate the following MyClass.h and MyClass.cpp files:
663 //~~~~{.cpp}
664//MyClass.h ======================================>>>>
665// //Created by KVClassFactory on Fri Mar 24 23:52:54 2006 (<-------creation date)
666// //Author: John Frankland (<----- full name of user who calls MakeClass method)
667//
668// #ifndef __MYCLASS_H
669// #define __MYCLASS_H
670//
671// #include <TObject.h> (<----- header file for parent class, if necessary)
672//
673// class MyClass : public TObject
674// {
675// public:
676//
677// MyClass();
678// virtual ~MyClass();
679//
680// ClassDef(MyClass,1)//A brand new class (<------- class description)
681// };
682//
683// #endif
684//<<<<<<<===========================================
685//
686 //~~~~
687 //~~~~{.cpp}
688//MyClass.cpp=================================>>>>>>>
689// //Created by KVClassFactory on Fri Mar 24 23:52:54 2006
690// //Author: John Frankland (<----- full name of user who calls MakeClass method)
691//
692// #include "MyClass.h"
693//
694// ClassImp(MyClass)
695//
696// ////////////////////////////////////////////////////////////////////////////////
697// // A brand new class (<------- class description)
698// ////////////////////////////////////////////////////////////////////////////////
699//
700// MyClass::MyClass()
701// {
702// //Default constructor
703// }
704//
705// MyClass::~MyClass()
706// {
707// //Destructor
708// }
709 //~~~~
710
711 KVClassFactory cf(classname, classdesc, base_class, withTemplate, templateFile);
712 if (!cf.IsZombie()) cf.GenerateCode();
713}
714
715
716
718
720{
721 if (!GetDefaultCtor()) {
722 KVClassConstructor* ctor(AddConstructor());// add default ctor
723 ctor->SetMethodComment("Default constructor");
724 }
725}
726
727
728
731
733{
734 // Generate header and implementation file for currently-defined class
735
736 if (IsZombie()) {
737 Warning("GenerateCode", "Object is zombie. No code will be generated.");
738 return;
739 }
740
742
743 if (fWithTemplate) {
746 }
747 else {
754 if (fBaseClassTObject) {
755 // check for base class which inherits from TObject
756 // if so, we add a skeleton Copy(const TObject&) method
757 // and use it in the copy ctor
759 }
760 else if (!fHasBaseClass) {
761 // if a base class is defined, even if it does not inherit TObject,
762 // we assume that it functions correctly with the ROOT CLI.
763 // otherwise, we need to add #include "Rtypes.h" for definition of ClassDef and ClassImp
764 AddHeaderIncludeFile("Rtypes.h");
765 }
769
772 }
773}
774
775
776
780
781KVClassFactory::KVClassMember* KVClassFactory::AddMember(const Char_t* name, const Char_t* type, const Char_t* comment, const Char_t* access)
782{
783 // Add a member variable to the class, with name 'f[name]' according to ROOT convention.
784 // The access type is by default "protected", in accordance with OO-encapsulation.
785
786 KVClassMember* m = new KVClassMember(name, type, comment, access);
787 fMembers.Add(m);
788 return m;
789}
790
791
792
796
798{
799 // for each member variable we generate inlined Get/Set methods
800 // for boolean members we generate Is/SetIs methods
801
803 TIter it(&fMembers);
805 while ((m = (KVClassMember*)it())) {
806 TString mem_name = m->GetRealName();
807 TString mem_type = m->GetType();
808 KVClassMethod* meth;
809 if (mem_type == "Bool_t") meth = AddMethod(Form("SetIs%s", mem_name.Data()), "void");
810 else meth = AddMethod(Form("Set%s", mem_name.Data()), "void");
811 meth->SetInline();
812 meth->AddArgument(mem_type);
813 meth->SetMethodComment(
814 Form("Set value of %s", m->GetName())
815 );
816 meth->SetMethodBody(
817 Form(" %s=arg1;", m->GetName())
818 );
819 if (mem_type == "Bool_t") meth = AddMethod(Form("Is%s", mem_name.Data()), mem_type, "public", kFALSE, kTRUE);
820 else meth = AddMethod(Form("Get%s", mem_name.Data()), mem_type, "public", kFALSE, kTRUE);
821 meth->SetInline();
822 meth->SetMethodComment(
823 Form("Get value of %s", m->GetName())
824 );
825 meth->SetMethodBody(
826 Form(" return %s;", m->GetName())
827 );
828 }
829 }
830}
831
832
833
837
839{
840 //Set date, time and user name based on current environment
841 //If available, we use the full name of the current user, otherwise we use the login name.
842
844 fAuthor = user->fRealName;
845 if (fAuthor == "")
846 fAuthor = user->fUser;
847 // remove trailing commas (???)
848 if (fAuthor.EndsWith(",")) {
849 Ssiz_t len = fAuthor.Length() - 1;
850 do {
852 --len;
853 }
854 while (fAuthor.EndsWith(","));
855 }
856 delete user;
857 fNow.Set();
858}
859
860
861
862
869
871{
872 // Return position of beginning of next uncommented line in file starting
873 // from position beg (default = 0).
874 // An uncommented line is a line outside of a "/* ... */" block
875 // containing non-whitespace material before any '/*' or '//'.
876 // If no uncommented line is found we return -1.
877
878 Ssiz_t pos = beg;
879 Ssiz_t beg_cur_line = beg;
880 Bool_t nonWS = kFALSE;
881
882 while (pos < file.Length()) {
883
884 if (file(pos) == ' ' || file(pos) == '\t') {
885 // skip whitespace & tab
886 pos++;
887 }
888 else if (file(pos) == '\n') {
889 // reached newline without seeing comment
890 // if there is non-whitespace stuff on line, this is OK
891 if (nonWS) return beg_cur_line;
892 pos++;
893 beg_cur_line = pos;
894 }
895 else if (file(pos) == '/') {
896
897 if (file(pos + 1) == '*') {
898 // beginning of comment block
899 // was there non-whitespace stuff before this ?
900 if (nonWS) return beg_cur_line;
901 Ssiz_t len = file.Index("*/", pos + 2); // find end of comment
902 if (len > -1) pos = len + 2;
903 else {
904 // end of comment block not found in rest of file
905 // return -1
906 pos = -1;
907 break;
908 }
909 }
910 else if (file(pos + 1) == '/') {
911 // beginning of 1-line comment
912 // was there non-whitespace stuff before this ?
913 if (nonWS) return beg_cur_line;
914 Ssiz_t len = file.Index('\n', pos + 2); // find end of line
915 if (len > 0) {
916 pos = len + 1;
917 beg_cur_line = pos;
918 }
919 else {
920 // end of comment not found in rest of file
921 // return -1
922 pos = -1;
923 break;
924 }
925 }
926 }
927 else {
928 //non-whitespace stuff
929 nonWS = kTRUE;
930 pos++;
931 }
932 }
933 // no new line at end of first uncommented file which is also the last line in the file
934 if (nonWS && pos > -1) return beg_cur_line;
935 return pos;
936}
937
938
939
943
945{
946 //Writes the header file for a class using a template file.
947 //The ClassDef line in the template file will be replaced with one corresponding to the new class.
948
949 ofstream file_h;
950
951 // make sure any required directories exist
953 file_h.open(GetHeaderFileName());
954
955 WritePreProc(file_h);
956 WriteWhoWhen(file_h);
957
958 ifstream file_h_template;
959
960 //open file whose full path was stored in fTemplateH
961 if (!KVBase::SearchAndOpenKVFile(fTemplateH.Data(), file_h_template)) {
962 //this should never happen!
963 cout <<
964 "<KVClassFactory::WriteClassWithTemplateHeader>: cannot open " <<
965 fTemplateH.Data() << endl;
966 return;
967 }
968
969 TString headFile;
970 headFile.ReadFile(file_h_template);
971 file_h_template.close();
972
973 //find ClassDef
974 Ssiz_t class_ind;
975 if ((class_ind = headFile.Index("ClassDef")) > -1) {
976
977 // find end of line just before ClassDef
978 Ssiz_t end_of_line = class_ind;
979 while (headFile(--end_of_line) != '\n') ;
980 //cut file into two parts: before ClassDef line, after ClassDef line
981 TString part1 = headFile(0, end_of_line + 1);
982 //keep part of file from "ClassDef" onwards.
983 TString subs = headFile(class_ind, headFile.Length() - 1);
984 //find next newline character i.e. the end of ClassDef line
985 Ssiz_t nl = subs.Index("\n");
986 TString part3 = subs(nl + 1, subs.Length() - 1);
987 //write ClassDef line
988 TString part2 = " ClassDef(";
989 part2 += fClassName;
990 part2 += ",1)//";
991 part2 += fClassDesc;
992 part2 += "\n";
993
994 KVString part_add;
995 //write declarations of added methods
996 // group by access type
997 if (fMethods.GetSize()) {
999 KVString acc_types[] = {"private", "protected", "public", "-"};
1000 int iac = 0;
1001 while (acc_types[iac] != "-") {
1002 std::unique_ptr<KVSeqCollection> sublist(fMethods.GetSubListWithLabel(acc_types[iac]));
1003 if (sublist->GetEntries()) {
1004 part_add += acc_types[iac];
1005 part_add += ":\n";
1006 TIter next(sublist.get());
1007 KVClassMethod* meth;
1008 while ((meth = (KVClassMethod*)next())) {
1009 meth->WriteDeclaration(line);
1010 part_add += line;
1011 part_add += "\n";
1012 }
1013 part_add += "\n";
1014 }
1015 ++iac;
1016 }
1017 }
1018
1019 //stick all parts together
1020 headFile = part1 + part_add + part2 + part3;
1021 }
1022
1023 file_h << headFile.ReplaceAll(fTemplateClassName.Data(),
1024 fClassName.Data());
1025 file_h << "\n#endif" << endl; //don't forget to close the preprocessor #if !!!
1026 file_h.close();
1027
1028 cout << "<KVClassFactory::WriteClassWithTemplateHeader> : File " << GetHeaderFileName() << " generated." << endl;
1029
1030}
1031
1032
1033
1036
1038{
1039 // Writes the implementation file for the class
1040
1041 ofstream file_cpp;
1042
1043 // make sure any required directories exist
1044 if (fClassPath != "") gSystem->mkdir(fClassPath, kTRUE);
1045 file_cpp.open(GetImpFileName());
1046
1047 file_cpp << "#include \"" << fClassName.Data() << ".h\"" << endl;
1048 if (fImpInc.GetSize()) {
1049 TIter next(&fImpInc);
1050 TObjString* str;
1051 while ((str = (TObjString*)next())) {
1052 file_cpp << "#include \"" << str->String().Data() << "\"" << endl;
1053 }
1054 }
1055 file_cpp << endl << "ClassImp(" << fClassName.Data() << ")\n" << endl;
1056
1057 TString cppFile;
1058 ifstream file_cpp_template;
1059
1060 //open file whose full path was stored in fTemplateCPP
1061 if (!KVBase::
1062 SearchAndOpenKVFile(fTemplateCPP.Data(), file_cpp_template)) {
1063 //this should never happen!
1064 cout << "<KVClassFactory::WriteClassWithTemplateImp>: cannot open "
1065 << fTemplateCPP.Data() << endl;
1066 return;
1067 }
1068
1069 cppFile.ReadFile(file_cpp_template);
1070 file_cpp_template.close();
1071 file_cpp << cppFile.ReplaceAll(fTemplateClassName.Data(),
1072 fClassName.Data());
1073
1074 //write implementations of added methods
1075 if (fMethods.GetSize()) {
1076 KVString line;
1077 TIter next(&fMethods);
1078 KVClassMethod* meth;
1079 while ((meth = (KVClassMethod*)next())) {
1081 file_cpp << line.Data();
1082 }
1083 }
1084 file_cpp.close();
1085
1086 cout << "<KVClassFactory::WriteClassWithTemplateImp> : File " << GetImpFileName() << " generated." << endl;
1087}
1088
1089
1090
1091
1108
1110 const Char_t* templateFile)
1111{
1112 //Check that we have the necessary template files to generate the new class.
1113 //
1114 // if templateFile="" (default), we expect base_class!="", and template files with names base_classTemplate.h and base_classTemplate.cpp
1115 // must be present in either $TEMPLATEDIR, $HOME or $PWD directories.
1116 // the dummy classname "base_classTemplate" will be replaced everywhere by the new class name
1117 //
1118 // if templateFile="/absolute/path/classTemplate" we use classTemplate.h & classTemplate.cpp in the given directory.
1119 // the dummy classname "classTemplate" will be replaced everywhere by the new class name
1120 //
1121 // if templateFile="classTemplate" we look for classTemplate.h & classTemplate.cpp in $TEMPLATEDIR, $HOME or $PWD directories.
1122 // the dummy classname "classTemplate" will be replaced everywhere by the new class name
1123 //
1124 //if all goes well, this method returns kTRUE and fTemplateClassName contains the dummy class name
1125 //which should be replaced in the template files with the name of the new class, while fTemplateH and fTemplateCPP
1126 //contain the full paths to the template files.
1127
1128 if (strcmp(base_class, "")) {
1129 //we have a base class name.
1130 //the dummy class name is base_classTemplate and we look for base_classTemplate.h and base_classTemplate.cpp
1131 fTemplateClassName = base_class;
1132 fTemplateClassName += "Template";
1133 }
1134 else {
1135 //no base class. we look for templateFile.h and templateFile.cpp
1136 fTemplateClassName = gSystem->BaseName(templateFile);
1137 }
1138
1140 //we look for the template .h file in $TEMPLATEDIR, in $HOME and in $PWD
1141 //if found, fTemplateH contains the full path to the file.
1142 //if not found, we return kFALSE as we cannot proceed with the class generation.
1143
1146 }
1147 filename = fTemplateClassName + ".cpp";
1148 //same treatment for '.cpp' file
1150 if (!KVBase::SearchKVFile(filename.Data(), fTemplateCPP)) return kFALSE;
1151 }
1152
1153 return kTRUE;
1154}
1155
1156
1157
1158
1162
1164{
1165 //A new KVClassMethod object will be created and added to the class,
1166 //copying the informations held in kvcm
1167
1168 KVClassMethod* meth = new KVClassMethod(kvcm);
1169 fMethods.Add(meth);
1170}
1171
1172
1173
1174
1185
1186KVClassFactory::KVClassMethod* KVClassFactory::AddMethod(const Char_t* name, const Char_t* return_type, const Char_t* access,
1187 Bool_t isVirtual, Bool_t isConst)
1188{
1189 // Add a method to the class.
1190 // User must give return type and name of method.
1191 // Optional arguments determine access type (public, protected or private)
1192 // and if the method is 'virtual' and/or 'const'
1193 //
1194 // If another method with the same name already exists, user should keep the returned
1195 // pointer to the new KVClassMethod object and use KVClassMethod::AddArgument(),
1196 // KVClassMethod::SetMethodBody() in order to define arguments, method body, etc.
1197 // instead of using the AddMethodArgument, AddMethodBody methods
1198
1199 KVClassMethod* meth = new KVClassMethod;
1200 fMethods.Add(meth);
1201 meth->SetName(name);
1202 meth->SetClassName(fClassName);
1203 meth->SetReturnType(return_type);
1204 meth->SetAccess(access);
1205 meth->SetVirtual(isVirtual);
1206 meth->SetConst(isConst);
1207 return meth;
1208}
1209
1210
1211
1212
1224
1226 const Char_t* argument_name, const Char_t* default_value, const Char_t* access)
1227{
1228 // Add a constructor with or without arguments to the class.
1229 // If no arguments are given, adds a default constructor (no arguments).
1230 //
1231 // Optional argument 'access' determines access type (public, protected or private) [default: "public"]
1232 //
1233 // If more than one argument is needed, user should keep the returned pointer
1234 // to the new object and use KVClassMethod::AddArgument() in order to add further arguments.
1235 //
1236 // In order to define the implementation of the ctor method, user should keep the returned pointer
1237 // to the new object and use KVClassMethod::SetMethodBody(KVString&).
1238
1239 KVClassConstructor* meth = new KVClassConstructor(this);
1240 fMethods.Add(meth);
1241 if (strcmp(argument_type, "")) {
1242 // use type of first argument as name of ctor method
1243 meth->SetName(argument_type);
1244 meth->AddArgument(argument_type, argument_name, default_value);
1245 }
1246 else {
1247 // default constructor
1248 meth->SetName("default_ctor");
1249 }
1250 meth->SetClassName(fClassName);
1252 meth->SetAccess(access);
1253 return meth;
1254}
1255
1256
1257
1258
1264
1265void KVClassFactory::AddMethodArgument(const Char_t* method_name, const Char_t* argument_type,
1266 const Char_t* argument_name, const Char_t* default_value)
1267{
1268 //Add an argument to the method 'method_name' added to the class using AddMethod.
1269 //User must give type of argument.
1270 //Optional argument argument_name gives name of argument (will be used in implementation declaration).
1271 //Optional argument default_value gives default value.
1272
1274 if (!meth) {
1275 Error("AddMethodArgument",
1276 "Method %s not found.", method_name);
1277 return;
1278 }
1279 meth->AddArgument(argument_type, argument_name, default_value);
1280}
1281
1282
1283
1284
1288
1289void KVClassFactory::AddMethodBody(const Char_t* method_name, const KVString& body)
1290{
1291 //Set the body of the code for method 'method_name' added to the class using AddMethod.
1292 //N.B. does not work for implementing constructors, see AddConstructor
1293
1295 if (!meth) {
1296 Error("AddMethodBody",
1297 "Method %s not found.", method_name);
1298 return;
1299 }
1300 meth->SetMethodBody(body);
1301}
1302
1303
1304
1307
1308void KVClassFactory::AddMethodComment(const Char_t* method_name, const KVString& comment)
1309{
1310 //Set the comments for method 'method_name' added to the class using AddMethod.
1311
1313 if (!meth) {
1314 Error("AddMethodComment",
1315 "Method %s not found.", method_name);
1316 return;
1317 }
1318 meth->SetMethodComment(comment);
1319}
1320
1321
1322
1323
1329
1331{
1332 //Add a file which will appear in the 'includes' list of the '.h' file
1333 //i.e. we will add a line
1334 // #include "filename"
1335 //to the .h file
1337}
1338
1339
1340
1341
1347
1349{
1350 //Add a file which will appear in the 'includes' list of the '.cpp' file
1351 //i.e. we will add a line
1352 // #include "filename"
1353 //to the .cpp file
1355// Info("AddImplIncludeFile", "Called for %s %#x. List now contains %d filenames.",
1356// ClassName(), (long)this, fImpInc.GetEntries());
1357}
1358
1359
1360
1361
1364
1366{
1367 //Print infos on object
1368 Info("Print", "object name = %s, address = %p", GetName(), this);
1369 cout << " * fClassName = " << fClassName.Data() << endl;
1370 cout << " * fClassDesc = " << fClassDesc.Data() << endl;
1371 cout << " * fBaseClass = " << fBaseClassName.Data() << endl;
1372 cout << " * fTemplateBase = " << fTemplateBase.Data() << endl;
1373 cout << "---------> Methods" << endl;
1374 fMethods.Print();
1375 cout << "---------> Header Includes" << endl;
1376 fHeadInc.Print();
1377 cout << "---------> Implementation Includes" << endl;
1378 fImpInc.Print();
1379}
1380
1381
1382
1385
1387{
1388 // For each named parameter in the list, we add protected member variables with the name and type of the parameter.
1389
1390 int npars = nvl.GetNpar();
1391 for (int i = 0; i < npars; i++) {
1392 KVNamedParameter* par = nvl.GetParameter(i);
1393 if (par->IsString()) {
1394 AddMember(par->GetName(), "TString", "member automatically generated by KVClassFactory::AddGetSetMethods");
1395 // make sure #include "TString.h" appears in header file
1396 if (! fHeadInc.FindObject("TString.h")) AddHeaderIncludeFile("TString.h");
1397 }
1398 else if (par->IsInt()) {
1399 AddMember(par->GetName(), "Int_t", "member automatically generated by KVClassFactory::AddGetSetMethods");
1400 }
1401 else if (par->IsDouble()) {
1402 AddMember(par->GetName(), "Double_t", "member automatically generated by KVClassFactory::AddGetSetMethods");
1403 }
1404 else if (par->IsBool()) {
1405 AddMember(par->GetName(), "Bool_t", "member automatically generated by KVClassFactory::AddGetSetMethods");
1406 }
1407 }
1408}
1409
1410
1411
1414
1416{
1417 // \param yes =true: Write implementation of all non-ctor/non-dtor methods in the header file of the class
1418
1419 TIter it(&fMethods);
1421 while ((m = (KVClassMethod*)it())) {
1422 if (!m->IsConstructor() && !m->IsDestructor()) m->SetInline(yes);
1423 }
1424 fInlineAllMethods = yes;
1425}
1426
1427
1428
1431
1433{
1434 // \param yes =true: Write implementation of all constructors & the destructor in the header file of the class.
1435
1436 unique_ptr<KVSeqCollection> ctors(fMethods.GetSubListWithMethod("1", "IsConstructor"));
1437 ctors->R__FOR_EACH(KVClassConstructor, SetInline)(yes);
1438 fInlineAllCtors = yes;
1440 if (dtor) dtor->SetInline(yes);
1441}
1442
1443
1444
1445
1449
1451{
1452 // Adds skeleton standard ROOT Copy method if class has
1453 // member variables
1454
1455 if (!GetNumberOfMemberVariables()) return;
1456
1457 AddMethod("Copy", "void", "public", kFALSE, kTRUE);
1458 AddMethodArgument("Copy", "TObject&", "obj");
1459 KVString body("This method copies the current state of 'this' object into 'obj'\n");
1460 body += "You should add here any member variables, for example:\n";
1461 body += "(supposing a member variable ";
1462 body += fClassName;
1463 body += "::fToto)\n";
1464 body += " CastedObj.fToto = fToto;\n";
1465 body += "or\n";
1466 body += " CastedObj.SetToto( GetToto() );";
1467 AddMethodComment("Copy", body);
1468 // call Copy method for base class
1469 body = "\n\n ";
1470 body += fBaseClassName;
1471 body += "::Copy(obj);\n";
1472 if (!fMembers.GetEntries()) body += " //";
1473 else body += " ";
1474 body += fClassName;
1475 body += "& CastedObj = (";
1476 body += fClassName;
1477 body += "&)obj;\n";
1478 if (fMembers.GetEntries()) {
1479 TIter it(&fMembers);
1481 while ((m = (KVClassMember*)it())) {
1482 body += " CastedObj.Set";
1483 body += m->GetRealName();
1484 body += "( Get";
1485 body += m->GetRealName();
1486 body += "() );\n";
1487 }
1488 }
1489 AddMethodBody("Copy", body);
1490}
1491
1492
1493
1497
1499{
1500 // Adds copy constructor if class has member variables
1501 // If class inherits from TObject, this just calls the Copy method
1502
1503 if (!GetNumberOfMemberVariables()) return;
1504
1505 KVClassConstructor* ctor = AddConstructor(Form("const %s&", fClassName.Data()), "obj");
1506 ctor->SetCopyCtor();
1507 ctor->SetMethodComment("Copy constructor");
1508 if (fBaseClassTObject) {
1509 ctor->SetMethodBody(" obj.Copy(*this);");
1510 }
1511
1512}
1513
1514
1515
1524
1526{
1527 // For classes with member variables, add a constructor which initialises
1528 // the values of all member variables
1529 // If base_ctor is non-null, it is assumed to point to a constructor which has
1530 // been deduced from the base class' list of constructors; in this case we
1531 // add our class' members to the beginning of the list of arguments
1532 // so that if any of the base class ctor arguments have default values, they
1533 // will be at the end of the list
1534
1535 if (!GetNumberOfMemberVariables()) return;
1536
1537 TIter next(&fMembers);
1538 KVClassMember* memb = (KVClassMember*)next();
1539 KVClassConstructor* ctor;
1540 Bool_t adding_to_base = kFALSE;
1541 Int_t add_to_base(1);
1542 if (base_ctor) {
1543 ctor = base_ctor;
1544 adding_to_base = kTRUE;
1545 ctor->AddArgument(add_to_base, memb->GetType(), memb->GetRealName());
1546 ctor->SetMemberVariableNameForArgument(add_to_base, memb->GetName());
1547 }
1548 else {
1549 ctor = AddConstructor(memb->GetType(), memb->GetRealName());
1550 ctor->SetMemberVariableNameForArgument(1, memb->GetName());
1551 }
1552 int arg_num = 2;
1553 while ((memb = (KVClassMember*)next())) {
1554 if (adding_to_base) {
1555 ctor->AddArgument(++add_to_base, memb->GetType(), memb->GetRealName());
1556 ctor->SetMemberVariableNameForArgument(add_to_base, memb->GetName());
1557 }
1558 else {
1559 ctor->AddArgument(memb->GetType(), memb->GetRealName());
1560 ctor->SetMemberVariableNameForArgument(arg_num++, memb->GetName());
1561 }
1562 }
1563 ctor->SetMethodComment("Constructor with initial values for all member variables");
1564}
1565
1566
1567
1571
1573{
1574 // Add "ClassName& operator= (const ClassName&)" method if class
1575 // has member variables
1576
1577 if (!GetNumberOfMemberVariables()) return;
1578
1579 KVClassMethod* oper = AddMethod("operator=", Form("%s&", fClassName.Data()));
1580 oper->AddArgument(Form("const %s&", fClassName.Data()), "other");
1581 oper->SetMethodComment("Assignment operator");
1582 KVString body = " if(this != &other) { // check for self-assignment\n";
1583 if (fBaseClassTObject) {
1584 body += " other.Copy(*this);\n";
1585 }
1586 else {
1587 if (fMembers.GetEntries()) {
1588 TIter it(&fMembers);
1590 while ((m = (KVClassMember*)it())) {
1591 body += " Set";
1592 body += m->GetRealName();
1593 body += "( other.Get";
1594 body += m->GetRealName();
1595 body += "() );\n";
1596 }
1597 }
1598 }
1599 body += " }\n";
1600 body += " return (*this);";
1601 oper->SetMethodBody(body);
1602}
1603
1604
1605
1606
1610//Helper classes for KVClassFactory
1611
1612
1613
1616
1617void KVClassFactory::KVClassMethod::WriteDeclaration(KVString& decl)
1618{
1619 //Write declaration in the KVString object
1620 //If method is inline write method body directly after declaration
1621
1622 decl = " ";
1623 if (fVirtual) decl += "virtual ";
1624 if (IsNormalMethod()) {
1625 decl += GetReturnType();
1626 decl += " ";
1627 decl += GetName();
1628 }
1629 else {
1630 if (IsDestructor()) decl += "~";
1631 decl += GetClassName();
1632 }
1633 decl += "(";
1634 for (int i = 1; i <= fNargs; i++) {
1635 decl += fFields.GetStringValue(Form("Arg_%d", i));
1636 if (fFields.HasParameter(Form("Arg_%d_name", i))) {
1637 decl += " ";
1638 decl += fFields.GetStringValue(Form("Arg_%d_name", i));
1639 }
1640 else
1641 decl += Form(" arg%d", i);
1642 if (fFields.HasParameter(Form("Arg_%d_default", i))) {
1643 decl += " = ";
1644 decl += fFields.GetStringValue(Form("Arg_%d_default", i));
1645 }
1646 if (i < fNargs) decl += ", ";
1647 }
1648 decl += ")";
1649 if (fConst) decl += " const";
1650 if (!IsInline()) {
1651 decl += ";";
1652 return;
1653 }
1654 // write method body of inline function
1655 write_method_body(decl);
1656}
1657
1658
1659
1662
1664{
1665 //Write declaration in the KVString object
1666
1667 decl = GetType();
1668 decl += " ";
1669 decl += GetName();
1670
1671 decl += ";//";
1672 decl += GetComment();
1673}
1674
1675
1676
1678
1680{
1681 KVString indentation = "";
1682 if (IsInline()) indentation = " ";
1683 decl += "\n";
1684 decl += __add_indented_line("{", indentation);
1685 if (!strcmp(GetAccess(), "private")) decl += __add_indented_line(" // PRIVATE method", indentation);
1686 else if (!strcmp(GetAccess(), "protected")) decl += __add_indented_line(" // PROTECTED method", indentation);
1687 if (fFields.HasParameter("Body")) {
1688 //write body of method
1689 decl += __add_indented_line(fFields.GetStringValue("Body"), indentation);
1690 }
1691 else {
1692 if (fFields.HasParameter("ReturnType") && strcmp(fFields.GetStringValue("ReturnType"), "void")) {
1693 KVString return_dir = "return (";
1694 return_dir += GetReturnType();
1695 return_dir += ")0;";
1696 __add_indented_line(return_dir, indentation);
1697 }
1698 }
1699 decl += __add_indented_line("}", indentation, kFALSE);
1700}
1701
1702
1703
1705
1707{
1708 KVString indentation = "";
1709 if (IsInline()) indentation = " ";
1710 if ((fNargs && !IsCopyCtor()) ||
1711 ((IsCopyCtor() || IsDefaultCtor()) && fFields.HasParameter("BaseClass"))
1712 || (IsCopyCtor() && !fParentClass->IsBaseClassTObject())) {
1713 decl += "\n : ";
1714 if (fFields.HasParameter("BaseClass")) {
1715 // initialise base class
1716 decl += fFields.GetStringValue("BaseClass");
1717 decl += "(";
1718 if (!IsCopyCtor() && fNargs) {
1719 Int_t base_args = 0;
1720 for (int i = 1; i <= fNargs; i++) {
1721 if (fFields.HasParameter(Form("Arg_%d_baseclass", i))) {
1722 ++base_args;
1723 if (fFields.HasParameter(Form("Arg_%d_name", i))) {
1724 if (base_args > 1) decl += ", ";
1725 decl += fFields.GetStringValue(Form("Arg_%d_name", i));
1726 }
1727 else {
1728 if (base_args > 1) decl += ", ";
1729 decl += Form("arg%d", i);
1730 }
1731 }
1732 }
1733 }
1734 else if (IsCopyCtor() && !fParentClass->IsBaseClassTObject()) {
1735 // for a derived object not inheriting TObject we call the copy ctor of the parent class
1736 decl += fFields.GetStringValue("Arg_1_name");
1737 }
1738 decl += ")";
1739 if ((fNargs && !IsCopyCtor() && fParentClass->GetNumberOfMemberVariables())
1740 || (IsCopyCtor() && !fParentClass->IsBaseClassTObject() && fParentClass->GetNumberOfMemberVariables())) decl += ", ";
1741 }
1742 if (fParentClass->GetNumberOfMemberVariables()) {
1743 // initialise member variables
1744 if (!IsCopyCtor() && fNargs) {
1745 Int_t mem_vars = 0;
1746 for (int i = 1; i <= fNargs; i++) {
1747 if (fFields.HasStringParameter(Form("Arg_%d_memvar", i))) {
1748 if (mem_vars) decl += ", ";
1749 decl += fFields.GetStringValue(Form("Arg_%d_memvar", i));
1750 decl += "(";
1751 decl += fFields.GetStringValue(Form("Arg_%d_name", i));
1752 decl += ")";
1753 ++mem_vars;
1754 }
1755 }
1756 }
1757 else if ((IsCopyCtor() && !fParentClass->IsBaseClassTObject())) {
1758 TIter it(fParentClass->GetListOfMembers());
1760 Int_t imem = 0;
1761 while ((m = (KVClassMember*)it())) {
1762 if (imem) decl += ", ";
1763 decl += m->GetName();
1764 decl += "( ";
1765 decl += fFields.GetStringValue("Arg_1_name");
1766 decl += ".Get";
1767 decl += m->GetRealName();
1768 decl += "() )";
1769 ++imem;
1770 }
1771 }
1772 }
1773 }
1774 decl += "\n";
1775 decl += __add_indented_line("{", indentation);
1776 if (!strcmp(GetAccess(), "private")) decl += __add_indented_line(" // PRIVATE constructor", indentation);
1777 else if (!strcmp(GetAccess(), "protected")) decl += __add_indented_line(" // PROTECTED constructor", indentation);
1778 if (fFields.HasParameter("Body")) {
1779 //write body of method
1780 decl += __add_indented_line(fFields.GetStringValue("Body"), indentation);
1781 }
1782 decl += __add_indented_line("}", indentation, kFALSE);
1783}
1784
1785
1786
1790
1792{
1793 //Write skeleton implementation in the KVString object
1794 //All constructors call the default ctor of the base class (if defined)
1795
1796 decl = "";
1797 if (fFields.HasParameter("Comment")) {
1798 // Go through comment line by line adding doxygen comment markers
1799 KVString comment(fFields.GetStringValue("Comment"));
1800 comment.Begin("\n");
1801 // find longest line
1802 Ssiz_t longest = 0;
1803 while (!comment.End()) {
1804 KVString line = comment.Next();
1805 if (line.Length() > longest) longest = line.Length();
1806 }
1807 longest += 4; // remember to add "/// " at beginning of each comment line
1808 // write "////...." as long as longest line
1809 while (longest--) decl += "/";
1810 decl += "\n";
1811 comment.Begin("\n");
1812 while (!comment.End()) {
1813 KVString line = comment.Next();
1814 decl += "/// ";
1815 decl += line;
1816 decl += "\n";
1817 }
1818 decl += "\n";
1819 }
1820 decl += GetReturnType();
1821 if (IsNormalMethod()) {
1822 decl += " ";
1823 }
1824 decl += GetClassName();
1825 decl += "::";
1826 if (IsNormalMethod())
1827 decl += GetName();
1828 else {
1829 if (IsDestructor()) decl += "~";
1830 decl += GetClassName();
1831 }
1832 decl += "(";
1833 for (int i = 1; i <= fNargs; i++) {
1834 decl += fFields.GetStringValue(Form("Arg_%d", i));
1835 if (fFields.HasParameter(Form("Arg_%d_name", i))) {
1836 decl += " ";
1837 decl += fFields.GetStringValue(Form("Arg_%d_name", i));
1838 }
1839 else
1840 decl += Form(" arg%d", i);
1841 if (i < fNargs) decl += ", ";
1842 }
1843 decl += ")";
1844 if (fConst) decl += " const";
1845 write_method_body(decl);
1846 decl += "\n\n";
1847
1848}
1849
1850
1851
1852
1855
1857{
1858 //ctor par copie
1859 obj.Copy(*this);
1860}
1861
1862
1863
1864
1867
1869{
1870 //ctor par copie
1871 obj.Copy(*this);
1872}
1873
1874
1875
1876
1879
1881{
1882 //copy this to obj
1883 KVBase::Copy(obj);
1884 ((KVClassMember&)obj).SetComment(GetComment());
1885 ((KVClassMember&)obj).fRealName = GetRealName();
1886}
1887
1888
1889
1890
1893
1895{
1896 //copy this to obj
1898 ((KVClassMethod&)obj).SetVirtual(IsVirtual());
1899 ((KVClassMethod&)obj).SetConst(IsConst());
1900 fFields.Copy(((KVClassMethod&)obj).fFields);
1901 ((KVClassMethod&)obj).SetNargs(GetNargs());
1902 ((KVClassMethod&)obj).SetInline(IsInline());
1903}
1904
1905
1906
1910
1911void KVClassFactory::KVClassMethod::AddArgument(Int_t i, const Char_t* type, const Char_t* argname, const Char_t* defaultvalue)
1912{
1913 // Add an argument to the method, which will be in i-th position in the argument list
1914 // Any existing arguments with indices [i,fNargs] will first be moved to [i+1,fNargs+1]
1915
1916 if (!(i > 0 && i <= fNargs + 1)) {
1917 Error("AddArgument(Int_t i, ...)", "Must be called with i>0 & i<=%d", fNargs + 1);
1918 return;
1919 }
1920
1921 if (i == fNargs + 1) { // this is just same as call to AddArgument(type,argname,...)
1922 AddArgument(type, argname, defaultvalue);
1923 return;
1924 }
1925
1926 for (int j = fNargs; j >= i; --j) {
1927 if (fFields.HasStringParameter(Form("Arg_%d", j))) {
1928 fFields.SetValue(Form("Arg_%d", j + 1), fFields.GetStringValue(Form("Arg_%d", j)));
1929 fFields.RemoveParameter(Form("Arg_%d", j));
1930 }
1931 if (fFields.HasStringParameter(Form("Arg_%d_name", j))) {
1932 fFields.SetValue(Form("Arg_%d_name", j + 1), fFields.GetStringValue(Form("Arg_%d_name", j)));
1933 fFields.RemoveParameter(Form("Arg_%d_name", j));
1934 }
1935 if (fFields.HasIntParameter(Form("Arg_%d_baseclass", j))) {
1936 fFields.SetValue(Form("Arg_%d_baseclass", j + 1), fFields.GetIntValue(Form("Arg_%d_baseclass", j)));
1937 fFields.RemoveParameter(Form("Arg_%d_baseclass", j));
1938 }
1939 if (fFields.HasStringParameter(Form("Arg_%d_default", j))) {
1940 fFields.SetValue(Form("Arg_%d_default", j + 1), fFields.GetStringValue(Form("Arg_%d_default", j)));
1941 fFields.RemoveParameter(Form("Arg_%d_default", j));
1942 }
1943 }
1944
1945 KVString _type(type);
1946 fFields.SetValue(Form("Arg_%d", i), _type);
1947 if (strcmp(defaultvalue, "")) {
1948 KVString _s(defaultvalue);
1949 fFields.SetValue(Form("Arg_%d_default", i), _s);
1950 }
1951 if (strcmp(argname, "")) {
1952 KVString _s(argname);
1953 fFields.SetValue(Form("Arg_%d_name", i), _s);
1954 }
1955
1956 ++fNargs;
1957}
1958
1959
1960
1963
1965{
1966 // print the KVClass method
1967 cout << "KVClassMethod object -----> " << GetName() << endl;
1968 fFields.Print();
1969 cout << "This method is " << GetAccess() << endl;
1970 if (fConst) cout << "This method is CONST" << endl;
1971 if (fVirtual) cout << "This method is VIRTUAL" << endl;
1972}
1973
1974
1975
1978
1980{
1981 // print the KVClass member
1982 cout << "KVClassMember object -----> " << GetType() << " " << GetName() << endl;
1983 cout << "This member is " << GetAccess() << endl;
1984}
1985
1986
1987
1988
1994
1996{
1997 // Add constructors with the same signature as all base class constructors
1998 // (apart from the default ctor or any copy constructors, which are a special case)
1999 // If this class has its own member variables, we add them to the argument list
2000 // of each base class constructor.
2001
2002 if (!fBaseClass) return;
2003
2004 KVHashList clist;
2006 unique_ptr<KVSeqCollection> constructors(clist.GetSubListWithName(fBaseClassName));
2007 TIter next_ctor(constructors.get());
2008 TMethod* method;
2009 while ((method = (TMethod*)next_ctor())) {
2010 if (!method->GetNargs()) continue; // ignore default ctor
2011 TList* args = method->GetListOfMethodArgs();
2012 TMethodArg* arg = (TMethodArg*)args->First();
2013 TString typenam = arg->GetFullTypeName();
2014 if (typenam.Contains(fBaseClassName)) continue; // ignore copy ctor
2015 KVClassConstructor* ctor;
2016 if (arg->GetDefault()) ctor = AddConstructor(typenam, arg->GetName(), arg->GetDefault());
2017 else ctor = AddConstructor(typenam, arg->GetName());
2018 ctor->SetBaseClassArgument(1);
2019 for (int i = 1; i < method->GetNargs(); i++) {
2020 arg = (TMethodArg*)args->At(i);
2021 if (arg->GetDefault()) ctor->AddArgument(arg->GetFullTypeName(), arg->GetName(), arg->GetDefault());
2022 else ctor->AddArgument(arg->GetFullTypeName(), arg->GetName());
2023 ctor->SetBaseClassArgument(i + 1);
2024 }
2025 ctor->SetMethodComment(Form("Constructor inherited from %s", GetBaseClass()));
2027 }
2028}
2029
2030
2031
2034
2036{
2037 // Add default destructor to class
2038
2039 if (!GetDestructor()) {
2041 d->SetClassName(fClassName);
2042 d->SetAccess(access);
2043 fMethods.Add(d);
2044 }
2045}
2046
2047
2048
2051
2052KVClassFactory::KVClassMember::KVClassMember(const Char_t* name, const Char_t* type, const Char_t* comment, const Char_t* access)
2053 : KVBase(Form("f%s", name), type), fComment(comment), fRealName(name)
2054{
2055 // New class member variable
2056 SetAccess(access);
2057}
2058
2059
int Int_t
#define d(i)
bool Bool_t
int Ssiz_t
char Char_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
const char Option_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
Base class for KaliVeda framework.
Definition KVBase.h:142
static const Char_t * GetTEMPLATEDIRFilePath(const Char_t *namefile="")
Definition KVBase.cpp:83
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition KVBase.cpp:538
static Bool_t SearchAndOpenKVFile(const Char_t *name, KVSQLite::database &dbfile, const Char_t *kvsubdir="")
Definition KVBase.cpp:649
virtual void Copy(TObject &) const
Make a copy of this object.
Definition KVBase.cpp:394
virtual const Char_t * GetType() const
Definition KVBase.h:177
Constructor for a class generated with KVClassFactory.
virtual void write_method_body(KVString &decl)
void SetMemberVariableNameForArgument(Int_t i, const Char_t *memvar)
Destructor for a class generated with KVClassFactory.
Member variable in a class generated with KVClassFactory.
virtual void WriteDeclaration(KVString &)
Write declaration in the KVString object.
const Char_t * GetRealName() const
get short name without leading 'f'
void Print(Option_t *="") const
print the KVClass member
void SetAccess(const Char_t *acc="public")
set access type : public, protected or private
const Char_t * GetComment() const
get access type : public, protected or private
void Copy(TObject &obj) const
copy this to obj
Method in a class generated with KVClassFactory.
virtual void write_method_body(KVString &decl)
void SetMethodComment(const KVString &com)
void Print(Option_t *="") const
print the KVClass method
KVClassMethod(Bool_t Virtual=kFALSE, Bool_t Const=kFALSE, Bool_t Inline=kFALSE)
void SetConst(Bool_t c=kTRUE)
void WriteImplementation(KVString &decl)
void SetBaseClass(const Char_t *name)
void Copy(TObject &obj) const
copy this to obj
void AddArgument(const Char_t *type, const Char_t *argname="", const Char_t *defaultvalue="")
void SetReturnType(const Char_t *type)
void SetClassName(const Char_t *name)
void SetVirtual(Bool_t c=kTRUE)
void SetInline(Bool_t yes=kTRUE)
void SetMethodBody(const KVString &body)
Factory class for generating skeleton files for new classes.
void Print(Option_t *opt="") const
Print infos on object.
Bool_t fInlineAllCtors
kTRUE if all ctor implementations written in header
void WriteWhoWhen(std::ofstream &)
Bool_t WithMultipleBaseClasses() const
void SetTemplate(Bool_t temp, const Char_t *temp_file)
KVList fMembers
list of member variables for class
Bool_t fInlineAllMethods
kTRUE if all (non-ctor) method implementations written in header
void AddMethodComment(const Char_t *method_name, const KVString &comment)
Set the comments for method 'method_name' added to the class using AddMethod.
void WriteClassWithTemplateImp()
Writes the implementation file for the class.
KVString fTemplateClassName
name of template dummy class
void GenerateGettersAndSetters()
const Char_t * GetBaseClass() const
const Char_t * GetClassName() const
const Char_t * GetClassDesc() const
KVList fMethods
list of methods added to class
void GenerateCode()
Generate header and implementation file for currently-defined class.
TDatime fNow
for dating files
Bool_t fHasBaseClass
kTRUE if class derived from another
void SetClassName(const Char_t *n)
KVString fTemplateCPP
full path to template .cpp
void AddMemberInitialiserConstructor(KVClassConstructor *=nullptr)
TClass * fBaseClass
description of base class
void WriteClassHeader()
Write the class header file.
KVString fClassDesc
class description
Bool_t fInheritAllCtors
kTRUE if all ctor from base class should be inherited
KVClassFactory()
Default ctor.
KVString fClassPath
directory in which to write source files, if not working directory
static void MakeClass(const Char_t *classname, const Char_t *classdesc, const Char_t *base_class="", Bool_t withTemplate=kFALSE, const Char_t *templateFile="")
void AddHeaderIncludeFile(const Char_t *filename)
void Copy(TObject &obj) const
Copy the state of this KVClassFactory to the one referenced by 'obj'.
void AddDestructor(const TString &access="public")
Add default destructor to class.
void WriteClassDec(std::ofstream &)
void AddImplIncludeFile(const Char_t *filename)
KVString fTemplateH
full path to template .h
KVString fBaseClassName
name of base class
KVClassConstructor * GetDefaultCtor() const
Bool_t CheckTemplateFiles(const Char_t *base_class, const Char_t *templateFile)
const Char_t * GetHeaderFileName() const
void SetClassDesc(const Char_t *d)
const Char_t * GetImpFileName() const
void WritePreProc(std::ofstream &)
Int_t GetNumberOfMemberVariables() const
void AddMethodBody(const Char_t *method_name, const KVString &body)
Ssiz_t FindNextUncommentedLine(TString &, Ssiz_t beg=0)
void WriteClassWithTemplateHeader()
void InlineAllMethods(bool yes=true)
Bool_t fBaseClassTObject
kTRUE if class derived from TObject
KVList fHeadInc
list of 'includes' to be added to header file
KVString fTemplateBase
template base name passed to SetTemplate method
void AddMethodArgument(const Char_t *method_name, const Char_t *argument_type, const Char_t *argument_name="", const Char_t *default_value="")
void InlineAllConstructors(bool yes=true)
KVString fClassName
name of class to generate
void SetBaseClass(const Char_t *b)
void AddGetSetMethods(const KVNameValueList &)
For each named parameter in the list, we add protected member variables with the name and type of the...
KVClassDestructor * GetDestructor() const
Bool_t fWithTemplate
true if class has a template
KVClassConstructor * AddConstructor(const Char_t *argument_type="", const Char_t *argument_name="", const Char_t *default_value="", const Char_t *access="public")
KVClassMember * AddMember(const Char_t *name, const Char_t *type, const Char_t *comment, const Char_t *access="protected")
KVString fAuthor
user who called ClassFactory to generate class
KVList fImpInc
list of 'includes' to be added to implementation file
KVClassMethod * AddMethod(const Char_t *name, const Char_t *return_type, const Char_t *access="public", Bool_t isVirtual=kFALSE, Bool_t isConst=kFALSE)
Extended version of ROOT THashList.
Definition KVHashList.h:29
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
KVNamedParameter * GetParameter(Int_t idx) const
return the parameter object with index idx
Int_t GetNpar() const
return the number of stored parameters
A generic named parameter storing values of different types.
Bool_t IsDouble() const
Bool_t IsInt() const
Bool_t IsBool() const
Bool_t IsString() const
virtual TObject * FindObject(const char *name) const
KVSeqCollection * GetSubListWithName(const Char_t *retvalue) const
KVSeqCollection * GetSubListWithMethod(const Char_t *retvalue, const Char_t *method) const
virtual Int_t GetSize() const
virtual TObject * FindObjectByName(const Char_t *name) const
virtual void Add(TObject *obj)
T * get_object(const TString &name) const
KVSeqCollection * GetSubListWithLabel(const Char_t *retvalue) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition KVString.h:73
void Begin(TString delim) const
Definition KVString.cpp:565
Bool_t End() const
Definition KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition KVString.cpp:695
TList * GetListOfMethods(Bool_t load=kTRUE)
virtual void Print(Option_t *option, const char *wildcard, Int_t recurse=1) const
virtual void AddAll(const TCollection *col)
virtual Int_t GetEntries() const
void Set()
const char * AsString() const
Int_t GetNargs() const
TObject * First() const override
TObject * At(Int_t idx) const override
const char * GetFullTypeName() const
const char * GetDefault() const
virtual TList * GetListOfMethodArgs()
const char * GetName() const override
virtual void SetName(const char *name)
virtual const char * GetName() const
void SetBit(UInt_t f)
virtual void Warning(const char *method, const char *msgfmt,...) const
R__ALWAYS_INLINE Bool_t IsZombie() const
virtual void Copy(TObject &object) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
Ssiz_t Length() const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
void ToUpper()
TString & Append(char c, Ssiz_t rep=1)
TString & Prepend(char c, Ssiz_t rep=1)
std::istream & ReadFile(std::istream &str)
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
virtual UserGroup_t * GetUserInfo(const char *user=nullptr)
virtual const char * BaseName(const char *pathname)
TLine * line
RPY_EXPORTED bool IsDestructor(TCppMethod_t method)
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Type GetType(const std::string &Name)
TString fRealName
TString fUser
TMarker m
ClassImp(TPyArg)