GCC Code Coverage Report


Directory: ./
File: src/main.cpp
Date: 2025-03-14 12:04:36
Exec Total Coverage
Lines: 136 158 86.1%
Branches: 185 261 70.9%

Line Branch Exec Source
1 /***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5 ****************************************/
6
7 #include "convertToString.h"
8 #include "PPath.h"
9 #include "OptionParser.h"
10 #include "pxml_utils.h"
11
12 #include "pinkscape_slide.h"
13
14 ///Create the OptionParser of this program
15 /** @return OptionParser of this program
16 */
17 1 OptionParser createOptionParser(){
18
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 OptionParser parser(true, __PROGRAM_VERSION__);
19
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 parser.setExampleLongOption("phoenix_inkscapesplitter --input=file.svg --output=output/dir/");
20
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 parser.setExampleShortOption("phoenix_inkscapesplitter -i file1.svg file1.svg fileN.svg -o output/dir/");
21
22
4/4
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 10 taken 1 times.
1 parser.addOption("input", "i", OptionType::FILENAME, true, "list of input files to be treated");
23
24
1/1
✓ Branch 1 taken 1 times.
1 PString defaultOutputDir(".");
25
5/5
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 13 taken 1 times.
1 parser.addOption("output", "o", defaultOutputDir, "Output directory");
26
27 2 return parser;
28 1 }
29
30 ///@brief Get the begin and end slide for current layer
31 struct PLayer{
32 ///first slide where the layer has to be printed
33 long unsigned int begin;
34 ///Last slide where the layer has to be printed
35 long unsigned int end;
36 ///Extra command
37 PString command;
38 };
39
40 ///Vector of layer
41 typedef std::vector<PLayer> PVecLayer;
42
43 ///Slide composed of layer
44 typedef std::vector<long unsigned int> PSlide;
45
46 ///Define the layer in slide
47 typedef std::vector<PSlide > PVecSlide;
48
49 ///Get the inkscape label of current PXml
50 /** @param layerXml : inkscape layer
51 * @return inkscape label of current PXml
52 */
53 12 PString getInkscapeLabel(const PXml & layerXml){
54
1/1
✓ Branch 1 taken 12 times.
12 PString attr("");
55
1/1
✓ Branch 1 taken 12 times.
12 PXmlAttr attrXml;
56
3/4
✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
12 if(pxml_getAttrIfExist(attrXml, layerXml, "inkscape:label")){
57
2/2
✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
12 attr = attrXml.getValue();
58 }
59 24 return attr;
60 12 }
61
62 ///Create the vector of slide layer
63 /** @param[out] vecLayerSlide : output vector of layer slide
64 * @param vecLayer : vector of layer from svg file
65 */
66 1 void createVectorSlide(PVecLayer & vecLayerSlide, const PVecXml & vecLayer){
67 1 long unsigned int i(0lu);
68
2/2
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 1 times.
13 for(PVecXml::const_iterator itLayer(vecLayer.begin()); itLayer != vecLayer.end(); ++itLayer){
69
1/1
✓ Branch 2 taken 12 times.
12 PString inkscapeLabel(getInkscapeLabel(*itLayer));
70
3/3
✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
✓ Branch 7 taken 12 times.
12 std::cout << "\tlayer '" << inkscapeLabel << "'";
71
1/1
✓ Branch 1 taken 12 times.
12 PVecString listNb(inkscapeLabel.split('-'));
72 12 long unsigned int begin(0lu), end(0lu);
73 12 bool isBeginDefined(false), isEndDefine(false);
74
1/1
✓ Branch 1 taken 12 times.
12 PString command("");
75
2/2
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 12 times.
47 for(PVecString::iterator it(listNb.begin()); it != listNb.end(); ++it){
76
3/3
✓ Branch 2 taken 35 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 23 times.
35 if(it->isNumber()){
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(isBeginDefined){
78 end = atol(it->c_str());
79 isEndDefine = true;
80 }else{
81 12 begin = atol(it->c_str());
82 12 isBeginDefined = true;
83 }
84 }else{
85
5/6
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 12 times.
23 if(*it == "N" && isBeginDefined){
86
1/1
✓ Branch 1 taken 11 times.
11 command = "UntilEnd";
87
1/1
✓ Branch 1 taken 11 times.
11 std::cout << "\t=> until end";
88 }
89
90 }
91 }
92
1/1
✓ Branch 1 taken 12 times.
12 std::cout << std::endl;
93
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if(!isBeginDefined && !isEndDefine){
94 begin = i;
95 end = i;
96 }
97
1/1
✓ Branch 1 taken 12 times.
12 PLayer layer;
98
1/1
✓ Branch 1 taken 12 times.
12 layer.command = command;
99 12 layer.begin = begin;
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(isEndDefine){layer.end = end;}
101 12 else{layer.end = begin;}
102
1/1
✓ Branch 1 taken 12 times.
12 vecLayerSlide.push_back(layer);
103 12 }
104 1 }
105
106 ///Create the slide to be generated
107 /** @param[out] slide : slide to be generated
108 * @param vecLayerSlide : vector of the desired slides for the layers
109 * @param index : index of the current slide to be generated
110 */
111 9 void createSlideWithLayer(PSlide & slide, const PVecLayer & vecLayerSlide, long unsigned int index){
112 9 long unsigned int i(0lu);
113
2/2
✓ Branch 3 taken 108 times.
✓ Branch 4 taken 9 times.
117 for(PVecLayer::const_iterator it(vecLayerSlide.begin()); it != vecLayerSlide.end(); ++it){
114
6/6
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 37 times.
✓ Branch 4 taken 64 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 64 times.
✓ Branch 7 taken 44 times.
108 if(index >= it->begin && index <= it->end){
115
1/1
✓ Branch 1 taken 64 times.
64 slide.push_back(i);
116 }
117 108 ++i;
118 }
119 9 }
120
121 ///Create the vector of slides
122 /** @param[out] vecSlide : vector of slides to be created
123 * @param vecLayerSlide : vector of the desired slides for the layers
124 */
125 1 void createVecSlide(PVecSlide & vecSlide, PVecLayer & vecLayerSlide){
126
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if(vecLayerSlide.size() == 0lu){return;}
127 1 PVecLayer::iterator it(vecLayerSlide.begin());
128 1 long unsigned int minSlide(it->begin), maxSlide(it->end);
129 1 ++it;
130
2/2
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1 times.
12 while(it != vecLayerSlide.end()){
131
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if(it->begin < minSlide){minSlide = it->begin;}
132
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 7 times.
11 if(it->end > maxSlide){maxSlide = it->end;}
133 11 ++it;
134 }
135
2/2
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 1 times.
13 for(PVecLayer::iterator itCmd(vecLayerSlide.begin()); itCmd != vecLayerSlide.end(); ++itCmd){
136
2/2
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1 times.
12 if(itCmd->command == "UntilEnd"){
137 11 itCmd->end = maxSlide;
138 }
139 }
140
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 for(long unsigned int i(minSlide); i < maxSlide + 1lu; ++i){
141 9 PSlide slide;
142
1/1
✓ Branch 1 taken 9 times.
9 createSlideWithLayer(slide, vecLayerSlide, i);
143
1/1
✓ Branch 1 taken 9 times.
9 vecSlide.push_back(slide);
144 9 }
145 }
146
147 ///Convert the slide index into string
148 /** @param i : slide index
149 * @return output string
150 */
151 18 PString getSlideNumber(long unsigned int i){
152
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(i < 10lu){
153
2/2
✓ Branch 2 taken 18 times.
✓ Branch 5 taken 18 times.
36 return "0" + valueToString(i);
154 }else{
155 return valueToString(i);
156 }
157 }
158
159 ///Save the slides
160 /** @param baseOutputName : base of the slides output names
161 * @param vecSlides : vector of slides to be created
162 * @param vecLayerXml : vector of xml layer to be used
163 * @param lighRoot : root xml without the layers in svg
164 * @return true on success, false otherwise
165 */
166 1 bool saveSlides(POutoutMode & outputMode, const PPath & baseOutputName,
167 const PVecSlide & vecSlides, const PVecXml & vecLayerXml, const PXml & lighRoot)
168 {
169 1 long unsigned int i(0lu);
170
2/2
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 1 times.
10 for(PVecSlide::const_iterator itSlide(vecSlides.begin()); itSlide != vecSlides.end(); ++itSlide){
171
1/1
✓ Branch 1 taken 9 times.
9 PXml tmpRoot(lighRoot);
172
2/2
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
9 tmpRoot.setName("");
173
2/2
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
9 PXml * svgPtr = pxml_getChildPtr(tmpRoot, "svg");
174 9 const PSlide & slide = *itSlide;
175
2/2
✓ Branch 4 taken 64 times.
✓ Branch 5 taken 9 times.
73 for(PSlide::const_iterator it(slide.begin()); it != slide.end(); ++it){
176 // We need to suppress attribute : style="display:none"
177
1/1
✓ Branch 3 taken 64 times.
64 PXml tmpLayer(vecLayerXml[*it]);
178
3/3
✓ Branch 1 taken 64 times.
✓ Branch 4 taken 64 times.
✓ Branch 7 taken 64 times.
64 pxml_setAttr(tmpLayer, "style", "display:inline");
179
2/2
✓ Branch 1 taken 64 times.
✓ Branch 4 taken 64 times.
64 svgPtr->getVecChild().push_back(tmpLayer); //We add the corresponding layer
180 64 }
181 //Save svg file
182
13/13
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 7 taken 9 times.
✓ Branch 10 taken 9 times.
✓ Branch 13 taken 9 times.
✓ Branch 16 taken 9 times.
✓ Branch 19 taken 9 times.
✓ Branch 22 taken 9 times.
✓ Branch 25 taken 9 times.
✓ Branch 28 taken 9 times.
✓ Branch 31 taken 9 times.
✓ Branch 34 taken 9 times.
✓ Branch 37 taken 9 times.
18 PPath outputSlide(PPath("./") + baseOutputName + PPath("_") + getSlideNumber(i) + PPath(".svg"));
183 //Get the svg content
184
1/1
✓ Branch 1 taken 9 times.
9 PString slideContent(pxml_baliseStr(tmpRoot, true));
185 //Check if the svg is already saved
186
2/3
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
9 if(pinkscape_isSlideKnown(outputMode, outputSlide, slideContent)){
187 continue;
188 }
189 //If not, save the svg into png image
190
2/3
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
9 if(!outputSlide.saveFileContent(slideContent)){
191 std::cerr << "saveSlides : can't save svg file '"<<outputSlide<<"'" << std::endl;
192 return false;
193 }
194 //Call inkscape to make png file
195
10/10
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 7 taken 9 times.
✓ Branch 10 taken 9 times.
✓ Branch 13 taken 9 times.
✓ Branch 16 taken 9 times.
✓ Branch 19 taken 9 times.
✓ Branch 22 taken 9 times.
✓ Branch 25 taken 9 times.
✓ Branch 28 taken 9 times.
18 PPath outputSlidePng(baseOutputName + PPath("_") + getSlideNumber(i) + PPath(".png"));
196 // PString command("inkscape --without-gui -e "+outputSlidePng+" "+outputSlide);
197
6/6
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 7 taken 9 times.
✓ Branch 10 taken 9 times.
✓ Branch 13 taken 9 times.
✓ Branch 16 taken 9 times.
18 PString command(PString("convert ") + outputSlide + PString(" ") + outputSlidePng);
198 // PString command("inkscape --batch-process -o "+outputSlidePng+" "+outputSlide); //for Inkscape 1.1.2 (0a00cf5339, 2022-02-04)
199
200
2/3
✓ Branch 2 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
9 if(system(command.c_str()) != 0){
201 std::cerr << "saveSlides : can't create png file with command '"<<command<<"'" << std::endl;
202 return false;
203 }
204 //Removing the temporary svg files
205
3/3
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 7 taken 9 times.
9 command = PString("rm ") + outputSlide;
206
2/3
✓ Branch 2 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
9 if(system(command.c_str()) != 0){
207 std::cerr << "saveSlides : can't remove temporary svg file with command '"<<command<<"'" << std::endl;
208 return false;
209 }
210 9 ++i;
211
5/13
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 15 taken 9 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
9 }
212 1 return true;
213 }
214
215 ///Process all the input files
216 /** @param inputFile : list of the input files
217 * @return true on success, false otherwise
218 */
219 1 bool processFileSvg(const PPath & inputFile){
220
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if(inputFile == ""){return false;}
221
1/1
✓ Branch 1 taken 1 times.
1 PXml root;
222
2/3
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 if(!pxml_parserFile(root, inputFile)){
223 std::cerr << "processFileSvg : can't load file '"<<inputFile<<"'" << std::endl;
224 return false;
225 }
226 // cout << "processFileSvg : root nbChild : " << root.getVecChild().size() << endl;
227 // PVecXml & vecChild = root.getVecChild();
228 // for(PVecXml::iterator it(vecChild.begin()); it != vecChild.end(); ++it){
229 // cout << "processFileSvg : '" << it->getName() << "'" << endl;
230 // }
231
1/1
✓ Branch 1 taken 1 times.
1 PXml svgBalise;
232
3/4
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
1 if(!pxml_getChildIfExist(svgBalise, root, "svg")){
233 std::cerr << "processFileSvg : can't find 'svg' balise in root" << std::endl;
234 return false;
235 }
236
237 // PVecXml & vecChildSvg = svgBalise.getVecChild();
238 // for(PVecXml::iterator it(vecChildSvg.begin()); it != vecChildSvg.end(); ++it){
239 // cout << "processFileSvg : svg '" << it->getName() << "'" << endl;
240 // }
241
242 1 PVecXml vecLayer;
243
3/4
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
1 if(!pxml_getVecChildIfExist(vecLayer, svgBalise, "g")){
244 std::cerr << "processFileSvg : can't find 'g' balise in svg" << std::endl;
245 return false;
246 }
247 1 long unsigned int nbCalque(vecLayer.size());
248
3/3
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
1 std::cout << "processFileSvg : get " << nbCalque << " layer";
249
2/3
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
1 if(nbCalque > 1lu){std::cout << "s";}
250
1/1
✓ Branch 1 taken 1 times.
1 std::cout << std::endl;
251
252 1 PVecLayer vecLayerSlide;
253
1/1
✓ Branch 1 taken 1 times.
1 createVectorSlide(vecLayerSlide, vecLayer);
254
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if(vecLayerSlide.size() == 0lu){
255 std::cerr << "processFileSvg : no layer defined with -begin-end synthax" << std::endl;
256 return false;
257 }
258 1 PVecSlide vecSlides;
259
1/1
✓ Branch 1 taken 1 times.
1 createVecSlide(vecSlides, vecLayerSlide);
260
261
1/1
✓ Branch 1 taken 1 times.
1 PXml lighRoot(root);
262
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 PXml * svgPtr = pxml_getChildPtr(lighRoot, "svg");
263
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 PXml svgNoLayer(pxml_eraseVecChild(*svgPtr, "g"));
264
1/1
✓ Branch 1 taken 1 times.
1 *svgPtr = svgNoLayer;
265
266 1 POutoutMode outputMode;
267
3/3
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
1 PString baseOutputSlideName(inputFile.getFileName().eraseExtension());
268
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 pinkscape_loadSlideMap(outputMode.mapSlide, baseOutputSlideName);
269
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 bool b = saveSlides(outputMode, baseOutputSlideName, vecSlides, vecLayer, lighRoot);
270
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 pinkscape_saveSlideMap(outputMode.mapSlide, baseOutputSlideName);
271 1 return b;
272 1 }
273
274 ///Process all the input files
275 /** @param listInputFile : list of the input files
276 * @return 0 on success, -1 otherwise
277 */
278 1 int processFiles(const std::vector<PPath> & listInputFile){
279
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if(listInputFile.size() == 0lu){
280 std::cerr << "processFiles : no input file" << std::endl;
281 return -1;
282 }
283 1 bool b(true);
284
5/6
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
2 for(std::vector<PPath>::const_iterator it(listInputFile.begin()); it != listInputFile.end() && b; ++it){
285
1/1
✓ Branch 2 taken 1 times.
1 b &= processFileSvg(*it);
286 }
287 1 return 1 - b;
288 }
289
290 1 int main(int argc, char** argv){
291
1/1
✓ Branch 1 taken 1 times.
1 OptionParser parser = createOptionParser();
292
1/1
✓ Branch 1 taken 1 times.
1 parser.parseArgument(argc, argv);
293
294
1/1
✓ Branch 1 taken 1 times.
1 const OptionMode & defaultMode = parser.getDefaultMode();
295 1 std::vector<PPath> listInputFile;
296
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 defaultMode.getValue(listInputFile, "input");
297
298
1/1
✓ Branch 1 taken 1 times.
1 return processFiles(listInputFile);
299 1 }
300
301
302