Launcher.pm 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. #
  2. # Software Index, Copyright 2010, Software Index Project Team
  3. # Link: http://swi.sourceforge.net
  4. #
  5. # This file is part of Software Index Tool.
  6. #
  7. # Software Index is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, version 3 of the License.
  10. #
  11. # Software Index is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Software Index. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. use strict;
  20. use XML::Simple;
  21. use FileHandle;
  22. #
  23. # Export section
  24. #
  25. require Exporter;
  26. use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $PREFERRED_PARSER);
  27. @ISA = qw(Exporter);
  28. @EXPORT = qw(swiLaunch);
  29. @EXPORT_OK = qw();
  30. $VERSION = '1.0';
  31. $PREFERRED_PARSER = undef;
  32. #
  33. # Subroutine for troubleshooting purposes
  34. #
  35. use Internal::Output;
  36. #
  37. # Include SWI libs
  38. #
  39. require SWI::Appraiser;
  40. require SWI::Converter;
  41. require SWI::Merger;
  42. require SWI::Processor;
  43. #
  44. # Global variables
  45. #
  46. my $config = undef;
  47. #
  48. # Enter point
  49. #
  50. sub swiLaunch
  51. {
  52. my $returnCode = 0;
  53. my $rootLocation = shift();
  54. my $swiConfiguration = shift();
  55. # $returnCode == 0 => no critical errors and warnings
  56. # $returnCode > 0 => no critical errors, there are warnings
  57. # $returnCode < 0 => there are critical errors
  58. if ( $returnCode >= 0 )
  59. {
  60. if ( $swiConfiguration eq "" )
  61. {
  62. STATUS("Configuration file should be specified!");
  63. $returnCode = -1;
  64. }
  65. else
  66. {
  67. STATUS("Configuration file: $swiConfiguration.");
  68. }
  69. }
  70. if ( $returnCode >= 0 )
  71. {
  72. if ( swiConfigurationValidate($swiConfiguration) != 0 )
  73. {
  74. STATUS("Wrong configuration file!");
  75. $returnCode = -2;
  76. }
  77. }
  78. if ( $returnCode >= 0 )
  79. {
  80. # Generate report for every module separately
  81. for (
  82. my $i = 0 ;
  83. $i <= $#{ $config->{"swi:modules"}->{"swi:module"} } ;
  84. $i++
  85. )
  86. {
  87. STATUS( "Processing module: '"
  88. . $config->{"swi:modules"}->{"swi:module"}[$i]->{"swi:name"}
  89. . "'." );
  90. my $result = swiProcess( $config, $i, $rootLocation );
  91. if ( $result < 0 )
  92. {
  93. STATUS("The are problems to report the index for the module!");
  94. $returnCode = -5;
  95. }
  96. elsif ( $result > 0 )
  97. {
  98. STATUS("The are scan warnings and/or errors.");
  99. $returnCode += $result;
  100. }
  101. else
  102. {
  103. STATUS("The module has been processed succesfully.");
  104. }
  105. }
  106. }
  107. if ( $returnCode >= 0 )
  108. {
  109. # Merge reports
  110. if ( swiMerge($config) )
  111. {
  112. STATUS("The are problems to merge files to one report!");
  113. $returnCode = -3;
  114. }
  115. else
  116. {
  117. STATUS("Merged report has been created.");
  118. }
  119. }
  120. if ( $returnCode >= 0 )
  121. {
  122. # Add average/min/max/total values and generate final XML report
  123. if ( swiAppraise($config) )
  124. {
  125. STATUS("The are problems to add average/min/max/total values!");
  126. $returnCode = -4;
  127. }
  128. else
  129. {
  130. STATUS("Average/min/max/total values have been added.");
  131. }
  132. }
  133. if ( $returnCode >= 0 )
  134. {
  135. # Convert results
  136. my $result = swiConvert($config);
  137. if ( $result < 0 )
  138. {
  139. STATUS("The are problems to convert the report!");
  140. $returnCode = -5;
  141. }
  142. elsif ( $result > 0 )
  143. {
  144. STATUS(
  145. "Report has been converted. There are exceeded limitations.");
  146. $returnCode += $result;
  147. }
  148. else
  149. {
  150. STATUS("Report has been converted.");
  151. }
  152. }
  153. STATUS("Execution completed with exit code '$returnCode'.");
  154. return $returnCode;
  155. }
  156. sub swiConfigurationValidate
  157. {
  158. my $result = 0;
  159. $config =
  160. XMLin( shift(),
  161. ForceArray => [ "swi:module", "swi:rule", "swi:pattern" ] );
  162. if ( !defined( $config->{'swi:info'} ) )
  163. {
  164. STATUS("Wrong configuration: 'swi:info' section missed.");
  165. $result++;
  166. }
  167. else
  168. {
  169. if ( !defined( $config->{'swi:info'}->{'swi:version'} ) )
  170. {
  171. STATUS(
  172. "Wrong configuration: 'swi:info/swi:version' section missed.");
  173. $result++;
  174. }
  175. elsif ( $config->{'swi:info'}->{'swi:version'} != 1 )
  176. {
  177. STATUS(
  178. "Wrong configuration: Unsupported version of the configuration file. Check 'swi:info/swi:version' section."
  179. );
  180. $result++;
  181. }
  182. if ( !defined( $config->{'swi:info'}->{'swi:project'} ) )
  183. {
  184. STATUS(
  185. "Wrong configuration: 'swi:info/swi:project' section missed.");
  186. $result++;
  187. }
  188. else
  189. {
  190. if (
  191. !defined(
  192. $config->{'swi:info'}->{'swi:project'}->{'swi:name'}
  193. )
  194. )
  195. {
  196. STATUS(
  197. "Wrong configuration: 'swi:info/swi:project/swi:name' section missed."
  198. );
  199. $result++;
  200. }
  201. elsif ( $config->{'swi:info'}->{'swi:project'}->{'swi:name'} eq "" )
  202. {
  203. STATUS(
  204. "Wrong configuration: 'swi:info/swi:project/swi:name' is empty."
  205. );
  206. $result++;
  207. }
  208. }
  209. }
  210. if ( !defined( $config->{'swi:general'} )
  211. || ref( $config->{'swi:general'} ) ne 'HASH' )
  212. {
  213. $config->{'swi:general'} = {};
  214. }
  215. if ( !defined( $config->{'swi:general'}->{'swi:debug'} )
  216. || ref( $config->{'swi:general'}->{'swi:debug'} ) ne 'HASH' )
  217. {
  218. $config->{'swi:general'}->{'swi:debug'} = {};
  219. }
  220. if ( !defined( $config->{'swi:general'}->{'swi:debug'}->{'swi:enabled'} ) )
  221. {
  222. $config->{'swi:general'}->{'swi:debug'}->{'swi:enabled'} = 'off';
  223. }
  224. DEBUG_ENABLED(
  225. ( $config->{'swi:general'}->{'swi:debug'}->{'swi:enabled'} eq 'on' )
  226. ? 1
  227. : 0
  228. );
  229. if ( !defined( $config->{'swi:modules'} )
  230. || ref( $config->{'swi:modules'} ) ne 'HASH' )
  231. {
  232. STATUS("Wrong configuration: 'swi:modules' section missed.");
  233. $result++;
  234. }
  235. else
  236. {
  237. if ( !defined( $config->{'swi:modules'}->{'swi:module'} )
  238. || ref( $config->{'swi:modules'}->{'swi:module'} ) ne 'ARRAY' )
  239. {
  240. STATUS(
  241. "Wrong configuration: 'swi:modules/swi:module' section missed."
  242. );
  243. $result++;
  244. }
  245. else
  246. {
  247. my $moduleId = 0;
  248. foreach my $module ( @{ $config->{'swi:modules'}->{'swi:module'} } )
  249. {
  250. if ( !defined( $module->{'swi:name'} ) )
  251. {
  252. STATUS(
  253. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:name' section missed."
  254. );
  255. $result++;
  256. }
  257. if ( !defined( $module->{'swi:location'} ) )
  258. {
  259. STATUS(
  260. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:location' section missed."
  261. );
  262. $result++;
  263. }
  264. if ( !defined( $module->{'swi:files'} )
  265. || ref( $module->{'swi:files'} ) ne 'HASH' )
  266. {
  267. $module->{'swi:files'} = {};
  268. }
  269. if ( !defined( $module->{'swi:files'}->{'swi:include'} ) )
  270. {
  271. $module->{'swi:files'}->{'swi:include'} = '.*';
  272. }
  273. if ( !defined( $module->{'swi:files'}->{'swi:exclude'} ) )
  274. {
  275. $module->{'swi:files'}->{'swi:exclude'} = '';
  276. }
  277. if ( !defined( $module->{'swi:preprocessor'} )
  278. || ref( $module->{'swi:preprocessor'} ) ne 'HASH' )
  279. {
  280. $module->{'swi:preprocessor'} = {};
  281. }
  282. if ( !defined( $module->{'swi:preprocessor'}->{'swi:rule'} ) )
  283. {
  284. $module->{'swi:preprocessor'}->{'swi:rule'} = [];
  285. }
  286. my $ruleId = 0;
  287. foreach
  288. my $rule ( @{ $module->{'swi:preprocessor'}->{'swi:rule'} } )
  289. {
  290. if ( !defined( $rule->{'swi:filepattern'} )
  291. || $rule->{'swi:filepattern'} eq "" )
  292. {
  293. STATUS(
  294. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:preprocessor/swi:rule[$ruleId]/swi:filepattern' section missed."
  295. );
  296. $result++;
  297. }
  298. if ( !defined( $rule->{'swi:searchpattern'} )
  299. || $rule->{'swi:searchpattern'} eq "" )
  300. {
  301. STATUS(
  302. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:preprocessor/swi:rule[$ruleId]/swi:searchpattern' section missed."
  303. );
  304. $result++;
  305. }
  306. if ( !defined( $rule->{'swi:replacepattern'} )
  307. || $rule->{'swi:replacepattern'} eq "" )
  308. {
  309. STATUS(
  310. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:preprocessor/swi:rule[$ruleId]/swi:replacepattern' section missed."
  311. );
  312. $result++;
  313. }
  314. $ruleId++;
  315. }
  316. if ( !defined( $module->{'swi:scanner'} )
  317. || ref( $module->{'swi:scanner'} ) ne 'HASH' )
  318. {
  319. $module->{'swi:scanner'} = {};
  320. }
  321. if ( !defined( $module->{'swi:scanner'}->{'swi:rule'} ) )
  322. {
  323. $module->{'swi:scanner'}->{'swi:rule'} = [];
  324. }
  325. $ruleId = 0;
  326. foreach my $rule ( @{ $module->{'swi:scanner'}->{'swi:rule'} } )
  327. {
  328. if ( !defined( $rule->{'swi:filepattern'} )
  329. || $rule->{'swi:filepattern'} eq "" )
  330. {
  331. STATUS(
  332. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:scanner/swi:rule[$ruleId]/swi:filepattern' section missed."
  333. );
  334. $result++;
  335. }
  336. if ( !defined( $rule->{'swi:searchpattern'} )
  337. || $rule->{'swi:searchpattern'} eq "" )
  338. {
  339. STATUS(
  340. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:scanner/swi:rule[$ruleId]/swi:searchpattern' section missed."
  341. );
  342. $result++;
  343. }
  344. if ( !defined( $rule->{'swi:messagepattern'} )
  345. || $rule->{'swi:messagepattern'} eq "" )
  346. {
  347. STATUS(
  348. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:scanner/swi:rule[$ruleId]/swi:messagepattern' section missed."
  349. );
  350. $result++;
  351. }
  352. if ( !defined( $rule->{'swi:codecontent'} )
  353. || $rule->{'swi:codecontent'} eq "" )
  354. {
  355. $rule->{'swi:codecontent'} = 'purified';
  356. }
  357. $ruleId++;
  358. }
  359. if ( !defined( $module->{'swi:scanner'}->{'swi:suppress'} ) )
  360. {
  361. $module->{'swi:scanner'}->{'swi:suppress'} = {};
  362. }
  363. if (
  364. !defined(
  365. $module->{'swi:scanner'}->{'swi:suppress'}
  366. ->{'swi:pattern'}
  367. )
  368. )
  369. {
  370. $module->{'swi:scanner'}->{'swi:suppress'}
  371. ->{'swi:pattern'} = [];
  372. }
  373. my $patternId = 0;
  374. foreach my $pattern (
  375. @{
  376. $module->{'swi:scanner'}->{'swi:suppress'}
  377. ->{'swi:pattern'}
  378. }
  379. )
  380. {
  381. if ( ref($pattern) ne 'HASH' )
  382. {
  383. STATUS(
  384. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:scanner/swi:suppress/swi:pattern[$patternId]' section is incorrect."
  385. );
  386. $result++;
  387. }
  388. else
  389. {
  390. if ( !defined( $pattern->{'swi:message'} )
  391. || $pattern->{'swi:message'} eq "" )
  392. {
  393. STATUS(
  394. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:scanner/swi:suppress/swi:pattern[$patternId]/swi:message' field is empty."
  395. );
  396. $result++;
  397. }
  398. if ( !defined( $pattern->{'content'} )
  399. || $pattern->{'content'} eq "" )
  400. {
  401. STATUS(
  402. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:scanner/swi:suppress/swi:pattern[$patternId]' object pattern is empty."
  403. );
  404. $result++;
  405. }
  406. }
  407. $patternId++;
  408. }
  409. if ( !defined( $module->{'swi:indexer:common'} )
  410. || ref( $module->{'swi:indexer:common'} ) ne 'HASH' )
  411. {
  412. $module->{'swi:indexer:common'} = {};
  413. }
  414. if ( !defined( $module->{'swi:indexer:dup'} )
  415. || ref( $module->{'swi:indexer:dup'} ) ne 'HASH' )
  416. {
  417. $module->{'swi:indexer:dup'} = {};
  418. }
  419. if (
  420. !defined(
  421. $module->{'swi:indexer:dup'}->{'swi:codecontent'}
  422. )
  423. )
  424. {
  425. $module->{'swi:indexer:dup'}->{'swi:codecontent'} =
  426. 'purified';
  427. }
  428. if ( !defined( $module->{'swi:indexer:dup'}->{'swi:enabled'} ) )
  429. {
  430. $module->{'swi:indexer:dup'}->{'swi:enabled'} = 'on';
  431. }
  432. if ( !defined( $module->{'swi:indexer:dup'}->{'swi:minlength'} )
  433. )
  434. {
  435. $module->{'swi:indexer:dup'}->{'swi:minlength'} = 100;
  436. }
  437. if ( $module->{'swi:indexer:dup'}->{'swi:minlength'} <= 0 )
  438. {
  439. STATUS(
  440. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:indexer:dup/swi:minlength' can not be less than or equal to zero."
  441. );
  442. $result++;
  443. }
  444. if ( !defined( $module->{'swi:indexer:dup'}->{'swi:proximity'} )
  445. )
  446. {
  447. $module->{'swi:indexer:dup'}->{'swi:proximity'} = 100;
  448. }
  449. if ( $module->{'swi:indexer:dup'}->{'swi:proximity'} <= 0
  450. || $module->{'swi:indexer:dup'}->{'swi:proximity'} > 100 )
  451. {
  452. STATUS(
  453. "Wrong configuration: 'swi:modules/swi:module[$moduleId]/swi:indexer:dup/swi:proximity' should be in the range from 1 till 100."
  454. );
  455. $result++;
  456. }
  457. if (
  458. !defined(
  459. $module->{'swi:indexer:dup'}->{'swi:globalcode'}
  460. )
  461. )
  462. {
  463. $module->{'swi:indexer:dup'}->{'swi:globalcode'} = 'off';
  464. }
  465. if ( !defined( $module->{'swi:indexer:gcov'} )
  466. || ref( $module->{'swi:indexer:gcov'} ) ne 'HASH' )
  467. {
  468. $module->{'swi:indexer:gcov'} = {};
  469. }
  470. if ( !defined( $module->{'swi:indexer:gcov'}->{'swi:enabled'} ) )
  471. {
  472. $module->{'swi:indexer:gcov'}->{'swi:enabled'} = 'off';
  473. }
  474. if ( !defined( $module->{'swi:indexer:gcov'}->{'swi:filepattern'} ) )
  475. {
  476. $module->{'swi:indexer:gcov'}->{'swi:filepattern'} = '.*';
  477. }
  478. if ( !defined( $module->{'swi:indexer:gcov'}->{'swi:sourcefile'} ) )
  479. {
  480. $module->{'swi:indexer:gcov'}->{'swi:sourcefile'} = '(.*)[.][cChH][pP]?[pP]?';
  481. }
  482. if ( !defined( $module->{'swi:indexer:gcov'}->{'swi:gcdafile'} ) )
  483. {
  484. $module->{'swi:indexer:gcov'}->{'swi:gcdafile'} = '${1}.gcda';
  485. }
  486. $moduleId++;
  487. }
  488. }
  489. }
  490. if ( !defined( $config->{'swi:report'} )
  491. || ref( $config->{'swi:report'} ) ne 'HASH' )
  492. {
  493. STATUS("Wrong configuration: 'swi:report' section missed.");
  494. $result++;
  495. }
  496. else
  497. {
  498. if ( !defined( $config->{'swi:report'}->{'swi:destination'} ) )
  499. {
  500. STATUS(
  501. "Wrong configuration: 'swi:report/swi:destination' section missed."
  502. );
  503. $result++;
  504. }
  505. if ( !defined( $config->{'swi:report'}->{'swi:xml'} ) )
  506. {
  507. STATUS("Wrong configuration: 'swi:report/swi:xml' section missed.");
  508. $result++;
  509. }
  510. else
  511. {
  512. if (
  513. !defined( $config->{'swi:report'}->{'swi:xml'}->{'swi:name'} ) )
  514. {
  515. STATUS(
  516. "Wrong configuration: 'swi:report/swi:xml/swi:name' section is empty."
  517. );
  518. $result++;
  519. }
  520. }
  521. if ( !defined( $config->{'swi:report'}->{'swi:notifications'} ) )
  522. {
  523. STATUS(
  524. "Wrong configuration: 'swi:report/swi:notifications' section missed."
  525. );
  526. $result++;
  527. }
  528. else
  529. {
  530. if (
  531. !defined(
  532. $config->{'swi:report'}->{'swi:notifications'}->{'swi:name'}
  533. )
  534. )
  535. {
  536. STATUS(
  537. "Wrong configuration: 'swi:report/swi:notifications/swi:name' section is empty."
  538. );
  539. $result++;
  540. }
  541. if (
  542. !defined(
  543. $config->{'swi:report'}->{'swi:notifications'}
  544. ->{'swi:error'}
  545. )
  546. || ref(
  547. $config->{'swi:report'}->{'swi:notifications'}
  548. ->{'swi:error'}
  549. ) ne 'HASH'
  550. )
  551. {
  552. $config->{'swi:report'}->{'swi:notifications'}->{'swi:error'} =
  553. {};
  554. }
  555. if (
  556. !defined(
  557. $config->{'swi:report'}->{'swi:notifications'}
  558. ->{'swi:error'}->{'swi:added'}
  559. )
  560. )
  561. {
  562. $config->{'swi:report'}->{'swi:notifications'}->{'swi:error'}
  563. ->{'swi:added'} = 'on';
  564. }
  565. if (
  566. !defined(
  567. $config->{'swi:report'}->{'swi:notifications'}
  568. ->{'swi:error'}->{'swi:removed'}
  569. )
  570. )
  571. {
  572. $config->{'swi:report'}->{'swi:notifications'}->{'swi:error'}
  573. ->{'swi:removed'} = 'on';
  574. }
  575. if (
  576. !defined(
  577. $config->{'swi:report'}->{'swi:notifications'}
  578. ->{'swi:error'}->{'swi:modified'}
  579. )
  580. )
  581. {
  582. $config->{'swi:report'}->{'swi:notifications'}->{'swi:error'}
  583. ->{'swi:modified'} = 'on';
  584. }
  585. if (
  586. !defined(
  587. $config->{'swi:report'}->{'swi:notifications'}
  588. ->{'swi:error'}->{'swi:cloned'}
  589. )
  590. )
  591. {
  592. $config->{'swi:report'}->{'swi:notifications'}->{'swi:error'}
  593. ->{'swi:cloned'} = 'on';
  594. }
  595. if (
  596. !defined(
  597. $config->{'swi:report'}->{'swi:notifications'}
  598. ->{'swi:error'}->{'swi:unmodified'}
  599. )
  600. )
  601. {
  602. $config->{'swi:report'}->{'swi:notifications'}->{'swi:error'}
  603. ->{'swi:unmodified'} = 'on';
  604. }
  605. if (
  606. !defined(
  607. $config->{'swi:report'}->{'swi:notifications'}
  608. ->{'swi:print'}
  609. )
  610. || ref(
  611. $config->{'swi:report'}->{'swi:notifications'}
  612. ->{'swi:print'}
  613. ) ne 'HASH'
  614. )
  615. {
  616. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'} =
  617. {};
  618. }
  619. swiUtilConfigFill_PrintSection($config, 'swi:added');
  620. swiUtilConfigFill_PrintSection($config, 'swi:removed');
  621. swiUtilConfigFill_PrintSection($config, 'swi:modified');
  622. swiUtilConfigFill_PrintSection($config, 'swi:cloned');
  623. swiUtilConfigFill_PrintSection($config, 'swi:unmodified');
  624. }
  625. }
  626. # swi:limits section is verified in runtime
  627. # no precheck currently
  628. DEBUG( "Configuration structure is: " . Dumper($config) );
  629. return $result;
  630. }
  631. sub swiUtilConfigFill_PrintSection
  632. {
  633. my $config = shift();
  634. my $modType = shift();
  635. if (
  636. !defined(
  637. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  638. ->{$modType}
  639. )
  640. || ref(
  641. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  642. ->{$modType}
  643. ) ne 'HASH'
  644. )
  645. {
  646. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  647. ->{$modType} = {};
  648. }
  649. if (
  650. !defined(
  651. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  652. ->{$modType}->{'swi:failures'}
  653. )
  654. )
  655. {
  656. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  657. ->{$modType}->{'swi:failures'} = 'on';
  658. }
  659. if (
  660. !defined(
  661. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  662. ->{$modType}->{'swi:modifications'}
  663. )
  664. )
  665. {
  666. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  667. ->{$modType}->{'swi:modifications'} = 'on';
  668. }
  669. if (
  670. !defined(
  671. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  672. ->{$modType}->{'swi:duplications'}
  673. )
  674. )
  675. {
  676. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  677. ->{$modType}->{'swi:duplications'} = 'off';
  678. }
  679. if (
  680. !defined(
  681. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  682. ->{$modType}->{'swi:scanmessages'}
  683. )
  684. )
  685. {
  686. $config->{'swi:report'}->{'swi:notifications'}->{'swi:print'}
  687. ->{$modType}->{'swi:scanmessages'} = 'on';
  688. }
  689. }
  690. return 1;