| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /*************************************** | ||
| 2 | Auteur : Thibaut Oprinsen | ||
| 3 | Mail : thibaut.oprinsen@lapp.in2p3.fr | ||
| 4 | Licence : CeCILL-C | ||
| 5 | ****************************************/ | ||
| 6 | |||
| 7 | #include <set> | ||
| 8 | #include "header_generator.h" | ||
| 9 | #include "nanobind_generator.h" | ||
| 10 | #include "phoenix_color.h" | ||
| 11 | #include "openFileStream.h" | ||
| 12 | |||
| 13 | ///Generate nanobind wrapper class | ||
| 14 | /** @param manager : PTraitBackendManager which handles all trait backend | ||
| 15 | * @param baseFileName : base file name to be used (without path and extension) | ||
| 16 | * @param sourceFile : source file to be saved | ||
| 17 | * @param headerFile : header to be used with this source file | ||
| 18 | * @param extraInclude : extra include to be added in the source file | ||
| 19 | * @param vecClassConfig : vector of configuration of the classes to be used | ||
| 20 | * @param mode : mode of the generator | ||
| 21 | * @return true on success, false otherwise | ||
| 22 | */ | ||
| 23 | 2 | bool generator_nanobind_class(const PNanobindTraitBackendManager &manager, PPath& baseFileName, const PPath &sourceFile, const PPath &headerFile, const PVecPath &extraInclude, const PVecClassConfig &vecClassConfig, const GeneratorMode &mode){ | |
| 24 |
2/3✓ Branch 0 (2→3) taken 2 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→13) taken 2 times.
|
2 | if(baseFileName == ""){ |
| 25 | ✗ | std::cerr << termRed() << "generator_class_cpp : baseFileName is empty" << termDefault() << std::endl; | |
| 26 | ✗ | return false; | |
| 27 | } | ||
| 28 |
1/1✓ Branch 0 (13→14) taken 2 times.
|
2 | std::ofstream fs; |
| 29 |
2/3✓ Branch 0 (14→15) taken 2 times.
✗ Branch 2 (15→16) not taken.
✓ Branch 3 (15→17) taken 2 times.
|
2 | if(!openFileStream(fs, sourceFile)){return false;} |
| 30 |
1/1✓ Branch 0 (17→18) taken 2 times.
|
2 | licenceSave(fs); |
| 31 |
7/7✓ Branch 0 (18→19) taken 2 times.
✓ Branch 2 (19→20) taken 2 times.
✓ Branch 4 (20→21) taken 2 times.
✓ Branch 6 (21→22) taken 2 times.
✓ Branch 8 (22→23) taken 2 times.
✓ Branch 10 (23→24) taken 2 times.
✓ Branch 12 (24→25) taken 2 times.
|
2 | fs << std::endl << "#include \"" << headerFile.getFileName() << "\"" << std::endl << std::endl; |
| 32 |
2/2✓ Branch 0 (26→27) taken 2 times.
✓ Branch 2 (27→28) taken 2 times.
|
2 | fs << "#include <nanobind/nanobind.h>" << std::endl; |
| 33 | 2 | std::set<std::string> extraIncludes; | |
| 34 |
2/2✓ Branch 0 (43→30) taken 2 times.
✓ Branch 1 (43→44) taken 2 times.
|
8 | for (std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){ |
| 35 |
1/1✓ Branch 0 (32→33) taken 2 times.
|
4 | manager.headerExtraInclude(extraIncludes, *it, mode); |
| 36 | } | ||
| 37 |
2/2✓ Branch 0 (51→46) taken 3 times.
✓ Branch 1 (51→52) taken 2 times.
|
5 | for (const std::string & include : extraIncludes){ |
| 38 |
2/2✓ Branch 0 (47→48) taken 3 times.
✓ Branch 2 (48→49) taken 3 times.
|
3 | fs << include << std::endl; |
| 39 | } | ||
| 40 |
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 << "\nnamespace nb = nanobind;" << std::endl << std::endl; |
| 41 |
3/3✓ Branch 0 (55→56) taken 2 times.
✓ Branch 2 (56→57) taken 2 times.
✓ Branch 4 (57→58) taken 2 times.
|
2 | PString fileModuleName = baseFileName.toLower() + "_module"; |
| 42 |
4/4✓ Branch 0 (60→61) taken 2 times.
✓ Branch 2 (61→62) taken 2 times.
✓ Branch 4 (62→63) taken 2 times.
✓ Branch 6 (63→64) taken 2 times.
|
2 | fs << "NB_MODULE(" << fileModuleName << ", m) {" << std::endl; |
| 43 |
4/4✓ Branch 0 (64→65) taken 2 times.
✓ Branch 2 (65→66) taken 2 times.
✓ Branch 4 (66→67) taken 2 times.
✓ Branch 6 (67→68) taken 2 times.
|
2 | fs << "\tm.doc() = \"Nanobind bindings for " << baseFileName << " classes\";\n" << std::endl; |
| 44 | |||
| 45 |
2/2✓ Branch 0 (108→69) taken 2 times.
✓ Branch 1 (108→109) taken 2 times.
|
8 | for (std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){ |
| 46 |
8/8✓ Branch 0 (69→70) taken 2 times.
✓ Branch 2 (72→73) taken 2 times.
✓ Branch 4 (73→74) taken 2 times.
✓ Branch 6 (74→75) taken 2 times.
✓ Branch 8 (77→78) taken 2 times.
✓ Branch 10 (78→79) taken 2 times.
✓ Branch 12 (79→80) taken 2 times.
✓ Branch 14 (80→81) taken 2 times.
|
6 | fs << "\tnb::class_<" << it->getName() << ">(m, \"" << it->getName() << "\")" << std::endl; |
| 47 |
2/2✓ Branch 0 (81→82) taken 2 times.
✓ Branch 2 (82→83) taken 2 times.
|
2 | fs << "\t\t//Attributes" << std::endl; |
| 48 |
1/1✓ Branch 0 (85→86) taken 2 times.
|
4 | manager.registerProperty(fs, *it, mode); |
| 49 |
1/1✓ Branch 0 (88→89) taken 2 times.
|
4 | manager.registerConstructor(fs, *it, mode); |
| 50 |
1/1✓ Branch 0 (91→92) taken 2 times.
|
4 | manager.registerStaticMethod(fs, *it, mode); |
| 51 | |||
| 52 |
1/1✓ Branch 0 (94→95) taken 2 times.
|
4 | manager.registerMethod(fs, *it, mode); |
| 53 |
3/3✓ Branch 0 (95→96) taken 2 times.
✓ Branch 2 (96→97) taken 2 times.
✓ Branch 4 (97→98) taken 2 times.
|
2 | fs << ";" << std::endl << std::endl; |
| 54 | |||
| 55 | } | ||
| 56 |
2/2✓ Branch 0 (109→110) taken 2 times.
✓ Branch 2 (110→111) taken 2 times.
|
2 | fs << "}" << std::endl; // Close NB_MODULE |
| 57 |
1/1✓ Branch 0 (111→112) taken 2 times.
|
2 | fs.close(); |
| 58 | 2 | return true; | |
| 59 | 2 | } | |
| 60 | |||
| 61 | 2 | bool generator_nanobind_test(const PNanobindTraitBackendManager & manager, const PPath & outputTestDir, const std::vector<PClassConfig> & vecClassConfig, const PString & projectName, const PPath & baseFileName, const GeneratorMode & mode){ | |
| 62 |
2/2✓ Branch 0 (71→3) taken 2 times.
✓ Branch 1 (71→72) taken 2 times.
|
8 | for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){ |
| 63 |
2/2✓ Branch 0 (5→6) taken 2 times.
✓ Branch 2 (6→7) taken 2 times.
|
2 | PString name = it->getName(); |
| 64 |
7/7✓ Branch 0 (7→8) taken 2 times.
✓ Branch 2 (8→9) taken 2 times.
✓ Branch 4 (9→10) taken 2 times.
✓ Branch 6 (10→11) taken 2 times.
✓ Branch 8 (11→12) taken 2 times.
✓ Branch 10 (12→13) taken 2 times.
✓ Branch 12 (13→14) taken 2 times.
|
2 | PPath outputCurrentTestDir(outputTestDir + PString("/TEST_") + name.toUpper() + "_BINDINGS"); |
| 65 |
2/3✓ Branch 0 (20→21) taken 2 times.
✗ Branch 2 (21→22) not taken.
✓ Branch 3 (21→27) taken 2 times.
|
2 | if(!outputCurrentTestDir.createDirectory()){ |
| 66 | ✗ | std::cerr << "generator_class_test : cannot create TEST directory '"<<outputCurrentTestDir<<"'" << std::endl; | |
| 67 | ✗ | return false; | |
| 68 | } | ||
| 69 |
1/1✓ Branch 0 (27→28) taken 2 times.
|
2 | std::ofstream fs; |
| 70 |
8/9✓ Branch 0 (28→29) taken 2 times.
✓ Branch 2 (29→30) taken 2 times.
✓ Branch 4 (30→31) taken 2 times.
✓ Branch 6 (31→32) taken 2 times.
✓ Branch 8 (32→33) taken 2 times.
✓ Branch 10 (33→34) taken 2 times.
✓ Branch 12 (34→35) taken 2 times.
✗ Branch 14 (41→42) not taken.
✓ Branch 15 (41→43) taken 2 times.
|
2 | if(!openFileStream(fs, PPath(outputCurrentTestDir + PString("/test_") + name + "_binding.py"))){return false;} |
| 71 |
1/1✓ Branch 0 (43→44) taken 2 times.
|
2 | manager.headerTestInclude(fs, mode, baseFileName); |
| 72 |
1/1✓ Branch 0 (46→47) taken 2 times.
|
4 | manager.testFunction(fs, *it, mode, baseFileName); |
| 73 |
1/1✓ Branch 0 (47→48) taken 2 times.
|
2 | fs.close(); |
| 74 | 2 | } | |
| 75 | 2 | return true; | |
| 76 | } | ||
| 77 | |||
| 78 | ///Generate the full sources and related unit tests from configuration | ||
| 79 | /** @param manager : PTraitBackendManager which handles all trait backend | ||
| 80 | * @param projectParam : description of classes and how and where to generate sources and test | ||
| 81 | * @return true on success, false otherwise | ||
| 82 | */ | ||
| 83 | 1 | bool generator_nanobind_full(const PNanobindTraitBackendManager & manager, const ProjectParam & projectParam) | |
| 84 | { | ||
| 85 | 1 | bool b(true); | |
| 86 | 1 | b &= projectParam.outputSourceDir.createDirectory(); | |
| 87 | 1 | b &= projectParam.outputTestDir.createDirectory(); | |
| 88 | 1 | const PVecDataConfig & vecDataConfig = projectParam.vecDataConfig; | |
| 89 | |||
| 90 |
2/2✓ Branch 0 (74→6) taken 2 times.
✓ Branch 1 (74→75) taken 1 times.
|
4 | for(const PDataConfig & config : vecDataConfig){ |
| 91 |
1/1✓ Branch 0 (8→9) taken 2 times.
|
2 | const PVecPath & extraInclude = config.getVecInclude(); |
| 92 |
4/4✓ Branch 0 (9→10) taken 2 times.
✓ Branch 2 (10→11) taken 2 times.
✓ Branch 4 (11→12) taken 2 times.
✓ Branch 6 (12→13) taken 2 times.
|
2 | PPath baseFileName = config.getFileName().getFileName().eraseExtension(); |
| 93 |
4/4✓ Branch 0 (14→15) taken 2 times.
✓ Branch 2 (15→16) taken 2 times.
✓ Branch 4 (16→17) taken 2 times.
✓ Branch 6 (17→18) taken 2 times.
|
2 | PPath headerFile = projectParam.outputSourceDir / PPath(baseFileName + ".h"); |
| 94 |
4/4✓ Branch 0 (21→22) taken 2 times.
✓ Branch 2 (22→23) taken 2 times.
✓ Branch 4 (23→24) taken 2 times.
✓ Branch 6 (24→25) taken 2 times.
|
2 | PPath sourceFile = projectParam.outputSourceDir / PPath(baseFileName + "_binding.cpp"); |
| 95 |
3/4✓ Branch 0 (28→29) taken 2 times.
✓ Branch 2 (29→30) taken 2 times.
✗ Branch 4 (30→31) not taken.
✓ Branch 5 (30→42) taken 2 times.
|
2 | if(!generator_nanobind_class(manager, baseFileName, sourceFile, headerFile, extraInclude, config.getVecClassConfig(), projectParam.mode)){ |
| 96 | ✗ | std::cerr << termRed() << "generator_nanobind_full : cannot generate nanobind sources at '"<<projectParam.outputSourceDir<<"'" << termDefault() << std::endl; | |
| 97 | ✗ | b = false; //best effort strategy | |
| 98 | } | ||
| 99 |
3/3✓ Branch 0 (42→43) taken 2 times.
✓ Branch 2 (43→44) taken 2 times.
✓ Branch 4 (44→45) taken 2 times.
|
2 | PPath outputCurrentTestDir = projectParam.outputTestDir / PPath("TEST_PYTHON_BINDINGS"); |
| 100 |
3/4✓ Branch 0 (47→48) taken 2 times.
✓ Branch 2 (48→49) taken 2 times.
✗ Branch 4 (49→50) not taken.
✓ Branch 5 (49→61) taken 2 times.
|
2 | if(!generator_nanobind_test(manager, outputCurrentTestDir, config.getVecClassConfig(), projectParam.name, baseFileName, projectParam.mode)){ |
| 101 | ✗ | std::cerr << termRed() << "generator_nanobind_full : cannot generate nanobind tests at '"<<projectParam.outputTestDir<<"'" << termDefault() << std::endl; | |
| 102 | ✗ | b = false; //best effort strategy | |
| 103 | } | ||
| 104 | 2 | } | |
| 105 | 1 | return b; | |
| 106 | } | ||
| 107 |