GCC Code Coverage Report


Directory: ./
File: src/BackEnd/wrapper_generator_struct.cpp
Date: 2025-12-15 11:32:44
Exec Total Coverage
Lines: 320 334 95.8%
Functions: 14 14 100.0%
Branches: 547 610 89.7%

Line Branch Exec Source
1 /***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5 ****************************************/
6
7 #include "openFileStream.h"
8 #include "header_generator.h"
9 #include "cmakelist_generator.h"
10 #include "wrapper_generator_module.h"
11
12 #include "wrapper_generator_struct.h"
13
14 ///Create the wrapper declaration of the given class
15 /** @param manager : PTraitBackendManager which handles all trait backend
16 * @param[out] fs : file to be completed
17 * @param classConfig : configuration of the class to be used
18 * @param mode : mode of the generator
19 */
20 2 void wrapper_generator_enum_header(const PWrapperTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
21
2/2
✓ Branch 0 (2→3) taken 2 times.
✓ Branch 2 (3→4) taken 2 times.
2 PString body, className(wrapper_getClassName(classConfig));
22
1/1
✓ Branch 0 (4→5) taken 2 times.
2 fs << "//Allocation and deallocation\n";
23
3/3
✓ Branch 0 (5→6) taken 2 times.
✓ Branch 2 (6→7) taken 2 times.
✓ Branch 4 (7→8) taken 2 times.
2 fs << "PyObject * "+className+"_newC(PyTypeObject * type, PyObject * args, PyObject * kwds);\n\n";
24
25 // fs << "\nextern PyGetSetDef "+className+"_getseters[];\n";
26 // fs << "extern PyMemberDef "+className+"_members[];\n";
27 // fs << "extern PyMethodDef "+className+"_methods[];\n";
28 // fs << "extern PyTypeObject "+className+"Type;\n\n";
29 2 }
30
31 ///Create the wrapper declaration of the given class
32 /** @param manager : PTraitBackendManager which handles all trait backend
33 * @param[out] fs : file to be completed
34 * @param classConfig : configuration of the class to be used
35 * @param mode : mode of the generator
36 */
37 3 void wrapper_generator_class_header(const PWrapperTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
38
2/2
✓ Branch 0 (2→3) taken 3 times.
✓ Branch 2 (3→4) taken 3 times.
3 PString body, className(wrapper_getClassName(classConfig));
39
3/3
✓ Branch 0 (4→5) taken 3 times.
✓ Branch 2 (5→6) taken 3 times.
✓ Branch 4 (6→7) taken 3 times.
3 fs << classConfig.getClassDocumentation() + "\n";
40
3/3
✓ Branch 0 (8→9) taken 3 times.
✓ Branch 2 (9→10) taken 3 times.
✓ Branch 4 (10→11) taken 3 times.
3 fs << "struct "+className+"{\n";
41
1/1
✓ Branch 0 (13→14) taken 3 times.
3 fs << "\tPyObject_HEAD\n";
42
1/1
✓ Branch 0 (14→15) taken 3 times.
3 const PVecClassAttribute & vecAttr = classConfig.getListAttribute();
43
2/2
✓ Branch 0 (31→16) taken 5 times.
✓ Branch 1 (31→32) taken 3 times.
16 for(PVecClassAttribute::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
44
2/2
✓ Branch 0 (18→19) taken 5 times.
✓ Branch 2 (19→20) taken 5 times.
10 fs << project_wrapper_attributeDef(*it);
45 }
46
1/1
✓ Branch 0 (32→33) taken 3 times.
3 fs << "};\n\n";
47 // fs << "//Check function\n";
48 // fs << "bool "+className+"_check(std::string & error, const "+className+" & obj);\n";
49
50
1/1
✓ Branch 0 (33→34) taken 3 times.
3 fs << "//TODO : add new and free for array data\n";
51
1/1
✓ Branch 0 (34→35) taken 3 times.
3 fs << "//getter and setters\n";
52 // for(PVecClassAttribute::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
53 // fs << project_wrapper_classGetterSetterDef(className, *it);
54 // }
55
1/1
✓ Branch 0 (35→36) taken 3 times.
3 manager.classMethodDeclaration(fs, classConfig, mode);
56 //Check when we defined std::vector
57 // fs << "//Allocation and deallocation\n";
58
3/3
✓ Branch 0 (36→37) taken 3 times.
✓ Branch 2 (37→38) taken 3 times.
✓ Branch 4 (38→39) taken 3 times.
3 fs << "PyObject * "+className+"_newC(PyTypeObject * type, PyObject * args, PyObject * kwds);\n";
59
5/5
✓ Branch 0 (41→42) taken 3 times.
✓ Branch 2 (42→43) taken 3 times.
✓ Branch 4 (43→44) taken 3 times.
✓ Branch 6 (44→45) taken 3 times.
✓ Branch 8 (45→46) taken 3 times.
3 fs << "void "+className+"_dealloc("+className+" * self);\n\n";
60
61
3/3
✓ Branch 0 (50→51) taken 3 times.
✓ Branch 2 (51→52) taken 3 times.
✓ Branch 4 (52→53) taken 3 times.
3 fs << "\nextern PyGetSetDef "+className+"_getseters[];\n";
62
3/3
✓ Branch 0 (55→56) taken 3 times.
✓ Branch 2 (56→57) taken 3 times.
✓ Branch 4 (57→58) taken 3 times.
3 fs << "extern PyMemberDef "+className+"_members[];\n";
63
3/3
✓ Branch 0 (60→61) taken 3 times.
✓ Branch 2 (61→62) taken 3 times.
✓ Branch 4 (62→63) taken 3 times.
3 fs << "extern PyMethodDef "+className+"_methods[];\n";
64
3/3
✓ Branch 0 (65→66) taken 3 times.
✓ Branch 2 (66→67) taken 3 times.
✓ Branch 4 (67→68) taken 3 times.
3 fs << "extern PyTypeObject "+className+"Type;\n\n";
65 3 }
66
67 ///Implement new and dealloc
68 /** @param[out] fs : output file stream to be used
69 * @param classConfig : class configuration
70 * @param moduleName : name of the module where the class should be defined
71 */
72 2 void project_wrapper_enumImplNewc(std::ofstream & fs, const PClassConfig & classConfig){
73
1/1
✓ Branch 0 (2→3) taken 2 times.
2 const std::vector<PClassAttribute> & vecAttr = classConfig.getListAttribute();
74
2/2
✓ Branch 0 (3→4) taken 2 times.
✓ Branch 2 (4→5) taken 2 times.
2 PString pythonClassName(classConfig.getName());
75
2/2
✓ Branch 0 (5→6) taken 2 times.
✓ Branch 2 (6→7) taken 2 times.
2 PString className("WP"+pythonClassName);
76
1/2
✗ Branch 0 (9→10) not taken.
✓ Branch 1 (9→17) taken 2 times.
2 if(vecAttr.size() == 0lu){
77 fs << "#error \""+className+" error : Missing enum values as attribute !\"" << std::endl;
78 return;
79 }
80
3/3
✓ Branch 0 (17→18) taken 2 times.
✓ Branch 2 (18→19) taken 2 times.
✓ Branch 4 (19→20) taken 2 times.
2 fs << "///Generic function to create a "+className+" or a variable\n";
81
1/1
✓ Branch 0 (22→23) taken 2 times.
2 fs << "/**\t@param extraPythonCode : extra python code to be added to the existing one\n";
82
1/1
✓ Branch 0 (23→24) taken 2 times.
2 fs << " * \t@param objectName : name of the object to get\n";
83
1/1
✓ Branch 0 (24→25) taken 2 times.
2 fs << " * \t@return pointer to the asked object name or NULL if the object was not found\n";
84
1/1
✓ Branch 0 (25→26) taken 2 times.
2 fs << "*/\n";
85
3/3
✓ Branch 0 (26→27) taken 2 times.
✓ Branch 2 (27→28) taken 2 times.
✓ Branch 4 (28→29) taken 2 times.
2 fs << "PyObject* "+className+"_newGeneric(const std::string & extraPythonCode, const std::string & objectName){\n";
86
1/1
✓ Branch 0 (31→32) taken 2 times.
2 fs << "\t//First let's write the python code in a string\n";
87
1/1
✓ Branch 0 (32→33) taken 2 times.
2 fs << "\t//Important note : it there is no default value of the enumerate values, we get a nice segmentation fault because why not\n";
88
1/1
✓ Branch 0 (33→34) taken 2 times.
2 fs << "\tstd::string pythonStr(\"from enum import Enum\\n\"\n";
89
3/3
✓ Branch 0 (34→35) taken 2 times.
✓ Branch 2 (35→36) taken 2 times.
✓ Branch 4 (36→37) taken 2 times.
2 fs << "\t\t\"class "+pythonClassName+"(Enum):\\n\"\n";
90 2 size_t index(0lu);
91
2/2
✓ Branch 0 (68→40) taken 4 times.
✓ Branch 1 (68→69) taken 2 times.
12 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
92
3/3
✓ Branch 0 (42→43) taken 4 times.
✓ Branch 2 (43→44) taken 4 times.
✓ Branch 4 (44→45) taken 4 times.
8 fs << "\t\t\"\t"+it->getName();
93
1/1
✓ Branch 0 (46→47) taken 4 times.
4 fs << " = ";
94
3/4
✓ Branch 0 (49→50) taken 4 times.
✓ Branch 2 (50→51) taken 4 times.
✗ Branch 4 (51→52) not taken.
✓ Branch 5 (51→56) taken 4 times.
4 if(it->getDefaultValue() != ""){
95 fs << it->getDefaultValue();
96 }else{
97
1/1
✓ Branch 0 (56→57) taken 4 times.
4 fs << index;
98 }
99
1/1
✓ Branch 0 (57→58) taken 4 times.
4 fs << "\\n\"\n";
100 4 ++index;
101 }
102
1/1
✓ Branch 0 (69→70) taken 2 times.
2 fs << "\t\t\"\tdef getTypeName():\\n\"\n";
103
3/3
✓ Branch 0 (70→71) taken 2 times.
✓ Branch 2 (71→72) taken 2 times.
✓ Branch 4 (72→73) taken 2 times.
2 fs << "\t\t\"\t\treturn \\\""+pythonClassName+"\\\"\\n\"\n";
104
1/1
✓ Branch 0 (75→76) taken 2 times.
2 fs << "\t\t\"\");\n";
105
1/1
✓ Branch 0 (76→77) taken 2 times.
2 fs << "\tpythonStr += extraPythonCode;\n";
106
1/1
✓ Branch 0 (77→78) taken 2 times.
2 fs << "\t//Now, we create the global dictionnary of python\n";
107
1/1
✓ Branch 0 (78→79) taken 2 times.
2 fs << "\tPyObject *global_dict = PyDict_New(), *outputEnum = NULL;\n";
108
1/1
✓ Branch 0 (79→80) taken 2 times.
2 fs << "\tif(global_dict != NULL){\t//If we can create the global_dict\n";
109
1/1
✓ Branch 0 (80→81) taken 2 times.
2 fs << "\t\t//Py_single_input\n";
110
1/1
✓ Branch 0 (81→82) taken 2 times.
2 fs << "\t\tPyObject * runRes = PyRun_String(pythonStr.c_str(), Py_file_input, global_dict, global_dict);\n";
111
1/1
✓ Branch 0 (82→83) taken 2 times.
2 fs << "\t\tif(runRes != NULL){\t//If Python is happy\n";
112
1/1
✓ Branch 0 (83→84) taken 2 times.
2 fs << "\t\t\t//We try to get our enum back from the interpretor\n";
113
1/1
✓ Branch 0 (84→85) taken 2 times.
2 fs << "\t\t\toutputEnum = PyDict_GetItemString(global_dict, objectName.c_str());\n";
114
1/1
✓ Branch 0 (85→86) taken 2 times.
2 fs << "\t\t\tif(outputEnum == NULL){\n";
115
3/3
✓ Branch 0 (86→87) taken 2 times.
✓ Branch 2 (87→88) taken 2 times.
✓ Branch 4 (88→89) taken 2 times.
2 fs << "\t\t\t\tPyErr_SetString(PyExc_KeyError, std::string(\""+className+"_newGeneric : could not get '\"+objectName+\"' with the ugly trick due to the fact that using an enum in a wrapper is even worst than using numpy\").c_str());\n";
116
1/1
✓ Branch 0 (91→92) taken 2 times.
2 fs << "\t\t\t}else{\n";
117
1/1
✓ Branch 0 (92→93) taken 2 times.
2 fs << "\t\t\t\tPy_INCREF(outputEnum);\n";
118
1/1
✓ Branch 0 (93→94) taken 2 times.
2 fs << "\t\t\t}\n";
119
1/1
✓ Branch 0 (94→95) taken 2 times.
2 fs << "\t\t}else{\n";
120
1/1
✓ Branch 0 (95→96) taken 2 times.
2 fs << "\t\t\tPyErr_Print();\n";
121
3/3
✓ Branch 0 (96→97) taken 2 times.
✓ Branch 2 (97→98) taken 2 times.
✓ Branch 4 (98→99) taken 2 times.
2 fs << "\t\t\tPyErr_SetString(PyExc_KeyError, \""+className+"_newGeneric : error when executing ugly python trick for enum\");\n";
122
1/1
✓ Branch 0 (101→102) taken 2 times.
2 fs << "\t\t}\n";
123
1/1
✓ Branch 0 (102→103) taken 2 times.
2 fs << "\t}else{\n";
124
3/3
✓ Branch 0 (103→104) taken 2 times.
✓ Branch 2 (104→105) taken 2 times.
✓ Branch 4 (105→106) taken 2 times.
2 fs << "\t\tPyErr_SetString(PyExc_KeyError, std::string(\""+className+"_newGeneric : error when creating dictionnary to get enum '\"+objectName+\"'\").c_str());\n";
125
1/1
✓ Branch 0 (108→109) taken 2 times.
2 fs << "\t}\n";
126
1/1
✓ Branch 0 (109→110) taken 2 times.
2 fs << "\tPy_XDECREF(global_dict);\t//Same import error with of without\n";
127
1/1
✓ Branch 0 (110→111) taken 2 times.
2 fs << "\treturn outputEnum;\n";
128
1/1
✓ Branch 0 (111→112) taken 2 times.
2 fs << "}\n\n";
129
130
3/3
✓ Branch 0 (112→113) taken 2 times.
✓ Branch 2 (113→114) taken 2 times.
✓ Branch 4 (114→115) taken 2 times.
2 fs << "///Allocate the "+className+"\n";
131
1/1
✓ Branch 0 (117→118) taken 2 times.
2 fs << "/**\t@param type : type variable\n";
132
1/1
✓ Branch 0 (118→119) taken 2 times.
2 fs << " * \t@param args : args variable\n";
133
1/1
✓ Branch 0 (119→120) taken 2 times.
2 fs << " * \t@param kwds : kwds variable\n";
134
1/1
✓ Branch 0 (120→121) taken 2 times.
2 fs << " * \t@return object to be allocated\n";
135
1/1
✓ Branch 0 (121→122) taken 2 times.
2 fs << "*/\n";
136
3/3
✓ Branch 0 (122→123) taken 2 times.
✓ Branch 2 (123→124) taken 2 times.
✓ Branch 4 (124→125) taken 2 times.
2 fs << "PyObject * "+className+"_newC(PyTypeObject * type, PyObject * args, PyObject * kwds){\n";
137
1/1
✓ Branch 0 (127→128) taken 2 times.
2 fs << "\t//Here, we will use a very ugly trick but since we are doing python nobody will notice\n";
138
5/5
✓ Branch 0 (128→129) taken 2 times.
✓ Branch 2 (129→130) taken 2 times.
✓ Branch 4 (130→131) taken 2 times.
✓ Branch 6 (131→132) taken 2 times.
✓ Branch 8 (132→133) taken 2 times.
2 fs << "\tPyObject* outputEnum = "+className+"_newGeneric(\"\", \""+pythonClassName+"\");\n";
139
1/1
✓ Branch 0 (137→138) taken 2 times.
2 fs << "\treturn outputEnum;\n";
140
1/1
✓ Branch 0 (138→139) taken 2 times.
2 fs << "}\n\n";
141
142
3/3
✓ Branch 0 (139→140) taken 2 times.
✓ Branch 2 (140→141) taken 2 times.
✓ Branch 4 (141→142) taken 2 times.
2 fs << "///Allocate the "+className+"\n";
143
1/1
✓ Branch 0 (144→145) taken 2 times.
2 fs << "/**\t@param type : type variable\n";
144
1/1
✓ Branch 0 (145→146) taken 2 times.
2 fs << " * \t@param args : args variable\n";
145
1/1
✓ Branch 0 (146→147) taken 2 times.
2 fs << " * \t@param kwds : kwds variable\n";
146
1/1
✓ Branch 0 (147→148) taken 2 times.
2 fs << " * \t@return object to be allocated\n";
147
1/1
✓ Branch 0 (148→149) taken 2 times.
2 fs << "*/\n";
148
3/3
✓ Branch 0 (149→150) taken 2 times.
✓ Branch 2 (150→151) taken 2 times.
✓ Branch 4 (151→152) taken 2 times.
2 fs << "PyObject * "+className+"_newAttributeC(){\n";
149
1/1
✓ Branch 0 (154→155) taken 2 times.
2 fs << "\t//Here, we will use a very ugly trick but since we are doing python nobody will notice\n";
150
8/8
✓ Branch 0 (156→157) taken 2 times.
✓ Branch 2 (157→158) taken 2 times.
✓ Branch 4 (158→159) taken 2 times.
✓ Branch 6 (159→160) taken 2 times.
✓ Branch 8 (160→161) taken 2 times.
✓ Branch 10 (161→162) taken 2 times.
✓ Branch 12 (162→163) taken 2 times.
✓ Branch 14 (163→164) taken 2 times.
2 fs << "\tPyObject* outputEnum = "+className+"_newGeneric(\"_var_______ = "+pythonClassName+"."+vecAttr.front().getName()+"\\n\\n\", \"_var_______\");\n";
151
1/1
✓ Branch 0 (170→171) taken 2 times.
2 fs << "\treturn outputEnum;\n";
152
1/1
✓ Branch 0 (171→172) taken 2 times.
2 fs << "}\n\n";
153 2 }
154
155 ///Create the wrapper implementation of the given class
156 /** @param manager : PTraitBackendManager which handles all trait backend
157 * @param[out] fs : file to be completed
158 * @param classConfig : configuration of the class to be used
159 * @param mode : mode of the generator
160 */
161 2 void wrapper_generator_enum_source(const PWrapperTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
162 2 project_wrapper_enumImplNewc(fs, classConfig);
163 // PString className(wrapper_getClassName(classConfig));
164 // manager.classMethodImplementation(fs, classConfig, mode);
165 // fs << project_wrapper_classImplPythonType(classConfig, mode.moduleName, "NULL");
166
167 2 }
168
169 ///Implement new and dealloc
170 /** @param[out] fs : file to be completed
171 * @param classConfig : class configuration
172 */
173 3 void wrapper_generator_class_implNewc(std::ofstream & fs, const PClassConfig & classConfig){
174
3/3
✓ Branch 0 (2→3) taken 3 times.
✓ Branch 2 (3→4) taken 3 times.
✓ Branch 4 (4→5) taken 3 times.
3 PString className("WP"+classConfig.getName());
175
176
3/3
✓ Branch 0 (6→7) taken 3 times.
✓ Branch 2 (7→8) taken 3 times.
✓ Branch 4 (8→9) taken 3 times.
3 fs << "///Allocate the "+className+"\n";
177
1/1
✓ Branch 0 (11→12) taken 3 times.
3 fs << "/**\t@param type : type variable\n";
178
1/1
✓ Branch 0 (12→13) taken 3 times.
3 fs << " * \t@param args : args variable\n";
179
1/1
✓ Branch 0 (13→14) taken 3 times.
3 fs << " * \t@param kwds : kwds variable\n";
180
1/1
✓ Branch 0 (14→15) taken 3 times.
3 fs << " * \t@return object to be allocated\n";
181
1/1
✓ Branch 0 (15→16) taken 3 times.
3 fs << "*/\n";
182
3/3
✓ Branch 0 (16→17) taken 3 times.
✓ Branch 2 (17→18) taken 3 times.
✓ Branch 4 (18→19) taken 3 times.
3 fs << "PyObject * "+className+"_newC(PyTypeObject * type, PyObject * args, PyObject * kwds){\n";
183
3/3
✓ Branch 0 (21→22) taken 3 times.
✓ Branch 2 (22→23) taken 3 times.
✓ Branch 4 (23→24) taken 3 times.
3 fs << "\t"+className+" *self;\n";
184
3/3
✓ Branch 0 (26→27) taken 3 times.
✓ Branch 2 (27→28) taken 3 times.
✓ Branch 4 (28→29) taken 3 times.
3 fs << "\tself = ("+className+" *)type->tp_alloc(type, 0);\n";
185
1/1
✓ Branch 0 (31→32) taken 3 times.
3 fs << "\tif(self != NULL){\n";
186
1/1
✓ Branch 0 (32→33) taken 3 times.
3 const std::vector<PClassAttribute> & vecAttr = classConfig.getListAttribute();
187
2/2
✓ Branch 0 (128→34) taken 5 times.
✓ Branch 1 (128→129) taken 3 times.
16 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
188
2/2
✓ Branch 0 (36→37) taken 5 times.
✓ Branch 2 (37→38) taken 5 times.
5 PString attrType(it->getType());
189
3/3
✓ Branch 0 (38→39) taken 5 times.
✓ Branch 2 (39→40) taken 3 times.
✓ Branch 3 (39→49) taken 2 times.
5 if(getIsSimpleType(attrType)){
190
4/4
✓ Branch 0 (42→43) taken 3 times.
✓ Branch 2 (43→44) taken 3 times.
✓ Branch 4 (44→45) taken 3 times.
✓ Branch 6 (45→46) taken 3 times.
6 fs << "\t\tself->"+it->getName()+" = 0;\n";
191
2/3
✓ Branch 0 (49→50) taken 2 times.
✓ Branch 2 (50→51) taken 2 times.
✗ Branch 3 (50→60) not taken.
2 }else if(attrType == "std::string"){
192
4/4
✓ Branch 0 (53→54) taken 2 times.
✓ Branch 2 (54→55) taken 2 times.
✓ Branch 4 (55→56) taken 2 times.
✓ Branch 6 (56→57) taken 2 times.
4 fs << "\t\tself->"+it->getName()+" = Py_BuildValue(\"s\", \"\");\n";
193 }else if(attrType == "DataStreamMsg"){
194 fs << "\t\tself->"+it->getName()+" = PyByteArray_FromStringAndSize(\"\", 0lu);\n";
195 }else if(generator_typeIsList(attrType)){
196 fs << "\t\tself->"+it->getName()+" = PyList_New(0);\n";
197 }else{
198 //TODO : check for complex types, vector, map, and nested types
199 if(it->getIsEnum()){
200 fs << "\t\t//There is not type for enum because of the very ugly trick of Python\n";
201 fs << "\t\tself->"+it->getName()+" = WP"+attrType+"_newAttributeC();\n";
202 }else{
203 fs << "\t\tself->"+it->getName()+" = WP"+attrType+"_newC(&WP"+attrType+"Type, NULL, NULL);\n";
204 }
205 }
206 5 }
207
1/1
✓ Branch 0 (129→130) taken 3 times.
3 fs << "\t}\n";
208
1/1
✓ Branch 0 (130→131) taken 3 times.
3 fs << "\treturn (PyObject *)self;\n";
209
1/1
✓ Branch 0 (131→132) taken 3 times.
3 fs << "}\n\n";
210 3 }
211
212 ///Implement new and dealloc
213 /** @param[out] fs : file to be completed
214 * @param classConfig : class configuration
215 */
216 3 void wrapper_generator_class_implDealloc(std::ofstream & fs, const PClassConfig & classConfig){
217
3/3
✓ Branch 0 (2→3) taken 3 times.
✓ Branch 2 (3→4) taken 3 times.
✓ Branch 4 (4→5) taken 3 times.
3 PString className("WP"+classConfig.getName());
218
3/3
✓ Branch 0 (6→7) taken 3 times.
✓ Branch 2 (7→8) taken 3 times.
✓ Branch 4 (8→9) taken 3 times.
3 fs << "///Deallocate the structure "+className+"\n";
219
1/1
✓ Branch 0 (11→12) taken 3 times.
3 fs << "/**\t@param self : object to be deallocated\n";
220
1/1
✓ Branch 0 (12→13) taken 3 times.
3 fs << "*/\n";
221
5/5
✓ Branch 0 (13→14) taken 3 times.
✓ Branch 2 (14→15) taken 3 times.
✓ Branch 4 (15→16) taken 3 times.
✓ Branch 6 (16→17) taken 3 times.
✓ Branch 8 (17→18) taken 3 times.
3 fs << "void "+className+"_dealloc("+className+" * self){\n";
222
1/1
✓ Branch 0 (22→23) taken 3 times.
3 const std::vector<PClassAttribute> & vecAttr = classConfig.getListAttribute();
223
2/2
✓ Branch 0 (69→24) taken 5 times.
✓ Branch 1 (69→70) taken 3 times.
16 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
224
4/4
✓ Branch 0 (26→27) taken 5 times.
✓ Branch 2 (27→28) taken 5 times.
✓ Branch 4 (28→29) taken 2 times.
✓ Branch 5 (28→59) taken 3 times.
5 if(!getIsSimpleType(it->getType())){
225
2/2
✓ Branch 0 (31→32) taken 2 times.
✓ Branch 2 (32→33) taken 2 times.
2 PString attrName = it->getName();
226
3/3
✓ Branch 0 (33→34) taken 2 times.
✓ Branch 2 (34→35) taken 2 times.
✓ Branch 4 (35→36) taken 2 times.
2 fs << "\t//Free the "+attrName+" attribute\n";
227
5/5
✓ Branch 0 (38→39) taken 2 times.
✓ Branch 2 (39→40) taken 2 times.
✓ Branch 4 (40→41) taken 2 times.
✓ Branch 6 (41→42) taken 2 times.
✓ Branch 8 (42→43) taken 2 times.
2 fs << "\tPyObject* "+attrName+"_tmp = self->"+attrName+";\n";
228
3/3
✓ Branch 0 (47→48) taken 2 times.
✓ Branch 2 (48→49) taken 2 times.
✓ Branch 4 (49→50) taken 2 times.
2 fs << "\tself->"+attrName+" = NULL;\n";
229
3/3
✓ Branch 0 (52→53) taken 2 times.
✓ Branch 2 (53→54) taken 2 times.
✓ Branch 4 (54→55) taken 2 times.
2 fs << "\tPy_XDECREF("+attrName+"_tmp);\n";
230 2 }
231 }
232
1/1
✓ Branch 0 (70→71) taken 3 times.
3 fs << "}\n\n";
233 3 }
234
235
236 ///Create the wrapper implementation of the given class
237 /** @param manager : PTraitBackendManager which handles all trait backend
238 * @param[out] fs : file to be completed
239 * @param classConfig : configuration of the class to be used
240 * @param mode : mode of the generator
241 */
242 3 void wrapper_generator_class_source(const PWrapperTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
243
1/1
✓ Branch 0 (2→3) taken 3 times.
3 PString className(wrapper_getClassName(classConfig));
244
3/3
✓ Branch 0 (3→4) taken 3 times.
✓ Branch 2 (4→5) taken 3 times.
✓ Branch 4 (5→6) taken 3 times.
3 fs << "///Getters and setters of the class "<<className<<"\n";
245
3/3
✓ Branch 0 (6→7) taken 3 times.
✓ Branch 2 (7→8) taken 3 times.
✓ Branch 4 (8→9) taken 3 times.
3 fs << "PyGetSetDef "<<className<<"_getseters[] = {\n";
246 //Only for complex types
247
1/1
✓ Branch 0 (9→10) taken 3 times.
3 manager.registerClassGetterSetter(fs, classConfig, mode);
248
1/1
✓ Branch 0 (10→11) taken 3 times.
3 fs << "\t{NULL} /* Sentinel */\n";
249
1/1
✓ Branch 0 (11→12) taken 3 times.
3 fs << "};\n\n";
250
251 //Only for simple types
252
3/3
✓ Branch 0 (12→13) taken 3 times.
✓ Branch 2 (13→14) taken 3 times.
✓ Branch 4 (14→15) taken 3 times.
3 fs << "///Members of class "+className+"\n";
253
3/3
✓ Branch 0 (17→18) taken 3 times.
✓ Branch 2 (18→19) taken 3 times.
✓ Branch 4 (19→20) taken 3 times.
3 fs << "PyMemberDef "+className+"_members[] = {\n";
254
1/1
✓ Branch 0 (22→23) taken 3 times.
3 manager.registerClassMember(fs, classConfig, mode);
255
1/1
✓ Branch 0 (23→24) taken 3 times.
3 fs << "\t{NULL} /* Sentinel */\n";
256
1/1
✓ Branch 0 (24→25) taken 3 times.
3 fs << "};\n\n";
257 // METH_VARARGS
258
3/3
✓ Branch 0 (25→26) taken 3 times.
✓ Branch 2 (26→27) taken 3 times.
✓ Branch 4 (27→28) taken 3 times.
3 fs << "///Methods of class "<<className<<"\n";
259
3/3
✓ Branch 0 (28→29) taken 3 times.
✓ Branch 2 (29→30) taken 3 times.
✓ Branch 4 (30→31) taken 3 times.
3 fs << "PyMethodDef "<<className<<"_methods[] = {\n";
260
1/1
✓ Branch 0 (31→32) taken 3 times.
3 manager.registerClassMethod(fs, classConfig, mode);
261
1/1
✓ Branch 0 (32→33) taken 3 times.
3 fs << "\t{NULL, NULL} /* Sentinel */\n";
262
1/1
✓ Branch 0 (33→34) taken 3 times.
3 fs << "};\n\n";
263
264
1/1
✓ Branch 0 (34→35) taken 3 times.
3 wrapper_generator_class_implNewc(fs, classConfig);
265
1/1
✓ Branch 0 (35→36) taken 3 times.
3 wrapper_generator_class_implDealloc(fs, classConfig);
266
267
1/1
✓ Branch 0 (36→37) taken 3 times.
3 manager.classMethodImplementation(fs, classConfig, mode);
268
269
3/3
✓ Branch 0 (37→38) taken 3 times.
✓ Branch 2 (38→39) taken 3 times.
✓ Branch 4 (39→40) taken 3 times.
3 fs << project_wrapper_classImplPythonType(classConfig, mode.moduleName, "NULL");
270 // fs << project_wrapper_classImplCheck(classConfig, moduleName);
271
272 3 }
273
274 ///Create the wrapper declaration of the given class
275 /** @param manager : PWrapperTraitBackendManager which handles all trait backend
276 * @param headerFile : file to be saved
277 * @param vecClassConfig : configuration of the class to be used
278 * @param mode : mode of the generator
279 * @param vecInclude : vector of include files to be added into the header
280 * @return true on success, false otherwise
281 */
282 3 bool wrapper_generator_class_headerFile(const PWrapperTraitBackendManager & manager, const PPath & headerFile, const PVecClassConfig & vecClassConfig, const GeneratorMode & mode, const PVecPath & vecInclude){
283
2/3
✓ Branch 0 (2→3) taken 3 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 3 times.
3 if(headerFile == "") return false;
284
1/1
✓ Branch 0 (5→6) taken 3 times.
3 std::ofstream fs;
285
2/3
✓ Branch 0 (6→7) taken 3 times.
✗ Branch 2 (7→8) not taken.
✓ Branch 3 (7→9) taken 3 times.
3 if(!openFileStream(fs, headerFile)){return false;}
286
1/1
✓ Branch 0 (9→10) taken 3 times.
3 licenceSave(fs);
287
2/2
✓ Branch 0 (10→11) taken 3 times.
✓ Branch 2 (11→12) taken 3 times.
3 PString macroDef(makeMultiIncludeDefineMacro(headerFile.getFileName()));
288
3/3
✓ Branch 0 (13→14) taken 3 times.
✓ Branch 2 (14→15) taken 3 times.
✓ Branch 4 (15→16) taken 3 times.
3 fs << "#ifndef " << macroDef << std::endl;
289
4/4
✓ Branch 0 (16→17) taken 3 times.
✓ Branch 2 (17→18) taken 3 times.
✓ Branch 4 (18→19) taken 3 times.
✓ Branch 6 (19→20) taken 3 times.
3 fs << "#define " << macroDef << std::endl << std::endl;
290
1/1
✓ Branch 0 (20→21) taken 3 times.
3 fs << "#include <Python.h>\n";
291
1/1
✓ Branch 0 (21→22) taken 3 times.
3 fs << "#include <structmember.h>\n";
292
1/1
✓ Branch 0 (22→23) taken 3 times.
3 fs << "#include <iostream>\n\n";
293
3/3
✓ Branch 0 (23→24) taken 3 times.
✓ Branch 2 (24→25) taken 3 times.
✓ Branch 4 (25→26) taken 3 times.
3 fs << "#include <string>" << std::endl<< std::endl;
294
1/2
✗ Branch 0 (27→28) not taken.
✓ Branch 1 (27→46) taken 3 times.
3 if(vecInclude.size() != 0lu){
295 for(PVecPath::const_iterator it(vecInclude.begin()); it != vecInclude.end(); ++it){
296 fs << "#include " << *it << std::endl;
297 }
298 fs << std::endl;
299 }
300
1/1
✓ Branch 0 (46→47) taken 3 times.
3 manager.headerExtraInclude(fs, mode);
301
1/1
✓ Branch 0 (47→48) taken 3 times.
3 fs << std::endl;
302
2/2
✓ Branch 0 (69→49) taken 5 times.
✓ Branch 1 (69→70) taken 3 times.
16 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
303
3/3
✓ Branch 0 (51→52) taken 5 times.
✓ Branch 2 (52→53) taken 2 times.
✓ Branch 3 (52→56) taken 3 times.
5 if(it->getIsEnum()){
304
1/1
✓ Branch 0 (55→59) taken 2 times.
2 wrapper_generator_enum_header(manager, fs, *it, mode);
305 // saveEnumDecl(fs, *it, mode);
306 }else{
307
1/1
✓ Branch 0 (58→59) taken 3 times.
3 wrapper_generator_class_header(manager, fs, *it, mode);
308 }
309 }
310
5/5
✓ Branch 0 (70→71) taken 3 times.
✓ Branch 2 (71→72) taken 3 times.
✓ Branch 4 (72→73) taken 3 times.
✓ Branch 6 (73→74) taken 3 times.
✓ Branch 8 (74→75) taken 3 times.
3 fs << std::endl << std::endl << "#endif" << std::endl << std::endl;
311
1/1
✓ Branch 0 (75→76) taken 3 times.
3 fs.close();
312 3 return true;
313 3 }
314
315 ///Create the wrapper implementation of the given file
316 /** @param manager : PWrapperTraitBackendManager which handles all trait backend
317 * @param sourceFile : source file to be saved
318 * @param headerFile : header to be used with this source file
319 * @param vecClassConfig : vector of configuration of the classes to be used
320 * @param mode : mode of the generator
321 * @return true on success, false otherwise
322 */
323 3 bool wrapper_generator_class_sourceFile(const PWrapperTraitBackendManager & manager, const PPath & sourceFile, const PPath & headerFile, const std::vector<PClassConfig> & vecClassConfig, const GeneratorMode & mode){
324
5/8
✓ Branch 0 (2→3) taken 3 times.
✓ Branch 2 (3→4) taken 3 times.
✗ Branch 3 (3→6) not taken.
✓ Branch 4 (4→5) taken 3 times.
✗ Branch 6 (5→6) not taken.
✓ Branch 7 (5→7) taken 3 times.
✗ Branch 8 (8→9) not taken.
✓ Branch 9 (8→10) taken 3 times.
3 if(sourceFile == "" || headerFile == "") return false;
325
1/1
✓ Branch 0 (10→11) taken 3 times.
3 std::ofstream fs;
326
2/3
✓ Branch 0 (11→12) taken 3 times.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→14) taken 3 times.
3 if(!openFileStream(fs, sourceFile)){return false;}
327
1/1
✓ Branch 0 (14→15) taken 3 times.
3 licenceSave(fs);
328
7/7
✓ Branch 0 (15→16) taken 3 times.
✓ Branch 2 (16→17) taken 3 times.
✓ Branch 4 (17→18) taken 3 times.
✓ Branch 6 (18→19) taken 3 times.
✓ Branch 8 (19→20) taken 3 times.
✓ Branch 10 (20→21) taken 3 times.
✓ Branch 12 (21→22) taken 3 times.
3 fs << std::endl << "#include \"" << headerFile.getFileName() << "\"" << std::endl << std::endl;
329
2/2
✓ Branch 0 (44→24) taken 5 times.
✓ Branch 1 (44→45) taken 3 times.
16 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
330
3/3
✓ Branch 0 (26→27) taken 5 times.
✓ Branch 2 (27→28) taken 2 times.
✓ Branch 3 (27→31) taken 3 times.
5 if(it->getIsEnum()){
331
1/1
✓ Branch 0 (30→34) taken 2 times.
2 wrapper_generator_enum_source(manager, fs, *it, mode);
332 }else{
333
1/1
✓ Branch 0 (33→34) taken 3 times.
3 wrapper_generator_class_source(manager, fs, *it, mode);
334 }
335 }
336
1/1
✓ Branch 0 (45→46) taken 3 times.
3 fs.close();
337 3 return true;
338 3 }
339
340 ///Creates wrapper header and source files
341 /** @param manager : PTraitBackendManager which handles all trait backend
342 * @param vecClassConfig : vector of class config we want to save
343 * @param baseFileName : base file name for header or source file
344 * @param outputSourceDir : output directory where to save sources
345 * @param mode : all modes of the generator (data/check/type/config stream)
346 * @return true on success, false otherwise
347 */
348 3 bool wrapper_generator_class_cpp(const PWrapperTraitBackendManager & manager, const std::vector<PClassConfig> & vecClassConfig, const PPath & outputSourceDir, const PPath & baseFileName, const GeneratorMode & mode, const PVecPath & vecInclude){
349
2/3
✓ Branch 0 (2→3) taken 3 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 3 times.
3 if(baseFileName == "") return false;
350
2/2
✓ Branch 0 (5→6) taken 3 times.
✓ Branch 2 (6→7) taken 3 times.
3 PPath outputDir = outputSourceDir / PPath(mode.moduleName);
351
2/3
✓ Branch 0 (8→9) taken 3 times.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→11) taken 3 times.
3 if(!outputDir.createDirectory()){return false;}
352
6/7
✓ Branch 0 (11→12) taken 3 times.
✓ Branch 2 (12→13) taken 3 times.
✓ Branch 4 (13→14) taken 3 times.
✓ Branch 6 (14→15) taken 3 times.
✓ Branch 8 (15→16) taken 3 times.
✗ Branch 10 (20→21) not taken.
✓ Branch 11 (20→22) taken 3 times.
3 if(!wrapper_generator_class_headerFile(manager, outputDir / PPath(baseFileName + "_wrapper.h"), vecClassConfig, mode, vecInclude)){return false;}
353
11/12
✓ Branch 0 (22→23) taken 3 times.
✓ Branch 2 (23→24) taken 3 times.
✓ Branch 4 (24→25) taken 3 times.
✓ Branch 6 (25→26) taken 3 times.
✓ Branch 8 (26→27) taken 3 times.
✓ Branch 10 (27→28) taken 3 times.
✓ Branch 12 (28→29) taken 3 times.
✓ Branch 14 (29→30) taken 3 times.
✓ Branch 16 (30→31) taken 3 times.
✓ Branch 18 (31→32) taken 3 times.
✗ Branch 20 (41→42) not taken.
✓ Branch 21 (41→43) taken 3 times.
3 if(!wrapper_generator_class_sourceFile(manager, outputDir / PPath(baseFileName + PString("_wrapper.cpp")), PPath(baseFileName + PString("_wrapper.h")), vecClassConfig, mode)){return false;}
354 3 return true;
355
356 3 }
357
358 ///Create the readme of the project directory
359 /** @param manager : manager to generated wrapper soruces
360 * @param projectParam : parameters of the project
361 * @param fileNameSetup : name of the file to be created
362 * @param projectVersion : version of the project
363 * @return true on success, false otherwise
364 */
365 2 bool project_wrapper_generator_setuppy(const PWrapperTraitBackendManager & manager, const ProjectParam & projectParam, const PPath & fileNameSetup, const PString & projectVersion){
366
1/1
✓ Branch 0 (2→3) taken 2 times.
2 std::ofstream fs;
367
2/3
✓ Branch 0 (3→4) taken 2 times.
✗ Branch 2 (4→5) not taken.
✓ Branch 3 (4→6) taken 2 times.
2 if(!openFileStream(fs, fileNameSetup)){return false;}
368
1/1
✓ Branch 0 (6→7) taken 2 times.
2 PString moduleName = projectParam.mode.moduleName;
369
2/2
✓ Branch 0 (7→8) taken 2 times.
✓ Branch 2 (8→9) taken 2 times.
2 fs << getCMakeListsHeader();
370
1/1
✓ Branch 0 (10→11) taken 2 times.
2 fs << "from setuptools import setup\n";
371
1/1
✓ Branch 0 (11→12) taken 2 times.
2 fs << "from setuptools import Extension\n";
372
1/1
✓ Branch 0 (12→13) taken 2 times.
2 fs << "import sys\n";
373
1/1
✓ Branch 0 (13→14) taken 2 times.
2 fs << "#import numpy as np\n";
374
1/1
✓ Branch 0 (14→15) taken 2 times.
2 fs << "import subprocess\n";
375
1/1
✓ Branch 0 (15→16) taken 2 times.
2 fs << "\n\n";
376
2/2
✓ Branch 0 (16→17) taken 2 times.
✓ Branch 2 (17→18) taken 2 times.
2 fs << "def getConfigInfo(commandName, option):" << std::endl;
377
2/2
✓ Branch 0 (18→19) taken 2 times.
✓ Branch 2 (19→20) taken 2 times.
2 fs << "\t\"\"\"" << std::endl;
378
2/2
✓ Branch 0 (20→21) taken 2 times.
✓ Branch 2 (21→22) taken 2 times.
2 fs << "\tGet information of a dependency from a command" << std::endl;
379
2/2
✓ Branch 0 (22→23) taken 2 times.
✓ Branch 2 (23→24) taken 2 times.
2 fs << "\t# Parameters" << std::endl;
380
2/2
✓ Branch 0 (24→25) taken 2 times.
✓ Branch 2 (25→26) taken 2 times.
2 fs << "\t- `commandName` : command to be executed" << std::endl;
381
2/2
✓ Branch 0 (26→27) taken 2 times.
✓ Branch 2 (27→28) taken 2 times.
2 fs << "\t- `option` : option to be used" << std::endl;
382
2/2
✓ Branch 0 (28→29) taken 2 times.
✓ Branch 2 (29→30) taken 2 times.
2 fs << "\t# Returns" << std::endl;
383
2/2
✓ Branch 0 (30→31) taken 2 times.
✓ Branch 2 (31→32) taken 2 times.
2 fs << "\tCorresponding dependency info" << std::endl;
384
2/2
✓ Branch 0 (32→33) taken 2 times.
✓ Branch 2 (33→34) taken 2 times.
2 fs << "\t\"\"\"" << std::endl;
385
2/2
✓ Branch 0 (34→35) taken 2 times.
✓ Branch 2 (35→36) taken 2 times.
2 fs << "\treturn subprocess.run([commandName, option], capture_output = True, text = True).stdout.strip(\"\\n\")" << std::endl;
386
1/1
✓ Branch 0 (36→37) taken 2 times.
2 fs << "\n\n";
387
2/2
✓ Branch 0 (37→38) taken 2 times.
✓ Branch 2 (38→39) taken 2 times.
2 fs << "def addWrapperDependency(listIncludeDir, listLibDir, listLib, dependencyConfigProgram, listLibDep):" << std::endl;
388
2/2
✓ Branch 0 (39→40) taken 2 times.
✓ Branch 2 (40→41) taken 2 times.
2 fs << "\t\"\"\"" << std::endl;
389
2/2
✓ Branch 0 (41→42) taken 2 times.
✓ Branch 2 (42→43) taken 2 times.
2 fs << "\tAdd a dependency to the list of existing ones" << std::endl;
390
2/2
✓ Branch 0 (43→44) taken 2 times.
✓ Branch 2 (44→45) taken 2 times.
2 fs << "\t# Parameters" << std::endl;
391
2/2
✓ Branch 0 (45→46) taken 2 times.
✓ Branch 2 (46→47) taken 2 times.
2 fs << "\t- `listIncludeDir` : list of include directories" << std::endl;
392
2/2
✓ Branch 0 (47→48) taken 2 times.
✓ Branch 2 (48→49) taken 2 times.
2 fs << "\t- `listLibDir` : list of libraries directories" << std::endl;
393
2/2
✓ Branch 0 (49→50) taken 2 times.
✓ Branch 2 (50→51) taken 2 times.
2 fs << "\t- `listLib` : list of libraries" << std::endl;
394
2/2
✓ Branch 0 (51→52) taken 2 times.
✓ Branch 2 (52→53) taken 2 times.
2 fs << "\t- `dependencyConfigProgram` : executable to be called to get include and lib dir of the dependency" << std::endl;
395
2/2
✓ Branch 0 (53→54) taken 2 times.
✓ Branch 2 (54→55) taken 2 times.
2 fs << "\t- `listLibDep` : list of libraries to be appended to the listLib" << std::endl;
396
2/2
✓ Branch 0 (55→56) taken 2 times.
✓ Branch 2 (56→57) taken 2 times.
2 fs << "\t\"\"\"" << std::endl;
397
2/2
✓ Branch 0 (57→58) taken 2 times.
✓ Branch 2 (58→59) taken 2 times.
2 fs << "\tlistIncludeDir.append(getConfigInfo(dependencyConfigProgram, \"--include\"))" << std::endl;
398
2/2
✓ Branch 0 (59→60) taken 2 times.
✓ Branch 2 (60→61) taken 2 times.
2 fs << "\tlistLibDir.append(getConfigInfo(dependencyConfigProgram, \"--lib\"))" << std::endl;
399
2/2
✓ Branch 0 (61→62) taken 2 times.
✓ Branch 2 (62→63) taken 2 times.
2 fs << "\tlistLib.extend(listLibDep)" << std::endl;
400
1/1
✓ Branch 0 (63→64) taken 2 times.
2 fs << "\n\n";
401
2/2
✓ Branch 0 (64→65) taken 2 times.
✓ Branch 2 (65→66) taken 2 times.
2 fs << "listIncludeDir = []" << std::endl;
402
2/2
✓ Branch 0 (66→67) taken 2 times.
✓ Branch 2 (67→68) taken 2 times.
2 fs << "listLibDir = []" << std::endl;
403
2/2
✓ Branch 0 (68→69) taken 2 times.
✓ Branch 2 (69→70) taken 2 times.
2 fs << "listLib = []" << std::endl;
404
405
2/2
✓ Branch 0 (70→71) taken 2 times.
✓ Branch 2 (71→72) taken 2 times.
2 fs << "#listIncludeDir.append(np.get_include())" << std::endl;
406
2/2
✓ Branch 0 (72→73) taken 2 times.
✓ Branch 2 (73→74) taken 2 times.
2 fs << "#Here we call all trait wrapper such as" << std::endl;
407
2/2
✓ Branch 0 (74→75) taken 2 times.
✓ Branch 2 (75→76) taken 2 times.
2 fs << "#addWrapperDependency(listIncludeDir, listLibDir, listLib, \"phoenixdatastream-config\", [\"phoenix_data_stream\"])" << std::endl;
408
1/1
✓ Branch 0 (76→77) taken 2 times.
2 manager.setupAddDependency(fs, projectParam.mode);
409
2/2
✓ Branch 0 (77→78) taken 2 times.
✓ Branch 2 (78→79) taken 2 times.
2 fs << "#The rest of the includes" << std::endl;
410
2/2
✓ Branch 0 (79→80) taken 2 times.
✓ Branch 2 (80→81) taken 2 times.
2 fs << "listIncludeDir.append(\"./\")" << std::endl;
411
4/4
✓ Branch 0 (81→82) taken 2 times.
✓ Branch 2 (82→83) taken 2 times.
✓ Branch 4 (83→84) taken 2 times.
✓ Branch 6 (84→85) taken 2 times.
2 fs << "listIncludeDir.append(\""<<moduleName<<"/\")" << std::endl;
412
413
1/1
✓ Branch 0 (85→86) taken 2 times.
2 fs << "ext_modules = [\n";
414
3/3
✓ Branch 0 (86→87) taken 2 times.
✓ Branch 2 (87→88) taken 2 times.
✓ Branch 4 (88→89) taken 2 times.
2 fs << "\tExtension(\""+moduleName+"\", sources=([\n";
415
2/2
✓ Branch 0 (117→93) taken 3 times.
✓ Branch 1 (117→118) taken 2 times.
7 for(const PDataConfig & config : projectParam.vecDataConfig){
416
8/8
✓ Branch 0 (95→96) taken 3 times.
✓ Branch 2 (96→97) taken 3 times.
✓ Branch 4 (97→98) taken 3 times.
✓ Branch 6 (98→99) taken 3 times.
✓ Branch 8 (99→100) taken 3 times.
✓ Branch 10 (100→101) taken 3 times.
✓ Branch 12 (101→102) taken 3 times.
✓ Branch 14 (102→103) taken 3 times.
3 fs << "\t\t\"src/"+moduleName+"/"+config.getFileName().getFileName().eraseExtension()+"_wrapper.cpp\",\n";
417 }
418
6/6
✓ Branch 0 (118→119) taken 2 times.
✓ Branch 2 (119→120) taken 2 times.
✓ Branch 4 (120→121) taken 2 times.
✓ Branch 6 (121→122) taken 2 times.
✓ Branch 8 (122→123) taken 2 times.
✓ Branch 10 (123→124) taken 2 times.
2 fs << "\t\t\"src/"+moduleName+"/"+projectParam.name.toLower()+"_module.cpp\"\n";
419
1/1
✓ Branch 0 (129→130) taken 2 times.
2 fs << "\t]),\n";
420
1/1
✓ Branch 0 (130→131) taken 2 times.
2 fs << "\textra_compile_args = [\"-O3\", \"-Werror\", \"-g\"],\n";
421
422
1/1
✓ Branch 0 (131→132) taken 2 times.
2 fs << "\tinclude_dirs = listIncludeDir,\n";
423
1/1
✓ Branch 0 (132→133) taken 2 times.
2 fs << "\tlibraries=listLib,\n";
424
1/1
✓ Branch 0 (133→134) taken 2 times.
2 fs << "\tlibrary_dirs=listLibDir,\n";
425
1/1
✓ Branch 0 (134→135) taken 2 times.
2 fs << "\t)\n";
426
1/1
✓ Branch 0 (135→136) taken 2 times.
2 fs << "]\n\n";
427
428
1/1
✓ Branch 0 (136→137) taken 2 times.
2 fs << "try:\n";
429
1/1
✓ Branch 0 (137→138) taken 2 times.
2 fs << "\tsetup(\n";
430
3/3
✓ Branch 0 (138→139) taken 2 times.
✓ Branch 2 (139→140) taken 2 times.
✓ Branch 4 (140→141) taken 2 times.
2 fs << "\t\tname=\""+moduleName+"\",\n";
431
3/3
✓ Branch 0 (143→144) taken 2 times.
✓ Branch 2 (144→145) taken 2 times.
✓ Branch 4 (145→146) taken 2 times.
2 fs << "\t\tversion=\""+projectVersion+"\",\n";
432
1/1
✓ Branch 0 (148→149) taken 2 times.
2 fs << "\t\text_modules=ext_modules,\n";
433
1/1
✓ Branch 0 (149→150) taken 2 times.
2 fs << "\t)\n";
434
1/1
✓ Branch 0 (150→151) taken 2 times.
2 fs << "except Exception as e:\n";
435
1/1
✓ Branch 0 (151→152) taken 2 times.
2 fs << "\tprint(str(e))\n";
436
1/1
✓ Branch 0 (152→153) taken 2 times.
2 fs << "\tsys.exit(-1)\n";
437
1/1
✓ Branch 0 (153→154) taken 2 times.
2 fs << "\n";
438
1/1
✓ Branch 0 (154→155) taken 2 times.
2 fs.close();
439 2 return true;
440 2 }
441
442 ///Generate the test for all class inside the module
443 /** @param manager : PTraitBackendManager which handles all trait backend
444 * @param testDirectory : directory whre to write tests
445 * @param moduleName : name of the python module
446 * @param classConfig : class confoguration
447 * @param mapClass : map of all classes/types defined for this configuration
448 * @param mode : enabled modes of the generator
449 * @return true on success, false otherwise
450 */
451 5 bool project_wrapper_classTest(const PWrapperTraitBackendManager & manager, const PPath & testDirectory, const PString & moduleName,
452 const PClassConfig & classConfig, const GeneratorMode & mode)
453 {
454
2/2
✓ Branch 0 (2→3) taken 5 times.
✓ Branch 2 (3→4) taken 5 times.
5 PString className(classConfig.getName());
455
5/5
✓ Branch 0 (4→5) taken 5 times.
✓ Branch 2 (5→6) taken 5 times.
✓ Branch 4 (6→7) taken 5 times.
✓ Branch 6 (7→8) taken 5 times.
✓ Branch 8 (8→9) taken 5 times.
5 PPath fileNameTest(testDirectory / PPath("test_" + className + ".py"));
456
1/1
✓ Branch 0 (13→14) taken 5 times.
5 std::ofstream fs;
457
2/3
✓ Branch 0 (14→15) taken 5 times.
✗ Branch 2 (15→16) not taken.
✓ Branch 3 (15→17) taken 5 times.
5 if(!openFileStream(fs, fileNameTest)){return false;}
458
459
1/1
✓ Branch 0 (17→18) taken 5 times.
5 fs << "\n";
460
2/2
✓ Branch 0 (18→19) taken 5 times.
✓ Branch 2 (19→20) taken 5 times.
5 fs << getCMakeListsHeader();
461
1/1
✓ Branch 0 (21→22) taken 5 times.
5 fs << "\n";
462
3/3
✓ Branch 0 (22→23) taken 5 times.
✓ Branch 2 (23→24) taken 3 times.
✓ Branch 3 (23→30) taken 2 times.
5 if(!classConfig.getIsEnum()){
463
3/3
✓ Branch 0 (24→25) taken 3 times.
✓ Branch 2 (25→26) taken 3 times.
✓ Branch 4 (26→27) taken 3 times.
3 fs << "import "+moduleName+"\n";
464 }
465
5/5
✓ Branch 0 (30→31) taken 5 times.
✓ Branch 2 (31→32) taken 5 times.
✓ Branch 4 (32→33) taken 5 times.
✓ Branch 6 (33→34) taken 5 times.
✓ Branch 8 (34→35) taken 5 times.
5 fs << "from "+moduleName+" import "+className+"\n";
466
1/1
✓ Branch 0 (39→40) taken 5 times.
5 fs << "\n";
467
468
1/1
✓ Branch 0 (40→41) taken 5 times.
5 manager.testFunction(fs, classConfig, mode);
469
470 // fs << "#Unit Test of the " + className + "\n";
471 // fs << "def test_"+className+"():\n";
472 //
473 // fs << "\tassert "+className+".getTypeName() == \"" + className + "\"\n";
474 // if(!classConfig.getIsEnum()){
475 // fs << "\t#Let's test the stream now\n";
476 // fs << "\tshadok = "+moduleName+"."+className+"()\n";
477 // const std::vector<PClassAttribute> & vecAttr = classConfig.getListAttribute();
478 // for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
479 // fs << pythonDefaultTestValue("shadok", *it, moduleName, "\t", mapClass);
480 // }
481 // fs << "\tstream = shadok.toBytes()\n";
482 // fs << "\tassert len(stream) != 0\n";
483 // fs << "\t\n";
484 // fs << "\tother = "+moduleName+"."+className+"()\n";
485 // fs << "\tother.fromBytes(stream)\n";
486 // for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
487 // fs << pythonAssertTestValue("other", *it, moduleName, "\t", mapClass);
488 // }
489 // fs << "\t\n";
490 // fs << "\t\n";
491 // fs << "\t\n";
492 // fs << "\t\n";
493 // fs << "\t\n";
494 // }
495
1/1
✓ Branch 0 (41→42) taken 5 times.
5 fs.close();
496 5 return true;
497 5 }
498
499 ///Generate the test for all class inside the module
500 /** @param manager : PTraitBackendManager which handles all trait backend
501 * @param testDirectory : directory whre to write tests
502 * @param moduleName : name of the python module
503 * @param vecClassConfig : vector of class confoguration
504 * @param mode : enabled modes of the generator
505 * @return true on success, false otherwise
506 */
507 3 bool wrapper_generator_class_cpp_test(const PWrapperTraitBackendManager & manager, const PPath & testDirectory, const PString & moduleName, const std::vector<PClassConfig> & vecClassConfig, const GeneratorMode & mode){
508
2/3
✓ Branch 0 (2→3) taken 3 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 3 times.
3 if(!testDirectory.createDirectory()){return false;}
509 3 bool b(true);
510
1/1
✓ Branch 0 (5→6) taken 3 times.
3 GeneratorMode updateMode(mode);
511
5/6
✓ Branch 0 (24→25) taken 5 times.
✓ Branch 1 (24→27) taken 3 times.
✓ Branch 2 (25→26) taken 5 times.
✗ Branch 3 (25→27) not taken.
✓ Branch 4 (28→7) taken 5 times.
✓ Branch 5 (28→29) taken 3 times.
16 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end() && b; ++it){
512
3/3
✓ Branch 0 (11→12) taken 5 times.
✓ Branch 2 (12→13) taken 5 times.
✓ Branch 4 (13→14) taken 5 times.
10 updateMode.mapClass[it->getName()] = *it;
513 }
514
5/6
✓ Branch 0 (43→44) taken 5 times.
✓ Branch 1 (43→46) taken 3 times.
✓ Branch 2 (44→45) taken 5 times.
✗ Branch 3 (44→46) not taken.
✓ Branch 4 (47→30) taken 5 times.
✓ Branch 5 (47→48) taken 3 times.
16 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end() && b; ++it){
515
1/1
✓ Branch 0 (32→33) taken 5 times.
5 b &= project_wrapper_classTest(manager, testDirectory, moduleName, *it, updateMode);
516 }
517 3 return b;
518 3 }
519
520 ///Generate the full sources and related unit tests from configuration
521 /** @param manager : PTraitBackendManager which handles all trait backend
522 * @param projectParam : description of classes and how and where to generate sources and test
523 * @return true on success, false otherwise
524 */
525 2 bool wrapper_generator_class_full(const PWrapperTraitBackendManager & manager, const ProjectParam & projectParam){
526 2 bool b(true);
527
1/1
✓ Branch 0 (2→3) taken 2 times.
2 b &= projectParam.outputSourceDir.createDirectory();
528
1/1
✓ Branch 0 (3→4) taken 2 times.
2 b &= projectParam.outputTestDir.createDirectory();
529
1/1
✓ Branch 0 (4→5) taken 2 times.
2 ProjectParam updatedParam(projectParam);
530
3/3
✓ Branch 0 (5→6) taken 2 times.
✓ Branch 2 (6→7) taken 2 times.
✓ Branch 4 (7→8) taken 2 times.
2 updatedParam.mode.moduleName = "py"+updatedParam.name.toLower();
531
2/2
✓ Branch 0 (34→12) taken 3 times.
✓ Branch 1 (34→35) taken 2 times.
7 for(const PDataConfig & config : updatedParam.vecDataConfig){
532
4/4
✓ Branch 0 (14→15) taken 3 times.
✓ Branch 2 (15→16) taken 3 times.
✓ Branch 4 (16→17) taken 3 times.
✓ Branch 6 (17→18) taken 3 times.
3 PPath baseFileName = config.getFileName().getFileName().eraseExtension();
533
3/3
✓ Branch 0 (19→20) taken 3 times.
✓ Branch 2 (20→21) taken 3 times.
✓ Branch 4 (21→22) taken 3 times.
3 b &= wrapper_generator_class_cpp(manager, config.getVecClassConfig(), updatedParam.outputSourceDir, baseFileName, updatedParam.mode, config.getVecInclude());
534
2/2
✓ Branch 0 (22→23) taken 3 times.
✓ Branch 2 (23→24) taken 3 times.
3 b &= wrapper_generator_class_cpp_test(manager, updatedParam.outputTestDir, updatedParam.mode.moduleName, config.getVecClassConfig(), updatedParam.mode);
535 3 }
536
7/7
✓ Branch 0 (35→36) taken 2 times.
✓ Branch 2 (36→37) taken 2 times.
✓ Branch 4 (37→38) taken 2 times.
✓ Branch 6 (38→39) taken 2 times.
✓ Branch 8 (39→40) taken 2 times.
✓ Branch 10 (40→41) taken 2 times.
✓ Branch 12 (41→42) taken 2 times.
2 PPath outputModuleSrc = updatedParam.outputSourceDir / PPath(updatedParam.mode.moduleName) / PPath(updatedParam.name.toLower() + "_module.cpp");
537
1/1
✓ Branch 0 (48→49) taken 2 times.
2 b &= project_wrapper_moduleGeneratorMain(outputModuleSrc, updatedParam);
538
4/4
✓ Branch 0 (49→50) taken 2 times.
✓ Branch 2 (50→51) taken 2 times.
✓ Branch 4 (51→52) taken 2 times.
✓ Branch 6 (52→53) taken 2 times.
2 b &= project_wrapper_generator_setuppy(manager, updatedParam, updatedParam.outputProjectDir / PPath("setup.py"), updatedParam.version);
539 2 return b;
540 2 }
541
542