GCC Code Coverage Report


./
File: src/XpertMass/CleaveSpec.cpp
Date: 2024-08-24 11:26:06
Lines:
92/185
49.7%
Functions:
7/15
46.7%
Branches:
100/294
34.0%

Line Branch Exec Source
1 /* BEGIN software license
2 *
3 * MsXpertSuite - mass spectrometry software suite
4 * -----------------------------------------------
5 * Copyright(C) 2009,...,2018 Filippo Rusconi
6 *
7 * http://www.msxpertsuite.org
8 *
9 * This file is part of the MsXpertSuite project.
10 *
11 * The MsXpertSuite project is the successor of the massXpert project. This
12 * project now includes various independent modules:
13 *
14 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
15 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
16 *
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 *
30 * END software license
31 */
32
33
34 /////////////////////// Local includes
35 #include "CleaveSpec.hpp"
36
37
38 namespace MsXpS
39 {
40
41 namespace libXpertMass
42 {
43
44
45 /*!
46 \class MsXpS::libXpertMass::CleaveSpec
47 \inmodule libXpertMass
48 \ingroup PolChemDefAqueousChemicalReactions
49 \inheaderfile CleaveSpec.hpp
50
51 \brief The CleaveSpec class provides a model for specifying aqueous cleavage
52 specifications (patterns) of \l{Polymer} \l{Sequence}s.
53
54 Cleavage specifications determine the specificity of cleavage in a
55 polymer sequence using a simple syntax. For example, Trypsin is able
56 to cleave after lysyl and arginyl residues. Its cleavage pattern is
57 thus "Lys/;Arg/". However, it is known that Trypsin fails to cleave
58 after Lys if that monomer is followed by a Prolyl residue, thus the
59 complete cleavage specification for Trypsin comprises three cleavage
60 motifs: "Lys/;Arg/;-Lys/Pro".
61
62 A cleavage specification might not be enough information to
63 determine the manner in which a polymer is cleaved. Cleavage rules
64 might be required to refine the specification. A cleavage
65 specification might hold as many cleavage rules as required.
66
67 \sa CleaveMotif, CleaveRule
68 */
69
70
71 /*!
72 \variable MsXpS::libXpertMass::CleaveSpec::m_pattern
73
74 \brief The cleavage pattern, that might comprise more than one \l CleaveMotif.
75
76 \sa CleaveMotif, CleaveRule
77 */
78
79 /*!
80 \variable MsXpS::libXpertMass::CleaveSpec::m_motifList
81
82 \brief The list of \l{CleaveMotif}s that together make the CleaveSpec.
83
84 \sa CleaveMotif
85 */
86
87 /*!
88 \variable MsXpS::libXpertMass::CleaveSpec::m_ruleList
89
90 \brief The list of \l{CleaveRule}s that might be requied to refine the
91 CleaveSpec.
92
93 \sa CleaveRule
94 */
95
96 /*!
97 \brief Constructs a CleaveSpec instance.
98
99 \list
100 \li \a pol_chem_def_csp: The polymer chemistry definition.
101 \li \a name: The name of the CleaveSpec.
102 \li \a pattern: The pattern of the CleaveSpec, like ("Lys/;Arg/;-Lys/Pro").
103 \endlist
104 */
105 3136 CleaveSpec::CleaveSpec(PolChemDefCstSPtr pol_chem_def_csp,
106 QString name,
107 3136 QString pattern)
108
1/2
✓ Branch 2 taken 3136 times.
✗ Branch 3 not taken.
3136 : PolChemDefEntity(pol_chem_def_csp, name), m_pattern(pattern)
109 {
110 3136 }
111
112 /*!
113 \brief Constructs a CleaveSpec instance as a copy of \a other.
114 */
115 CleaveSpec::CleaveSpec(const CleaveSpec &other)
116 : PolChemDefEntity(other), m_pattern(other.m_pattern)
117 {
118 for(int iter = 0; iter < other.m_motifList.size(); ++iter)
119 {
120 CleaveMotif *cleaveMotif = new CleaveMotif(*other.m_motifList.at(iter));
121
122 m_motifList.append(cleaveMotif);
123 }
124
125 for(int iter = 0; iter < other.m_ruleList.size(); ++iter)
126 {
127 CleaveRule *cleaveRule = new CleaveRule(*other.m_ruleList.at(iter));
128
129 m_ruleList.append(cleaveRule);
130 }
131 }
132
133 /*!
134 \brief Destructs this CleaveSpec instance.
135 */
136 CleaveSpec::~CleaveSpec()
137 {
138 while(!m_motifList.isEmpty())
139 delete m_motifList.takeFirst();
140
141 while(!m_ruleList.isEmpty())
142 delete m_ruleList.takeFirst();
143 }
144
145 /*!
146 \brief Assigns \a other to this CleaveSpec instance.
147
148 Returns a reference to this CleaveSpec instance.
149 */
150 CleaveSpec &
151 CleaveSpec::operator=(const CleaveSpec &other)
152 {
153 if(&other == this)
154 return *this;
155
156 PolChemDefEntity::operator=(other);
157
158 m_pattern = other.m_pattern;
159
160 while(!m_ruleList.isEmpty())
161 delete m_ruleList.takeFirst();
162
163 for(int iter = 0; iter < other.m_ruleList.size(); ++iter)
164 {
165 CleaveRule *cleaveRule = new CleaveRule(*other.m_ruleList.at(iter));
166 m_ruleList.append(cleaveRule);
167 }
168
169 while(!m_motifList.isEmpty())
170 delete m_motifList.takeFirst();
171
172 for(int iter = 0; iter < other.m_motifList.size(); ++iter)
173 {
174 CleaveMotif *cleaveMotif = new CleaveMotif(*other.m_motifList.at(iter));
175 m_motifList.append(cleaveMotif);
176 }
177
178 return *this;
179 }
180
181 /*!
182 \brief Returns true if \c this and \a other are identical.
183 */
184 bool
185 CleaveSpec::operator==(const CleaveSpec &other)
186 {
187 if(&other == this)
188 return true;
189
190 if(PolChemDefEntity::operator!=(other))
191 return false;
192
193 if(m_pattern != other.m_pattern)
194 return false;
195
196 if(m_motifList.size() != other.m_motifList.size())
197 return false;
198
199 for(int iter = 0; iter < m_motifList.size(); ++iter)
200 {
201 if(m_motifList.at(iter) != other.m_motifList.at(iter))
202 return false;
203 }
204
205 if(m_ruleList.size() != other.m_ruleList.size())
206 return false;
207
208 for(int iter = 0; iter < m_ruleList.size(); ++iter)
209 {
210 if(m_ruleList.at(iter) != other.m_ruleList.at(iter))
211 return false;
212 }
213
214 return true;
215 }
216
217 /*!
218 \brief Returns true if \c this and \a other are different.
219 */
220 bool
221 CleaveSpec::operator!=(const CleaveSpec &other)
222 {
223 if(&other == this)
224 return false;
225
226 return !operator==(other);
227 }
228
229
230 /*!
231 \brief Sets the \a pattern.
232 */
233 void
234 CleaveSpec::setPattern(const QString &pattern)
235 {
236 m_pattern = pattern;
237 }
238
239 /*!
240 \brief Returns the pattern.
241 */
242 const QString &
243 12 CleaveSpec::pattern()
244 {
245 12 return m_pattern;
246 }
247
248 /*!
249 \brief Returns the list of CleaveMotif instances.
250 */
251 QList<CleaveMotif *> *
252 CleaveSpec::motifList()
253 {
254 return &m_motifList;
255 }
256
257 /*!
258 \brief Returns the list of CleaveRule instances.
259 */
260 QList<CleaveRule *> *
261 4 CleaveSpec::ruleList()
262 {
263 4 return &m_ruleList;
264 }
265
266 /*!
267 \brief Searches for a CleaveSpec instance by \a name in \a cleave_spec_list.
268
269 If the CleaveSpec instance is found, it is copied into \a other.
270
271 Returns the index of the found cleavage specification or -1 if none is found
272 or if \a other is empty.
273 */
274 int
275 CleaveSpec::isNameInList(const QString &name,
276 const QList<CleaveSpec *> &cleave_spec_list,
277 CleaveSpec *other)
278 {
279 CleaveSpec *cleaveSpec = 0;
280
281 if(name.isEmpty())
282 return -1;
283
284 for(int iter = 0; iter < cleave_spec_list.size(); ++iter)
285 {
286 cleaveSpec = cleave_spec_list.at(iter);
287 Q_ASSERT(cleaveSpec);
288
289 if(cleaveSpec->m_name == name)
290 {
291 if(other)
292 other = new CleaveSpec(*cleaveSpec);
293
294 return iter;
295 }
296 }
297
298 return -1;
299 }
300
301 /*!
302 \brief Parses this CleaveSpec instance.
303
304 The parsing involves separating the components found in the m_pattern string
305 and making CleaveMotif instances out of them.
306
307 Starting from a pattern "Lys/;Arg/;-Lys/Pro", the parsing would
308 first split it into three site strings:
309
310 \list
311 \li "Lys/";
312 \li "Arg/";
313 \li "-Lys/Pro"
314 \endlist
315
316 Each of these site strings will be deconstructed into motifs, stored
317 in CleaveMotif objects:
318
319 \list
320 \li First motif has a code list "[0] Lys", an offset of 1 and is for
321 cleavage;
322 \li Second motif has a code list "[0] Arg", an offset of 1 and is for
323 cleavage;
324 \li Third motif has a code list "[0] Lys, [1] Pro", an offset of 1
325 and is not for cleavage (see the '-')
326 \endlist
327
328 Returns true if parsing is successful, false otherwise.
329 */
330 bool
331 3136 CleaveSpec::parse()
332 {
333
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3136 times.
3136 if(m_pattern.isEmpty())
334 return false;
335
336 // The 'm_pattern' is a ';'-delimited string, in which each
337 // sub-string is a 'site'. Each site is in turn constituted by a
338 // motif and a '/' that indicates where the motif is actually
339 // cleaved.
340 //
341 // For example the "-Lys/Pro" site is actually a motif of sequence
342 // "LysPro" and the site holds two more informations with respect to
343 // the mere motif: it says that the motif should not be cleaved
344 //('-') and that if the '-' were not there, the cleavage would
345 // occur between the Lys and the Pro('/' symbolizes the cleavage).
346
347 // For example, if the cleavespec had a "Lys/;Arg/;-Lys/Pro" string,
348 // it would be split into 3 strings: "Lys/" and "Arg/" and
349 // "-Lys/Pro"(these are 'site' strings). These three site string
350 // would further be deconstructed into motif string(removal of '-'
351 // and '/' characters). Where would these 3 motif strings be stored?
352 // They would be set into one cleavemotif instance for each
353 // motif. Thus, for example, "-Lys/Pro" would yield a cleavemotif of
354 // 'motif' LysPro, with a FALSE cleave member and a 1 offset member.
355
356 // Will return the number of cleavemotif instances that were created.
357 // Upon error -1 is returned.
358
359
360 // "Lys/;Arg/;-Lys/Pro" --> [0] Lys/, [1] Arg/, [2] -Lys/Pro
361
2/4
✓ Branch 2 taken 3136 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3136 times.
✗ Branch 6 not taken.
3136 QStringList sites = m_pattern.split(";", Qt::SkipEmptyParts);
362
363 // for (int iter = 0; iter < sites.size() ; ++iter)
364 // qDebug() << __FILE__ << __LINE__
365 // << sites.at(iter);
366
367 3136 bool isForCleave = true;
368
369
2/2
✓ Branch 1 taken 5880 times.
✓ Branch 2 taken 3136 times.
9016 for(int iter = 0; iter < sites.size(); ++iter)
370 {
371 5880 isForCleave = true;
372
373 5880 QString currSite = sites.at(iter);
374
375
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5880 times.
5880 if(currSite.length() < 2)
376 {
377 qDebug() << currSite << "is an invalid cleavage site";
378 return false;
379 }
380
381
1/2
✓ Branch 2 taken 5880 times.
✗ Branch 3 not taken.
5880 int count = currSite.count(QChar('/'));
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5880 times.
5880 if(count != 1)
383 {
384 qDebug() << "The must be one and only one '/' "
385 "in the cleavage site";
386 return false;
387 }
388
389 // Remove spaces.
390
3/6
✓ Branch 1 taken 5880 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5880 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5880 times.
✗ Branch 8 not taken.
5880 currSite.remove(QRegularExpression("\\s+"));
391
392 // Is there a '-' in the site string indicating that this site
393 // is NOT for cleavage? If so, there should be only one such
394 // sign and in position 0.
395
396
1/2
✓ Branch 2 taken 5880 times.
✗ Branch 3 not taken.
5880 count = currSite.count(QChar('-'));
397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5880 times.
5880 if(count > 1)
398 return false;
399
2/2
✓ Branch 0 taken 784 times.
✓ Branch 1 taken 5096 times.
5880 else if(count == 1)
400 {
401
2/4
✓ Branch 2 taken 784 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 784 times.
784 if(currSite.indexOf(QChar('-'), 0, Qt::CaseInsensitive) != 0)
402 return false;
403
404 784 isForCleave = false;
405
406 // We can remove the '-' character, as we now know
407 // that the site is NOT for cleavage.
408
1/2
✓ Branch 1 taken 784 times.
✗ Branch 2 not taken.
784 currSite.remove(0, 1);
409 }
410 // else: site is for cleavage: no '-' found.
411
412
413 // We can create a new cleavage motif.
414
3/8
✓ Branch 1 taken 5880 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5880 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 5880 times.
✗ Branch 10 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
5880 CleaveMotif *motif = new CleaveMotif(mcsp_polChemDef, "NOT_SET");
415
416
1/2
✓ Branch 1 taken 5880 times.
✗ Branch 2 not taken.
5880 motif->setForCleave(isForCleave);
417
418
2/4
✓ Branch 1 taken 5880 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 5880 times.
5880 if(motif->parse(currSite) == -1)
419 {
420 qDebug() << "Failed to parse site" << currSite;
421
422 delete motif;
423
424 return false;
425 }
426
427 // qDebug() << __FILE__ << __LINE__
428 // << "Appending motif" << motif->motif();
429
430 // Append the newly created motif to the list.
431
1/2
✓ Branch 1 taken 5880 times.
✗ Branch 2 not taken.
5880 m_motifList.append(motif);
432
1/2
✓ Branch 1 taken 5880 times.
✗ Branch 2 not taken.
5880 }
433
434 3136 return true;
435 3136 }
436
437 /*!
438 \brief Validates this CleaveSpec instance.
439
440 The validation involves checking that:
441
442 \list
443 \li The name is not empty.
444 \li The pattern is nt empty.
445 \li The parsing of the pattern is successful.
446 \li Each CleaveRule instance (if any) validates successfully.
447 \endlist
448
449 Returns true if the validation is successful, false otherwise.
450 */
451 bool
452 3136 CleaveSpec::validate()
453 {
454
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3136 times.
3136 if(m_name.isEmpty())
455 return false;
456
457
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3136 times.
3136 if(m_pattern.isEmpty())
458 return false;
459
460
461
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3136 times.
3136 if(!parse())
462 return false;
463
464 // If there are rules, we have to check them all.
465
466
2/2
✓ Branch 1 taken 392 times.
✓ Branch 2 taken 3136 times.
3528 for(int iter = 0; iter < m_ruleList.size(); ++iter)
467 {
468
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 392 times.
392 if(!m_ruleList.at(iter)->validate())
469 return false;
470 }
471
472 3136 return true;
473 }
474
475 /*!
476 \brief Parses a cleavage specification XML \a element using a \a{version}ed
477 function.
478
479 The data in the element are validated and if successful they are set to this
480 instance, thus initializing it.
481
482 Returns true upon success, false otherwise.
483 */
484 bool
485 3136 CleaveSpec::renderXmlClsElement(const QDomElement &element, int version)
486 {
487 // For the time being the version is not necessary here. As of
488 // version up to 2, the current function works ok.
489
490
1/2
✓ Branch 0 taken 3136 times.
✗ Branch 1 not taken.
3136 if(version == 1)
491 {
492 // NoOp
493 3136 version = 1;
494 }
495
496
1/2
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
3136 QDomElement child;
497
1/2
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
3136 QDomElement childRule;
498
499 3136 CleaveRule *cleaveRule = 0;
500
501 /* The xml node we are in is structured this way:
502 *
503 * <cls>
504 * <name>CyanogenBromide</name>
505 * <pattern>M/</pattern>
506 * <clr>
507 * <le-mnm-code>M</le-mnm-code>
508 * <le-formula>-C1H2S1+O1</le-formula>
509 * <re-mnm-code>M</re-mnm-code>
510 * <re-formula>-C1H2S1+O1</re-formula>
511 * </clr>
512 * </cls>
513 *
514 * And the element parameter points to the
515 *
516 * <cls> element tag:
517 * ^
518 * |
519 * +----- here we are right now.
520 *
521 * Which means that element.tagName() == "cls" and that
522 * we'll have to go one step down to the first child of the
523 * current node in order to get to the <name> element.
524 */
525
526
2/4
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 3136 times.
3136 if(element.tagName() != "cls")
527 return false;
528
529
3/6
✓ Branch 2 taken 3136 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3136 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3136 times.
✗ Branch 9 not taken.
3136 child = element.firstChildElement("name");
530
531
2/4
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3136 times.
3136 if(child.isNull())
532 return false;
533
534
1/2
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
3136 m_name = child.text();
535 // qDebug() << "CleaveSpec name is" << m_name;
536
537
3/6
✓ Branch 2 taken 3136 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3136 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3136 times.
✗ Branch 9 not taken.
3136 child = child.nextSiblingElement("pattern");
538
539
2/4
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3136 times.
3136 if(child.isNull())
540 return false;
541
542
1/2
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
3136 m_pattern = child.text();
543
544 // At this point there might be 0, 1 or more cleavage rules.
545
3/6
✓ Branch 2 taken 3136 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3136 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3136 times.
✗ Branch 9 not taken.
3136 child = child.nextSiblingElement("clr");
546
547
3/4
✓ Branch 1 taken 3528 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 392 times.
✓ Branch 4 taken 3136 times.
3528 while(!child.isNull())
548 {
549
3/8
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 392 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 392 times.
✗ Branch 13 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
392 cleaveRule = new CleaveRule(mcsp_polChemDef, "NOT_SET");
550
551
2/4
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 392 times.
392 if(!cleaveRule->renderXmlClrElement(child, version))
552 {
553 delete cleaveRule;
554 return false;
555 }
556
557
2/4
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 392 times.
392 if(!cleaveRule->validate())
558 {
559 delete cleaveRule;
560 return false;
561 }
562
563
1/2
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
392 m_ruleList.append(cleaveRule);
564
565
3/6
✓ Branch 2 taken 392 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 392 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 392 times.
✗ Branch 9 not taken.
392 child = child.nextSiblingElement("clr");
566 }
567
568
2/4
✓ Branch 1 taken 3136 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3136 times.
3136 if(!validate())
569 return false;
570
571 3136 return true;
572 3136 }
573
574 /*!
575 \brief Formats a string describing this CleaveSpec instance suitable to be
576 used as an XML element.
577
578 The XML element is typically used in a polymer chemistry defintion and looks
579 like this:
580
581 \code
582 <cls>
583 <name>CyanogenBromide</name>
584 <pattern>M/</pattern>
585 <clr>
586 <re-mnm-code>M</re-mnm-code>
587 <re-formula>-CH2S+O</re-formula>
588 </clr>
589 </cls>
590 \endcode
591
592
593 The formatting of the XML element takes into account \a offset and \a
594 indent by prepending the string with \a offset * \a indent character
595 substring.
596
597 \a indent defaults to two spaces.
598
599 Returns a dynamically allocated string that needs to be freed after use.
600 */
601 QString *
602 32 CleaveSpec::formatXmlClsElement(int offset, const QString &indent)
603 {
604
605 int newOffset;
606 32 int iter = 0;
607
608
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 QString lead("");
609
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 QString *string = new QString();
610
611
612 // Prepare the lead.
613 32 newOffset = offset;
614
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 32 times.
128 while(iter < newOffset)
615 {
616
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 lead += indent;
617 96 ++iter;
618 }
619
620
621
3/6
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
64 *string += QString("%1<cls>\n").arg(lead);
622
623 // Prepare the lead.
624 32 ++newOffset;
625 32 lead.clear();
626 32 iter = 0;
627
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 32 times.
160 while(iter < newOffset)
628 {
629
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 lead += indent;
630 128 ++iter;
631 }
632
633 // Continue with indented elements.
634
635
4/8
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
96 *string += QString("%1<name>%2</name>\n").arg(lead).arg(m_name);
636
637
4/8
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
96 *string += QString("%1<pattern>%2</pattern>\n").arg(lead).arg(m_pattern);
638
639
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 32 times.
36 for(int iter = 0; iter < m_ruleList.size(); ++iter)
640 {
641
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 QString *ruleString = m_ruleList.at(iter)->formatXmlClrElement(newOffset);
642
643
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 *string += *ruleString;
644
645
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 delete ruleString;
646 }
647
648 // Prepare the lead for the closing element.
649 32 --newOffset;
650 32 lead.clear();
651 32 iter = 0;
652
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 32 times.
128 while(iter < newOffset)
653 {
654
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 lead += indent;
655 96 ++iter;
656 }
657
658
3/6
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
64 *string += QString("%1</cls>\n").arg(lead);
659
660 32 return string;
661 32 }
662
663 } // namespace libXpertMass
664
665 } // namespace MsXpS
666