srcanamdw/codescanner/codescanner.py
changeset 1 22878952f6e2
equal deleted inserted replaced
0:509e4801c378 1:22878952f6e2
       
     1 # #################################################################
       
     2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # 
       
     5 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
     6 # 
       
     7 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
     8 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
     9 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
    10 # 
       
    11 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
    12 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
    13 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
    14 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
    15 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
    16 #
       
    17 # linescanner.py - the main body of CodeScanner
       
    18 #
       
    19 # #################################################################
       
    20 
       
    21 import base64
       
    22 import datetime
       
    23 import encodings
       
    24 import getopt
       
    25 import os
       
    26 import os.path
       
    27 import psyco
       
    28 import re
       
    29 import sys
       
    30 import xml.dom.minidom
       
    31 import zlib
       
    32 
       
    33 # Ignore flags
       
    34 KIgnoreNothing = 0
       
    35 KIgnoreComments = 1
       
    36 KIgnoreCommentsAndQuotes = 2
       
    37 KIgnoreQuotes = 3
       
    38 
       
    39 # Severities for the scripts
       
    40 KSeverityHigh = 0
       
    41 KSeverityMedium = 1
       
    42 KSeverityLow = 2
       
    43 
       
    44 # The names used in the XML configuration file for severity element names.
       
    45 KSeverityConfigMap = {
       
    46 			KSeverityHigh		: "high",
       
    47 			KSeverityMedium		: "medium",
       
    48 			KSeverityLow		: "low"}
       
    49 
       
    50 # The names used in the HTML summary file for severity element names.
       
    51 KSeverityHTMLMap = {
       
    52 			KSeverityHigh		: "High",
       
    53 			KSeverityMedium		: "Medium",
       
    54 			KSeverityLow		: "Low"}
       
    55 
       
    56 # Categories for the scripts
       
    57 KCategoryLegal = "Legal Code" 
       
    58 KCategoryDefinitePanic = "Always Panic"
       
    59 KCategoryCanPanic = "Can Panic"
       
    60 KCategoryWrongFunctionality = "Wrong Functionality"
       
    61 KCategoryLocalisation = "Localisation"
       
    62 KCategoryPerformance = "Performance"
       
    63 KCategoryCodingStandards = "Coding Standard"
       
    64 KCategoryDocumentation = "Documentation"
       
    65 KCategoryCodeReviewGuides = "Code Review Guide"
       
    66 KCategoryOther = "Other"
       
    67 
       
    68 KCategoryHtmlDisplayOrder = [KCategoryLegal,
       
    69 	KCategoryDefinitePanic,
       
    70 	KCategoryCanPanic,
       
    71 	KCategoryWrongFunctionality,
       
    72 	KCategoryLocalisation,
       
    73 	KCategoryPerformance,
       
    74 	KCategoryCodingStandards,
       
    75 	KCategoryDocumentation,
       
    76 	KCategoryCodeReviewGuides,
       
    77 	KCategoryOther]
       
    78 
       
    79 # The names used in the XML configuration file for category element names.
       
    80 KCategoryConfigMap = {
       
    81 			KCategoryLegal				:	"legal", 
       
    82 			KCategoryDefinitePanic		:	"panic", 
       
    83 			KCategoryCanPanic			:	"canpanic", 
       
    84 			KCategoryWrongFunctionality	:	"functionality",
       
    85 			KCategoryLocalisation		:	"localisation",
       
    86 			KCategoryPerformance		:	"performance",
       
    87 			KCategoryCodingStandards	:	"codingstandards",
       
    88 			KCategoryDocumentation		:	"documentation",
       
    89 			KCategoryCodeReviewGuides	:	"codereview",
       
    90 			KCategoryOther				:	"other"}
       
    91 
       
    92 #Custom rule keyword types
       
    93 KKeywordBaseClass = "baseclass"
       
    94 KKeywordCall = "call"
       
    95 KKeywordClassName = "class"
       
    96 KKeywordComment = "comment"
       
    97 KKeywordGeneric = "generic"
       
    98 KKeywordLocal = "local"
       
    99 KKeywordMacro = "macro"
       
   100 KKeywordMember = "member"
       
   101 KKeywordMethod = "method"
       
   102 KKeywordParameter = "parameter"
       
   103 KKeywordUnknown = "unknown"
       
   104 
       
   105 #The names used in the XML configuration file for custom rule keyword types.
       
   106 KCustomRuleKeywordMap = {
       
   107 			KKeywordBaseClass           :   "baseclass",
       
   108 			KKeywordCall                :   "call",
       
   109 			KKeywordClassName           :   "class",
       
   110 			KKeywordComment             :   "comment",
       
   111 			KKeywordGeneric             :   "generic",
       
   112 			KKeywordLocal               :   "local",
       
   113 			KKeywordMacro               :   "macro",
       
   114 			KKeywordMember              :   "member",
       
   115 			KKeywordMethod              :   "method",
       
   116 			KKeywordParameter           :   "parameter",
       
   117 			KKeywordUnknown             :   "unknown"}
       
   118 
       
   119 KVersion = "Nokia CodeScanner version 2.1.4"
       
   120 KCopyrightLine1 = "Copyright (c) 2007-2009. Nokia Corporation. All rights reserved."
       
   121 KCopyrightLine1Html = "Copyright © 2007-2009. Nokia Corporation. All rights reserved."
       
   122 KCopyrightLine2 = "For product and support information, visit www.forum.nokia.com."
       
   123 KWww = "www.forum.nokia.com"
       
   124 
       
   125 stringPool = {}
       
   126 #
       
   127 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
   128 # All rights reserved.
       
   129 # 
       
   130 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
   131 # 
       
   132 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
   133 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
   134 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
   135 # 
       
   136 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
   137 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
   138 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
   139 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
   140 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
   141 #
       
   142 
       
   143 # English.loc
       
   144 # localised string for Script accessArrayElementWithoutCheck
       
   145 
       
   146 stringPool[ "accessArrayElementWithoutCheck!title" ]       = "Array element accessed by At() function without checking index is within array range"
       
   147 stringPool[ "accessArrayElementWithoutCheck!description" ] = "Whenever an element in an array is accessed, the index should be checked to ensure that it is less than array.Count(). CodeScanner checks for explicit calls to a Count() function; so if the array index is checked in a different way, it gives false positives. Accessing an invalid index can cause a panic."
       
   148 stringPool[ "accessArrayElementWithoutCheck!ideTitle" ]    = "array element accessed by At() function without checking index is within array range"
       
   149 
       
   150 # localised string for Script accessArrayElementWithoutCheck2
       
   151 stringPool[ "accessArrayElementWithoutCheck2!title" ]       = "Array element accessed by [] without checking range"
       
   152 stringPool[ "accessArrayElementWithoutCheck2!description" ] = "Whenever an element in an array is accessed, the index should first be checked to ensure that it is within range. CodeScanner checks for explicit calls to a Count() or Length() function; so if the array index is checked in a different way, it gives false positives. Accessing an invalid index can cause a panic."
       
   153 stringPool[ "accessArrayElementWithoutCheck2!ideTitle" ]    = "array element accessed by [] without checking range"
       
   154 
       
   155 # localised string for Script activestart
       
   156 stringPool[ "activestart!title" ]       = "Using CActiveScheduler::Start"
       
   157 stringPool[ "activestart!description" ] = "Using CActiveScheduler::Start() can mean that something asynchronous is being made synchronous. Instead, use active objects correctly in an asynchronous way."
       
   158 stringPool[ "activestart!ideTitle" ]    = "using CActiveScheduler::Start"
       
   159 
       
   160 # localised string for Script activestop
       
   161 stringPool[ "activestop!title" ]       = "Using CActiveScheduler::Stop"
       
   162 stringPool[ "activestop!description" ] = "Using CActiveScheduler::Stop() can mean that something asynchronous is being made synchronous. Instead, use active objects correctly in an asynchronous way."
       
   163 stringPool[ "activestop!ideTitle" ]    = "using CActiveScheduler::Stop"
       
   164 
       
   165 # localised string for Script arraypassing
       
   166 stringPool[ "arraypassing!title" ]       = "Passing arrays by value rather than reference"
       
   167 stringPool[ "arraypassing!description" ] = "Passing arrays by value causes the array to be copied needlessly, which takes up time and memory. For efficiency, references should be used."
       
   168 stringPool[ "arraypassing!ideTitle" ]    = "passing arrays by value rather than reference"
       
   169 
       
   170 # localised string for Script arrayptrcleanup
       
   171 stringPool[ "arrayptrcleanup!title" ]       = "Using local CArrayPtr classes without cleanup items"
       
   172 stringPool[ "arrayptrcleanup!description" ] = "It is not enough to push a local CArrayPtr class onto the cleanup stack. A TCleanupItem and callback function must be used to avoid leaking the elements."
       
   173 stringPool[ "arrayptrcleanup!ideTitle" ]    = "using local CArrayPtr classes without cleanup items"
       
   174 
       
   175 # localised string for Script assertdebuginvariant
       
   176 stringPool[ "assertdebuginvariant!title" ]       = "__ASSERT_DEBUG with User::Invariant"
       
   177 stringPool[ "assertdebuginvariant!description" ] = "Replace __ASSERT_DEBUG(<condition>, User::Invariant()) with ASSERT(<condition>), because it is easier to read."
       
   178 stringPool[ "assertdebuginvariant!ideTitle" ]    = "__ASSERT_DEBUG with User::Invariant"
       
   179 
       
   180 # localised string for Script baddefines
       
   181 stringPool[ "baddefines!title" ]       = "Lowercase definition names"
       
   182 stringPool[ "baddefines!description" ] = "Badly-named definitions makes the code harder to maintain and can lead to defects."
       
   183 stringPool[ "baddefines!ideTitle" ]    = "lowercase definition names"
       
   184 
       
   185 # localised string for Script baseconstruct
       
   186 stringPool[ "baseconstruct!title" ]       = "Leaving function called before BaseConstructL()"
       
   187 stringPool[ "baseconstruct!description" ] = "If a leave occurs before BaseConstructL() is called, the system can panic because it is trying to clean up an application that has not been fully initialised."
       
   188 stringPool[ "baseconstruct!ideTitle" ]    = "leaving method called before BaseConstructL"
       
   189 
       
   190 # localised string for Script callActiveObjectWithoutCheckingOrStopping
       
   191 stringPool[ "callActiveObjectWithoutCheckingOrStopping!title" ]       = "Active object called without checking whether it is active or canceling it first"
       
   192 stringPool[ "callActiveObjectWithoutCheckingOrStopping!description" ] = "If an active object is started twice, a panic occurs. CodeScanner picks out places where there is a call to a Start(), Queue(), or After() function on a member variable, without a previous call to IsActive(), Cancel(), or Stop(). In general, if starting a timer, there should at least be a call to IsActive() to ensure that the timer is not already running."
       
   193 stringPool[ "callActiveObjectWithoutCheckingOrStopping!ideTitle" ]    = "active object called without checking whether it is active or canceling it first"
       
   194 
       
   195 # localised string for Script changenotification
       
   196 stringPool[ "changenotification!title" ]       = "Using RSAVarChangeNotify to see System Agent changes"
       
   197 stringPool[ "changenotification!description" ] = "When watching for System Agent changes, use RSystemAgent rather than RSAVarChangeNotify, which can fail."
       
   198 stringPool[ "changenotification!ideTitle" ]    = "using RSAVarChangeNotify to see System Agent changes"
       
   199 
       
   200 # localised string for Script cleanup
       
   201 stringPool[ "cleanup!title" ]       = "CleanupStack::Pop(AndDestroy) parameters"
       
   202 stringPool[ "cleanup!description" ] = "These functions should be called with explicit variable parameters to avoid misalignment."
       
   203 stringPool[ "cleanup!ideTitle" ]    = "missing CleanupStack::Pop parameter"
       
   204 
       
   205 # localised string for Script commentcode
       
   206 stringPool[ "commentcode!title" ]       = "Commented-out code"
       
   207 stringPool[ "commentcode!description" ] = "Instances of code that are commented out make the code hard to maintain and to interpret clearly. The commented out code should be removed. Any requirement to rediscover old code should be made through source control and not by trawling through commented-out code."
       
   208 stringPool[ "commentcode!ideTitle" ]    = "commented-out code"
       
   209 
       
   210 # localised string for Script connect
       
   211 stringPool[ "connect!title" ]       = "Ignoring Connect() return value"
       
   212 stringPool[ "connect!description" ] = "Ignoring the error returned from Connect() functions means that if the Connect() function fails due to OOM or other problems, the next access to the resource will panic."
       
   213 stringPool[ "connect!ideTitle" ]    = "ignoring Connect() return value"
       
   214 
       
   215 # localised string for Script ConnectAndDontCloseMemberVariable
       
   216 stringPool[ "ConnectAndDontCloseMemberVariable!title" ]       = "Calling Connect() or Open() on a member variable without calling Close() in the destructor"
       
   217 stringPool[ "ConnectAndDontCloseMemberVariable!description" ] = "If Connect() or Open() is called on any member variable, then Close() must be called in the destructor."
       
   218 stringPool[ "ConnectAndDontCloseMemberVariable!ideTitle" ]    = "calling Connect() or Open() on a member variable without calling Close() in the destructor"
       
   219 
       
   220 # localised string for Script constnames
       
   221 stringPool[ "constnames!title" ]       = "Badly-named constants"
       
   222 stringPool[ "constnames!description" ] = "Badly-named constant will make the source code harder to maintain and make defects more likely."
       
   223 stringPool[ "constnames!ideTitle" ]    = "badly-named constant"
       
   224 
       
   225 # localised string for Script consttdescptr
       
   226 stringPool[ "consttdescptr!title" ]       = "Const descriptor pointer as argument"
       
   227 stringPool[ "consttdescptr!description" ] = "Use \"const TDesC&\" instead of \"const TDesC*\"."
       
   228 stringPool[ "consttdescptr!ideTitle" ]    = "const descriptor pointer as argument"
       
   229 
       
   230 # localised string for Script controlornull
       
   231 stringPool[ "controlornull!title" ]       = "Accessing return value of ControlOrNull()"
       
   232 stringPool[ "controlornull!description" ] = "The return value might be NULL, so it should be checked before access."
       
   233 stringPool[ "controlornull!ideTitle" ]    = "accessing return value of ControlOrNull()"
       
   234 
       
   235 # localised string for Script crepository
       
   236 stringPool[ "crepository!title" ]       = "Ignoring CRepository::get() return value"
       
   237 stringPool[ "crepository!description" ] = "Independent application cannot assume that the Central Repository is set up fully. This means the return value of CRepository::get() cannot be ignored."
       
   238 stringPool[ "crepository!ideTitle" ]    = "ignoring CRepository::get() return value"
       
   239 
       
   240 # localised string for Script ctltargettype
       
   241 stringPool[ "ctltargettype!title" ]       = "Use of targettype ctl"
       
   242 stringPool[ "ctltargettype!description" ] = "The ctl target type should not be used. Instead, use DLL and explicitly refer to the Control Panel's DEF file. Note: Code that causes this issue only needs attention if it is found in code developed for Nokia Series 90 code that has extra exports for resetting the Control Panel item's data."
       
   243 stringPool[ "ctltargettype!ideTitle" ]    = "use of targettype ctl"
       
   244 
       
   245 # localised string for Script customizableicons
       
   246 stringPool[ "customizableicons!title" ]       = "Use of customizable icons"
       
   247 stringPool[ "customizableicons!description" ] = "Due to device customization requirements, independent application must not remove any customization done by the variant team. This means independent application cannot include customizable icons."
       
   248 stringPool[ "customizableicons!ideTitle" ]    = "use of customizable icons"
       
   249 
       
   250 # localised string for Script debugrom
       
   251 stringPool[ "debugrom!title" ]       = "Debug components in ROM"
       
   252 stringPool[ "debugrom!description" ] = "Debug versions of components in the ROM could mean that ROM space is being taken up with debugging information or that logging is being put out. Release versions should be in the ROM unless there is a good reason why they are not."
       
   253 stringPool[ "debugrom!ideTitle" ]    = "debug components in ROM"
       
   254 
       
   255 # localised string for Script declarename
       
   256 stringPool[ "declarename!title" ]       = "Use of __DECLARE_NAME"
       
   257 stringPool[ "declarename!description" ] = "The __DECLARE_NAME macro is historical and serves no purpose anymore and should be removed."
       
   258 stringPool[ "declarename!ideTitle" ]    = "use of __DECLARE_NAME"
       
   259 
       
   260 # localised string for Script deleteMemberVariable
       
   261 stringPool[ "deleteMemberVariable!title" ]       = "Member variable deleted incorrectly"
       
   262 stringPool[ "deleteMemberVariable!description" ] = "When a member variable is deleted, it should be assigned either to NULL or to another value. This prevents accidental access of the deleted object. If a NewL() or other leaving function is called to reassign the member variable, it should first be assigned to NULL in case that function leaves."
       
   263 stringPool[ "deleteMemberVariable!ideTitle" ]    = "member variable deleted incorrectly"
       
   264 
       
   265 # localised string for Script destructor
       
   266 stringPool[ "destructor!title" ]       = "Pointer access in destructors"
       
   267 stringPool[ "destructor!description" ] = "Accessing pointers to objects in destructors without checking whether they are not NULL could result in a panic because they may not have been constructed. The pointers should be checked to determine whether they are owned objects. If they are not owned, they should really be references rather than pointers."
       
   268 stringPool[ "destructor!ideTitle" ]    = "destructor is accessing/dereferencing data member"
       
   269 
       
   270 # localised string for Script doubleSemiColon
       
   271 stringPool[ "doubleSemiColon!title" ]       = "Use of double semicolon"
       
   272 stringPool[ "doubleSemiColon!description" ] = "Double semicolons at the end of a line are not necessary and cause a CodeWarrior compiler error."
       
   273 stringPool[ "doubleSemiColon!ideTitle" ]    = "use of double semicolon"
       
   274 
       
   275 # localised string for Script driveletters
       
   276 stringPool[ "driveletters!title" ]       = "Hard-coded drive letters"
       
   277 stringPool[ "driveletters!description" ] = "Drive letters should not be hard-coded."
       
   278 stringPool[ "driveletters!ideTitle" ]    = "hard-coded drive letters"
       
   279 
       
   280 # localised string for Script eikbuttons
       
   281 stringPool[ "eikbuttons!title" ]       = "Checks that the R_EIK_BUTTONS_* resources are not being used"
       
   282 stringPool[ "eikbuttons!description" ] = "R_EIK_BUTTONS_* resources will not be internationalised, and should not be used. Instead, create your own button resource. No button resource (or indeed, rls string) should be used in more than one location. Note: This issue is only relevant for development on Nokia platforms."
       
   283 stringPool[ "eikbuttons!ideTitle" ]    = "use of R_EIK_BUTTONS_ resources"
       
   284 
       
   285 # localised string for Script eikonenvstatic
       
   286 stringPool[ "eikonenvstatic!title" ]       = "Using CEikonEnv::Static"
       
   287 stringPool[ "eikonenvstatic!description" ] = "CEikonEnv::Static() calls should be kept to a minimum, because this involves TLS. All applications, controls, and dialogs already have a pointer to the singleton instance of CEikonEnv as a member variable and so do not need to find it again. If a class does not have access to a CEikonEnv and needs to use it repeatedly, then it should store one."
       
   288 stringPool[ "eikonenvstatic!ideTitle" ]    = "using CEikonEnv::Static"
       
   289 
       
   290 # localised string for Script enummembers
       
   291 stringPool[ "enummembers!title" ]       = "Enums with badly-named members"
       
   292 stringPool[ "enummembers!description" ] = "Enums with badly-named members make the code harder to maintain and may cause defects."
       
   293 stringPool[ "enummembers!ideTitle" ]    = "enum with badly-named member"
       
   294 
       
   295 # localised string for Script enumnames
       
   296 stringPool[ "enumnames!title" ]       = "Badly-named enums"
       
   297 stringPool[ "enumnames!description" ] = "Badly-named enums make the code harder to maintain and may cause defects."
       
   298 stringPool[ "enumnames!ideTitle" ]    = "badly-named enum"
       
   299 
       
   300 # localised string for Script exportinline
       
   301 stringPool[ "exportinline!title" ]       = "Exporting inline functions"
       
   302 stringPool[ "exportinline!description" ] = "Inline functions should not be exported because this can cause those that link to the DLL to fail to build. Exporting functions limits the changes that can be made in the future due to considerations of binary-compatibility."
       
   303 stringPool[ "exportinline!ideTitle" ]    = "exporting inline functions"
       
   304 
       
   305 # localised string for Script exportpurevirtual
       
   306 stringPool[ "exportpurevirtual!title" ]       = "Exporting pure virtual functions"
       
   307 stringPool[ "exportpurevirtual!description" ] = "Symbian recommends against the exportation of pure virtual functions."
       
   308 stringPool[ "exportpurevirtual!ideTitle" ]    = "exporting pure virtual functions"
       
   309 
       
   310 # localised string for Script externaldriveletters
       
   311 # stringPool[ "externaldriveletters!title" ]       = "Hard-coded external drive letters"
       
   312 # stringPool[ "externaldriveletters!description" ] = "External drive letters should not be hard-coded as the external drive may change between platforms and releases. This may cause confusion over ownership leading to classes being deleted erroneously and leaks occurring."
       
   313 # stringPool[ "externaldriveletters!ideTitle" ]    = "hard-coded external drive letter"
       
   314 
       
   315 # localised string for Script flags
       
   316 stringPool[ "flags!title" ]       = "Use of R&D flags or feature flags"
       
   317 stringPool[ "flags!description" ] = "Independent application must not use R&D flags nor feature flags via preprocessor statements in the source code. This means bld*.hrh and productvariant.hrh should not be used."
       
   318 stringPool[ "flags!ideTitle" ]    = "use of R&D flags or feature flags"
       
   319 
       
   320 # localised string for Script foff
       
   321 stringPool[ "foff!title" ]       = "Use of _FOFF"
       
   322 stringPool[ "foff!description" ] = "_FOFF allows access to data in classes that were not intended for public access. This may cause problems, especially when the location of the data changes."
       
   323 stringPool[ "foff!ideTitle" ]    = "use of _FOFF"
       
   324 
       
   325 # localised string for Script forbiddenwords
       
   326 stringPool[ "forbiddenwords!title" ]       = "Use of forbidden words in header files"
       
   327 stringPool[ "forbiddenwords!description" ] = "Some words should not be used in header files; especially those header files destined for external release. Some words may be forbidden for legal reasons or for platform consistency. Where they exist, alternative allowed words should be used. For example, \"NMP\" and \"Nokia Mobile Phones\" should be replaced by \"Nokia\"."
       
   328 stringPool[ "forbiddenwords!ideTitle" ]    = "use of forbidden words in header files"
       
   329 
       
   330 # localised string for Script forgottoputptroncleanupstack
       
   331 stringPool[ "forgottoputptroncleanupstack!title" ]       = "Neglected to put variable on cleanup stack"
       
   332 stringPool[ "forgottoputptroncleanupstack!description" ] = "If a variable is not put on the cleanup stack and a leaving function or ELeave is called, a memory leak occurs. CodeScanner occasionally gives false positives for this issue. Individual cases should be investigated."
       
   333 stringPool[ "forgottoputptroncleanupstack!ideTitle" ]    = "neglected to put variable on cleanup stack"
       
   334 
       
   335 # localised string for Script friend
       
   336 stringPool[ "friend!title" ]       = "Use of friends"
       
   337 stringPool[ "friend!description" ] = "The friend directive is often misused and can indicate problems in the OO design."
       
   338 stringPool[ "friend!ideTitle" ]    = "use of friends"
       
   339 
       
   340 # localised string for Script goto
       
   341 stringPool[ "goto!title" ]       = "Use of goto"
       
   342 stringPool[ "goto!description" ] = "Goto should not be used if it can be avoided because it makes the program flow more difficult to follow."
       
   343 stringPool[ "goto!ideTitle" ]    = "use of goto"
       
   344 
       
   345 # localised string for Script ifassignments
       
   346 stringPool[ "ifassignments!title" ]       = "Assignment in an If statement"
       
   347 stringPool[ "ifassignments!description" ] = "Assignments inside an If statement often indicate that the assignment was not intended. Even if the assignment was intended, it is clearer to separate out the assignment from the conditional. The script that detects such occurrences has a few false positives when the action statements are on the same line as the conditional check. However, this is also against the coding standards and the action should be on a separate line."
       
   348 stringPool[ "ifassignments!ideTitle" ]    = "assignment in an If statement"
       
   349 
       
   350 # localised string for Script ifpreprocessor
       
   351 stringPool[ "ifpreprocessor!title" ]       = "Use of #if in .h files"
       
   352 stringPool[ "ifpreprocessor!description" ] = "#if in header files should only be used before the main include guards and not around #include statements or around functional blocks in class definitions. The reason for the latter is to aid readability and to make BC breaks more difficult."
       
   353 stringPool[ "ifpreprocessor!ideTitle" ]    = "use of #if in .h files (not as main include guards)"
       
   354 
       
   355 # localised string for Script inheritanceorder
       
   356 stringPool[ "inheritanceorder!title" ]       = "Incorrect inheritance order of M and C classes"
       
   357 stringPool[ "inheritanceorder!description" ] = "If a C class inherits first from an M class and then a C class, a panic can occur when trying to pop a CBase pointer pointing to such a class from the cleanup stack when in fact a pointer pointing to the first predecessor, the mixin class, was popped instead."
       
   358 stringPool[ "inheritanceorder!ideTitle" ]    = "incorrect inheritance order of M and C classes"
       
   359 
       
   360 # localised string for Script intleaves
       
   361 stringPool[ "intleaves!title" ]       = "Methods that leave AND return a TInt error"
       
   362 stringPool[ "intleaves!description" ] = "Returning an error code as well as being able to leave is problematical for the caller. It is preferable to adhere to one method of returning the error. Note: CodeScanner is likely to return false positives for this situation, because some returned TInt values will not be error codes."
       
   363 stringPool[ "intleaves!ideTitle" ]    = "methods that leave AND return a TInt error"
       
   364 
       
   365 # localised string for Script jmp
       
   366 stringPool[ "jmp!title" ]       = "Use of setjmp and/or longjmp"
       
   367 stringPool[ "jmp!description" ] = "Using setjmp and/or longjmp makes code less maintainable."
       
   368 stringPool[ "jmp!ideTitle" ]    = "use of setjmp and/or longjmp"
       
   369 
       
   370 # localised string for Script leave
       
   371 stringPool[ "leave!title" ]       = "Leaving functions called in non-leaving functions"
       
   372 stringPool[ "leave!description" ] = "Non-leaving functions should not call leaving functions. Note: Operator functions are considered to be able to leave when scanning the code inside them."
       
   373 stringPool[ "leave!ideTitle" ]    = "leaving function called in non-leaving function"
       
   374 
       
   375 # localised string for Script LeaveNoError
       
   376 stringPool[ "LeaveNoError!title" ]       = "Leaving with KErrNone"
       
   377 stringPool[ "LeaveNoError!description" ] = "Leaving with KErrNone usually indicates that there is a makeshift way around a design issue rather than a true and proper fix to the architecture."
       
   378 stringPool[ "LeaveNoError!ideTitle" ]    = "leaving with KErrNone"
       
   379 
       
   380 # localised string for Script leavingoperators
       
   381 stringPool[ "leavingoperators!title" ]       = "Leaving functions called in operator functions"
       
   382 stringPool[ "leavingoperators!description" ] = "It is not obvious that operator functions can leave. Calling leaving functions in operator functions should be considered carefully."
       
   383 stringPool[ "leavingoperators!ideTitle" ]    = "leaving functions called in operator functions"
       
   384 
       
   385 # localised string for Script LFunctionCantLeave
       
   386 stringPool[ "LFunctionCantLeave!title" ]       = "L-functions that cannot leave"
       
   387 stringPool[ "LFunctionCantLeave!description" ] = "A function should not be named with an 'L' if it cannot leave. The only exception is in virtual functions where the function name is defined in the base class so the L cannot be removed. For example, RunL()."
       
   388 stringPool[ "LFunctionCantLeave!ideTitle" ]    = "L-functions that cannot leave"
       
   389 
       
   390 # localised string for Script longlines
       
   391 stringPool[ "longlines!title" ]       = "Overly long lines of code"
       
   392 stringPool[ "longlines!description" ] = "Lines longer than about 100 characters can indicate messy or badly-structured code that is hard to maintain."
       
   393 stringPool[ "longlines!ideTitle" ]    = "overly long line of code"
       
   394 
       
   395 # localised string for Script magicnumbers
       
   396 stringPool[ "magicnumbers!title" ]       = "Use of magic numbers"
       
   397 stringPool[ "magicnumbers!description" ] = "Magic numbers - that is, numbers that are hard-coded into the source code and instead of being presented as constants - make code difficult to maintain and give no indication of why a calculation is the way it is. Magic numbers should be replaced with named constants."
       
   398 stringPool[ "magicnumbers!ideTitle" ]    = "use of magic numbers"
       
   399 
       
   400 # localised string for Script mclassdestructor
       
   401 stringPool[ "mclassdestructor!title" ]       = "M class has destructor"
       
   402 stringPool[ "mclassdestructor!description" ] = "M classes should not contain a destructor."
       
   403 stringPool[ "mclassdestructor!ideTitle" ]    = "M class has destructor"
       
   404 
       
   405 # localised string for Script memberlc
       
   406 stringPool[ "memberlc!title" ]       = "Assigning LC methods to member variables"
       
   407 stringPool[ "memberlc!description" ] = "Objects on the cleanup stack should not be assigned to member variables"
       
   408 stringPool[ "memberlc!ideTitle" ]    = "LC method assigned to data member"
       
   409 
       
   410 # localised string for Script membervariablecallld
       
   411 stringPool[ "membervariablecallld!title" ]       = "Calling LD function on member variable"
       
   412 stringPool[ "membervariablecallld!description" ] = "LD functions should not be called on a member variable because ownership can be unclear and may lead to double deletes."
       
   413 stringPool[ "membervariablecallld!ideTitle" ]    = "calling LD function on member variable"
       
   414 
       
   415 # localised string for Script missingcancel
       
   416 stringPool[ "missingcancel!title" ]       = "Cancel() not called in active object's destructor"
       
   417 stringPool[ "missingcancel!description" ] = "Cancel() should always be called in active object's destructor to cancel an outstanding request if there is one. If there is no request pending then Cancel() just does nothing, but if we do not call Cancel() when having an outstanding request a panic will be raised. CodeScanner occasionally gives false positives for this issue. Individual cases should be investigated."
       
   418 stringPool[ "missingcancel!ideTitle" ]    = "Cancel() not called in active object's destructor"
       
   419 
       
   420 # localised string for Script missingcclass
       
   421 stringPool[ "missingcclass!title" ]       = "C class not inheriting from another C class"
       
   422 stringPool[ "missingcclass!description" ] = "All C classes should inherit from another C class to ensure that all data members are zeroed."
       
   423 stringPool[ "missingcclass!ideTitle" ]    = "C class not inheriting from another C class"
       
   424 
       
   425 # localised string for Script mmpsourcepath
       
   426 stringPool[ "mmpsourcepath!title" ]       = "Use of absolute path names in MMP files"
       
   427 stringPool[ "mmpsourcepath!description" ] = "Use of absolute paths in MMP files makes it impossible to relocate the source. Relative paths should be used instead."
       
   428 stringPool[ "mmpsourcepath!ideTitle" ]    = "use of absolute path names in MMP files"
       
   429 
       
   430 # localised string for Script multilangrsc
       
   431 stringPool[ "multilangrsc!title" ]       = "Not using BaflUtils::NearestLanguageFile() when loading a resource file"
       
   432 stringPool[ "multilangrsc!description" ] = "If AddResourceFileL() is used without first using BaflUtils::NearestLanguageFile(), then not all language versions of resources will be picked up."
       
   433 stringPool[ "multilangrsc!ideTitle" ]    = "not using BaflUtils::NearestLanguageFile() when loading a resource file"
       
   434 
       
   435 # localised string for Script multipledeclarations
       
   436 stringPool[ "multipledeclarations!title" ]       = "Multiple declarations on one line"
       
   437 stringPool[ "multipledeclarations!description" ] = "Multiple declarations on one line can be confusing. Separate them out so that each declaration is on its own separate line."
       
   438 stringPool[ "multipledeclarations!ideTitle" ]    = "multiple declarations on one line"
       
   439 
       
   440 # localised string for Script multipleinheritance
       
   441 stringPool[ "multipleinheritance!title" ]       = "Non M-class multiple inheritance"
       
   442 stringPool[ "multipleinheritance!description" ] = "It is bad Symbian OS practice to derive from two classes that have implemented functions. Complex behaviour that was not intended can result."
       
   443 stringPool[ "multipleinheritance!ideTitle" ]    = "multiple inheritance from non M-classes"
       
   444 
       
   445 # localised string for Script mydocs
       
   446 stringPool[ "mydocs!title" ]       = "Hard-coded mydocs directory strings"
       
   447 stringPool[ "mydocs!description" ] = "The mydocs directory is subject to change so should not be referenced directly. Note: @	This issue will only occur in code developed for the Nokia Series 90 platform."
       
   448 stringPool[ "mydocs!ideTitle" ]    = "hard-coded mydocs directory strings"
       
   449 
       
   450 # localised string for Script namespace
       
   451 stringPool[ "namespace!title" ]       = "Use of namespace"
       
   452 stringPool[ "namespace!description" ] = "Namespaces are often used to work around a poor naming convention."
       
   453 stringPool[ "namespace!ideTitle" ]    = "use of namespace"
       
   454 
       
   455 # localised string for Script newlreferences
       
   456 stringPool[ "newlreferences!title" ]       = "NewL() returning a reference"
       
   457 stringPool[ "newlreferences!description" ] = "NewL() and NewLC() functions should return a pointer to an object created on the heap."
       
   458 stringPool[ "newlreferences!ideTitle" ]    = "NewL() returning a reference"
       
   459 
       
   460 # localised string for Script noleavetrap
       
   461 stringPool[ "noleavetrap!title" ]       = "TRAP used with no leaving functions"
       
   462 stringPool[ "noleavetrap!description" ] = "A TRAP is unnecessary if there are no leaving functions."
       
   463 stringPool[ "noleavetrap!ideTitle" ]    = "TRAP contains no leaving functions"
       
   464 
       
   465 # localised string for Script nonconsthbufc
       
   466 stringPool[ "nonconsthbufc!title" ]       = "Non-const HBufC* parameter passing"
       
   467 stringPool[ "nonconsthbufc!description" ] = "HBufC* parameters should almost always be passed as a const pointer."
       
   468 stringPool[ "nonconsthbufc!ideTitle" ]    = "non-const HBufC* parameter passing"
       
   469 
       
   470 # localised string for Script nonconsttdesc
       
   471 stringPool[ "nonconsttdesc!title" ]       = "Non-const TDesC& parameter passing"
       
   472 stringPool[ "nonconsttdesc!description" ] = "TDesC& parameters should be passed as a const. If it is not, it may indicate that the coder does not understand descriptors, for example, passing descriptors by value."
       
   473 stringPool[ "nonconsttdesc!ideTitle" ]    = "non-const TDesC& parameter passing"
       
   474 
       
   475 # localised string for Script nonleavenew
       
   476 stringPool[ "nonleavenew!title" ]       = "Use of new without (ELeave)"
       
   477 stringPool[ "nonleavenew!description" ] = "Using new without (ELeave) is only used in special circumstances. The leaving variant should typically be used in preference. A common exception is for application creation, where NULL is returned for failed creation."
       
   478 stringPool[ "nonleavenew!ideTitle" ]    = "new used without (ELeave)"
       
   479 
       
   480 # localised string for Script nonunicodeskins
       
   481 stringPool[ "nonunicodeskins!title" ]       = "Non-Unicode skins"
       
   482 stringPool[ "nonunicodeskins!description" ] = "Skin definition files (SKN, SKE) must be Unicode. Note: Code that causes this issue only needs attention if it is found in code developed for Nokia Series 90 code."
       
   483 stringPool[ "nonunicodeskins!ideTitle" ]    = "non-Unicode skins"
       
   484 
       
   485 # localised string for Script null
       
   486 stringPool[ "null!title" ]       = "NULL equality check"
       
   487 stringPool[ "null!description" ] = "There is no need to compare pointer variables to NULL. Use If(ptr)."
       
   488 stringPool[ "null!ideTitle" ]    = "NULL equality check"
       
   489 
       
   490 # localised string for Script open
       
   491 stringPool[ "open!title" ]       = "Ignoring Open() return value"
       
   492 stringPool[ "open!description" ] = "Ignoring the return value from Open() functions (due to OOM, etc.) means that when the resource is accessed next, a panic will result."
       
   493 stringPool[ "open!ideTitle" ]    = "ignoring Open() return value"
       
   494 
       
   495 # localised string for Script pointertoarrays
       
   496 stringPool[ "pointertoarrays!title" ]       = "Pointer to arrays as members of a C class"
       
   497 stringPool[ "pointertoarrays!description" ] = "In C classes, there is no need to use pointers to arrays as data members. Instead, use the arrays themselves. Using pointers leads to obscure notation like \"(*array)[n]\" for the more usual \"array[n]\". It also makes it necessary to explicitly delete the arrays in the destructor. Using the arrays themselves also simplifies notation, reduces indirection, and reduces heap fragmentation."
       
   498 stringPool[ "pointertoarrays!ideTitle" ]    = "pointer to arrays as members of a C class"
       
   499 
       
   500 # localised string for Script pragmadisable
       
   501 stringPool[ "pragmadisable!title" ]       = "Use of #pragma warning"
       
   502 stringPool[ "pragmadisable!description" ] = "Disabling warnings can lead to problems, because the warnings are probably there for a reason."
       
   503 stringPool[ "pragmadisable!ideTitle" ]    = "use of #pragma warning"
       
   504 
       
   505 # localised string for Script pragmamessage
       
   506 stringPool[ "pragmamessage!title" ]       = "Use of #pragma message"
       
   507 stringPool[ "pragmamessage!description" ] = "#pragma messages during the build stage can interfere with the build log parsing."
       
   508 stringPool[ "pragmamessage!ideTitle" ]    = "use of #pragma message"
       
   509 
       
   510 # localised string for Script pragmaother
       
   511 stringPool[ "pragmaother!title" ]       = "Use of #pragma other than warning and message"
       
   512 stringPool[ "pragmaother!description" ] = "#pragma directives should only be used in very edge cases (for example, functions consisting of inline assembler without explicit return statements) because, typically, their usage masks valid build warnings and error messages."
       
   513 stringPool[ "pragmaother!ideTitle" ]    = "use of #pragma other than warning and message"
       
   514 
       
   515 # localised string for Script privateinheritance
       
   516 stringPool[ "privateinheritance!title" ]       = "Use of private inheritance"
       
   517 stringPool[ "privateinheritance!description" ] = "Classes should not be inherited privately. If public or protected inheritance is not appropriate, consider using an amalgamation; that is, have an object of that type as a member variable."
       
   518 stringPool[ "privateinheritance!ideTitle" ]    = "use of private inheritance"
       
   519 
       
   520 # localised string for Script pushaddrvar
       
   521 stringPool[ "pushaddrvar!title" ]       = "Pushing address of a variable onto the cleanup stack"
       
   522 stringPool[ "pushaddrvar!description" ] = "If the variable is owned by the code pushing it, it should be stored as a pointer. If it is not, it should not be pushed onto the cleanup stack."
       
   523 stringPool[ "pushaddrvar!ideTitle" ]    = "pushing address of a variable onto the cleanup stack"
       
   524 
       
   525 # localised string for Script pushmember
       
   526 stringPool[ "pushmember!title" ]       = "Pushing data members onto the cleanup stack"
       
   527 stringPool[ "pushmember!description" ] = "Pushing member variables is likely to lead to double deletes or leakage in certain circumstances and so should be avoided. Even if no panic can result, it is bad practice and makes maintenance more difficult."
       
   528 stringPool[ "pushmember!ideTitle" ]    = "data member pushed to cleanup stack"
       
   529 
       
   530 # localised string for Script readresource
       
   531 stringPool[ "readresource!title" ]       = "Using ReadResource() instead of ReadResourceL()"
       
   532 stringPool[ "readresource!description" ] = "ReadResourceL() should always be used in preference to ReadResource() because in an error scenario ReadResource() effectively fails silently. If no check is performed on the resulting descriptor afterwards, unexpected states can ensue. These states are often characterized by buffer overflows."
       
   533 stringPool[ "readresource!ideTitle" ]    = "Using ReadResource() instead of ReadResourceL()"
       
   534 
       
   535 # localised string for Script resourcenotoncleanupstack
       
   536 stringPool[ "resourcenotoncleanupstack!title" ]       = "Neglected to put resource objects on cleanup stack"
       
   537 stringPool[ "resourcenotoncleanupstack!description" ] = "If a stack-based resource object is not put on the cleanup stack with CleanupResetAndDestroyPushL() or CleanupClosePushL(), and a leaving function or ELeave is called, a memory leak occurs. CodeScanner occasionally gives false positives for this issue. Individual cases should be investigated."
       
   538 stringPool[ "resourcenotoncleanupstack!ideTitle" ]    = "neglected to put resource objects on cleanup stack"
       
   539 
       
   540 # localised string for Script resourcesonheap
       
   541 stringPool[ "resourcesonheap!title" ]       = "Resource objects on the heap"
       
   542 stringPool[ "resourcesonheap!description" ] = "There is very rarely any real need to put R classes on the heap (unless they are not real R classes!).  Doing so can lead to inefficiency and cleanup stack problems."
       
   543 stringPool[ "resourcesonheap!ideTitle" ]    = "resource objects on the heap"
       
   544 
       
   545 # localised string for Script returndescriptoroutofscope
       
   546 stringPool[ "returndescriptoroutofscope!title" ]       = "Return descriptor out of scope"
       
   547 stringPool[ "returndescriptoroutofscope!description" ] = "Returning a TBuf descriptor that is declared locally takes it out of scope. This can cause a crash on WINSCW, although not on WINS."
       
   548 stringPool[ "returndescriptoroutofscope!ideTitle" ]    = "return descriptor out of scope"
       
   549 
       
   550 # localised string for Script rfs
       
   551 stringPool[ "rfs!title" ]       = "Use of non-pointer/reference RFs"
       
   552 stringPool[ "rfs!description" ] = "Connecting to an RFs is a time-consuming operation. (It can take approximately 0.1 seconds on some devices.) To minimise wasted time and resources, use the already-connected one in EikonEnv or elsewhere, if possible."
       
   553 stringPool[ "rfs!ideTitle" ]    = "use of non-pointer/reference RFs"
       
   554 
       
   555 # localised string for Script rssnames
       
   556 stringPool[ "rssnames!title" ]       = "Duplicate RSS names"
       
   557 stringPool[ "rssnames!description" ] = "Resource files with clashing NAME fields can cause the wrong resource file to be accessed. This can lead to incorrect functionality or panics."
       
   558 stringPool[ "rssnames!ideTitle" ]    = "duplicate RSS names"
       
   559 
       
   560 # localised string for Script stringliterals
       
   561 stringPool[ "stringliterals!title" ]       = "Use of _L string literals"
       
   562 stringPool[ "stringliterals!description" ] = "_L() string literals should be replaced by the _LIT() macro."
       
   563 stringPool[ "stringliterals!ideTitle" ]    = "use of _L string literals"
       
   564 
       
   565 # localised string for Script stringsinresourcefiles
       
   566 stringPool[ "stringsinresourcefiles!title" ]       = "Strings in RSS or RA files"
       
   567 stringPool[ "stringsinresourcefiles!description" ] = "Strings should not be defined in RSS or RA files. Instead, they should be put in RLS or other localisable files."
       
   568 stringPool[ "stringsinresourcefiles!ideTitle" ]    = "strings in RSS or RA files"
       
   569 
       
   570 # localised string for Script struct
       
   571 stringPool[ "struct!title" ]       = "Use of struct"
       
   572 stringPool[ "struct!description" ] = "C-style structs should not generally be used. The correct idiom is to use a class with public members. A permissible use of a C-style struct is if it is used to group non-semantically related entities together for convenience, and if a class-related hierarchy would be too heavy-weight."
       
   573 stringPool[ "struct!ideTitle" ]    = "use of struct"
       
   574 
       
   575 # localised string for Script tcclasses
       
   576 stringPool[ "tcclasses!title" ]       = "T classes inheriting from C classes"
       
   577 stringPool[ "tcclasses!description" ] = "T classes that are derived from C classes may have a complex constructor and so need to be handled differently. It is better to make the T class into a C class, which will make the code easier to maintain."
       
   578 stringPool[ "tcclasses!ideTitle" ]    = "T class inherits from C class"
       
   579 
       
   580 # localised string for Script tclassdestructor
       
   581 stringPool[ "tclassdestructor!title" ]       = "T class has destructor"
       
   582 stringPool[ "tclassdestructor!description" ] = "T classes should not have a destructor"
       
   583 stringPool[ "tclassdestructor!ideTitle" ]    = "T class has destructor"
       
   584 
       
   585 # localised string for Script todocomments
       
   586 stringPool[ "todocomments!title" ]       = "\"To do\" comments"
       
   587 stringPool[ "todocomments!description" ] = "\"To do\" comments in code suggest that it is not finished."
       
   588 stringPool[ "todocomments!ideTitle" ]    = "\"To do\" comment"
       
   589 
       
   590 # localised string for Script trapcleanup
       
   591 stringPool[ "trapcleanup!title" ]       = "Use of LC function in TRAPs"
       
   592 stringPool[ "trapcleanup!description" ] = "You cannot trap something that leaves something on the cleanup stack because it will panic."
       
   593 stringPool[ "trapcleanup!ideTitle" ]    = "LC function used in TRAP"
       
   594 
       
   595 # localised string for Script trapeleave
       
   596 stringPool[ "trapeleave!title" ]       = "Trapping new(ELeave)"
       
   597 stringPool[ "trapeleave!description" ] = "The trapping of a \"new(ELeave) CXxx\" call is redundant and wasteful as the code to support TRAP is surprisingly large. If the instantiation process really needs not to leave, use \"new CXxx\" and check for NULL."
       
   598 stringPool[ "trapeleave!ideTitle" ]    = "trapping new(ELeave)"
       
   599 
       
   600 # localised string for Script traprunl
       
   601 stringPool[ "traprunl!title" ]       = "Trapping of (Do)RunL() rather than using RunError()"
       
   602 stringPool[ "traprunl!description" ] = "The RunError() function should be used rather than the CActive derivative using its own TRAPD solution within a RunL()."
       
   603 stringPool[ "traprunl!ideTitle" ]    = "trapping of (Do)RunL() rather than using RunError()"
       
   604 
       
   605 # localised string for Script trspassing
       
   606 stringPool[ "trspassing!title" ]       = "Passing TRequestStatus parameters by value"
       
   607 stringPool[ "trspassing!description" ] = "TRequestStatus parameters should be passed by reference. If TRequestStatus is just being used as an error code, then convert it to a TInt."
       
   608 stringPool[ "trspassing!ideTitle" ]    = "passing TRequestStatus parameters by value"
       
   609 
       
   610 # localised string for Script uids
       
   611 stringPool[ "uids!title" ]       = "Duplicate UIDs"
       
   612 stringPool[ "uids!description" ] = "UIDs must be unique."
       
   613 stringPool[ "uids!ideTitle" ]    = "duplicate UIDs"
       
   614 
       
   615 # localised string for Script uncompressedaif
       
   616 stringPool[ "uncompressedaif!title" ]       = "Uncompressed AIFs in ROM"
       
   617 stringPool[ "uncompressedaif!description" ] = "AIF files should be referenced as \"AIF=\" rather than \"data=\" or \"file=\" otherwise they can bloat the ROM size and slow down application loading."
       
   618 stringPool[ "uncompressedaif!ideTitle" ]    = "uncompressed AIFs in ROM"
       
   619 
       
   620 # localised string for Script uncompressedbmp
       
   621 stringPool[ "uncompressedbmp!title" ]       = "Uncompressed bitmaps in ROM"
       
   622 stringPool[ "uncompressedbmp!description" ] = "Using uncompressed bitmaps can significantly bloat the size of ROM images. All occurrences of \"bitmap=\" in iby/hby files should be replaced with \"auto-bitmap=\". Also, including bitmaps using \"data=\" or \"file=\" causes bloat and load-speed reductions."
       
   623 stringPool[ "uncompressedbmp!ideTitle" ]    = "uncompressed bitmaps in ROM"
       
   624 
       
   625 # localised string for Script unicodesource
       
   626 stringPool[ "unicodesource!title" ]       = "Unicode source files"
       
   627 stringPool[ "unicodesource!description" ] = "Having Unicode source files (CPP, H, RLS, LOC, RSS, and RA) will break most build systems."
       
   628 stringPool[ "unicodesource!ideTitle" ]    = "Unicode source files"
       
   629 
       
   630 # localised string for Script userafter
       
   631 stringPool[ "userafter!title" ]       = "Use of User::After"
       
   632 stringPool[ "userafter!description" ] = "Generally, User::After() functions are used to skirt around timing problems. Typically, they should be removed and the defects fixed properly: that is, by waiting for the correct event to continue execution."
       
   633 stringPool[ "userafter!ideTitle" ]    = "use of User::After"
       
   634 
       
   635 # localised string for Script userfree
       
   636 stringPool[ "userfree!title" ]       = "Using User::Free directly"
       
   637 stringPool[ "userfree!description" ] = "User::Free() should never be called, because all objects free their memory on deletion; their destructors are not called and further resources cannot be freed or closed. This function should be removed and replaced by explicit deletes."
       
   638 stringPool[ "userfree!ideTitle" ]    = "using User::Free directly"
       
   639 
       
   640 # localised string for Script userWaitForRequest
       
   641 stringPool[ "userWaitForRequest!title" ]       = "Use of User::WaitForRequest"
       
   642 stringPool[ "userWaitForRequest!description" ] = "User::WaitForRequest() should not generally be used in UI code because the UI will not respond to redraw events while its thread is stopped."
       
   643 stringPool[ "userWaitForRequest!ideTitle" ]    = "use of User::WaitForRequest"
       
   644 
       
   645 # localised string for Script variablenames
       
   646 stringPool[ "variablenames!title" ]       = "Local variables with member/argument names"
       
   647 stringPool[ "variablenames!description" ] = "Local variable names should be of the form localVariable and not aLocalVar or iLocalVar. Badly-named variables can be misleading and cause maintenance and coding errors."
       
   648 stringPool[ "variablenames!ideTitle" ]    = "local variables with member/argument names"
       
   649 
       
   650 # localised string for Script voidparameter
       
   651 stringPool[ "voidparameter!title" ]       = "Void parameter explicitly declared"
       
   652 stringPool[ "voidparameter!description" ] = "Declaring a void parameter is unnecessary. A function declared as DoSomething(void) may as well be declared as DoSomething(). Void casts are also unnecessary."
       
   653 stringPool[ "voidparameter!ideTitle" ]    = "void parameter explicitly declared"
       
   654 
       
   655 # localised string for Script worryingcomments
       
   656 stringPool[ "worryingcomments!title" ]       = "Worrying comments"
       
   657 stringPool[ "worryingcomments!description" ] = "Typically, exclamation and question marks in comments indicate that something odd is in the code or that it is unfinished or not understood fully."
       
   658 stringPool[ "worryingcomments!ideTitle" ]    = "worrying comments"
       
   659 
       
   660 #!LOCALISEHERE
       
   661 
       
   662 def Usage(code, msg=""):
       
   663 	print msg
       
   664 	print
       
   665 	print KVersion
       
   666 	print
       
   667 	print "Usage: CodeScanner [options] <source dir> [<output dir>]"	
       
   668 	print "   or: CodeScanner [options] <source file> [<output dir>]"
       
   669 	print 
       
   670 	print "options:"
       
   671 	print "    -h - display command help"
       
   672 	print "    -v - display verbose messages"
       
   673 	print "    -c <config file> - use specified configuration file"
       
   674 	print "    -i <source dir/file> - specify additional directory/file to scan"
       
   675 	print "    -l <log file> - create debug log with specified filename"
       
   676 	print "    -o html|xml|std - specify output format : HTML, XML or StdOut; default is HTML"
       
   677 	print "    -x url to lxr site"
       
   678 	print "    -r lxr version"
       
   679 	print "    -t on/off - create a time-stamped directory for results, default is on"
       
   680 	print
       
   681 	print "<source dir> is the directory containing the source code to scan"
       
   682 	print "<source file> is the single file containing the source code to scan"
       
   683 	print "<output dir> is the directory in which to produce the output"
       
   684 	print
       
   685 	print "Notes:"
       
   686 	print "<source dir> and <output dir> cannot be identical"
       
   687 	print "<output dir> cannot be the root of a drive"
       
   688 	print
       
   689 	print KCopyrightLine1
       
   690 	print KCopyrightLine2
       
   691 	if scanner.iLog <> None:
       
   692 		scanner.iLog.Write("usage(): exiting with code " + str(code))
       
   693 		scanner.iLog.Close()
       
   694 	sys.exit(code)
       
   695 
       
   696 def DefaultCompare(aLines, aCurrentline, aRematch, aFilename):
       
   697 	if aRematch.search(aLines[aCurrentline]):
       
   698 		return 1
       
   699 	else:
       
   700 		return 0
       
   701 
       
   702 def DefaultFuncParamCompare(lines, currentline, rematch, filename):
       
   703 	# distinguish local declaration from function parameter
       
   704     line = lines[currentline]
       
   705     m = rematch.search(line)
       
   706     if m:
       
   707         isFuncParam = (line.find(")") <> -1)
       
   708         isLocal = (line.find(";") <> -1)
       
   709 
       
   710         while (not isFuncParam) and (not isLocal) and (currentline + 1 < len(lines)):
       
   711             currentline += 1
       
   712             line = lines[currentline]
       
   713             isFuncParam = (line.find(")") <> -1)
       
   714             isLocal = (line.find(";") <> -1)
       
   715 
       
   716         if isFuncParam:
       
   717             return 1
       
   718         elif isLocal:
       
   719             return 0
       
   720 
       
   721     return 0
       
   722 
       
   723 def ScanDirOrFile(argument):
       
   724 	if os.path.isdir(argument):
       
   725 		scanner.iComponentManager.SetRoot(argument)
       
   726 		scanner.TraverseDirectory(argument)
       
   727 	elif os.path.isfile(argument):
       
   728 		parentDir = os.path.dirname(argument)
       
   729 		scanner.iComponentManager.SetRoot(parentDir)
       
   730 		scanner.iComponentManager.BeginDirectory(parentDir)
       
   731 		numberOfLinesScanned = 0
       
   732 		numberOfLinesScanned += scanner.ScanFile(argument)
       
   733 		scanner.iComponentManager.EndDirectory(parentDir, numberOfLinesScanned)
       
   734 	else:
       
   735 		print "Unable to open specified source file: " + argument
       
   736 		sys.exit(2)
       
   737 
       
   738 
       
   739 class CScript:
       
   740 
       
   741 	# #######################################################
       
   742 	# CScript - a test script
       
   743 
       
   744 	def __init__(self, aScriptName):
       
   745 		self.iScriptName = aScriptName
       
   746 		self.iCompare = DefaultCompare
       
   747 		self.iReString = ""
       
   748 		self.iReMatch = re.compile("")
       
   749 		self.iTitle = stringPool[aScriptName + "!title"]
       
   750 		self.iIdeTitle = stringPool[aScriptName + "!ideTitle"]
       
   751 		self.iFileExts = []
       
   752 		self.iIgnore = KIgnoreNothing
       
   753 		self.iDescription = stringPool[aScriptName + "!description"]
       
   754 		self.iSeverity = KSeverityMedium
       
   755 		self.iBaseClass = ""
       
   756 
       
   757 	def ScriptConfig(self):
       
   758 		if (scanner.iDomConfig <> None):
       
   759 			for scriptsNode in scanner.iDomConfig.getElementsByTagName("scripts"):
       
   760 				for scriptNode in scriptsNode.getElementsByTagName(self.iScriptName):
       
   761 					return scriptNode
       
   762 		return None
       
   763 	
       
   764 	def DefaultInheritanceCompare(self, lines, currentline, rematch, filename):
       
   765 		m = rematch.search(lines[currentline])
       
   766 		if m:
       
   767 			inheritanceString = m.group(3)
       
   768 			# check for inheritance list spanning multiple lines
       
   769 			i = currentline + 1
       
   770 			while (inheritanceString.find("{") == -1) and i < len(lines):
       
   771 				if (inheritanceString.find(";") <> -1):
       
   772 					return 0
       
   773 				inheritanceString += lines[i]
       
   774 				i += 1
       
   775 
       
   776 			# construct inheritance class list
       
   777 			inheritancelist = inheritanceString.split(",")
       
   778 			reclass = re.compile("[\s:]*(public|protected|private)?\s*([\w:]+)")
       
   779 			classlist = []
       
   780 			for inheritance in inheritancelist:
       
   781 				match = reclass.search(inheritance)
       
   782 				if match:
       
   783 					inheritclass = match.group(2)
       
   784 					colonpos = inheritclass.rfind(":")
       
   785 					if (colonpos <> -1):
       
   786 						inheritclass = inheritclass[colonpos + 1:]
       
   787 					classlist.append(inheritclass)
       
   788 
       
   789 			# search for inheritance class
       
   790 			for classname in classlist:
       
   791 				if classname == self.iBaseClass:
       
   792 					return 1
       
   793 
       
   794 		return 0
       
   795 
       
   796 
       
   797 class CCustomScript(CScript):
       
   798 
       
   799 	# #######################################################
       
   800 	# CScript - a test script based on a custom rule
       
   801 
       
   802 	def __init__(self, aScriptName):
       
   803 		self.iScriptName = aScriptName
       
   804 		self.iCompare = DefaultCompare
       
   805 		self.iReString = ""
       
   806 		self.iTitle = ""
       
   807 		self.iIdeTitle = ""
       
   808 		self.iFileExts = []
       
   809 		self.iIgnore = KIgnoreNothing
       
   810 		self.iDescription = ""
       
   811 
       
   812 
       
   813 class CCategorisedScripts:
       
   814 
       
   815 	# #######################################################
       
   816 	# CCategorisedScripts - a collection of scripts sorted
       
   817 	# by script category (panic, can panic, etc.)
       
   818 
       
   819 	def AddScript(self, aScript):
       
   820 		# do we have a category for this already?
       
   821 		category = aScript.iCategory
       
   822 		if (not self.iScripts.has_key(category)):
       
   823 			# no, create a linear array here
       
   824 			self.iScripts[category] = []
       
   825 
       
   826 		# append to the correct category
       
   827 		self.iScripts[category].append(aScript)
       
   828 
       
   829 		# compile the reg-ex otherwise will get continuous hits
       
   830 		aScript.iReMatch = re.compile(aScript.iReString, re.VERBOSE)
       
   831 
       
   832 	def AllScripts(self):
       
   833 		result = []
       
   834 		for scripts in self.iScripts.values():
       
   835 			result += scripts
       
   836 
       
   837 		return result
       
   838 
       
   839 	def PrintListOfTestScripts(self):
       
   840 		for category in self.iScripts.keys():
       
   841 			print(category + "\n----------------------------------")
       
   842 			for script in self.iScripts[category]:
       
   843 				print("\t" + script.iScriptName)
       
   844 
       
   845 		print("")
       
   846 
       
   847 	# iScripts is a 2D array, 1st level is a hash of categories
       
   848 	#                         2nd level is linear array
       
   849 	iScripts = {}        
       
   850 
       
   851 class CLogger:
       
   852 
       
   853 	# #######################################################
       
   854 	# CLogger
       
   855 	# a simple log file interface
       
   856 
       
   857 	def __init__(self, aFilename):
       
   858 		if aFilename != None and len(aFilename) > 0:
       
   859 			self.iFile = file(aFilename, "w")
       
   860 			self.iFile.write(KVersion + " started at " + datetime.datetime.now().ctime() + "\n")
       
   861 		else:
       
   862 			self.iFile = None
       
   863 
       
   864 	def Write(self, aText):
       
   865 		if self.iFile <> None:
       
   866 			self.iFile.write(str(datetime.datetime.now().time())+":"+aText+"\n")
       
   867 			self.iFile.flush()
       
   868 
       
   869 	def Close(self):
       
   870 		if self.iFile <> None:
       
   871 			self.iFile.write(KVersion + " ended at " + datetime.datetime.now().ctime() + "\n")
       
   872 			self.iFile.close()
       
   873 
       
   874 
       
   875 class CRendererBase:
       
   876 
       
   877 	# #######################################################
       
   878 	# CRendererBase - base class for renderers
       
   879 
       
   880 	def RegisterSelf(self, aName, aDescription, aRendererManager):
       
   881 		self.iName = aName
       
   882 		self.iDescription = aDescription
       
   883 		aRendererManager.AddRenderer(self)
       
   884 	def BeginComponent(self, aComponent):
       
   885 		return
       
   886 	def BeginFile(self, aFilename):
       
   887 		return
       
   888 	def ReportError(self, aLineContext, aScript):
       
   889 		return
       
   890 	def EndFile(self):
       
   891 		return
       
   892 	def EndComponent(self, aComponent):
       
   893 		return
       
   894 
       
   895 
       
   896 class CStdOutRenderer(CRendererBase):
       
   897 
       
   898 	# #######################################################
       
   899 	# CStdOutRenderer - renderer for Standard Console Output
       
   900 	# Output goes to standard output; when run in Carbide, 
       
   901 	# this shows up in the output window. Correctly formatted 
       
   902 	# lines can then be selected, automatically selecting 
       
   903 	# the corresponding line of the associated source file. 
       
   904 	# The format is:
       
   905 	#   <filename>(<line>) : <comment>
       
   906 
       
   907 	def __init__(self, aRendererManager):
       
   908 		self.RegisterSelf("stdout", "StdOut renderer", aRendererManager)
       
   909 		print KVersion
       
   910 
       
   911 	def BeginComponent(self, aComponent):
       
   912 		return
       
   913 
       
   914 	def BeginFile(self, aFilename):
       
   915 		self.iErrorCount = 0
       
   916 		scanner.ReportAction("Scanning file " + aFilename)
       
   917 
       
   918 	def ReportError(self, aLineContext, aScript):
       
   919 		self.iErrorCount += 1
       
   920 		if (aScript.iSeverity == KSeverityLow):
       
   921 			msgType = "info"
       
   922 		elif (aScript.iSeverity == KSeverityMedium):
       
   923 			msgType = "warning"
       
   924 		elif (aScript.iSeverity == KSeverityHigh):
       
   925 			msgType = "error"
       
   926 		print(aLineContext.iFileName + "(" + str(aLineContext.iLineNumber) + ") : " + msgType + ": " + aScript.iScriptName + ": " + KSeverityConfigMap[aScript.iSeverity] + ": " + KCategoryConfigMap[aScript.iCategory] + ": " + aScript.iIdeTitle)
       
   927 		if len(scanner.iRendererManager.iAnnotation)>0:
       
   928 			print scanner.iRendererManager.iAnnotation
       
   929 			scanner.iRendererManager.iAnnotation = ""
       
   930 
       
   931 	def EndFile(self):
       
   932 		scanner.ReportAction("Total problems found in file: " + str(self.iErrorCount))
       
   933 
       
   934 	def EndComponent(self, aComponent):
       
   935 		scanner.iEndTime = datetime.datetime.now().ctime()
       
   936 		return
       
   937 
       
   938 
       
   939 class CXmlComponentSummaryFile:
       
   940 	# #########################################################
       
   941 	# CXmlComponentSummaryFile
       
   942 	# Encapsulates the script (problem) summary for XML output.
       
   943 	# For each script, there is a listing for occurrences
       
   944 	# of that script's problem and location of each occurrence.
       
   945 
       
   946 	def CreateSummary(self, aXmlRenderer):
       
   947 		try:
       
   948 			outputPath = os.path.normpath(os.path.join(aXmlRenderer.iOutputDirectory, "problemIndex.xml"))
       
   949 			outputFile = file(outputPath, "w")
       
   950 		except IOError:
       
   951 			scanner.ReportError("IOError : Unable to create output file " + outputPath)
       
   952 		else:
       
   953 			errors = aXmlRenderer.iErrors
       
   954 			level = 0
       
   955 			indent = "   "
       
   956 			outputFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
       
   957 			outputFile.write(level * indent + "<problemIndex>\n")
       
   958 			level += 1
       
   959 			for category in KCategoryHtmlDisplayOrder:
       
   960 				found = False
       
   961 				if scanner.iCategoriedScripts.iScripts.has_key(category):
       
   962 					for script in scanner.iCategoriedScripts.iScripts[category]:
       
   963 						if errors.has_key(script.iScriptName):
       
   964 							found = True
       
   965 							break
       
   966 					if found:
       
   967 						outputFile.write(level * indent + "<category")
       
   968 						outputFile.write(" name=\"" + KCategoryConfigMap[category] + "\">\n")
       
   969 						level += 1
       
   970 						for script in scanner.iCategoriedScripts.iScripts[category]:
       
   971 							if errors.has_key(script.iScriptName):
       
   972 								outputFile.write(level * indent + "<problem")
       
   973 								outputFile.write(" name=\"" + script.iScriptName + "\"")
       
   974 								outputFile.write(" severity=\"" + KSeverityConfigMap[script.iSeverity] + "\">\n")
       
   975 								level += 1
       
   976 								for fileName, lines in errors[script.iScriptName].items():
       
   977 									outputFile.write(level * indent + "<file")
       
   978 									outputFile.write(" path=\"" + fileName + "\">\n")
       
   979 									level += 1
       
   980 									for lineNo in lines:
       
   981 										outputFile.write(level * indent + str(lineNo) + "\n")
       
   982 									level -= 1
       
   983 									outputFile.write(level * indent + "</file>\n")
       
   984 								level -= 1
       
   985 								outputFile.write(level * indent + "</problem>\n")
       
   986 						level -= 1
       
   987 						outputFile.write(level * indent + "</category>\n")
       
   988 			level -= 1
       
   989 			outputFile.write(level * indent + "</problemIndex>\n")
       
   990 			outputFile.close()
       
   991 
       
   992 
       
   993 class CXmlRenderer(CRendererBase):
       
   994 
       
   995 	# ########################################
       
   996 	# CXmlRenderer - a renderer for XML output
       
   997 
       
   998 	def __init__(self, aRendererManager, aOutputDirectory):
       
   999 		self.RegisterSelf("xml", "XML renderer", aRendererManager)
       
  1000 		self.iOutputDirectory = aOutputDirectory
       
  1001 		if os.path.isdir(self.iOutputDirectory) != True :
       
  1002 			os.makedirs(self.iOutputDirectory)
       
  1003 		self.iErrors = {} 
       
  1004 		print
       
  1005 		print KVersion
       
  1006 		print KCopyrightLine1
       
  1007 		print KCopyrightLine2
       
  1008 
       
  1009 	def BeginComponent(self, aComponent):
       
  1010 		return
       
  1011 
       
  1012 	def BeginFile(self, aFilename):
       
  1013 		self.iFilename = aFilename
       
  1014 		scanner.ReportAction("Scanning file " + aFilename)
       
  1015 
       
  1016 	def ReportError(self, aLineContext, aScript):
       
  1017 		scriptName = aScript.iScriptName
       
  1018 		fileName = aLineContext.iFileName
       
  1019 		lineNumber = aLineContext.iLineNumber
       
  1020 		if (not self.iErrors.has_key(scriptName)):
       
  1021 			self.iErrors[scriptName] = {}
       
  1022 		if (not self.iErrors[scriptName].has_key(fileName)):
       
  1023 			self.iErrors[scriptName][fileName] = []
       
  1024 		self.iErrors[scriptName][fileName].append(lineNumber)
       
  1025 
       
  1026 	def EndFile(self):
       
  1027 		#tbd
       
  1028 		return
       
  1029 
       
  1030 	def EndComponent(self, aComponent):
       
  1031 		relativeComponentName = scanner.iComponentManager.RelativeComponentName(aComponent.iFullPath)
       
  1032 		if len(relativeComponentName) < 1:	# root component - final component
       
  1033 			scanner.iEndTime = datetime.datetime.now().ctime()
       
  1034 			componentSummaryFile = CXmlComponentSummaryFile()
       
  1035 			componentSummaryFile.CreateSummary(self)
       
  1036 
       
  1037 
       
  1038 class CHtmlOutputFileBase:
       
  1039 
       
  1040 	# #######################################################
       
  1041 	# CHtmlOutputFileBase - base class for HTML output files
       
  1042 
       
  1043 	def WriteHeader(self, aOutputFile):
       
  1044 		aOutputFile.write("<html><body>")
       
  1045 
       
  1046 	def Write(self, aOutputFile, aText):
       
  1047 		aOutputFile.write(aText)
       
  1048 
       
  1049 	def WriteLink(self, aOutputFile, aHref, aText):
       
  1050 		aHref = self.CleanupLink(aHref)
       
  1051 		aOutputFile.write("<a href=\"" + aHref + "\">" + aText + "</a>")
       
  1052 
       
  1053 	def WriteElement(self, aOutputFile, aElementName, aElementValue):
       
  1054 		aOutputFile.write("<"+aElementName+">"+aElementValue+"</"+aElementName+">")
       
  1055 
       
  1056 	def WriteBreak(self, aOutputFile):
       
  1057 		aOutputFile.write("<br>")
       
  1058 
       
  1059 	def WriteFooter(self, aOutputFile):
       
  1060 		aOutputFile.write("<br><hr><center><h5>"+KCopyrightLine1Html+"</h5>")
       
  1061 		aOutputFile.write("<h5>")
       
  1062 		CHtmlOutputFileBase.WriteLink(self, aOutputFile, "http://"+KWww, KWww)
       
  1063 		aOutputFile.write("</h5></center></body></html>")
       
  1064 
       
  1065 	def CleanupLink(self, aHref):
       
  1066 		# Mozilla Firefox does not handle link with the '#' character correctly, 
       
  1067 		# so we need to replace it with the equivalent URL encoding "%23"
       
  1068 		aHref = aHref.replace("#", "%23")
       
  1069 		# Mozilla Firefox sometimes does not handle link with '\' correctly,
       
  1070 		# so we need to replace it with '/'
       
  1071 		aHref = aHref.replace('\\', '/')
       
  1072 		return aHref
       
  1073 
       
  1074 
       
  1075 class CHtmlOutputFile(CHtmlOutputFileBase):
       
  1076 
       
  1077 	# #######################################################
       
  1078 	# CHtmlOutputFile - simplified access to HTML output file
       
  1079 
       
  1080 	def __init__(self, aOutputPath):
       
  1081 		if not os.path.isdir(os.path.dirname(aOutputPath)):
       
  1082 			os.makedirs(os.path.dirname(aOutputPath))
       
  1083 		self.iOutputFile = file(aOutputPath, "w")
       
  1084 		self.WriteHeader(self.iOutputFile)
       
  1085 
       
  1086 	def Write(self, aText):
       
  1087 		CHtmlOutputFileBase.Write(self, self.iOutputFile, aText)
       
  1088 
       
  1089 	def WriteLink(self, aHref, aText):
       
  1090 		CHtmlOutputFileBase.WriteLink(self, self.iOutputFile, aHref, aText)
       
  1091 
       
  1092 	def WriteElement(self, aElementName, aElementValue):
       
  1093 		CHtmlOutputFileBase.WriteElement(self, self.iOutputFile, aElementName, aElementValue)
       
  1094 
       
  1095 	def WriteBreak(self):
       
  1096 		CHtmlOutputFileBase.WriteBreak(self, self.iOutputFile)
       
  1097 		
       
  1098 	def Close(self):
       
  1099 		self.WriteFooter(self.iOutputFile)
       
  1100 		self.iOutputFile.close()
       
  1101 
       
  1102 
       
  1103 class CHtmlComponentSummaryFiles:
       
  1104 
       
  1105 	# #######################################################
       
  1106 	# CHtmlComponentSummaryFiles
       
  1107 	# Encapsulates the component summary files for HTML output.
       
  1108 	# For each component, there is a component report file listing the number 
       
  1109 	# of occurrences of each problem type. There is also a single index or 
       
  1110 	# summary file with links to each of the component report files.
       
  1111 
       
  1112 	def CreateSummaries(self, aHtmlRenderer, aOutputDirectory):
       
  1113 		totalErrorCount = 0
       
  1114 		outputPath = os.path.normpath(os.path.join(aOutputDirectory, "componentIndex.html"))
       
  1115 		componentSummaryFile = CHtmlOutputFile(outputPath)
       
  1116 		componentSummaryFile.Write("<font face=verdana>")
       
  1117 		componentSummaryFile.WriteElement("h2", "Component Summary")
       
  1118 		componentSummaryFile.Write("Source: "+scanner.iSource)
       
  1119 		componentSummaryFile.WriteBreak()
       
  1120 		componentSummaryFile.Write("Scan started at:   " + scanner.iStartTime)
       
  1121 		componentSummaryFile.WriteBreak()
       
  1122 		componentSummaryFile.Write("Scan completed at: " + scanner.iEndTime)
       
  1123 		componentSummaryFile.WriteBreak()
       
  1124 		componentSummaryFile.WriteBreak()
       
  1125 		componentSummaryFile.WriteLink("problemIndex.html", "View problems by type")
       
  1126 		componentSummaryFile.WriteBreak()
       
  1127 		componentSummaryFile.Write("<hr>")
       
  1128 		componentSummaryFile.WriteBreak()
       
  1129 		componentSummaryFile.Write("<table border=\"1\" width=\"100%\">")
       
  1130 		componentSummaryFile.Write("<tr bgcolor=\"#0099ff\">")
       
  1131 		componentSummaryFile.WriteElement("th width=\"75%\"", "Component")
       
  1132 		componentSummaryFile.WriteElement("th", "Items Found")
       
  1133 		componentSummaryFile.WriteElement("th", "Lines of Code")
       
  1134 		componentSummaryFile.WriteElement("th", "Possible Defects/KLOC")
       
  1135 		componentSummaryFile.Write("</tr>")
       
  1136 		for component in scanner.iComponentManager.iCompletedComponents:
       
  1137 			componentName = scanner.iComponentManager.ComponentName(component.iFullPath)
       
  1138 			outputPath = os.path.normpath(os.path.join(aOutputDirectory, "byComponent"))
       
  1139 			outputPath = os.path.normpath(os.path.join(outputPath, componentName))
       
  1140 			outputPath = os.path.normpath(os.path.join(outputPath, "componentSummary.html"))
       
  1141 			errorCount = self.WriteComponentReport(aHtmlRenderer, outputPath, component.iFullPath, componentName)
       
  1142 			if (errorCount > 0):
       
  1143 				totalErrorCount = totalErrorCount + errorCount
       
  1144 				numberOfLinesScanned = component.iNumberOfLinesScanned
       
  1145 				if (numberOfLinesScanned > 0):
       
  1146 					defectsPerKLOC = int((1000.0 / numberOfLinesScanned) * errorCount)
       
  1147 				else:
       
  1148 					defectsPerKLOC = 0
       
  1149 				componentSummaryFile.Write("<tr>")
       
  1150 				componentSummaryFile.Write("<td>")
       
  1151 				relOutputPath = os.path.normpath(os.path.join("byComponent", componentName))
       
  1152 				relOutputPath = os.path.normpath(os.path.join(relOutputPath, "componentSummary.html"))
       
  1153 				componentSummaryFile.WriteLink(relOutputPath, component.iFullPath)
       
  1154 				componentSummaryFile.Write("</td>")
       
  1155 				componentSummaryFile.Write("<td>")
       
  1156 				componentSummaryFile.WriteElement("center",str(errorCount))
       
  1157 				componentSummaryFile.Write("</td>")
       
  1158 				componentSummaryFile.Write("<td>")
       
  1159 				componentSummaryFile.WriteElement("center",str(numberOfLinesScanned))
       
  1160 				componentSummaryFile.Write("</td>")
       
  1161 				componentSummaryFile.Write("<td>")
       
  1162 				componentSummaryFile.WriteElement("center",str(defectsPerKLOC))
       
  1163 				componentSummaryFile.Write("</td>")
       
  1164 				componentSummaryFile.Write("</tr>")
       
  1165 
       
  1166 		componentSummaryFile.Write("<tr>")
       
  1167 		componentSummaryFile.Write("<td>")
       
  1168 		componentSummaryFile.WriteElement("b", "Total")
       
  1169 		componentSummaryFile.Write("</td>")
       
  1170 		componentSummaryFile.Write("<td><center>")
       
  1171 		componentSummaryFile.WriteElement("b", str(totalErrorCount))
       
  1172 		componentSummaryFile.Write("</center></td>")
       
  1173 		componentSummaryFile.Write("</tr>")
       
  1174 
       
  1175 		componentSummaryFile.Write("</table>")
       
  1176 		componentSummaryFile.Close()
       
  1177 
       
  1178 	def WriteComponentReport(self, aHtmlRenderer, aOutputPath, aComponentFullPath, aComponentName):
       
  1179 		totalErrorCount = 0
       
  1180 		componentReportFile = CHtmlOutputFile(aOutputPath)
       
  1181 		componentReportFile.Write("<font face=verdana>")
       
  1182 		componentReportFile.WriteElement("h2", "Component Report")
       
  1183 		componentReportFile.WriteElement("h3", "Component: "+aComponentFullPath)
       
  1184 		componentReportFile.Write("<font face=verdana color=black>")
       
  1185 		found = False
       
  1186 		for category in KCategoryHtmlDisplayOrder:
       
  1187 			if scanner.iCategoriedScripts.iScripts.has_key(category):
       
  1188 				for script in scanner.iCategoriedScripts.iScripts[category]:
       
  1189 					errorCount = scanner.iComponentManager.ScriptComponentErrorCount(aComponentFullPath, script.iScriptName)
       
  1190 					if errorCount > 0:
       
  1191 						found = True
       
  1192 						break
       
  1193 
       
  1194 		if found:
       
  1195 			componentReportFile.Write("<table border=\"1\" width=\"100%\">")
       
  1196 			componentReportFile.Write("<tr bgcolor=\"#0099ff\">")
       
  1197 			componentReportFile.WriteElement("th width=\"75%\"", "Problem")
       
  1198 			componentReportFile.WriteElement("th", "Items Found")
       
  1199 			componentReportFile.WriteElement("th", "Severity")
       
  1200 			componentReportFile.Write("</tr>")
       
  1201 			for category in KCategoryHtmlDisplayOrder:
       
  1202 				if scanner.iCategoriedScripts.iScripts.has_key(category):
       
  1203 					for script in scanner.iCategoriedScripts.iScripts[category]:
       
  1204 						errorCount = scanner.iComponentManager.ScriptComponentErrorCount(aComponentFullPath, script.iScriptName)
       
  1205 						if errorCount > 0:
       
  1206 							componentReportFile.Write("<tr>")
       
  1207 							componentReportFile.Write("<td>")
       
  1208 							#scriptComponentPath = aHtmlRenderer.ScriptComponentPath(aComponentFullPath, script.iScriptName)
       
  1209 							#componentReportFile.WriteLink(scriptComponentPath, script.iTitle)
       
  1210 							componentReportFile.WriteLink(script.iScriptName+".html", script.iTitle)
       
  1211 							componentReportFile.Write("</td>")
       
  1212 							componentReportFile.Write("<td>")
       
  1213 							componentReportFile.WriteElement("center", str(errorCount))
       
  1214 							componentReportFile.Write("</td>")
       
  1215 							componentReportFile.Write("<td>")
       
  1216 							componentReportFile.WriteElement("center", KSeverityHTMLMap[script.iSeverity])
       
  1217 							componentReportFile.Write("</td>")
       
  1218 							componentReportFile.Write("</tr>")
       
  1219 							totalErrorCount = totalErrorCount + errorCount
       
  1220 			componentReportFile.Write("<tr>")
       
  1221 			componentReportFile.Write("<td>")
       
  1222 			componentReportFile.WriteElement("b", "Total")
       
  1223 			componentReportFile.Write("</td>")
       
  1224 			componentReportFile.Write("<td><center>")
       
  1225 			componentReportFile.WriteElement("b", str(totalErrorCount))
       
  1226 			componentReportFile.Write("</center></td>")
       
  1227 			componentReportFile.Write("</tr>")
       
  1228 			componentReportFile.Write("</table>")
       
  1229 		else:
       
  1230 			componentReportFile.WriteBreak()
       
  1231 			componentReportFile.WriteElement("i", "There are no items to report for this component.")
       
  1232 			componentReportFile.WriteBreak()
       
  1233 		componentReportFile.Close()
       
  1234 		return totalErrorCount
       
  1235 
       
  1236 
       
  1237 class CHtmlScriptSummaryFiles:
       
  1238 
       
  1239 	# #######################################################
       
  1240 	# CHtmlScriptSummaryFiles
       
  1241 	# Encapsulates the script (problem) summary files for HTML output.
       
  1242 	# For each script, there is a file listing the number of occurrences
       
  1243 	# of that script's problem for each component. There is also a single
       
  1244 	# index or summary file with links to each of the problem report file.
       
  1245 
       
  1246 	def CreateSummaries(self, aHtmlRenderer, aOutputDirectory):
       
  1247 
       
  1248 		totalErrorCount = 0
       
  1249 
       
  1250 		outputPath = os.path.normpath(os.path.join(aOutputDirectory, "problemIndex.html"))
       
  1251 		scriptSummaryFile = CHtmlOutputFile(outputPath)
       
  1252 		scriptSummaryFile.Write("<font face=verdana>")
       
  1253 		scriptSummaryFile.WriteElement("h2", "Problem Summary")
       
  1254 		scriptSummaryFile.Write("Source: "+scanner.iSource)
       
  1255 		scriptSummaryFile.WriteBreak()
       
  1256 		scriptSummaryFile.Write("Scan started at:   " + scanner.iStartTime)
       
  1257 		scriptSummaryFile.WriteBreak()
       
  1258 		scriptSummaryFile.Write("Scan completed at: " + scanner.iEndTime)
       
  1259 		scriptSummaryFile.WriteBreak()
       
  1260 		scriptSummaryFile.WriteBreak()
       
  1261 		scriptSummaryFile.WriteLink("componentIndex.html", "View problems by component")
       
  1262 		scriptSummaryFile.WriteBreak()
       
  1263 		scriptSummaryFile.Write("<hr>")
       
  1264 		scriptSummaryFile.WriteBreak()
       
  1265 		for category in KCategoryHtmlDisplayOrder:
       
  1266 			if scanner.iCategoriedScripts.iScripts.has_key(category):
       
  1267 				scriptSummaryFile.WriteElement("h3", "Category: "+category)
       
  1268 				scriptSummaryFile.Write("<table border=\"1\" width=\"100%\">")
       
  1269 				scriptSummaryFile.Write("<tr bgcolor=\"#0099ff\">")
       
  1270 				scriptSummaryFile.WriteElement("th width=\"75%\"", "Problem")
       
  1271 				scriptSummaryFile.WriteElement("th", "Items Found")
       
  1272 				scriptSummaryFile.WriteElement("th", "Severity")
       
  1273 				scriptSummaryFile.Write("</tr>")
       
  1274 				categoryErrorCount = 0
       
  1275 				for script in scanner.iCategoriedScripts.iScripts[category]:
       
  1276 					outputPath = os.path.normpath(os.path.join(aOutputDirectory, "byProblem"))
       
  1277 					outputPath = os.path.normpath(os.path.join(outputPath, script.iScriptName+"Summary.html"))
       
  1278 					errorCount = self.WriteScriptReport(aHtmlRenderer, outputPath, script)
       
  1279 					categoryErrorCount = categoryErrorCount + errorCount
       
  1280 					scriptSummaryFile.Write("<tr>")
       
  1281 					scriptSummaryFile.Write("<td>")
       
  1282 					relOutputPath = os.path.normpath(os.path.join("byProblem", script.iScriptName+"Summary.html"))
       
  1283 					scriptSummaryFile.WriteLink(relOutputPath, script.iTitle)
       
  1284 					scriptSummaryFile.Write("</td>")
       
  1285 					scriptSummaryFile.Write("<td>")
       
  1286 					scriptSummaryFile.WriteElement("center", str(errorCount))
       
  1287 					scriptSummaryFile.Write("</td>")
       
  1288 					scriptSummaryFile.Write("<td>")
       
  1289 					scriptSummaryFile.WriteElement("center", KSeverityHTMLMap[script.iSeverity])
       
  1290 					scriptSummaryFile.Write("</td>")
       
  1291 					scriptSummaryFile.Write("</tr>")
       
  1292 				totalErrorCount = totalErrorCount + categoryErrorCount
       
  1293 				scriptSummaryFile.Write("<tr>")
       
  1294 				scriptSummaryFile.Write("<td>")
       
  1295 				scriptSummaryFile.WriteElement("b", "Category Total")
       
  1296 				scriptSummaryFile.Write("</td>")
       
  1297 				scriptSummaryFile.Write("<td>")
       
  1298 				scriptSummaryFile.WriteElement("center", "<b>"+str(categoryErrorCount)+"</b>")
       
  1299 				scriptSummaryFile.Write("</td>")
       
  1300 				scriptSummaryFile.Write("</tr>")
       
  1301 				scriptSummaryFile.Write("</table>")
       
  1302 
       
  1303 		scriptSummaryFile.WriteBreak()
       
  1304 		scriptSummaryFile.WriteElement("b", "Total: " + str(totalErrorCount))
       
  1305 		scriptSummaryFile.WriteBreak()
       
  1306 
       
  1307 		scriptSummaryFile.Close()
       
  1308 
       
  1309 	def WriteScriptReport(self, aHtmlRenderer, aOutputPath, aScript):
       
  1310 		totalErrorCount = 0
       
  1311 		scriptReportFile = CHtmlOutputFile(aOutputPath)
       
  1312 		scriptReportFile.Write("<font face=verdana>")
       
  1313 		scriptReportFile.WriteElement("h2", "Problem Report")
       
  1314 		scriptReportFile.WriteElement("h3", "Problem: " + aScript.iTitle)
       
  1315 		scriptReportFile.Write(aScript.iDescription)
       
  1316 		scriptReportFile.WriteBreak()
       
  1317 		scriptReportFile.WriteBreak()
       
  1318 
       
  1319 		found = False
       
  1320 		for component in scanner.iComponentManager.iCompletedComponents:
       
  1321 			errorCount = scanner.iComponentManager.ScriptComponentErrorCount(component.iFullPath, aScript.iScriptName)
       
  1322 			if errorCount > 0:
       
  1323 				found = True
       
  1324 				break
       
  1325 
       
  1326 		if found:
       
  1327 			scriptReportFile.Write("<table border=\"1\" width=\"100%\">")
       
  1328 			scriptReportFile.Write("<tr bgcolor=\"#0099ff\">")
       
  1329 			scriptReportFile.WriteElement("th width=\"80%\"", "Component")
       
  1330 			scriptReportFile.WriteElement("th", "Items Found")
       
  1331 			scriptReportFile.Write("</tr>")
       
  1332 			for component in scanner.iComponentManager.iCompletedComponents:
       
  1333 				errorCount = scanner.iComponentManager.ScriptComponentErrorCount(component.iFullPath, aScript.iScriptName)
       
  1334 				if errorCount > 0:
       
  1335 					scriptReportFile.Write("<tr>")
       
  1336 					scriptReportFile.Write("<td>")
       
  1337 					scriptComponentPath = aHtmlRenderer.ScriptComponentPath(component.iFullPath, aScript.iScriptName, "..")
       
  1338 					scriptReportFile.WriteLink(scriptComponentPath, component.iFullPath)
       
  1339 					scriptReportFile.Write("</td>")
       
  1340 					scriptReportFile.Write("<td>")
       
  1341 					scriptReportFile.WriteElement("center", str(errorCount))
       
  1342 					scriptReportFile.Write("</td>")
       
  1343 					scriptReportFile.Write("</tr>")
       
  1344 					totalErrorCount = totalErrorCount + errorCount
       
  1345 			scriptReportFile.Write("<tr>")
       
  1346 			scriptReportFile.Write("<td>")
       
  1347 			scriptReportFile.WriteElement("b", "Total")
       
  1348 			scriptReportFile.Write("</td>")
       
  1349 			scriptReportFile.Write("<td><center>")
       
  1350 			scriptReportFile.WriteElement("b", str(totalErrorCount))
       
  1351 			scriptReportFile.Write("</center></td>")
       
  1352 			scriptReportFile.Write("</tr>")
       
  1353 			scriptReportFile.Write("</table>")
       
  1354 		else:
       
  1355 			scriptReportFile.WriteBreak()
       
  1356 			scriptReportFile.WriteElement("i", "There are no items of this problem type to report.")
       
  1357 			scriptReportFile.WriteBreak()
       
  1358 
       
  1359 		scriptReportFile.Close()
       
  1360 		return totalErrorCount
       
  1361 
       
  1362 
       
  1363 class CHtmlScriptComponentFile:
       
  1364 
       
  1365 	# #######################################################
       
  1366 	# CHtmlScriptComponentFile
       
  1367 	# Encapsulates access to the HTML output files with the greatest amount of detail.
       
  1368 	# Each of these files is for a specific problem (script) and for a specific component.
       
  1369 
       
  1370 	# The file handle is closed between each call to avoid exhausting the system
       
  1371 	# limit for open file handles. Many of these files may be open at one time,
       
  1372 	# and the number of open files is dependent on both the directory structure
       
  1373 	# being traversed and the number of types of problems found.
       
  1374 
       
  1375 	def __init__(self, aLxrUrl, aLxrVersion):
       
  1376 		self.iLxrUrl = aLxrUrl
       
  1377 		self.iLxrVersion = aLxrVersion
       
  1378 		
       
  1379 	def BeginOutputFile(self, aOutputPath, aScript, aComponentName):
       
  1380 		if not os.path.isdir(os.path.dirname(aOutputPath)):
       
  1381 			os.makedirs(os.path.dirname(aOutputPath))
       
  1382 		outputFile = file(aOutputPath, "w")
       
  1383 		self.iScriptComponentFile = CHtmlOutputFileBase()
       
  1384 		self.iScriptComponentFile.Write(outputFile, "<font face=verdana>")
       
  1385 		self.iScriptComponentFile.WriteHeader(outputFile)
       
  1386 		self.iScriptComponentFile.WriteElement(outputFile, "h2", "Detailed Problem Report")
       
  1387 		self.iScriptComponentFile.WriteElement(outputFile, "h3", "Component: "+aComponentName)
       
  1388 		self.iScriptComponentFile.WriteElement(outputFile, "h3", "Problem: "+aScript.iTitle)
       
  1389 		self.iScriptComponentFile.Write(outputFile, aScript.iDescription)
       
  1390 		self.iScriptComponentFile.WriteBreak(outputFile)
       
  1391 		self.iScriptComponentFile.Write(outputFile, "<hr>")
       
  1392 		self.iScriptComponentFile.WriteBreak(outputFile)
       
  1393 		outputFile.close()
       
  1394 
       
  1395 	def ReportError(self, aOutputPath, aLineContext):
       
  1396 		outputFile = file(aOutputPath, "a")
       
  1397 		if self.iLxrUrl == None:
       
  1398 			# Mozilla Firefox cannot open links to local files, 
       
  1399 			# so it is necessary to convert local file path
       
  1400 			filePath = "file:///" + aLineContext.iFileName
       
  1401 		else:
       
  1402 			# generate link to LXR server instead of local file system
       
  1403 			filePath = self.iLxrUrl + aLineContext.iFileName[len(scanner.iComponentManager.iRootPath):]
       
  1404 			if self.iLxrVersion <> None:
       
  1405 				filePath = filePath + "?v="+self.iLxrVersion
       
  1406 			filePath = filePath + '#%03d'%aLineContext.iLineNumber
       
  1407 		self.iScriptComponentFile.WriteLink(outputFile, filePath, self.TrimFileName(aLineContext))
       
  1408 		self.iScriptComponentFile.Write(outputFile, "(" + str(aLineContext.iLineNumber) + ") ")
       
  1409 		self.iScriptComponentFile.Write(outputFile, aLineContext.iClassName+"::"+aLineContext.iMethodName+" ")
       
  1410 		self.iScriptComponentFile.Write(outputFile, "<code><font color=red>"+self.CleanUpText(aLineContext.iLineText))
       
  1411 		self.iScriptComponentFile.Write(outputFile, "</font></code>")
       
  1412 		self.iScriptComponentFile.WriteBreak(outputFile)
       
  1413 		if len(scanner.iRendererManager.iAnnotation)>0:
       
  1414 			self.iScriptComponentFile.Write(outputFile, scanner.iRendererManager.iAnnotation)
       
  1415 			self.iScriptComponentFile.WriteBreak(outputFile)
       
  1416 			scanner.iRendererManager.iAnnotation = ""
       
  1417 		outputFile.close()
       
  1418 
       
  1419 	def EndOutputFile(self, aOutputPath):
       
  1420 		outputFile = file(aOutputPath, "a")
       
  1421 		self.iScriptComponentFile.WriteFooter(outputFile)
       
  1422 		outputFile.close()
       
  1423 
       
  1424 	def TrimFileName(self, aLineContext):
       
  1425 		filename = aLineContext.iFileName
       
  1426 		componentNameLen = len(aLineContext.iComponentName)
       
  1427 		if len(filename) > componentNameLen:
       
  1428 			if filename[0:componentNameLen] == aLineContext.iComponentName:
       
  1429 				filename = filename[componentNameLen:]
       
  1430 				if filename[0] == os.path.sep:
       
  1431 					filename = filename[1:]
       
  1432 		return filename
       
  1433 
       
  1434 	def CleanUpText(self, aLineText):
       
  1435 		# check for sub-strings that look like HTML tags and preform clean up if needed
       
  1436 		reTag = re.compile(r"""(<.+>)""", re.VERBOSE)
       
  1437 		foundTag = reTag.search(aLineText)
       
  1438 		if foundTag:
       
  1439 			aNewLineText = aLineText.replace("<", "&lt;")
       
  1440 			aNewLineText = aNewLineText.replace(">", "&gt;")
       
  1441 			return aNewLineText
       
  1442 		else:
       
  1443 			return aLineText		
       
  1444 
       
  1445 			
       
  1446 def ComponentCompare(a, b):
       
  1447 	return cmp(os.path.normcase(a.iFullPath), os.path.normcase(b.iFullPath))
       
  1448 
       
  1449 
       
  1450 class CHtmlRenderer(CRendererBase):
       
  1451 
       
  1452 	# #######################################################
       
  1453 	# CHtmlRenderer - a renderer for HTML output
       
  1454 
       
  1455 	# I have nothing to offer but blood, toil, tears and sweat. 
       
  1456 	#  - Winston Churchill, 1940 
       
  1457 
       
  1458 	def __init__(self, aRendererManager, aOutputDirectory, aLxrUrl, aLxrVersion):
       
  1459 		self.RegisterSelf("html", "HTML renderer", aRendererManager)
       
  1460 		self.iOutputDirectory = aOutputDirectory
       
  1461 		if os.path.isdir(self.iOutputDirectory) != True :
       
  1462 			os.makedirs(self.iOutputDirectory)
       
  1463 		self.iScriptComponentFile = CHtmlScriptComponentFile(aLxrUrl, aLxrVersion)
       
  1464 		self.iScriptComponentFilePaths = {}
       
  1465 		print
       
  1466 		print KVersion
       
  1467 		print KCopyrightLine1
       
  1468 		print KCopyrightLine2
       
  1469 
       
  1470 	def BeginFile(self, aFilename):
       
  1471 		self.iFilename = aFilename
       
  1472 		scanner.ReportAction("Scanning file " + aFilename)
       
  1473 
       
  1474 	def ReportError(self, aLineContext, aScript):
       
  1475 		outputPath = self.ScriptComponentPath(aLineContext.iComponentName, aScript.iScriptName)
       
  1476 		if not os.path.isfile(outputPath):
       
  1477 			self.iScriptComponentFilePaths[aLineContext.iComponentName].append(outputPath)
       
  1478 			self.iScriptComponentFile.BeginOutputFile(outputPath, aScript, aLineContext.iComponentName)
       
  1479 		self.iScriptComponentFile.ReportError(outputPath, aLineContext)
       
  1480 
       
  1481 	def EndFile(self):
       
  1482 		return
       
  1483 
       
  1484 	def BeginComponent(self, aComponent):
       
  1485 		self.iScriptComponentFilePaths[aComponent.iFullPath] = []
       
  1486 
       
  1487 	def EndComponent(self, aComponent):
       
  1488 		if self.iScriptComponentFilePaths.has_key(aComponent.iFullPath):
       
  1489 			for outputPath in self.iScriptComponentFilePaths[aComponent.iFullPath]:
       
  1490 				self.iScriptComponentFile.EndOutputFile(outputPath)
       
  1491 			del self.iScriptComponentFilePaths[aComponent.iFullPath]
       
  1492 		relativeComponentName = scanner.iComponentManager.RelativeComponentName(aComponent.iFullPath)
       
  1493 		if len(relativeComponentName) < 1:	# root component - final component
       
  1494 			scanner.iEndTime = datetime.datetime.now().ctime()
       
  1495 			scanner.iComponentManager.iCompletedComponents.sort(ComponentCompare)
       
  1496 			scriptSummaryFiles = CHtmlScriptSummaryFiles()
       
  1497 			scriptSummaryFiles.CreateSummaries(self, self.iOutputDirectory)
       
  1498 			componentSummaryFiles = CHtmlComponentSummaryFiles()
       
  1499 			componentSummaryFiles.CreateSummaries(self, self.iOutputDirectory)
       
  1500 
       
  1501 	def ScriptComponentPath(self, aComponentName, aScriptName, aRel=None):
       
  1502 		componentName = scanner.iComponentManager.ComponentName(aComponentName)
       
  1503 		if aRel==None:
       
  1504 			aRel = self.iOutputDirectory
       
  1505 		outputPath = os.path.normpath(os.path.join(aRel, "byComponent"))
       
  1506 		outputPath = os.path.normpath(os.path.join(outputPath, componentName))
       
  1507 		outputPath = os.path.normpath(os.path.join(outputPath, aScriptName+".html"))
       
  1508 		return outputPath
       
  1509 
       
  1510 
       
  1511 class CRendererManager:
       
  1512 
       
  1513 	# #######################################################
       
  1514 	# CRendererManager
       
  1515 	# this class handles all the renderers 
       
  1516 
       
  1517 	def __init__(self):
       
  1518 		# declare associative list of renderers: iRendererList[name]=renderer
       
  1519 		self.iRendererList = {}
       
  1520 		self.iAnnotation = ""
       
  1521 
       
  1522 	def AddRenderer(self, aRenderer):
       
  1523 		self.iRendererList[aRenderer.iName.lower()] = aRenderer
       
  1524 
       
  1525 	def PrintListOfRenderers(self):
       
  1526 		print("Renderers:")        
       
  1527 		for name, renderer in self.iRendererList.items():
       
  1528 			print("\t" + name + "\t" + renderer.iDescription)
       
  1529 
       
  1530 		print("")
       
  1531 
       
  1532 	def BeginFile(self, aFilename):
       
  1533 		for name, renderer in self.iRendererList.items():
       
  1534 			renderer.BeginFile(aFilename)
       
  1535 
       
  1536 	def ReportError(self, aLineContext, aScript):
       
  1537 		for name, renderer in self.iRendererList.items():
       
  1538 			renderer.ReportError(aLineContext, aScript)
       
  1539 
       
  1540 	def ReportAnnotation(self, aAnnotation):
       
  1541 		self.iAnnotation = aAnnotation
       
  1542 
       
  1543 	def EndFile(self):
       
  1544 		for name, renderer in self.iRendererList.items():
       
  1545 			renderer.EndFile()
       
  1546 
       
  1547 	def BeginComponent(self, aComponent):
       
  1548 		for name, renderer in self.iRendererList.items():
       
  1549 			renderer.BeginComponent(aComponent)
       
  1550 
       
  1551 	def EndComponent(self, aComponent):
       
  1552 		for name, renderer in self.iRendererList.items():
       
  1553 			renderer.EndComponent(aComponent)
       
  1554 
       
  1555 
       
  1556 class CComponent:
       
  1557 
       
  1558 	# #######################################################
       
  1559 	# CComponent - a single component, identified by the
       
  1560 	# directory path to its source code
       
  1561 
       
  1562 	def __init__(self, aPath):
       
  1563 		self.iFullPath = aPath
       
  1564 		self.iScriptErrorCounts = {}
       
  1565 		self.iHasGroupDir = False
       
  1566 		self.iNumberOfLinesScanned = 0
       
  1567 
       
  1568 	def appendComponent(self, aComponent):
       
  1569 		for scriptName in aComponent.iScriptErrorCounts.keys():
       
  1570 			if self.iScriptErrorCounts.has_key(scriptName):
       
  1571 				self.iScriptErrorCounts[scriptName] += aComponent.iScriptErrorCounts[scriptName]
       
  1572 			else:
       
  1573 				self.iScriptErrorCounts[scriptName] = aComponent.iScriptErrorCounts[scriptName]
       
  1574 		self.iNumberOfLinesScanned += aComponent.iNumberOfLinesScanned
       
  1575 		return
       
  1576 
       
  1577 
       
  1578 class CComponentManager:
       
  1579 
       
  1580 	# #######################################################
       
  1581 	# CComponentManager - controls access to components
       
  1582 
       
  1583 	def __init__(self):
       
  1584 		self.iComponentStack = []
       
  1585 		self.iCompletedComponents = []
       
  1586 		self.iRootComponent = CComponent("")
       
  1587 		self.iUseFullComponentPath = False
       
  1588 
       
  1589 	def SetRoot(self, aRootPath):
       
  1590 		# set the list of root directories - used to left-trim component names
       
  1591 		self.iRootPath = self.SanitizePath(aRootPath)
       
  1592 
       
  1593 	def BeginDirectory(self, aPath):
       
  1594 		aPath = self.SanitizePath(aPath)
       
  1595 		if os.path.isdir(aPath):
       
  1596 			newComponent = CComponent(aPath)
       
  1597 			contents = os.listdir(aPath)
       
  1598 			for entry in contents:
       
  1599 				if (entry.upper() == "GROUP"):
       
  1600 					entryPath = os.path.normpath(os.path.join(aPath, entry))
       
  1601 					if os.path.isdir(entryPath):
       
  1602 						newComponent.iHasGroupDir = True
       
  1603 						break
       
  1604 			if len(self.iComponentStack) > 0:
       
  1605 				topComponent = self.iComponentStack[len(self.iComponentStack)-1]
       
  1606 				if (newComponent.iHasGroupDir or (not topComponent.iHasGroupDir)):
       
  1607 					self.BeginComponent(newComponent)
       
  1608 				else:
       
  1609 					scanner.iLog.Write(aPath + " taken as part of " + topComponent.iFullPath)
       
  1610 			else:
       
  1611 				self.BeginComponent(newComponent)
       
  1612 		else:
       
  1613 			scanner.iLog.Write("ERROR: CComponentManager::BeginDirectory: bad path "+aPath)
       
  1614 		return aPath
       
  1615 
       
  1616 	def EndDirectory(self, aPath, numberOfLinesScanned):
       
  1617 		aPath = self.SanitizePath(aPath)
       
  1618 		if len(self.iComponentStack) > 0:
       
  1619 			topComponent = self.iComponentStack[len(self.iComponentStack)-1]
       
  1620 			topComponent.iNumberOfLinesScanned += numberOfLinesScanned
       
  1621 			if (topComponent.iFullPath == aPath):
       
  1622 				self.EndComponent()
       
  1623 
       
  1624 	def ReportError(self, aLineContext, aScript):
       
  1625 		scanner.iRendererManager.ReportError(aLineContext, aScript)
       
  1626 		for component in self.iComponentStack:
       
  1627 			if component.iFullPath == aLineContext.iComponentName:
       
  1628 				if component.iScriptErrorCounts.has_key(aScript.iScriptName):
       
  1629 					component.iScriptErrorCounts[aScript.iScriptName] = component.iScriptErrorCounts[aScript.iScriptName] + 1
       
  1630 				else:
       
  1631 					component.iScriptErrorCounts[aScript.iScriptName] = 1
       
  1632 
       
  1633 	def ScriptComponentErrorCount(self, aComponentName, aScriptName):
       
  1634 		for component in self.iCompletedComponents:
       
  1635 			if component.iFullPath == aComponentName:
       
  1636 				if component.iScriptErrorCounts.has_key(aScriptName):
       
  1637 					return component.iScriptErrorCounts[aScriptName]
       
  1638 				else:
       
  1639 					return 0
       
  1640 		return 0
       
  1641 
       
  1642 	def BeginComponent(self, aComponent):
       
  1643 		scanner.iRendererManager.BeginComponent(aComponent)
       
  1644 		scanner.ReportAction("Begin component: " + aComponent.iFullPath)
       
  1645 		self.iComponentStack.append(aComponent)
       
  1646 
       
  1647 	def EndComponent(self):
       
  1648 		previousComponent = self.iComponentStack.pop()
       
  1649 		matchingComponent = self.MatchingComponent(previousComponent)
       
  1650 		if (matchingComponent <> None):
       
  1651 			matchingComponent.appendComponent(previousComponent)
       
  1652 		else:
       
  1653 			self.iCompletedComponents.append(previousComponent)
       
  1654 		scanner.ReportAction("End component: " + previousComponent.iFullPath)
       
  1655 		scanner.iRendererManager.EndComponent(previousComponent)
       
  1656 
       
  1657 	def MatchingComponent(self, aComponent):
       
  1658 		for component in self.iCompletedComponents:
       
  1659 			if (ComponentCompare(component, aComponent) == 0):
       
  1660 				return component
       
  1661 		return None
       
  1662 
       
  1663 	def CurrentComponentName(self):
       
  1664 		if len(self.iComponentStack) < 1:
       
  1665 			return None
       
  1666 		return self.iComponentStack[len(self.iComponentStack)-1].iFullPath
       
  1667 
       
  1668 	def SanitizePath(self, aPath):
       
  1669 		# Translate an unspecified or relative pathname into an absolute pathname
       
  1670 		if len(aPath) < 1:
       
  1671 			aPath = "."
       
  1672 		aPath = os.path.normpath(aPath)
       
  1673 		# translate "." and ".." into absolute paths
       
  1674 		aPath = os.path.abspath(aPath)
       
  1675 		return aPath
       
  1676 
       
  1677 	def ComponentName(self, aFullComponentName):
       
  1678 		if (self.iUseFullComponentPath):
       
  1679 			(unused, componentName) = os.path.splitdrive(aFullComponentName)
       
  1680 			if len(componentName) > 0:
       
  1681 				if componentName[0] == os.path.sep and len(componentName) > 1:
       
  1682 					componentName = componentName[1:]
       
  1683 			return componentName
       
  1684 		else:
       
  1685 			return self.RelativeComponentName(aFullComponentName)
       
  1686 
       
  1687 	def RelativeComponentName(self, aFullComponentName):
       
  1688 		# Remove the root path from the specified component name
       
  1689 		rootLen = len(self.iRootPath)
       
  1690 		if aFullComponentName[0:rootLen] == self.iRootPath:
       
  1691 			relativeComponentName = aFullComponentName[rootLen:]
       
  1692 		else:
       
  1693 			# this case is unexpected...but we'll try to make the best of it
       
  1694 			(unused, relativeComponentName) = os.path.splitdrive(aFullComponentName)
       
  1695 		# trim leading path separator, if present
       
  1696 		if len(relativeComponentName) > 0:
       
  1697 			if relativeComponentName[0] == os.path.sep and len(relativeComponentName) > 1:
       
  1698 				relativeComponentName = relativeComponentName[1:]
       
  1699 		return relativeComponentName
       
  1700 
       
  1701 
       
  1702 class CLineContext:
       
  1703 
       
  1704 	# #######################################################
       
  1705 	# CLineContext
       
  1706 	# A description of the line of source code currently being scanned
       
  1707 
       
  1708 	iComponentName = ""
       
  1709 	iFileName = ""
       
  1710 	iLineNumber = 0
       
  1711 	iClassName = ""
       
  1712 	iMethodName = ""
       
  1713 	iLineText = ""
       
  1714 
       
  1715 
       
  1716 class CCodeScanner:
       
  1717 
       
  1718 	# #######################################################
       
  1719 	# CCodeScanner - main application class
       
  1720 
       
  1721 	def __init__(self):
       
  1722 		self.iCategoriedScripts = CCategorisedScripts()
       
  1723 		self.iRendererManager   = CRendererManager()
       
  1724 		self.iComponentManager = CComponentManager()
       
  1725 		self.iLineContext = CLineContext()
       
  1726 		self.iDomConfig = None
       
  1727 		self.iVerbose = False
       
  1728 		self.iLog = None
       
  1729 		self.iSource = None
       
  1730 		self.iEncodedFileList = None
       
  1731 		self.iOutputDirectory = None
       
  1732 		self.iStartTimeObj = None
       
  1733 		self.iStartTime = None
       
  1734 		self.iEndTime = None
       
  1735 		self.iLxrUrl = None
       
  1736 		self.iLxrVersion = None
       
  1737 		self.iConfigFilename = ""
       
  1738 		self.iInputFilenames = ""
       
  1739 		self.iLogFilename = ""
       
  1740 		self.iOutputFormat = ""
       
  1741 		self.iTimeStampedOutput = ""
       
  1742 		self.iReMethod = re.compile(r"""
       
  1743 			((?P<class>\w+)::~?)?
       
  1744 			(?P<method>[A-Za-z0-9<>=!*\-+/]+)
       
  1745 			[\s\n]*
       
  1746 			\(
       
  1747 			[^;]*
       
  1748 			$
       
  1749 			""", re.VERBOSE)
       
  1750 
       
  1751 	def ReportError(self, aErrorMsg):
       
  1752 		self.iLog.Write(aErrorMsg)
       
  1753 		print aErrorMsg
       
  1754 
       
  1755 	def ReportAction(self, aAction):
       
  1756 		self.iLog.Write(aAction)
       
  1757 		if self.iVerbose:
       
  1758 			print aAction
       
  1759 
       
  1760 	def ReportInfo(self, aInfoMsg):
       
  1761 		self.iLog.Write(aInfoMsg)
       
  1762 		print aInfoMsg
       
  1763 
       
  1764 	def CleanOutputDirectory(self):
       
  1765 		self.iLog.Write("Deleting existing contents of output directory " + self.iOutputDirectory)
       
  1766 		for root, dirs, files in os.walk(self.iOutputDirectory, topdown = False):
       
  1767 			for name in files:
       
  1768 				os.remove(os.path.join(root, name))
       
  1769 			for name in dirs:
       
  1770 				os.rmdir(os.path.join(root, name))
       
  1771 
       
  1772 	def CheckSourceIncluded(self, aSourceFileName):
       
  1773 		if (self.iDomConfig <> None):
       
  1774 			for sourceNode in self.iDomConfig.getElementsByTagName("sources"):
       
  1775 				for excludeSourceNode in sourceNode.getElementsByTagName("exclude"):
       
  1776 					reExcludeSourceStr = excludeSourceNode.firstChild.nodeValue
       
  1777 					reExcludeSource = re.compile(reExcludeSourceStr, re.IGNORECASE)
       
  1778 					if reExcludeSource.search(aSourceFileName):
       
  1779 						self.ReportInfo("Note: excluding " + aSourceFileName + " : " + reExcludeSourceStr)
       
  1780 						return False
       
  1781 		return True
       
  1782 
       
  1783 	def CheckScriptEnabled(self, aScript):
       
  1784 		if (self.iDomConfig <> None):
       
  1785 			for scriptsNode in self.iDomConfig.getElementsByTagName("scripts"):
       
  1786 				for scriptNode in scriptsNode.getElementsByTagName(aScript.iScriptName):
       
  1787 					enabledAttr = scriptNode.getAttribute("enable")
       
  1788 					if (enabledAttr.lower() == "false"):
       
  1789 						return False
       
  1790 			for severitiesNode in self.iDomConfig.getElementsByTagName("severities"):
       
  1791 				for severityNode in severitiesNode.getElementsByTagName(KSeverityConfigMap[aScript.iSeverity]):
       
  1792 					enabledAttr = severityNode.getAttribute("enable")
       
  1793 					if (enabledAttr.lower() == "false"):
       
  1794 						return False
       
  1795 			for categoriesNode in self.iDomConfig.getElementsByTagName("categories"):
       
  1796 				for categoryNode in categoriesNode.getElementsByTagName(KCategoryConfigMap[aScript.iCategory]):
       
  1797 					enabledAttr = categoryNode.getAttribute("enable")
       
  1798 					if (enabledAttr.lower() == "false"):
       
  1799 						return False
       
  1800 		return True
       
  1801 
       
  1802 	def UpdateScriptCategory(self, aScript):
       
  1803 		if (self.iDomConfig <> None):
       
  1804 			for scriptsNode in self.iDomConfig.getElementsByTagName("scripts"):
       
  1805 				for scriptNode in scriptsNode.getElementsByTagName(aScript.iScriptName):
       
  1806 					if scriptNode.hasAttribute("category"):
       
  1807 						newCategory = scriptNode.getAttribute("category").lower()
       
  1808 						if (newCategory <> KCategoryConfigMap[aScript.iCategory]):
       
  1809 							for name, value in KCategoryConfigMap.items():
       
  1810 								if (newCategory == value):
       
  1811 									return name
       
  1812 		# no update needed, return original category
       
  1813 		return aScript.iCategory
       
  1814 
       
  1815 	def UpdateScriptSeverity(self, aScript):
       
  1816 		if (self.iDomConfig <> None):
       
  1817 			for scriptsNode in self.iDomConfig.getElementsByTagName("scripts"):
       
  1818 				for scriptNode in scriptsNode.getElementsByTagName(aScript.iScriptName):
       
  1819 					if scriptNode.hasAttribute("severity"):
       
  1820 						newSeverity = scriptNode.getAttribute("severity").lower()
       
  1821 						if (newSeverity <> KSeverityConfigMap[aScript.iSeverity]):
       
  1822 							for name, value in KSeverityConfigMap.items():
       
  1823 								if (newSeverity == value):
       
  1824 									return name
       
  1825 		# no update needed, return original severity
       
  1826 		return aScript.iSeverity
       
  1827 
       
  1828 	def ScanFile(self, aSourceFile):
       
  1829 		self.iLineContext.iFileName = aSourceFile
       
  1830 		self.iLineContext.iLineNumber = 0
       
  1831 		self.iLineContext.iClassName = ""
       
  1832 		self.iLineContext.iMethodName = ""
       
  1833 		self.iLineContext.iComponentName = self.iComponentManager.CurrentComponentName()
       
  1834 
       
  1835 		self.iRendererManager.BeginFile(aSourceFile)
       
  1836 
       
  1837 		# note source file extension - used for filtering later on
       
  1838 		(unused, sourceFileExt) = os.path.splitext(aSourceFile)
       
  1839 		if len(sourceFileExt) > 0 and sourceFileExt[0] == '.':
       
  1840 			sourceFileExt = sourceFileExt[1:]
       
  1841 
       
  1842 		# open, read, and preparse source file
       
  1843 		inputFileHandle = file(aSourceFile, "r")
       
  1844 		inputFileLines = inputFileHandle.readlines()
       
  1845 		inputFileHandle.close()
       
  1846 		
       
  1847 		(noQuoteFileLines, noCommentFileLines, noCommentOrQuoteFileLines, csCommands) = self.PreParseSourceFile(inputFileLines)
       
  1848 
       
  1849 		# bundle all the filtered versions of the file contents into
       
  1850 		# a hash to re-factor code
       
  1851 		fileContentsToTest = { KIgnoreNothing           : inputFileLines,
       
  1852 							   KIgnoreComments          : noCommentFileLines,
       
  1853 							   KIgnoreQuotes            : noQuoteFileLines,
       
  1854 							   KIgnoreCommentsAndQuotes : noCommentOrQuoteFileLines
       
  1855 							   }
       
  1856 
       
  1857 		# now apply test scripts to source file
       
  1858 		iBraceCount = 0
       
  1859 		iBraceCountList = []
       
  1860 		newCurrentClassName = ""
       
  1861 		newCurrentMethodName = ""
       
  1862 		self.iCurrentClassName = ""
       
  1863 		self.iCurrentMethodName = ""
       
  1864 		self.iCurrentMethodStart = -1
       
  1865 
       
  1866 		totalNumberOfLines = len(inputFileLines)
       
  1867 		reConstant = re.compile(r"""
       
  1868 			^\s*
       
  1869 			(static\s+)?
       
  1870 			const
       
  1871 			\s+
       
  1872 			\w+		# type
       
  1873 			\s*
       
  1874 			[\*&]?	# reference or pointer
       
  1875 			\s*
       
  1876 			\w+		# name
       
  1877 			\s*
       
  1878 			(=|\()
       
  1879 			""", re.VERBOSE)
       
  1880 		reInheritance = re.compile("[\s:]*(public|protected|private)\s*([\w:]+)")
       
  1881 		rePreprocessorIf = re.compile("^\s*\#(el)*if(.*)")
       
  1882 		rePreprocessorElse = re.compile("^\s*\#else")
       
  1883 		rePreprocessorEnd = re.compile("^\s*\#endif")
       
  1884 		reTypedef = re.compile("^\s*typedef")
       
  1885 		i = 0
       
  1886 		while (i < totalNumberOfLines):
       
  1887 			# for extra open braces in #if blocks
       
  1888 			if (rePreprocessorIf.search(noCommentOrQuoteFileLines[i])):
       
  1889 				iBraceCountList.append(iBraceCount)
       
  1890 			if (rePreprocessorElse.search(noCommentOrQuoteFileLines[i])):
       
  1891 				if (len(iBraceCountList) > 0):
       
  1892 					iBraceCount = iBraceCountList.pop()
       
  1893 			if (rePreprocessorEnd.search(noCommentOrQuoteFileLines[i])):
       
  1894 				if (len(iBraceCountList) > 0):
       
  1895 					iBraceCountList.pop()
       
  1896 
       
  1897 			if (newCurrentMethodName == ""):
       
  1898 				methodString = noCommentOrQuoteFileLines[i]
       
  1899 				currentLine = i
       
  1900 				m = self.iReMethod.search(methodString)
       
  1901 				if not m and (i + 1 < totalNumberOfLines):
       
  1902 					currentLine = i + 1
       
  1903 					methodString += noCommentOrQuoteFileLines[currentLine]
       
  1904 					m = self.iReMethod.search(methodString)
       
  1905 
       
  1906 				if m and (iBraceCount == 0) and (methodString.find("#") == -1) and (methodString.find("_LIT") == -1):	# must be at root level and not a preprocessor directive or a _LIT
       
  1907 					if not reTypedef.match(methodString) and not reConstant.match(methodString):  # must not be typedef or constant declaration 
       
  1908 						# check for cases where macros are used to declare a class
       
  1909 						# by searching for the inheritance part
       
  1910 						# eg. NONSHARABLE_CLASS(CMyClass) : public CBase
       
  1911 						isClass = reInheritance.search(methodString)
       
  1912 						if not isClass and (currentLine + 1 < totalNumberOfLines):
       
  1913 							methodString += noCommentOrQuoteFileLines[currentLine + 1]
       
  1914 							isClass = reInheritance.search(methodString)
       
  1915 						if not isClass:
       
  1916 							newCurrentMethodName = m.group('method')
       
  1917 							if m.group('class'):
       
  1918 								newCurrentClassName = m.group('class')
       
  1919 							else:
       
  1920 								newCurrentClassName = ""
       
  1921 
       
  1922 			iBraceCount += noCommentOrQuoteFileLines[i].count("{")
       
  1923 			if (iBraceCount > 0) and (newCurrentMethodName <> ""):
       
  1924 				self.iCurrentClassName = newCurrentClassName
       
  1925 				self.iCurrentMethodName = newCurrentMethodName
       
  1926 				self.iCurrentMethodStart = i
       
  1927 				newCurrentClassName = ""
       
  1928 				newCurrentMethodName = ""
       
  1929 
       
  1930 			self.iLineContext.iLineNumber = i+1
       
  1931 			self.iLineContext.iClassName = self.iCurrentClassName
       
  1932 			self.iLineContext.iMethodName = self.iCurrentMethodName
       
  1933 
       
  1934 			# perform all test scripts onto source file									   
       
  1935 			for script in self.iCategoriedScripts.AllScripts():
       
  1936 				if (script.iFileExts.count(sourceFileExt) > 0
       
  1937 				    and fileContentsToTest[script.iIgnore][i] != "\n"
       
  1938 					and	script.iCompare(fileContentsToTest[script.iIgnore], i, script.iReMatch, aSourceFile)):
       
  1939 					# skip any script that has been disabled via CodeScanner command(s) in sources
       
  1940 					if script.iScriptName.lower() in csCommands[i].lower():
       
  1941 						continue
       
  1942 					self.iLineContext.iLineText = fileContentsToTest[script.iIgnore][i]
       
  1943 					self.iComponentManager.ReportError(self.iLineContext, script)
       
  1944 
       
  1945 			iBraceCount -= noCommentOrQuoteFileLines[i].count("}")
       
  1946 			if (iBraceCount < 0):	# for extra close braces in #if blocks
       
  1947 				iBraceCount = 0
       
  1948 
       
  1949 			if (iBraceCount == 0):
       
  1950 				self.iCurrentClassName = ""
       
  1951 				self.iCurrentMethodName = ""
       
  1952 				self.iCurrentMethodStart = -1
       
  1953 
       
  1954 			i = i + 1
       
  1955 
       
  1956 		self.iRendererManager.EndFile()
       
  1957 		return totalNumberOfLines
       
  1958 
       
  1959 	def TraverseDirectory(self, aDirectory):
       
  1960 		# skip folders marked to be excluded in configuration file
       
  1961 		aPath = self.iComponentManager.SanitizePath(aDirectory)
       
  1962 		if (not self.CheckSourceIncluded(aPath)) or (not self.CheckSourceIncluded(aPath + os.path.sep)):
       
  1963 			return
       
  1964 		aDirectory = self.iComponentManager.BeginDirectory(aDirectory)
       
  1965 		contents = os.listdir(aDirectory)
       
  1966 		numberOfLinesScanned = 0
       
  1967 		for entry in contents:
       
  1968 			entryPath = os.path.normpath(os.path.join(aDirectory, entry))
       
  1969 			if os.path.isdir(entryPath):
       
  1970 				self.TraverseDirectory(entryPath)
       
  1971 			else:
       
  1972 				if self.CheckSourceIncluded(entryPath):
       
  1973 					numberOfLinesScanned += self.ScanFile(entryPath)
       
  1974 		self.iComponentManager.EndDirectory(aDirectory, numberOfLinesScanned)
       
  1975 
       
  1976 	def AddScript(self, aScript):
       
  1977 		enabled = self.CheckScriptEnabled(script)
       
  1978 		if enabled:
       
  1979 			aScript.iCategory = self.UpdateScriptCategory(aScript)
       
  1980 			aScript.iSeverity = self.UpdateScriptSeverity(aScript)
       
  1981 			self.iCategoriedScripts.AddScript(aScript)
       
  1982 		else:
       
  1983 			self.ReportInfo("Note: script '" + aScript.iScriptName + "' DISABLED")
       
  1984 
       
  1985 	def AddCustomScript(self, aScript):
       
  1986 		self.ReportInfo("Note: custom rule '" + aScript.iScriptName + "' ADDED")
       
  1987 		self.iCategoriedScripts.AddScript(aScript)
       
  1988 
       
  1989 	def PreParseSourceFile(self, aLines):
       
  1990 		# it provides 3 versions of input:
       
  1991 		# 	1. without quotes
       
  1992 		# 	2. without comments
       
  1993 		# 	3. without quotes and without comments
       
  1994 		
       
  1995 		inCommentBlock = 0
       
  1996 		noQuoteLines = []
       
  1997 		noCommentLines = []
       
  1998 		noCommentOrQuoteLines = []
       
  1999 		csCommands = []
       
  2000 		reCSCommand = re.compile("codescanner((::\w+)+)") # CodeScanner command(s) in comments
       
  2001 
       
  2002 		for line in aLines:
       
  2003 			noQuoteLine = ""
       
  2004 			noCommentLine = ""
       
  2005 			noCommentOrQuoteLine = ""
       
  2006 			csCommand = "\n"
       
  2007 
       
  2008 			i = 0
       
  2009 			startQuote = 0
       
  2010 			b = 0
       
  2011 			escCount = 0
       
  2012 
       
  2013 			while i < len(line):
       
  2014 				# skip quotes
       
  2015 				if not inCommentBlock and ((line[i] == "\"") or (line[i] == "\'")):
       
  2016 					startQuote = i
       
  2017 					i += 1
       
  2018 					while (i < len(line)):
       
  2019 						endIndex = line[i:].find(line[startQuote])
       
  2020 						if (endIndex <> -1):
       
  2021 							b = i + endIndex - 1
       
  2022 							escCount = 0
       
  2023 							while (line[b] == "\\"):
       
  2024 								escCount += 1
       
  2025 								b -= 1
       
  2026 
       
  2027 							i += endIndex + 1
       
  2028 							if (escCount % 2 == 0):
       
  2029 								noQuoteLine += "\"\""
       
  2030 								noCommentOrQuoteLine += "\"\""
       
  2031 								noCommentLine += line[startQuote:i]
       
  2032 								break
       
  2033 						else:
       
  2034 							#	print "Unterminated quote : " + line
       
  2035 							break
       
  2036 					continue	
       
  2037 				
       
  2038 				# parse comments
       
  2039 				if not inCommentBlock:
       
  2040 					if (line[i] == "/"):
       
  2041 						if (i < (len(line)-1)):
       
  2042 							if (line[i + 1] == "/"):
       
  2043 								noCommentLine += "\n"
       
  2044 								noCommentOrQuoteLine += "\n"
       
  2045 								noQuoteLine += line[i:]
       
  2046 								# look for CodeScanner command(s) in comments
       
  2047 								m = reCSCommand.search(line[i:])
       
  2048 								if m:
       
  2049 									csCommand = m.group(1)
       
  2050 								break
       
  2051 							elif (line[i + 1] == "*"):
       
  2052 								inCommentBlock = 1
       
  2053 								i += 2
       
  2054 								noQuoteLine += "/*"
       
  2055 								continue
       
  2056 
       
  2057 					noCommentLine += line[i]
       
  2058 					noCommentOrQuoteLine += line[i]
       
  2059 					noQuoteLine += line[i]
       
  2060 				else:
       
  2061 					# look for CodeScanner command(s) in comments
       
  2062 					m = reCSCommand.search(line[i:])
       
  2063 					if m:
       
  2064 						csCommand = m.group(1)
       
  2065 					endIndex = line[i:].find("*/")
       
  2066 					if (endIndex <> -1):
       
  2067 						inCommentBlock = 0
       
  2068 						noQuoteLine += line[i:i + endIndex + 2]
       
  2069 						i += endIndex + 2
       
  2070 						continue
       
  2071 					else:
       
  2072 						noCommentLine += "\n"
       
  2073 						noCommentOrQuoteLine += "\n"
       
  2074 						noQuoteLine = line[i:]
       
  2075 						break
       
  2076 				
       
  2077 				i += 1
       
  2078 
       
  2079 			noCommentLines.append(noCommentLine)
       
  2080 			noCommentOrQuoteLines.append(noCommentOrQuoteLine)
       
  2081 			noQuoteLines.append(noQuoteLine)
       
  2082 			csCommands.append(csCommand)
       
  2083 
       
  2084 		return [noQuoteLines, noCommentLines, noCommentOrQuoteLines, csCommands]
       
  2085 
       
  2086 	def ReadConfigFile(self):
       
  2087 		if self.iConfigFilename <> "":
       
  2088 			if (os.path.isfile(self.iConfigFilename)):
       
  2089 				self.iDomConfig = xml.dom.minidom.parse(self.iConfigFilename)
       
  2090 				if self.iVerbose:
       
  2091 					print "Note: using configuration file " + self.iConfigFilename
       
  2092 			else:
       
  2093 				self.ReportInfo("Unable to open specified configuration file: " + self.iConfigFilename)
       
  2094 				self.iLog.Close()
       
  2095 				sys.exit(2)
       
  2096 
       
  2097 	def ReadArgumentsFromConfigFile(self):
       
  2098 		if (self.iDomConfig <> None):
       
  2099 			for argumentsNode in self.iDomConfig.getElementsByTagName("arguments"):
       
  2100 				# read input file names
       
  2101 				for inputFileNode in argumentsNode.getElementsByTagName("input"):
       
  2102 					self.iInputFilenames += inputFileNode.firstChild.nodeValue + "::"
       
  2103 				# read output format
       
  2104 				for outputFormatNode in argumentsNode.getElementsByTagName("outputformat"):
       
  2105 					self.iOutputFormat += outputFormatNode.firstChild.nodeValue
       
  2106 				# read lxr URL
       
  2107 				for lxrURLNode in argumentsNode.getElementsByTagName("lxr"):
       
  2108 					self.iLxrUrl = lxrURLNode.firstChild.nodeValue
       
  2109 				# read lxr version
       
  2110 				for lxrVersionNode in argumentsNode.getElementsByTagName("lxrversion"):
       
  2111 					self.iLxrVersion = lxrVersionNode.firstChild.nodeValue
       
  2112 				# read time stamped output option
       
  2113 				for timeStampedOutputNode in argumentsNode.getElementsByTagName("timestampedoutput"):
       
  2114 					self.iTimeStampedOutput = timeStampedOutputNode.firstChild.nodeValue
       
  2115 
       
  2116 	def ReadCustomRulesFromConfigFile(self):
       
  2117 		if (self.iDomConfig <> None):
       
  2118 			for customRulesNode in self.iDomConfig.getElementsByTagName("customrules"):
       
  2119 				for customRuleNode in customRulesNode.getElementsByTagName("customrule"):
       
  2120 					ignoreComments = True
       
  2121 
       
  2122 					# read the name of the rule
       
  2123 					ruleName = ""
       
  2124 					for ruleNameNode in customRuleNode.getElementsByTagName("name"):
       
  2125 						if (ruleNameNode == None) or (ruleNameNode.firstChild == None) or (ruleNameNode.firstChild.nodeValue == None):
       
  2126 							continue
       
  2127 						else:
       
  2128 							ruleName = ruleNameNode.firstChild.nodeValue
       
  2129 					if len(ruleName) == 0:
       
  2130 						self.ReportError("Missing custom rule name in configuration file: " + self.iConfigFilename)
       
  2131 						continue
       
  2132 
       
  2133 					# read the keywords associated with the rule
       
  2134 					keywordList = []
       
  2135 					badKeywordElement = False
       
  2136 					for keywordNode in customRuleNode.getElementsByTagName("keyword"):
       
  2137 						# read keyword content
       
  2138 						if (keywordNode == None) or (keywordNode.firstChild == None) or (keywordNode.firstChild.nodeValue == None):
       
  2139 							badKeywordElement = True
       
  2140 							continue
       
  2141 						newKeyword = CCustomRuleKeyword()
       
  2142 						newKeyword.iContent = keywordNode.firstChild.nodeValue
       
  2143 
       
  2144 						# read keyword type
       
  2145 						if not keywordNode.hasAttribute("type"):
       
  2146 							badKeywordElement = True
       
  2147 							continue
       
  2148 						type = keywordNode.getAttribute("type").lower()
       
  2149 						if type in KCustomRuleKeywordMap.values():
       
  2150 							if type == KKeywordComment:
       
  2151 								ignoreComments = False
       
  2152 						else:
       
  2153 							type = KCustomRuleKeywordMap[KKeywordUnknown]
       
  2154 						newKeyword.iType = type
       
  2155 						keywordList.append(newKeyword)
       
  2156 					if (len(keywordList) == 0) or (badKeywordElement == True):
       
  2157 						self.ReportBadCustomRuleElement(ruleName, "keyword")
       
  2158 						continue
       
  2159 
       
  2160 					# read the file types associated with the rule
       
  2161 					fileTypeList = []
       
  2162 					badFileTypeElement = False
       
  2163 					for fileTypeNode in customRuleNode.getElementsByTagName("filetype"):
       
  2164 						if (fileTypeNode == None) or (fileTypeNode.firstChild == None) or (fileTypeNode.firstChild.nodeValue == None):
       
  2165 							badFileTypeElement = True
       
  2166 							continue
       
  2167 						newFileType = fileTypeNode.firstChild.nodeValue
       
  2168 						fileTypeList.append(newFileType.lower())
       
  2169 					if (len(fileTypeList) == 0) or (badFileTypeElement == True):
       
  2170 						self.ReportBadCustomRuleElement(ruleName, "file type")
       
  2171 						continue
       
  2172 
       
  2173 					# read the severity level of the rule
       
  2174 					severity = KSeverityLow
       
  2175 					for severityNode in customRuleNode.getElementsByTagName("severity"):
       
  2176 						if (severityNode == None) or (severityNode.firstChild == None) or (severityNode.firstChild.nodeValue == None):
       
  2177 							self.ReportBadCustomRuleElement(ruleName, "severity")
       
  2178 							continue
       
  2179 						severityValue = severityNode.firstChild.nodeValue
       
  2180 						for severityKey in KSeverityConfigMap.keys():
       
  2181 							if severityValue == KSeverityConfigMap[severityKey]:
       
  2182 								severity = severityKey
       
  2183 
       
  2184 					# read the tile of the rule
       
  2185 					title = ""
       
  2186 					for titleNode in customRuleNode.getElementsByTagName("title"):
       
  2187 						if (titleNode == None) or (titleNode.firstChild == None) or (titleNode.firstChild.nodeValue == None):
       
  2188 							continue
       
  2189 						title = titleNode.firstChild.nodeValue
       
  2190 					if len(title) == 0:
       
  2191 						self.ReportBadCustomRuleElement(ruleName, "title")
       
  2192 						continue
       
  2193 
       
  2194 					# read the description of the rule
       
  2195 					description = ""
       
  2196 					for descriptionNode in customRuleNode.getElementsByTagName("description"):
       
  2197 						if (descriptionNode == None) or (descriptionNode.firstChild == None) or (descriptionNode.firstChild.nodeValue == None):
       
  2198 							continue
       
  2199 						description = descriptionNode.firstChild.nodeValue
       
  2200 					if len(description) == 0:
       
  2201 						self.ReportBadCustomRuleElement(ruleName, "description")
       
  2202 						continue
       
  2203 
       
  2204 					# read the optional link of the rule
       
  2205 					link = None
       
  2206 					for linkNode in customRuleNode.getElementsByTagName("link"):
       
  2207 						if (linkNode == None) or (linkNode.firstChild == None) or (linkNode.firstChild.nodeValue == None):
       
  2208 							self.ReportBadCustomRuleElement(ruleName, "link")
       
  2209 							continue
       
  2210 						link = linkNode.firstChild.nodeValue
       
  2211 
       
  2212 					# create the RE string for the custom rule
       
  2213 					keywordMap = self.ConstructCustomRuleKeywordMap(keywordList)
       
  2214 					reString = self.ConstructCustomRuleREString(keywordMap)
       
  2215 					if len(reString) == 0:
       
  2216 						continue
       
  2217 					
       
  2218 					# create a script based on the custom rule
       
  2219 					aScript = CCustomScript(ruleName)
       
  2220 					aScript.iReString = reString
       
  2221 					aScript.iReMatch = re.compile(reString)
       
  2222 					aScript.iFileExts = fileTypeList
       
  2223 					aScript.iCategory = KCategoryOther
       
  2224 					if keywordMap.has_key(KKeywordBaseClass):
       
  2225 						aScript.iBaseClass = keywordMap[KKeywordBaseClass]
       
  2226 						aScript.iCompare = aScript.DefaultInheritanceCompare
       
  2227 					if ignoreComments:
       
  2228 						aScript.iIgnore = KIgnoreComments
       
  2229 					else:
       
  2230 						aScript.iIgnore = KIgnoreQuotes
       
  2231 					aScript.iSeverity = severity
       
  2232 					aScript.iTitle = title
       
  2233 					aScript.iIdeTitle = title
       
  2234 					aScript.iDescription = description
       
  2235 					if link <> None:
       
  2236 						aScript.iLink = link
       
  2237 					self.AddCustomScript(aScript)
       
  2238 		return
       
  2239 
       
  2240 	def ReportBadCustomRuleElement(self, name, element):
       
  2241 		self.ReportError("<customrule> element '" + name + "' has bad <" + element + "> child element in configuration file: " + self.iConfigFilename)
       
  2242 
       
  2243 	def ConstructCustomRuleKeywordMap(self, keywordList):
       
  2244 		reString = ""
       
  2245 		keywordMap = {}
       
  2246 		for keyword in keywordList:
       
  2247 			if keywordMap.has_key(keyword.iType):
       
  2248 				keywordMap[keyword.iType] = keywordMap[keyword.iType] + "|" + keyword.iContent
       
  2249 			else:
       
  2250 				keywordMap[keyword.iType] = keyword.iContent
       
  2251 		return keywordMap
       
  2252 
       
  2253 	def ConstructCustomRuleREString(self, keywordMap):
       
  2254 		# generate RE string based on the keyword types
       
  2255 		if keywordMap.has_key(KKeywordBaseClass):
       
  2256 			reString = "^\s*class\s+(\w+::)?(\w+)\s*:(.*)"
       
  2257 		elif keywordMap.has_key(KKeywordCall):
       
  2258 			reString = "(" + keywordMap[KKeywordCall] + ")\s*\(.*\)\s*;"
       
  2259 		elif keywordMap.has_key(KKeywordClassName):
       
  2260 			if keywordMap.has_key(KKeywordMethod):
       
  2261 				reString = "([A-Za-z0-9]+\s+" + keywordMap[KKeywordClassName] + "::)?(" + keywordMap[KKeywordMethod] + ")\s*\(.*\)\s*[^;]"
       
  2262 			else:
       
  2263 				reString = "^\s*class\s+(\w+::)?(" + keywordMap[KKeywordClassName] + ")"
       
  2264 		elif keywordMap.has_key(KKeywordComment):
       
  2265 			reString = "/(/|\*).*(" + keywordMap[KKeywordComment] + ")"
       
  2266 		elif keywordMap.has_key(KKeywordGeneric):
       
  2267 			reString = "(" + keywordMap[KKeywordGeneric] + ")"
       
  2268 		elif keywordMap.has_key(KKeywordLocal):
       
  2269 			reString = "^\s*[A-Z]\w*\s*[\*&\s]\s*(" + keywordMap[KKeywordLocal] + ")\w*\s*[;\(=]"
       
  2270 		elif keywordMap.has_key(KKeywordMacro):
       
  2271 			reString = "^\s*\#define\s+(" + keywordMap[KKeywordMacro] + ")"
       
  2272 		elif keywordMap.has_key(KKeywordMember):
       
  2273 			reString = "^\s*[A-Z]\w*\s*[\*&\s]\s*(" + keywordMap[KKeywordMember] + ")\w*\s*[;\(=]"
       
  2274 		elif keywordMap.has_key(KKeywordMethod):
       
  2275 			reString = "[A-Za-z0-9]+\s+[C|T|R][A-Za-z0-9]+::(" + keywordMap[KKeywordMethod] + ")\s*\(.*\)\s*[^;]"
       
  2276 		elif keywordMap.has_key(KKeywordParameter):
       
  2277 			reString = "({)*\s*(" + keywordMap[KKeywordParameter] + ")\s*=\s*(.*);"
       
  2278 		return reString
       
  2279 
       
  2280 
       
  2281 class CCustomRuleKeyword:
       
  2282 	# #######################################################
       
  2283 	# CCustomRuleKeyword - keyword associated with custom rules
       
  2284 
       
  2285 	def __init__(self):
       
  2286 		iContent = ""
       
  2287 		iType = "unknown"
       
  2288 
       
  2289 
       
  2290 # #######################################################
       
  2291 
       
  2292 class CEncodedFile:
       
  2293     def Extract(self, aBaseDirectory):
       
  2294         outputFileHandle = open(os.path.join(aBaseDirectory, self.iFilename), 'wb')
       
  2295         outputFileBinary = zlib.decompress(base64.decodestring(self.iFileBody))
       
  2296         outputFileHandle.write(outputFileBinary)
       
  2297         outputFileHandle.close()
       
  2298 
       
  2299 	iFilename = ""
       
  2300 	iFileBody = ""
       
  2301 
       
  2302 # #######################################################
       
  2303 
       
  2304 
       
  2305 class CEncodedFileList:
       
  2306 	def AddEncodedFile(self, aEncodedFile):
       
  2307 		self.iEncodedFileList[aEncodedFile.iFilename.lower()] = aEncodedFile
       
  2308 
       
  2309 	def ExtractEncodedFile(self, aFilename, aBaseDirectory):
       
  2310 		# look for the filename in our list of files
       
  2311 		filename = aFilename.lower()
       
  2312 		if (self.iEncodedFileList.has_key(filename)):
       
  2313 			self.iEncodedFileList[filename].Extract(aBaseDirectory)
       
  2314 		else:
       
  2315 			scanner.iLog.Write("Missing "+filename)
       
  2316 
       
  2317 	def ExtractAllEncodedFiles(self, aBaseDirectory):
       
  2318 		# run through associative array and extract everything
       
  2319 		for filename in self.iEncodedFileList.keys():
       
  2320 			self.ExtractEncodedFile(filename, aBaseDirectory)
       
  2321 
       
  2322 	# declare iEncodedFileList is an associative array
       
  2323 	iEncodedFileList = {}
       
  2324 
       
  2325 
       
  2326 # #######################################################
       
  2327 # main()
       
  2328 scanner = CCodeScanner()
       
  2329 
       
  2330 # process command line arguments
       
  2331 opts, args = getopt.getopt(sys.argv[1:], "hvc:i:l:o:x:r:t:", ["help", "verbose", "config=", "input=", "logfile=", "outputformat=", "lxr=", "lxrversion=", "timestampedoutput="])
       
  2332 for o, a in opts:
       
  2333 	if o in ("-h", "--help"):
       
  2334 		Usage(0)
       
  2335 	if o in ("-v", "--verbose"):
       
  2336 		scanner.iVerbose = True
       
  2337 	if o in ("-c", "--config"):
       
  2338 		scanner.iConfigFilename = a
       
  2339 	if o in ("-i", "--input"):
       
  2340 		scanner.iInputFilenames += a + "::"
       
  2341 	if o in ("-l", "--logfile"):
       
  2342 		scanner.iLogFilename = a
       
  2343 	if o in ("-o", "--outputformat"):
       
  2344 		scanner.iOutputFormat += a			
       
  2345 	if o in ("-x", "--lxr"):
       
  2346 		scanner.iLxrUrl = a
       
  2347 	if o in ("-r", "--lxrversion"):
       
  2348 		scanner.iLxrVersion = a
       
  2349 	if o in ("-t", "--timestampedoutput"):
       
  2350 		scanner.iTimeStampedOutput = a
       
  2351 
       
  2352 if len(args) < 1:
       
  2353 	Usage(1)
       
  2354 
       
  2355 scanner.iLog = CLogger(scanner.iLogFilename)
       
  2356 scanner.iLog.Write("Command line: " + str(sys.argv[1:]))
       
  2357 scanner.iLog.Write("Current working directory: " + os.getcwd())
       
  2358 
       
  2359 scanner.ReadConfigFile()
       
  2360 scanner.ReadArgumentsFromConfigFile()
       
  2361 scanner.ReadCustomRulesFromConfigFile()
       
  2362 
       
  2363 scanner.iSource = args[0]
       
  2364 scanner.iEncodedFileList = CEncodedFileList()
       
  2365 scanner.iStartTimeObj = datetime.datetime.now()
       
  2366 scanner.iStartTime = scanner.iStartTimeObj.ctime()
       
  2367 scanner.iOutputDirectory = scanner.iStartTimeObj.strftime("%a-%b-%d-%H-%M-%S-%Y")
       
  2368 
       
  2369 # invoke the pysco module to improve performance
       
  2370 psyco.full()
       
  2371 
       
  2372 # choose renderer based on command line arguments
       
  2373 if len(args) > 1:
       
  2374 	if ("off" in scanner.iTimeStampedOutput.lower()):
       
  2375 		scanner.iOutputDirectory = args[1]
       
  2376 	else:
       
  2377 		scanner.iOutputDirectory = os.path.normpath(os.path.join(args[1], scanner.iOutputDirectory))
       
  2378 	scanner.CleanOutputDirectory()
       
  2379 	if scanner.iOutputFormat <> "":
       
  2380 	#user specified output format
       
  2381 		if ("xml" in scanner.iOutputFormat.lower()):
       
  2382 			CXmlRenderer(scanner.iRendererManager, scanner.iOutputDirectory)
       
  2383 		if ("html" in scanner.iOutputFormat.lower()):
       
  2384 			CHtmlRenderer(scanner.iRendererManager, scanner.iOutputDirectory, scanner.iLxrUrl, scanner.iLxrVersion)
       
  2385 		if ("std" in scanner.iOutputFormat.lower()):
       
  2386 			CStdOutRenderer(scanner.iRendererManager)
       
  2387 	else:
       
  2388 	#default output format
       
  2389 		CHtmlRenderer(scanner.iRendererManager, scanner.iOutputDirectory, scanner.iLxrUrl, scanner.iLxrVersion)
       
  2390 else:
       
  2391 	CStdOutRenderer(scanner.iRendererManager)
       
  2392 
       
  2393 
       
  2394 # #################################################################
       
  2395 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  2396 # All rights reserved.
       
  2397 # 
       
  2398 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  2399 # 
       
  2400 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  2401 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  2402 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  2403 # 
       
  2404 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  2405 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  2406 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  2407 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  2408 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  2409 #
       
  2410 # accessArrayElementWithoutCheck.py
       
  2411 #
       
  2412 # Checks : Array element accessed by At() function without checking 
       
  2413 # index is within array range.
       
  2414 #
       
  2415 # Reason : Whenever an element in an array is accessed, the index 
       
  2416 # should be checked to ensure that it is less than array.Count(). 
       
  2417 # CodeScanner checks for explicit calls to a Count() function; so 
       
  2418 # if the array index is checked in a different way, it gives 
       
  2419 # false positives. Accessing an invalid index can cause a panic.
       
  2420 #
       
  2421 # #################################################################
       
  2422 
       
  2423 script = CScript("accessArrayElementWithoutCheck")
       
  2424 script.iReString = r"""
       
  2425 	(->|\.)		# pointer/instance of array
       
  2426 	\s*			# optional whitespace
       
  2427 	At
       
  2428 	\s*			# optional whitespace
       
  2429 	\(			# opening bracket
       
  2430 	"""
       
  2431 script.iFileExts = ["cpp"]
       
  2432 script.iCategory = KCategoryCodeReviewGuides
       
  2433 script.iIgnore = KIgnoreCommentsAndQuotes
       
  2434 script.iSeverity = KSeverityLow
       
  2435 
       
  2436 accessArrayCountFn = re.compile("""
       
  2437 	(\.|->)
       
  2438 	\s*
       
  2439 	Count
       
  2440 	\s*
       
  2441 	\(
       
  2442 	\s*
       
  2443 	\)
       
  2444 	""", re.VERBOSE)
       
  2445 
       
  2446 accessArrayDeclaration = re.compile("""
       
  2447 	\w+			# array type
       
  2448 	[0-9<>*& ]*	# optional array element
       
  2449 	\w+			# array name
       
  2450 	\s*
       
  2451 	\[
       
  2452 	.*			# array size
       
  2453 	\]
       
  2454 	\s*
       
  2455 	;
       
  2456 	""", re.VERBOSE)
       
  2457 
       
  2458 def isTimerObject(lines, currentline, varname):
       
  2459 	if (varname.lower().find("array") <> -1) or (varname.lower().find("list") <> -1):
       
  2460 		return False
       
  2461 	if (varname.lower().find("heartbeat") <> -1):
       
  2462 		return True
       
  2463 	if (varname.lower().find("periodic") <> -1):
       
  2464 		return True
       
  2465 	if (varname.lower().find("timer") <> -1):
       
  2466 		return True
       
  2467 
       
  2468 	vartype = GetLocalVariableType(lines, currentline, varname)
       
  2469 	if (len(vartype) > 0):
       
  2470 		if (vartype.lower().find("array") <> -1) or (vartype.lower().find("list") <> -1):
       
  2471 			return False
       
  2472 		if (vartype.lower().find("heartbeat") <> -1):
       
  2473 			return True
       
  2474 		if (vartype.lower().find("periodic") <> -1):
       
  2475 			return True
       
  2476 		if (vartype.lower().find("timer") <> -1):
       
  2477 			return True
       
  2478 
       
  2479 	return False
       
  2480 
       
  2481 def arrayAccessCompare(lines, currentline, rematch, filename):
       
  2482 	line = lines[currentline]
       
  2483 	m = rematch.search(line)
       
  2484 
       
  2485 	if m:
       
  2486 		if (line.count("At") == 1):
       
  2487 			openBracketPos = line.find("At")
       
  2488 		else:
       
  2489 			openBracketPos = line.find("At(")
       
  2490 		cutLine = line[openBracketPos+1:]
       
  2491 		closeBracketPos = cutLine.find(")") + len(line) - len(cutLine)
       
  2492 		if (closeBracketPos > openBracketPos) and (openBracketPos >= 0):
       
  2493 			variable = line[openBracketPos+3:closeBracketPos]
       
  2494 			variable = TrimVariableName(variable)
       
  2495 
       
  2496 			if (len(variable) == 0):
       
  2497 				return 0
       
  2498 
       
  2499 			# if a constant index assume it's going to be ok!
       
  2500 			if (variable[0] == "E") or (variable[0] == "K"):
       
  2501 				return 0
       
  2502 
       
  2503 			variableIsNumeric = 1
       
  2504 			varPos = 0
       
  2505 			while (varPos < len(variable)):
       
  2506 				if (variable[varPos] < '0') or (variable[varPos] > '9'):
       
  2507 					variableIsNumeric = 0
       
  2508 					break
       
  2509 				varPos = varPos + 1
       
  2510 
       
  2511 			linePos = openBracketPos - 1
       
  2512 			while (linePos > 0) and (isNonAlpha(line[linePos])):
       
  2513 				linePos = linePos - 1
       
  2514 			arrayNameEnd = linePos + 1
       
  2515 			while (linePos >= 0) and (isNonAlpha(line[linePos]) == 0):
       
  2516 				linePos = linePos - 1
       
  2517 			arrayNameStart = linePos + 1
       
  2518 		
       
  2519 			arrayName = ""
       
  2520 			if (arrayNameStart >= 0):
       
  2521 				arrayName = line[arrayNameStart:arrayNameEnd]
       
  2522 				arrayName = TrimVariableName(arrayName)
       
  2523 
       
  2524 				if (len(arrayName) > 0):
       
  2525 					# if a constant array assume it's going to be ok!
       
  2526 					if (arrayName[0] == "E") or (arrayName[0] == "K"):
       
  2527 						return 0
       
  2528 
       
  2529 					# ignore any heartbeat/periodic/timer object that is not an array or list
       
  2530 					if isTimerObject(lines, currentline, arrayName):
       
  2531 						return 0
       
  2532 
       
  2533 			if (variableIsNumeric):
       
  2534 				if (len(arrayName) > 2):
       
  2535 					if (arrayName[0] == "i") and (arrayName[1] >= 'A') and (arrayName[1] <= 'Z'):
       
  2536 						return 0 
       
  2537 
       
  2538 			i = currentline
       
  2539 
       
  2540 			while (i >= 0) and (i >= scanner.iCurrentMethodStart):
       
  2541 				line = lines[i]
       
  2542 
       
  2543 				# check to see if index is compared to array size
       
  2544 				if (len(arrayName) > 0):
       
  2545 					arrayNamePos = line.find(arrayName)
       
  2546 					if (arrayNamePos >= 0):
       
  2547 						cutLine = line[arrayNamePos + len(arrayName):]
       
  2548 						if (accessArrayCountFn.search(cutLine)):
       
  2549 							return 0
       
  2550 
       
  2551 					if (variableIsNumeric == 1):
       
  2552 						if (accessArrayDeclaration.search(line)):
       
  2553 							openBracketPos = line.find("[")
       
  2554 							cutLine = line[openBracketPos:]
       
  2555 							closeBracketPos = cutLine.find("]") + len(line) - len(cutLine)
       
  2556 							if (closeBracketPos > openBracketPos) and (openBracketPos >= 0):
       
  2557 								declVariable = line[openBracketPos:closeBracketPos]
       
  2558 								declVariable = TrimVariableName(declVariable)
       
  2559 								if (len(declVariable) > 0):
       
  2560 									# if a constant index assume it's going to be ok!
       
  2561 									if (declVariable[0] == "E") or (declVariable[0] == "K"):
       
  2562 										return 0
       
  2563 
       
  2564 								declVariableIsNumeric = 1
       
  2565 								varPos = 0
       
  2566 								while (varPos < len(declVariable)):
       
  2567 									if (declVariable[varPos] < '0') or (declVariable[varPos] > '9'):
       
  2568 										declVariableIsNumeric = 0
       
  2569 										break
       
  2570 									varPos = varPos + 1
       
  2571 								if (declVariableIsNumeric == 1):
       
  2572 									if (int(variable) < int(declVariable)):
       
  2573 										return 0
       
  2574 
       
  2575 				i = i - 1
       
  2576 			return 1
       
  2577 
       
  2578 	return 0
       
  2579 
       
  2580 script.iCompare	= arrayAccessCompare
       
  2581 scanner.AddScript(script)
       
  2582 
       
  2583 # #################################################################
       
  2584 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  2585 # All rights reserved.
       
  2586 # 
       
  2587 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  2588 # 
       
  2589 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  2590 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  2591 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  2592 # 
       
  2593 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  2594 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  2595 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  2596 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  2597 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  2598 #
       
  2599 # accessArrayElementWithoutCheck2.py
       
  2600 #
       
  2601 # Checks : Array element accessed by [] without checking range.
       
  2602 #
       
  2603 # Reason : Whenever an element in an array is accessed, the index 
       
  2604 # should first be checked to ensure that it is within range. 
       
  2605 # CodeScanner checks for explicit calls to a Count() or Length() 
       
  2606 # function; so if the array index is checked in a different way, 
       
  2607 # it gives false positives. Accessing an invalid index can cause 
       
  2608 # a panic.
       
  2609 #
       
  2610 # #################################################################
       
  2611 
       
  2612 script = CScript("accessArrayElementWithoutCheck2")
       
  2613 script.iReString = r"""
       
  2614 	\w+
       
  2615 	\s*		# optional whitespace
       
  2616 	\)*		# optional closing bracket
       
  2617 	\s*		# optional whitespace
       
  2618 	\[
       
  2619 	"""
       
  2620 script.iFileExts = ["cpp"]
       
  2621 script.iCategory = KCategoryCodeReviewGuides
       
  2622 script.iIgnore = KIgnoreCommentsAndQuotes
       
  2623 script.iSeverity = KSeverityLow
       
  2624 
       
  2625 accessArrayCountFn = re.compile("""
       
  2626 	(\.|->)
       
  2627 	\s*
       
  2628 	Count
       
  2629 	\s*
       
  2630 	\(
       
  2631 	\s*
       
  2632 	\)
       
  2633 	""", re.VERBOSE)
       
  2634 
       
  2635 accessArrayLengthFn = re.compile("""
       
  2636 	(\.|->)
       
  2637 	\s*
       
  2638 	Length
       
  2639 	\s*
       
  2640 	\(
       
  2641 	\s*
       
  2642 	\)
       
  2643 	""", re.VERBOSE)
       
  2644 
       
  2645 accessArrayDeclareNew = re.compile("""
       
  2646 	\s*
       
  2647 	=
       
  2648 	\s*
       
  2649 	new
       
  2650 	\s*
       
  2651 	""", re.VERBOSE)
       
  2652 
       
  2653 bufferArrayDeclaration = re.compile("""
       
  2654 	\w+		# array type
       
  2655 	\s*
       
  2656 	<
       
  2657 	\s*
       
  2658 	[0-9]+
       
  2659 	\s*
       
  2660 	>
       
  2661 	\s*
       
  2662 	\w+		# array name
       
  2663 	\s*
       
  2664 	;
       
  2665 	""", re.VERBOSE)
       
  2666 
       
  2667 accessArrayDeclaration = re.compile("""
       
  2668 	\w+		# array type
       
  2669 	\s*
       
  2670 	(\*|&)*
       
  2671 	\s*
       
  2672 	\[
       
  2673 	.*		# array size
       
  2674 	\]
       
  2675 	\s*
       
  2676 	;
       
  2677 	""", re.VERBOSE)
       
  2678 
       
  2679 constArrayDeclaration = re.compile("""
       
  2680 	\w+		# array type
       
  2681 	[0-9<>*& ]*	# optional array element
       
  2682 	\s+
       
  2683 	\w+		# array name
       
  2684 	\s*
       
  2685 	\[
       
  2686 	.*		# array size
       
  2687 	\]
       
  2688 	\s*
       
  2689 	=
       
  2690 	[^=]
       
  2691 	""", re.VERBOSE)
       
  2692 
       
  2693 def arrayAccessCompare2(lines, currentline, rematch, filename):
       
  2694 	line = lines[currentline]
       
  2695 	m = rematch.search(line)
       
  2696 
       
  2697 	if m:
       
  2698 		if (accessArrayDeclareNew.search(line)):
       
  2699 			return 0
       
  2700 
       
  2701 		if (accessArrayDeclaration.search(line)):
       
  2702 			return 0
       
  2703 
       
  2704 		if (constArrayDeclaration.search(line)):
       
  2705 			return 0
       
  2706 
       
  2707 		openBracketPos = line.find("[")
       
  2708 		cutLine = line[openBracketPos:]
       
  2709 		closeBracketPos = cutLine.find("]") + len(line) - len(cutLine)
       
  2710 		if (closeBracketPos > openBracketPos) and (openBracketPos >= 0):
       
  2711 			variable = line[openBracketPos:closeBracketPos]
       
  2712 			variable = TrimVariableName(variable)
       
  2713 
       
  2714 			if (len(variable) == 0):
       
  2715 				return 0
       
  2716 
       
  2717 			# if a constant index assume it's going to be ok!
       
  2718 			if (variable[0] == "E") or (variable[0] == "K"):
       
  2719 				return 0
       
  2720 
       
  2721 			variableIsNumeric = 1
       
  2722 			varPos = 0
       
  2723 			while (varPos < len(variable)):
       
  2724 				if (variable[varPos] < '0') or (variable[varPos] > '9'):
       
  2725 					variableIsNumeric = 0
       
  2726 					break
       
  2727 				varPos = varPos + 1
       
  2728 
       
  2729 			linePos = openBracketPos
       
  2730 			while (linePos > 0) and (isNonAlpha(line[linePos])):
       
  2731 				linePos = linePos - 1
       
  2732 			arrayNameEnd = linePos + 1
       
  2733 			while (linePos >= 0) and (isNonAlpha(line[linePos]) == 0):
       
  2734 				linePos = linePos - 1
       
  2735 			arrayNameStart = linePos + 1
       
  2736 		
       
  2737 			arrayName = ""
       
  2738 			if (arrayNameStart >= 0):
       
  2739 				arrayName = line[arrayNameStart:arrayNameEnd]
       
  2740 				arrayName = TrimVariableName(arrayName)
       
  2741 
       
  2742 				if (len(arrayName) > 0):
       
  2743 					# if a constant array assume it's going to be ok!
       
  2744 					if (arrayName[0] == "E") or (arrayName[0] == "K"):
       
  2745 						return 0
       
  2746 
       
  2747 			if (variableIsNumeric):
       
  2748 				if (len(arrayName) > 2):
       
  2749 					if (arrayName[0] == "i") and (arrayName[1] >= 'A') and (arrayName[1] <= 'Z'):
       
  2750 						return 0 
       
  2751 
       
  2752 			i = currentline
       
  2753 
       
  2754 			while (i >= 0) and (i >= scanner.iCurrentMethodStart):
       
  2755 				line = lines[i]
       
  2756 				
       
  2757 				# check to see if index is compared to array size
       
  2758 				if (len(arrayName) > 0):
       
  2759 					arrayNamePos = line.find(arrayName)
       
  2760 					if (arrayNamePos >= 0):
       
  2761 						cutLine = line[arrayNamePos + len(arrayName):]
       
  2762 						if (accessArrayCountFn.search(cutLine)):
       
  2763 							return 0
       
  2764 						if (accessArrayLengthFn.search(cutLine)):
       
  2765 							return 0
       
  2766 
       
  2767 					if (variableIsNumeric == 1):
       
  2768 						doCheck = 0
       
  2769 						if (accessArrayDeclaration.search(line)):
       
  2770 							openBracketPos = line.find("[")
       
  2771 							cutLine = line[openBracketPos:]
       
  2772 							closeBracketPos = cutLine.find("]") + len(line) - len(cutLine)
       
  2773 							if (closeBracketPos > openBracketPos) and (openBracketPos >= 0):
       
  2774 								declVariable = line[openBracketPos:closeBracketPos]
       
  2775 								declVariable = TrimVariableName(declVariable)
       
  2776 								if (len(declVariable) > 0):
       
  2777 									doCheck = 1
       
  2778 
       
  2779 						if (bufferArrayDeclaration.search(line)):
       
  2780 							openBracketPos = line.find("<")
       
  2781 							cutLine = line[openBracketPos:]
       
  2782 							closeBracketPos = cutLine.find(">") + len(line) - len(cutLine)
       
  2783 							if (closeBracketPos > openBracketPos) and (openBracketPos >= 0):
       
  2784 								declVariable = line[openBracketPos:closeBracketPos]
       
  2785 								declVariable = TrimVariableName(declVariable)
       
  2786 								if (len(declVariable) > 0):
       
  2787 									doCheck = 1
       
  2788 
       
  2789 						if (doCheck == 1):
       
  2790 							# if a constant index assume it's going to be ok!
       
  2791 							if (declVariable[0] == "E") or (declVariable[0] == "K"):
       
  2792 								return 0
       
  2793 
       
  2794 							declVariableIsNumeric = 1
       
  2795 							varPos = 0
       
  2796 							while (varPos < len(declVariable)):
       
  2797 								if (declVariable[varPos] < '0') or (declVariable[varPos] > '9'):
       
  2798 									declVariableIsNumeric = 0
       
  2799 									break
       
  2800 								varPos = varPos + 1
       
  2801 							if (declVariableIsNumeric == 1):
       
  2802 								if (int(variable) < int(declVariable)):
       
  2803 									return 0
       
  2804 
       
  2805 				i = i - 1
       
  2806 			return 1
       
  2807 
       
  2808 	return 0
       
  2809 
       
  2810 script.iCompare	= arrayAccessCompare2
       
  2811 scanner.AddScript(script)
       
  2812 
       
  2813 # #################################################################
       
  2814 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  2815 # All rights reserved.
       
  2816 # 
       
  2817 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  2818 # 
       
  2819 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  2820 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  2821 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  2822 # 
       
  2823 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  2824 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  2825 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  2826 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  2827 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  2828 #
       
  2829 # activestart.py
       
  2830 #
       
  2831 # Checks : Using CActiveScheduler::Start.
       
  2832 #
       
  2833 # Reason : Using CActiveScheduler::Start() can mean that something 
       
  2834 # asynchronous is being made synchronous. Instead, use active 
       
  2835 # objects correctly in an asynchronous way.
       
  2836 #
       
  2837 # #################################################################
       
  2838 
       
  2839 script = CScript("activestart")
       
  2840 script.iReString = "CActiveScheduler::Start"
       
  2841 script.iFileExts = ["cpp"]
       
  2842 script.iCategory = KCategoryCodeReviewGuides
       
  2843 script.iIgnore = KIgnoreCommentsAndQuotes
       
  2844 script.iSeverity = KSeverityLow
       
  2845 
       
  2846 scanner.AddScript(script)
       
  2847 
       
  2848 # #################################################################
       
  2849 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  2850 # All rights reserved.
       
  2851 # 
       
  2852 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  2853 # 
       
  2854 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  2855 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  2856 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  2857 # 
       
  2858 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  2859 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  2860 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  2861 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  2862 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  2863 #
       
  2864 # activestop.py
       
  2865 #
       
  2866 # Checks : Using CActiveScheduler::Stop.
       
  2867 #
       
  2868 # Reason : Using CActiveScheduler::Stop() can mean that something 
       
  2869 # asynchronous is being made synchronous. Instead, use active 
       
  2870 # objects correctly in an asynchronous way.
       
  2871 #
       
  2872 # #################################################################
       
  2873 
       
  2874 script = CScript("activestop")
       
  2875 script.iReString = "CActiveScheduler::Stop"
       
  2876 script.iFileExts = ["cpp"]
       
  2877 script.iCategory = KCategoryCodeReviewGuides
       
  2878 script.iIgnore = KIgnoreCommentsAndQuotes
       
  2879 script.iSeverity = KSeverityLow
       
  2880 
       
  2881 scanner.AddScript(script)
       
  2882 
       
  2883 # #################################################################
       
  2884 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  2885 # All rights reserved.
       
  2886 # 
       
  2887 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  2888 # 
       
  2889 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  2890 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  2891 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  2892 # 
       
  2893 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  2894 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  2895 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  2896 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  2897 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  2898 #
       
  2899 # arraypassing.py
       
  2900 #
       
  2901 # Checks : Passing arrays by value rather than reference.
       
  2902 #
       
  2903 # Reason : Passing arrays by value causes the array to be copied 
       
  2904 # needlessly, which takes up time and memory. For efficiency, 
       
  2905 # references should be used.
       
  2906 #
       
  2907 # #################################################################
       
  2908 
       
  2909 script = CScript("arraypassing")
       
  2910 script.iReString = r"""
       
  2911     (\(|,)?         # open bracket or preceeding comma
       
  2912     \s*             # whitespace
       
  2913 	(R|C)\w*Array	# skip to a parameter type containing "R...Array..." or "C...Array..."
       
  2914     \s*				# whitespace
       
  2915 	(<.*>)?			# optional class in angle brackets
       
  2916 	\s+				# whitespace
       
  2917 	(\w+)			# parameter name
       
  2918     (=|\w|\s)*      # optional parameter initialization or whitespace
       
  2919     (\)|,)			# close bracket or trailing comma
       
  2920 	"""
       
  2921 script.iFileExts = ["cpp"]
       
  2922 script.iCategory = KCategoryPerformance
       
  2923 script.iIgnore = KIgnoreCommentsAndQuotes
       
  2924 script.iSeverity = KSeverityMedium
       
  2925 script.iCompare = DefaultFuncParamCompare
       
  2926 
       
  2927 scanner.AddScript(script)
       
  2928 
       
  2929 # #################################################################
       
  2930 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  2931 # All rights reserved.
       
  2932 # 
       
  2933 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  2934 # 
       
  2935 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  2936 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  2937 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  2938 # 
       
  2939 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  2940 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  2941 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  2942 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  2943 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  2944 #
       
  2945 # arrayptrcleanup.py
       
  2946 #
       
  2947 # Checks : Using local CArrayPtr classes without cleanup items.
       
  2948 #
       
  2949 # Reason : It is not enough to push a local CArrayPtr class onto 
       
  2950 # the cleanup stack. A TCleanupItem and callback function must be 
       
  2951 # used to avoid leaking the elements.
       
  2952 #
       
  2953 # #################################################################
       
  2954 
       
  2955 script = CScript("arrayptrcleanup")
       
  2956 script.iReString = r"""
       
  2957 	\s+
       
  2958 	(
       
  2959 	\w+
       
  2960 	)
       
  2961 	\s*
       
  2962 	=
       
  2963 	\s*
       
  2964 	new
       
  2965 	\s*
       
  2966 	\(
       
  2967 	\s*
       
  2968 	ELeave
       
  2969 	\s*
       
  2970 	\)
       
  2971 	\s*
       
  2972 	CArrayPtr
       
  2973 	"""
       
  2974 script.iFileExts = ["cpp"]
       
  2975 script.iCategory = KCategoryCodeReviewGuides
       
  2976 script.iIgnore = KIgnoreCommentsAndQuotes
       
  2977 script.iSeverity = KSeverityLow
       
  2978 
       
  2979 def arrayptrcleanupcompare(lines, currentline, rematch, filename):
       
  2980 	m = rematch.search(lines[currentline])
       
  2981 	if m:
       
  2982 		varName = m.group(1)
       
  2983 		if (len(varName) == 1) or (varName[0] not in "ai") or varName[1].islower():
       
  2984 			for i in range(currentline, currentline + 10):
       
  2985 				if i >= len(lines):
       
  2986 					break
       
  2987 				elif (lines[i].find("TCleanupItem") <> -1) and (lines[i].find(varName) <> -1):
       
  2988 					return 0
       
  2989 			return 1
       
  2990 	return 0
       
  2991 
       
  2992 script.iCompare = arrayptrcleanupcompare
       
  2993 scanner.AddScript(script)
       
  2994 
       
  2995 # #################################################################
       
  2996 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  2997 # All rights reserved.
       
  2998 # 
       
  2999 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3000 # 
       
  3001 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3002 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3003 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3004 # 
       
  3005 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3006 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3007 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3008 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3009 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3010 #
       
  3011 # assertdebuginvariant.py
       
  3012 #
       
  3013 # Checks : __ASSERT_DEBUG with User::Invariant.
       
  3014 #
       
  3015 # Reason : Replace __ASSERT_DEBUG(<condition>, User::Invariant()) 
       
  3016 # with ASSERT(<condition>), because it is easier to read.
       
  3017 #
       
  3018 # #################################################################
       
  3019 
       
  3020 script = CScript("assertdebuginvariant")
       
  3021 	
       
  3022 script.iReString = "__ASSERT_DEBUG\s*\(\w*\s*,\s*User::Invariant\s*\(\s*\)\s*\)\s*;"
       
  3023 script.iFileExts = ["h", "cpp", ".inl", "c"]
       
  3024 script.iCategory = KCategoryCodingStandards
       
  3025 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3026 script.iSeverity = KSeverityLow
       
  3027 
       
  3028 scanner.AddScript(script)
       
  3029 
       
  3030 # #################################################################
       
  3031 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3032 # All rights reserved.
       
  3033 # 
       
  3034 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3035 # 
       
  3036 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3037 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3038 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3039 # 
       
  3040 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3041 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3042 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3043 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3044 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3045 #
       
  3046 # baddefines.py
       
  3047 #
       
  3048 # Checks : Lowercase definition names.
       
  3049 #
       
  3050 # Reason : Badly-named definitions makes the code harder to 
       
  3051 # maintain and can lead to defects.
       
  3052 #
       
  3053 # #################################################################
       
  3054 
       
  3055 script = CScript("baddefines")
       
  3056 script.iReString = r"""
       
  3057 	\#define
       
  3058 	\s+					# at least one whitespace char
       
  3059 	[A-Z0-9_]*[a-z]+	# find a lower case character
       
  3060 	"""
       
  3061 script.iFileExts = ["h", "cpp"]
       
  3062 script.iCategory = KCategoryCodingStandards
       
  3063 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3064 script.iSeverity = KSeverityLow
       
  3065 
       
  3066 scanner.AddScript(script)
       
  3067 
       
  3068 # #################################################################
       
  3069 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3070 # All rights reserved.
       
  3071 # 
       
  3072 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3073 # 
       
  3074 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3075 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3076 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3077 # 
       
  3078 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3079 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3080 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3081 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3082 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3083 #
       
  3084 # baseconstruct.py
       
  3085 #
       
  3086 # Checks : Leaving function called before BaseConstructL().
       
  3087 #
       
  3088 # Reason : If a leave occurs before BaseConstructL() is called, 
       
  3089 # the system can panic because it is trying to clean up an 
       
  3090 # application that has not been fully initialised.
       
  3091 #
       
  3092 # #################################################################
       
  3093 
       
  3094 script = CScript("baseconstruct")
       
  3095 script.iReString = r"""
       
  3096 	^
       
  3097 	\s*
       
  3098 	BaseConstructL
       
  3099 	\s*
       
  3100 	\(
       
  3101 	"""
       
  3102 script.iFileExts = ["cpp"]
       
  3103 script.iCategory = KCategoryCodeReviewGuides
       
  3104 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3105 script.iSeverity = KSeverityLow
       
  3106 
       
  3107 def baseconstructcompare(lines, currentline, rematch, filename):
       
  3108 	m = rematch.search(lines[currentline])
       
  3109 	if m:
       
  3110 		if scanner.iCurrentMethodStart >= 0:
       
  3111 			for i in range(scanner.iCurrentMethodStart, currentline):
       
  3112 				line = lines[i]
       
  3113 				n = KReLeavingLine.search(line)
       
  3114 				if n:
       
  3115 					return 1
       
  3116 	return 0
       
  3117 
       
  3118 script.iCompare = baseconstructcompare
       
  3119 scanner.AddScript(script)
       
  3120 
       
  3121 # #################################################################
       
  3122 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3123 # All rights reserved.
       
  3124 # 
       
  3125 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3126 # 
       
  3127 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3128 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3129 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3130 # 
       
  3131 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3132 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3133 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3134 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3135 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3136 #
       
  3137 # callActiveObjectWithoutCheckingOrStopping.py
       
  3138 #
       
  3139 # Checks : Active object called without checking whether it is 
       
  3140 # active or canceling it first.
       
  3141 #
       
  3142 # Reason : If an active object is started twice, a panic occurs. 
       
  3143 # CodeScanner picks out places where there is a call to a Start(), 
       
  3144 # Queue(), or After() function on a member variable, without a 
       
  3145 # previous call to IsActive(), Cancel(), or Stop(). In general, 
       
  3146 # if starting a timer, there should at least be a call to IsActive() 
       
  3147 # to ensure that the timer is not already running.
       
  3148 #
       
  3149 # #################################################################
       
  3150 
       
  3151 script = CScript("callActiveObjectWithoutCheckingOrStopping")
       
  3152 script.iReString = r"""\("""
       
  3153 script.iFileExts = ["cpp"]
       
  3154 script.iCategory = KCategoryCodeReviewGuides
       
  3155 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3156 script.iSeverity = KSeverityLow
       
  3157 
       
  3158 activeObjectIsActive = re.compile("""
       
  3159 	(\.|->)
       
  3160 	\s*
       
  3161 	IsActive
       
  3162 	\s*
       
  3163 	\(
       
  3164 	\s*
       
  3165 	\)
       
  3166 	""", re.VERBOSE)
       
  3167 
       
  3168 activeObjectCancel = re.compile("""
       
  3169 	(\.|->)
       
  3170 	\s*
       
  3171 	Cancel
       
  3172 	\s*
       
  3173 	\(
       
  3174 	\s*
       
  3175 	\)
       
  3176 	""", re.VERBOSE)
       
  3177 
       
  3178 activeObjectStop = re.compile("""
       
  3179 	(\.|->)
       
  3180 	\s*
       
  3181 	Stop
       
  3182 	\s*
       
  3183 	\(
       
  3184 	\s*
       
  3185 	\)
       
  3186 	""", re.VERBOSE)
       
  3187 
       
  3188 activeObjectCreate = re.compile("""
       
  3189 	=
       
  3190 	\s*
       
  3191 	\w+
       
  3192 	::
       
  3193 	New
       
  3194 	\w*
       
  3195 	\s*
       
  3196 	\(
       
  3197 	""", re.VERBOSE)
       
  3198 
       
  3199 activeObjectCreate2 = re.compile("""
       
  3200 	=
       
  3201 	\s*
       
  3202 	new
       
  3203 	\s*
       
  3204 	\(
       
  3205 	\s*
       
  3206 	ELeave
       
  3207 	\s*
       
  3208 	\)
       
  3209 	""", re.VERBOSE)
       
  3210 
       
  3211 activeObjectStart = re.compile("""
       
  3212 	(\.|->)
       
  3213 	\s*
       
  3214 	Start
       
  3215 	\s*
       
  3216 	\(
       
  3217 	""", re.VERBOSE)
       
  3218 
       
  3219 activeObjectQueue = re.compile("""
       
  3220 	(\.|->)
       
  3221 	\s*
       
  3222 	Queue
       
  3223 	\s*
       
  3224 	\(
       
  3225 	""", re.VERBOSE)
       
  3226 
       
  3227 activeObjectAfter = re.compile("""
       
  3228 	(\.|->)
       
  3229 	\s*
       
  3230 	After
       
  3231 	\s*
       
  3232 	\(
       
  3233 	""", re.VERBOSE)
       
  3234 
       
  3235 # RTimer::After() takes 2 arguments
       
  3236 rtimerObjectAfter = re.compile("""
       
  3237 	(\.|->)
       
  3238 	\s*
       
  3239 	After
       
  3240 	\s*
       
  3241 	\(
       
  3242 	\s*
       
  3243 	\w+			# first argument
       
  3244 	\s*
       
  3245 	,
       
  3246 	""", re.VERBOSE)
       
  3247 
       
  3248 # Non-active types with After(), Queue() or Start() function
       
  3249 KNonActiveTypes = {
       
  3250 	"KAnimation"					: "Animation",
       
  3251 	"KAnimator"						: "Animator",
       
  3252 	"KClockSourcePeriodicUtility"	: "ClockSourcePeriodicUtility",
       
  3253 	"KCodecWrapper"					: "CodecWrapper",
       
  3254 	"KCommTimer"					: "CommTimer",
       
  3255 	"KEmbeddedStore"				: "EmbeddedStore",
       
  3256 	"KFormulaTextLexer"				: "FormulaTextLexer",
       
  3257 	"KObexServer"					: "ObexServer",
       
  3258 	"KSpriteAnimation"				: "SpriteAnimation",
       
  3259 	"KRConnection"					: "RConnection",
       
  3260 	"KRSubConnection"				: "RSubConnection",
       
  3261 	"KRTest"						: "RTest",
       
  3262 	"KRTimer"						: "RTimer",
       
  3263 	"KValidityPeriod"				: "ValidityPeriod",
       
  3264 	"KVideoPlayHwDevice"			: "VideoPlayHwDevice",
       
  3265 	"KVideoRecordHwDevice"			: "VideoRecordHwDevice",
       
  3266 }
       
  3267 
       
  3268 def isNonActiveObject(variable):
       
  3269 	for name, value in KNonActiveTypes.items():
       
  3270 		if (variable.lower().find(value.lower()) <> -1):
       
  3271 			return True
       
  3272 	return False
       
  3273 
       
  3274 def activeObjectCompare(lines, currentline, rematch, filename):
       
  3275 	line = lines[currentline]
       
  3276 	m = rematch.search(line)
       
  3277 
       
  3278 	if m:
       
  3279 		if (scanner.iCurrentMethodName == "Start"):
       
  3280 			return 0
       
  3281 		if (scanner.iCurrentMethodName == "Queue"):
       
  3282 			return 0
       
  3283 		if (scanner.iCurrentMethodName == "After"):
       
  3284 			return 0
       
  3285 
       
  3286 		checkForIsActive = 0	
       
  3287 		if (activeObjectStart.search(line)):
       
  3288 			checkForIsActive = 1
       
  3289 		if (activeObjectQueue.search(line)):
       
  3290 			checkForIsActive = 1
       
  3291 		if (activeObjectAfter.search(line)):
       
  3292 			# make sure we are not dealing with RTimer::After()
       
  3293 			if (not rtimerObjectAfter.search(line)):
       
  3294 				checkForIsActive = 1
       
  3295 		if (checkForIsActive == 1):
       
  3296 			varEnd = line.find("->")
       
  3297 			if (varEnd < 0):
       
  3298 				varEnd = line.find(".")
       
  3299 			if (varEnd < 0):
       
  3300 				return 0
       
  3301 			
       
  3302 			variable = TrimVariableName(line[:varEnd])
       
  3303 			if (len(variable) == 0):
       
  3304 				return 0
       
  3305 
       
  3306 			# if a local variable then unlikely to have been started already
       
  3307 			if (len(variable) > 2):
       
  3308 				if (variable[0] != 'i'):
       
  3309 					return 0
       
  3310 				else:
       
  3311 					if (variable[1] < 'A') or (variable[1] > 'Z'):
       
  3312 						return 0
       
  3313 
       
  3314 			# ignore non-active object
       
  3315 			if isNonActiveObject(variable):
       
  3316 				return 0
       
  3317 
       
  3318 			i = currentline
       
  3319 			while (i > scanner.iCurrentMethodStart):
       
  3320 				line = lines[i]
       
  3321 				varPos = line.find(variable)
       
  3322 				if (varPos >= 0):
       
  3323 					cutLine = line[varPos:]
       
  3324 					if (activeObjectIsActive.search(cutLine)):
       
  3325 						return 0
       
  3326 					if (activeObjectCancel.search(cutLine)):
       
  3327 						return 0
       
  3328 					if (activeObjectStop.search(cutLine)):
       
  3329 						return 0
       
  3330 					if (activeObjectCreate.search(cutLine)):
       
  3331 						return 0
       
  3332 					if (activeObjectCreate2.search(cutLine)):
       
  3333 						return 0
       
  3334 				i = i - 1
       
  3335 			return 1
       
  3336 
       
  3337 	return 0
       
  3338 
       
  3339 script.iCompare	= activeObjectCompare
       
  3340 scanner.AddScript(script)
       
  3341 
       
  3342 # #################################################################
       
  3343 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3344 # All rights reserved.
       
  3345 # 
       
  3346 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3347 # 
       
  3348 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3349 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3350 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3351 # 
       
  3352 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3353 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3354 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3355 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3356 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3357 #
       
  3358 # changenotification.py
       
  3359 #
       
  3360 # Checks : Using RSAVarChangeNotify to see System Agent changes.
       
  3361 #
       
  3362 # Reason : When watching for System Agent changes, use RSystemAgent 
       
  3363 # rather than RSAVarChangeNotify, which can fail.
       
  3364 #
       
  3365 # #################################################################
       
  3366 
       
  3367 script = CScript("changenotification")
       
  3368 script.iReString = "RSAVarChangeNotify"
       
  3369 script.iFileExts = ["cpp", "h", "inl", "hpp"]
       
  3370 script.iCategory = KCategoryCodeReviewGuides
       
  3371 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3372 script.iSeverity = KSeverityLow
       
  3373 
       
  3374 scanner.AddScript(script)
       
  3375 
       
  3376 # #################################################################
       
  3377 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3378 # All rights reserved.
       
  3379 # 
       
  3380 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3381 # 
       
  3382 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3383 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3384 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3385 # 
       
  3386 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3387 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3388 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3389 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3390 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3391 #
       
  3392 # cleanup.py
       
  3393 #
       
  3394 # Checks : CleanupStack::Pop(AndDestroy) parameters.
       
  3395 #
       
  3396 # Reason : These functions should be called with explicit variable 
       
  3397 # parameters to avoid misalignment.
       
  3398 #
       
  3399 # #################################################################
       
  3400 
       
  3401 script = CScript("cleanup")
       
  3402 script.iReString = r"""
       
  3403 	CleanupStack::Pop(AndDestroy)?
       
  3404 	\s*
       
  3405 	\(
       
  3406 	\s*
       
  3407 	([0-9]+\s*\)|\))
       
  3408 	"""
       
  3409 script.iFileExts = ["cpp"]
       
  3410 script.iCategory = KCategoryCodingStandards
       
  3411 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3412 script.iSeverity = KSeverityLow
       
  3413 
       
  3414 scanner.AddScript(script)
       
  3415 
       
  3416 # #################################################################
       
  3417 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3418 # All rights reserved.
       
  3419 # 
       
  3420 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3421 # 
       
  3422 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3423 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3424 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3425 # 
       
  3426 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3427 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3428 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3429 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3430 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3431 #
       
  3432 # commentcode.py
       
  3433 #
       
  3434 # Checks : Commented-out code.
       
  3435 #
       
  3436 # Reason : Instances of code that are commented out make the code 
       
  3437 # hard to maintain and to interpret clearly. The commented out code 
       
  3438 # should be removed. Any requirement to rediscover old code 
       
  3439 # should be made through source control and not by trawling through 
       
  3440 # commented-out code.
       
  3441 #
       
  3442 # #################################################################
       
  3443 
       
  3444 script = CScript("commentcode")
       
  3445 script.iReString = r"""
       
  3446 	/(/|\*)			# "//" or "/*"
       
  3447 	(.*);			# skip to semicolon
       
  3448 	\s*				# optional whitespace
       
  3449 	(//.*)?			# optional comment
       
  3450 	$				# end of line
       
  3451 	"""
       
  3452 script.iFileExts = ["h","cpp"]
       
  3453 script.iCategory = KCategoryCodeReviewGuides
       
  3454 script.iIgnore = KIgnoreQuotes
       
  3455 script.iSeverity = KSeverityLow
       
  3456 
       
  3457 reDeclaration = re.compile("""
       
  3458 	\s*
       
  3459 	[A-Z][\w<>*&]+
       
  3460 	\s+
       
  3461 	\w+
       
  3462 	\s*
       
  3463 	""", re.VERBOSE)
       
  3464 
       
  3465 def commentcodecompare(lines, currentline, rematch, filename):
       
  3466 	m = rematch.search(lines[currentline])
       
  3467 	if m:
       
  3468 		if ((m.group(2)[-1:] == ")") or (m.group(2).find("=") <> -1)) or (reDeclaration.match(m.group(2))):
       
  3469 			line = lines[currentline]
       
  3470 			i = 0
       
  3471 			inCommentBlock = 0
       
  3472 
       
  3473 			while i < len(line):
       
  3474 				if not inCommentBlock:
       
  3475 					if (line[i] == "/"):
       
  3476 						if (line[i + 1] == "/"):
       
  3477 							return 1
       
  3478 						elif (line[i + 1] == "*"):
       
  3479 							inCommentBlock = 1
       
  3480 							i += 2
       
  3481 							continue
       
  3482 				else:
       
  3483 					endIndex = line[i:].find("*/")
       
  3484 					if (endIndex <> -1):
       
  3485 						inCommentBlock = 0
       
  3486 						if line[i:i + endIndex + 2].find(";") <> -1:
       
  3487 							return 1
       
  3488 						i += endIndex + 2
       
  3489 						continue
       
  3490 					else:
       
  3491 						return 1
       
  3492 				
       
  3493 				i += 1
       
  3494 		
       
  3495 	return 0
       
  3496 
       
  3497 script.iCompare = commentcodecompare
       
  3498 scanner.AddScript(script)
       
  3499 
       
  3500 
       
  3501 # #################################################################
       
  3502 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3503 # All rights reserved.
       
  3504 # 
       
  3505 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3506 # 
       
  3507 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3508 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3509 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3510 # 
       
  3511 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3512 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3513 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3514 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3515 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3516 #
       
  3517 # CommonFunctions.py
       
  3518 #
       
  3519 # Some commonly used functions.
       
  3520 #
       
  3521 # #################################################################
       
  3522 
       
  3523 KReStringLeavingLine = "(\w*[a-z]\w*L(C*|D|P))\s*\(|ELeave|User::Leave|tream\s+<<|tream\s+>>"
       
  3524 
       
  3525 KReLeavingLine = re.compile(KReStringLeavingLine, re.VERBOSE)
       
  3526 
       
  3527 def isNonAlpha(char):
       
  3528 	if (char >= 'A'):
       
  3529 		if (char <= 'Z'):
       
  3530 			return 0
       
  3531 	if (char >= 'a'):
       
  3532 		if (char <= 'z'):
       
  3533 			return 0
       
  3534 	if (char >= '0'):
       
  3535 		if (char <= '9'):
       
  3536 			return 0
       
  3537 	return 1
       
  3538 
       
  3539 def TrimVariableName(var):
       
  3540 	while (len(var) > 0) and (isNonAlpha(var[0])):
       
  3541 		var = var[1:len(var)]
       
  3542 	while (len(var) > 0) and (isNonAlpha(var[len(var)-1])):
       
  3543 		var = var[0:len(var)-1]
       
  3544 
       
  3545 	if (len(var) > 0):
       
  3546 		spaceIndex = var.find(" ")
       
  3547 		if (spaceIndex <> -1):
       
  3548 			cutVar = var[spaceIndex:]
       
  3549 			return TrimVariableName(cutVar)
       
  3550 	return var
       
  3551 
       
  3552 def GetBracketDepth(lines, currentline):
       
  3553 	i = scanner.iCurrentMethodStart
       
  3554 	bracketdepth = 0
       
  3555 	while (i < currentline):
       
  3556 		thisline = lines[i]
       
  3557 		commentBegin = thisline.find("//")
       
  3558 		if (commentBegin != -1):
       
  3559 			thisline = thisline[:commentBegin]
       
  3560 		bracketdepth += thisline.count("{")
       
  3561 		bracketdepth -= thisline.count("}")
       
  3562 		i = i + 1
       
  3563 
       
  3564 	return bracketdepth	
       
  3565 
       
  3566 varDeclaration = re.compile("""
       
  3567 	\s*					# whitespace
       
  3568 	([A-Z]\w*)			# variable type
       
  3569 	\s*             	# whitespace
       
  3570 	(<.*>)?				# optional class in angle brackets
       
  3571 	\s*[\*&\s]\s*		# optional "*" or "&" plus at least one whitespace char
       
  3572 	(\w+)				# variable name
       
  3573 	\s*             	# whitespace
       
  3574 	[;\(=]				# ";" or "(" or "="
       
  3575 	""", re.VERBOSE)
       
  3576 
       
  3577 def GetLocalVariableType(lines, currentline, varname):
       
  3578 	# skip non-local object
       
  3579 	if (len(varname) > 2):
       
  3580 		if (varname[0] == 'i'):
       
  3581 			return ""
       
  3582 
       
  3583 	# lookup type of local variable or function parameter
       
  3584 	if (scanner.iCurrentMethodStart <> -1):
       
  3585 		i = scanner.iCurrentMethodStart
       
  3586 		while (i < currentline):
       
  3587 			line = lines[i]
       
  3588 			if (line.find(varname) <> -1):
       
  3589 				# look up variable declaration
       
  3590 				m = varDeclaration.search(line)
       
  3591 				if m:
       
  3592 					# return variable type
       
  3593 					return m.group(1)
       
  3594 			i = i + 1
       
  3595 	return ""
       
  3596 
       
  3597 # #################################################################
       
  3598 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3599 # All rights reserved.
       
  3600 # 
       
  3601 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3602 # 
       
  3603 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3604 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3605 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3606 # 
       
  3607 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3608 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3609 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3610 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3611 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3612 #
       
  3613 # connect.py
       
  3614 #
       
  3615 # Checks : Ignoring Connect() return value.
       
  3616 #
       
  3617 # Reason : Ignoring the error returned from Connect() functions 
       
  3618 # means that if the Connect() function fails due to OOM or 
       
  3619 # other problems, the next access to the resource will panic.
       
  3620 #
       
  3621 # #################################################################
       
  3622 
       
  3623 script = CScript("connect")
       
  3624 script.iReString = r"""
       
  3625 	^\s*				# start of line plus optional whitespace
       
  3626 	\w+					# variable name
       
  3627 	(\.|->)				# "." or "->"
       
  3628 	Connect\s*\(\s*\)
       
  3629 	\s*;
       
  3630 	"""
       
  3631 script.iFileExts = ["cpp"]
       
  3632 script.iCategory = KCategoryCanPanic
       
  3633 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3634 script.iSeverity = KSeverityHigh
       
  3635 
       
  3636 scanner.AddScript(script)
       
  3637 
       
  3638 
       
  3639 
       
  3640 
       
  3641 # #################################################################
       
  3642 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3643 # All rights reserved.
       
  3644 # 
       
  3645 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3646 # 
       
  3647 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3648 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3649 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3650 # 
       
  3651 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3652 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3653 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3654 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3655 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3656 #
       
  3657 # ConnectAndDontCloseMemberVariable.py
       
  3658 #
       
  3659 # Checks : Calling Connect() or Open() on a member variable without 
       
  3660 # calling Close() in the destructor.
       
  3661 #
       
  3662 # Reason : If Connect() or Open() is called on any member variable, 
       
  3663 # then Close() must be called in the destructor.
       
  3664 #
       
  3665 # #################################################################
       
  3666 
       
  3667 script = CScript("ConnectAndDontCloseMemberVariable")
       
  3668 script.iReString = r"""
       
  3669 	^\s*				# start of line plus optional whitespace
       
  3670 	i[A-Z]\w+			# member variable name
       
  3671 	(\.|->)				# "." or "->"
       
  3672 	(Connect|Open)
       
  3673 	\s*\(\s*\)
       
  3674 	\s*;
       
  3675 	"""
       
  3676 script.iFileExts = ["cpp"]
       
  3677 script.iCategory = KCategoryWrongFunctionality
       
  3678 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3679 script.iSeverity = KSeverityMedium
       
  3680 
       
  3681 ConnectAndDontCloseLeavingFunction = re.compile("""
       
  3682 	[A-Za-z0-9]+
       
  3683 	L
       
  3684 	(C|D|P)*
       
  3685 	\s*
       
  3686 	\(
       
  3687 	""", re.VERBOSE)
       
  3688 
       
  3689 def ConnectNotCloseCompare(lines, currentline, rematch, filename):
       
  3690 	line = lines[currentline]
       
  3691 	m = rematch.search(line)
       
  3692 
       
  3693 	if m:
       
  3694 		# get the variable name, between the '*' and the '='
       
  3695 		startindex = line.find("i")
       
  3696 		if (startindex == -1):
       
  3697 			startindex = 0
       
  3698 		endindex = line.find("Connect")
       
  3699 		if (endindex == -1):
       
  3700 			endindex = line.find("Open")
       
  3701 		variable = line[startindex:endindex]
       
  3702 		if (len(variable) < 1):
       
  3703 			return 0
       
  3704 		variable = TrimVariableName(variable)
       
  3705 
       
  3706 		# see if variable is closed within this function before a Leave
       
  3707 		i = currentline
       
  3708 		bracketdepth = GetBracketDepth(lines, i)
       
  3709 		while (i < len(lines)) and (bracketdepth  > 0):
       
  3710 			line = lines[i]
       
  3711 			if (line.find(variable) >= 0):
       
  3712 				if (line.find("Close") >= 0):
       
  3713 					return 0
       
  3714 
       
  3715 			bracketdepth += line.count("{")
       
  3716 			bracketdepth -= line.count("}")
       
  3717 
       
  3718 			if (line.find("User::Leave") >= 0):
       
  3719 				bracketdepth = 0
       
  3720 			if (line.find("ELeave") >= 0):
       
  3721 				bracketdepth = 0
       
  3722 			if (ConnectAndDontCloseLeavingFunction.search(line)):
       
  3723 				bracketdepth = 0
       
  3724 				
       
  3725 			i = i + 1
       
  3726 		
       
  3727 		# look for destructor and see if variable is closed there
       
  3728 		stringToFind = "~" + scanner.iCurrentClassName
       
  3729 		i = 1
       
  3730 		foundDestructor = 0
       
  3731 		bracketdepth = 0
       
  3732 		while (i < len(lines)):
       
  3733 			thisLine = lines[i]
       
  3734 			if (thisLine.find(stringToFind) >= 0) and (foundDestructor == 0):
       
  3735 				while (i < len(lines)) and (foundDestructor == 0):
       
  3736 					thisLine = lines[i]
       
  3737 					if (thisLine.find('{') >= 0):
       
  3738 						foundDestructor = 1
       
  3739 					else:
       
  3740 						i = i + 1
       
  3741 
       
  3742 			if (foundDestructor):
       
  3743 				bracketdepth += thisLine.count("{")
       
  3744 				bracketdepth -= thisLine.count("}")
       
  3745 				if (bracketdepth == 0):
       
  3746 					return 1
       
  3747 				
       
  3748 				if (thisLine.find(variable) >= 0):
       
  3749 					if (thisLine.find("Close") >= 0):
       
  3750 						return 0
       
  3751 			i = i + 1
       
  3752 
       
  3753 		if (foundDestructor):
       
  3754 			return 1
       
  3755 	return 0
       
  3756 
       
  3757 script.iCompare	= ConnectNotCloseCompare
       
  3758 scanner.AddScript(script)
       
  3759 
       
  3760 # #################################################################
       
  3761 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3762 # All rights reserved.
       
  3763 # 
       
  3764 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3765 # 
       
  3766 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3767 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3768 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3769 # 
       
  3770 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3771 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3772 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3773 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3774 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3775 #
       
  3776 # constnames.py
       
  3777 #
       
  3778 # Checks : Badly-named constants.
       
  3779 #
       
  3780 # Reason : Badly-named constant will make the source code harder to 
       
  3781 # maintain and make defects more likely.
       
  3782 #
       
  3783 # #################################################################
       
  3784 
       
  3785 script = CScript("constnames")
       
  3786 script.iReString = r"""
       
  3787 	^
       
  3788 	\s*
       
  3789 	const
       
  3790 	\s+
       
  3791 	\w+		# type
       
  3792 	\s*
       
  3793 	[\*&]?	# reference or pointer
       
  3794 	\s*
       
  3795 	[^K\s]	# name initial letter
       
  3796 	\w+		# name
       
  3797 	\s*
       
  3798 	=
       
  3799 	[^()]*
       
  3800 	;
       
  3801 	"""
       
  3802 script.iFileExts = ["h", "cpp"]
       
  3803 script.iCategory = KCategoryCodingStandards
       
  3804 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3805 script.iSeverity = KSeverityLow
       
  3806 
       
  3807 def constnamescompare(lines, currentline, rematch, filename):
       
  3808 	if (scanner.iCurrentMethodName == ""):
       
  3809 		if rematch.search(lines[currentline]):
       
  3810 			return 1
       
  3811 
       
  3812 	return 0
       
  3813 
       
  3814 script.iCompare = constnamescompare
       
  3815 scanner.AddScript(script)
       
  3816 
       
  3817 # #################################################################
       
  3818 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3819 # All rights reserved.
       
  3820 # 
       
  3821 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3822 # 
       
  3823 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3824 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3825 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3826 # 
       
  3827 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3828 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3829 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3830 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3831 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3832 #
       
  3833 # consttdescptr.py
       
  3834 #
       
  3835 # Checks : Const descriptor pointer as argument.
       
  3836 #
       
  3837 # Reason : Use "const TDesC&" instead of "const TDesC*".
       
  3838 #
       
  3839 # #################################################################
       
  3840 
       
  3841 script = CScript("consttdescptr")
       
  3842 script.iReString = r"""
       
  3843     (\(|,)?        # open bracket or preceeding comma
       
  3844     \s*            # whitespace
       
  3845 	const
       
  3846     \s+            # whitespace
       
  3847 	TDesC
       
  3848     \s*            # whitespace
       
  3849 	\*
       
  3850     \s*            # whitespace
       
  3851     (=|\w|\s)*     # optional parameter name, parameter initialization or whitespace
       
  3852     (\)|,)         # close bracket or trailing comma
       
  3853 	"""
       
  3854 script.iFileExts = ["h"]
       
  3855 script.iCategory = KCategoryCodingStandards
       
  3856 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3857 script.iSeverity = KSeverityLow
       
  3858 
       
  3859 scanner.AddScript(script)
       
  3860 
       
  3861 # #################################################################
       
  3862 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3863 # All rights reserved.
       
  3864 # 
       
  3865 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3866 # 
       
  3867 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3868 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3869 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3870 # 
       
  3871 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3872 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3873 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3874 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3875 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3876 #
       
  3877 # controlornull.py
       
  3878 #
       
  3879 # Checks : Accessing return value of ControlOrNull().
       
  3880 #
       
  3881 # Reason : The return value might be NULL, so it should be checked 
       
  3882 # before access.
       
  3883 #
       
  3884 # #################################################################
       
  3885 
       
  3886 script = CScript("controlornull")
       
  3887 script.iReString = "(\.|->)ControlOrNull\(.*\)->"
       
  3888 script.iFileExts = ["cpp"]
       
  3889 script.iCategory = KCategoryCanPanic
       
  3890 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3891 script.iSeverity = KSeverityHigh
       
  3892 
       
  3893 scanner.AddScript(script)
       
  3894 
       
  3895 # #################################################################
       
  3896 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3897 # All rights reserved.
       
  3898 # 
       
  3899 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3900 # 
       
  3901 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3902 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3903 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3904 # 
       
  3905 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3906 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3907 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3908 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3909 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3910 #
       
  3911 # crepository.py
       
  3912 #
       
  3913 # Checks : Ignoring CRepository::get() return value.
       
  3914 #
       
  3915 # Reason : Independent application cannot assume that the 
       
  3916 # Central Repository is set up fully. This means the return value 
       
  3917 # of CRepository::get() cannot be ignored.
       
  3918 #
       
  3919 # #################################################################
       
  3920 
       
  3921 script = CScript("crepository")
       
  3922 script.iReString = r"""
       
  3923     ^\s*
       
  3924     (\w+)
       
  3925     (\.|->)
       
  3926     (G|g)et\s*\(
       
  3927     """
       
  3928 script.iFileExts = ["cpp"]
       
  3929 script.iCategory = KCategoryOther
       
  3930 script.iIgnore = KIgnoreCommentsAndQuotes
       
  3931 script.iSeverity = KSeverityLow
       
  3932 
       
  3933 reCRepositoryAssignStr = "=\s+$"
       
  3934 reCRepositoryAssign = re.compile(reCRepositoryAssignStr, re.IGNORECASE)
       
  3935 
       
  3936 reCRepositoryConditionalStr = "(if|while)\s+\($"
       
  3937 reCRepositoryConditional = re.compile(reCRepositoryConditionalStr, re.IGNORECASE)
       
  3938 
       
  3939 def crepositorycompare(lines, currentline, rematch, filename):
       
  3940     m = rematch.search(lines[currentline])
       
  3941     if m:
       
  3942         objectName = m.group(1)
       
  3943         objectType = GetLocalVariableType(lines, currentline, objectName)
       
  3944         if (objectType.find("CRepository") == -1):
       
  3945             return 0
       
  3946 
       
  3947         # look for handler of CRepository::get() return value on a different line
       
  3948         i = currentline - 1
       
  3949         if (i > 0) and (i >= scanner.iCurrentMethodStart):
       
  3950             line = lines[i]
       
  3951             bracketCount = line.count("(") - line.count(")")
       
  3952             if (bracketCount > 0):
       
  3953                 return 0
       
  3954             r1 = reCRepositoryAssign.search(line)
       
  3955             if r1:
       
  3956                 return 0
       
  3957             r2 = reCRepositoryConditional.search(line)
       
  3958             if r2:
       
  3959                 return 0
       
  3960         return 1
       
  3961     else:
       
  3962         return 0
       
  3963 
       
  3964 script.iCompare = crepositorycompare
       
  3965 scanner.AddScript(script)
       
  3966 
       
  3967 # #################################################################
       
  3968 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  3969 # All rights reserved.
       
  3970 # 
       
  3971 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  3972 # 
       
  3973 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  3974 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  3975 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  3976 # 
       
  3977 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  3978 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  3979 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  3980 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  3981 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  3982 #
       
  3983 # ctltargettype.py
       
  3984 #
       
  3985 # Checks : Use of targettype ctl.
       
  3986 #
       
  3987 # Reason : The ctl target type should not be used. Instead, use DLL 
       
  3988 # and explicitly refer to the Control Panel's DEF file. 
       
  3989 # Note: Code that causes this issue only needs attention if it is 
       
  3990 # found in code developed for Nokia Series 90 code that has extra 
       
  3991 # exports for resetting the Control Panel item's data.
       
  3992 #
       
  3993 # #################################################################
       
  3994 
       
  3995 script = CScript("ctltargettype")
       
  3996 script.iReString = r"""
       
  3997 	^\s*
       
  3998 	[Tt][Aa][Rr][Gg][Ee][Tt][Tt][Yy][Pp][Ee]
       
  3999 	\s+
       
  4000 	"""
       
  4001 script.iFileExts = ["mmp"]
       
  4002 script.iCategory = KCategoryWrongFunctionality
       
  4003 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4004 script.iSeverity = KSeverityMedium
       
  4005 
       
  4006 reTargetPath = re.compile("""
       
  4007 	^\s*
       
  4008 	[Tt][Aa][Rr][Gg][Ee][Tt][Pp][Aa][Tt][Hh]
       
  4009 	\s+
       
  4010 	""", re.VERBOSE)
       
  4011 
       
  4012 reDefFile = re.compile("""
       
  4013 	^\s*
       
  4014 	[Dd][Ee][Ff][Ff][Ii][Ll][Ee]
       
  4015 	""", re.VERBOSE)
       
  4016 	
       
  4017 def ctltargettypecompare(lines, currentline, rematch, filename):
       
  4018 	m = rematch.search(lines[currentline])
       
  4019 	if m:
       
  4020 		if lines[currentline].upper().find("CTL") <> -1:
       
  4021 			return 1
       
  4022 
       
  4023 		if lines[currentline].upper().find("DLL") <> -1:
       
  4024 			foundDefFile = 0
       
  4025 			foundSystemControls = 0
       
  4026 
       
  4027 			for line in lines:
       
  4028 				if reTargetPath.search(line):
       
  4029 					if line.upper().find("SYSTEM\\CONTROLS") <> -1:
       
  4030 						foundSystemControls = 1
       
  4031 
       
  4032 				if reDefFile.search(line):
       
  4033 					if line.upper().find("CTRL.DEF") <> -1:
       
  4034 						foundDefFile = 1
       
  4035 
       
  4036 				if (foundSystemControls == 1) and (foundDefFile == 1):
       
  4037 					break
       
  4038 		
       
  4039 			if (foundSystemControls == 1) and (foundDefFile <> 1):
       
  4040 				return 1
       
  4041 			
       
  4042 	return 0
       
  4043 
       
  4044 script.iCompare	= ctltargettypecompare
       
  4045 scanner.AddScript(script)
       
  4046 
       
  4047 # #################################################################
       
  4048 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4049 # All rights reserved.
       
  4050 # 
       
  4051 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4052 # 
       
  4053 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4054 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4055 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4056 # 
       
  4057 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4058 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4059 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4060 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4061 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4062 #
       
  4063 # customizableicons.py
       
  4064 #
       
  4065 # Checks : Use of customizable icons.
       
  4066 #
       
  4067 # Reason : Due to device customization requirements, independent 
       
  4068 # application must not remove any customization done by the 
       
  4069 # variant team. This means independent application cannot include 
       
  4070 # customizable icons.
       
  4071 #
       
  4072 # #################################################################
       
  4073 
       
  4074 script = CScript("customizableicons")
       
  4075 script.iReString = ""
       
  4076 script.iFileExts = ["mk", "mmp"]
       
  4077 script.iCategory = KCategoryOther
       
  4078 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4079 script.iSeverity = KSeverityLow
       
  4080 
       
  4081 reCustomizableIconsStr = ""
       
  4082 scriptNode = script.ScriptConfig()
       
  4083 if (scriptNode <> None):
       
  4084     for wordNode in scriptNode.getElementsByTagName("iconsRE"):
       
  4085         reCustomizableIconsStr = wordNode.firstChild.nodeValue
       
  4086         print "Note: 'customizable icons' pattern configured as:  " + reCustomizableIconsStr
       
  4087         break
       
  4088 if len(reCustomizableIconsStr) > 0:
       
  4089     reCustomizableIcons = re.compile(reCustomizableIconsStr, re.IGNORECASE)
       
  4090 else:
       
  4091     reCustomizableIcons = None
       
  4092 
       
  4093 def customizableIconsCompare(lines, currentline, rematch, filename):
       
  4094     if reCustomizableIcons:
       
  4095         return reCustomizableIcons.search(lines[currentline])
       
  4096 
       
  4097 script.iCompare = customizableIconsCompare
       
  4098 scanner.AddScript(script)
       
  4099 
       
  4100 # #################################################################
       
  4101 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4102 # All rights reserved.
       
  4103 # 
       
  4104 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4105 # 
       
  4106 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4107 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4108 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4109 # 
       
  4110 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4111 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4112 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4113 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4114 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4115 #
       
  4116 # debugrom.py
       
  4117 #
       
  4118 # Checks : Debug components in ROM.
       
  4119 #
       
  4120 # Reason : Debug versions of components in the ROM could mean that 
       
  4121 # ROM space is being taken up with debugging information or that 
       
  4122 # logging is being put out. Release versions should be in the ROM 
       
  4123 # unless there is a good reason why they are not.
       
  4124 #
       
  4125 # #################################################################
       
  4126 
       
  4127 script = CScript("debugrom")
       
  4128 script.iReString = "DEBUG_DIR|\\udeb\\\\"
       
  4129 script.iFileExts = ["iby", "hby"]
       
  4130 script.iCategory = KCategoryPerformance
       
  4131 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4132 script.iSeverity = KSeverityMedium
       
  4133 
       
  4134 scanner.AddScript(script)
       
  4135 
       
  4136 # #################################################################
       
  4137 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4138 # All rights reserved.
       
  4139 # 
       
  4140 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4141 # 
       
  4142 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4143 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4144 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4145 # 
       
  4146 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4147 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4148 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4149 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4150 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4151 #
       
  4152 # declarename.py
       
  4153 #
       
  4154 # Checks : Use of __DECLARE_NAME.
       
  4155 #
       
  4156 # Reason : The __DECLARE_NAME macro is historical and serves 
       
  4157 # no purpose anymore and should be removed.
       
  4158 #
       
  4159 # #################################################################
       
  4160 
       
  4161 script = CScript("declarename")
       
  4162 script.iReString = r"""
       
  4163 	^\s*				# start of line plus optional whitespace
       
  4164 	__DECLARE_NAME
       
  4165 	\s*					# optional whitespace
       
  4166 	\(					# open bracket
       
  4167 	"""
       
  4168 script.iFileExts = ["cpp"]
       
  4169 script.iCategory = KCategoryCodingStandards
       
  4170 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4171 script.iSeverity = KSeverityLow
       
  4172 
       
  4173 scanner.AddScript(script)
       
  4174 
       
  4175 # #################################################################
       
  4176 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4177 # All rights reserved.
       
  4178 # 
       
  4179 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4180 # 
       
  4181 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4182 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4183 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4184 # 
       
  4185 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4186 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4187 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4188 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4189 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4190 #
       
  4191 # deleteMemberVariable.py
       
  4192 #
       
  4193 # Checks : Member variable deleted incorrectly.
       
  4194 #
       
  4195 # Reason : When a member variable is deleted, it should be assigned 
       
  4196 # either to NULL or to another value. This prevents accidental 
       
  4197 # access of the deleted object. If a NewL() or other leaving 
       
  4198 # function is called to reassign the member variable, it should 
       
  4199 # first be assigned to NULL in case that function leaves.
       
  4200 #
       
  4201 # #################################################################
       
  4202 
       
  4203 script = CScript("deleteMemberVariable")
       
  4204 script.iReString = r"""
       
  4205 	delete		# delete command
       
  4206 	\s*			# optional space
       
  4207 	\(*			# optional open bracket
       
  4208 	\s*			# optional space
       
  4209 	i[A-Z]		# member variable name
       
  4210 	"""
       
  4211 script.iFileExts = ["cpp"]
       
  4212 script.iCategory = KCategoryCanPanic
       
  4213 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4214 script.iSeverity = KSeverityHigh
       
  4215 
       
  4216 deleteMemberVariableLeavingFunction = re.compile("""
       
  4217 	[A-Za-z0-9]+
       
  4218 	L
       
  4219 	(C|D)*
       
  4220 	\s*
       
  4221 	\(
       
  4222 	""", re.VERBOSE)
       
  4223 
       
  4224 deleteMemberVariableNewELeave = re.compile("""
       
  4225 	new
       
  4226 	\s*
       
  4227 	\(
       
  4228 	\s*
       
  4229 	ELeave
       
  4230 	\s*
       
  4231 	\)
       
  4232 	""", re.VERBOSE)
       
  4233 
       
  4234 deleteMemberVariableLeave = re.compile("""
       
  4235 	User::Leave
       
  4236 	""", re.VERBOSE)
       
  4237 
       
  4238 deleteMemberVariableArrayDeletion = re.compile("""
       
  4239 	(\.|->)
       
  4240 	\s*
       
  4241 	Delete
       
  4242 	\s*
       
  4243 	\(
       
  4244 	""", re.VERBOSE)
       
  4245 
       
  4246 deleteMemberVariableArrayDeletion2 = re.compile("""
       
  4247 	(\.|->)
       
  4248 	\s*
       
  4249 	Remove
       
  4250 	\s*
       
  4251 	\(
       
  4252 	""", re.VERBOSE)
       
  4253 
       
  4254 def deleteMemberVariableCompare(lines, currentline, rematch, filename):
       
  4255 	line = lines[currentline]
       
  4256 	m = rematch.search(line)
       
  4257 
       
  4258 	if m:
       
  4259 		if (scanner.iCurrentMethodName.find(scanner.iCurrentClassName) > -1):
       
  4260 			return 0
       
  4261 
       
  4262 		deletingArrayMember = 0
       
  4263 		if (line.find("[")):
       
  4264 			deletingArrayMember = 1
       
  4265 
       
  4266 		# get the variable name, between the 'delete' and the ';'
       
  4267 		endindex = line.find(";")
       
  4268 		if (endindex == -1):
       
  4269 			endindex = len(line)
       
  4270 		startindex = line.find("delete")
       
  4271 		variable = line[startindex+6:endindex]
       
  4272 		variable2 = TrimVariableName(variable)
       
  4273 
       
  4274 		bracketdepth = GetBracketDepth(lines, currentline)
       
  4275 
       
  4276 		i = currentline
       
  4277 		while (i < len(lines)):
       
  4278 			nextLine = lines[i]
       
  4279 
       
  4280 			if deleteMemberVariableLeavingFunction.search(nextLine):
       
  4281 				return 1
       
  4282 			if deleteMemberVariableLeave.search(nextLine):
       
  4283 				return 1
       
  4284 			if deleteMemberVariableNewELeave.search(nextLine):
       
  4285 				return 1
       
  4286 			
       
  4287 			if (deletingArrayMember == 1):
       
  4288 				if (nextLine.find(variable2)):
       
  4289 					if deleteMemberVariableArrayDeletion.search(nextLine):
       
  4290 						return 0
       
  4291 					if deleteMemberVariableArrayDeletion2.search(nextLine):
       
  4292 						return 0
       
  4293 
       
  4294 			foundAssignment = nextLine.find("=")
       
  4295 			if (foundAssignment > -1 and nextLine[foundAssignment+1] != "="):
       
  4296 				assigned = nextLine[:foundAssignment]
       
  4297 				if (assigned.find(variable2)):
       
  4298 					return 0
       
  4299 
       
  4300 			if (nextLine.find('{') >= 0):
       
  4301 				bracketdepth = bracketdepth + 1
       
  4302 			if (nextLine.find('}') >= 0):
       
  4303 				bracketdepth = bracketdepth - 1
       
  4304 				if (bracketdepth == 0):
       
  4305 					return 1
       
  4306 
       
  4307 			i = i + 1
       
  4308 	return 0
       
  4309 
       
  4310 script.iCompare	= deleteMemberVariableCompare
       
  4311 scanner.AddScript(script)
       
  4312 
       
  4313 # #################################################################
       
  4314 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4315 # All rights reserved.
       
  4316 # 
       
  4317 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4318 # 
       
  4319 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4320 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4321 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4322 # 
       
  4323 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4324 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4325 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4326 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4327 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4328 #
       
  4329 # destructor.py
       
  4330 #
       
  4331 # Checks : Pointer access in destructors.
       
  4332 # 
       
  4333 # Reason : Accessing pointers to objects in destructors without 
       
  4334 # checking whether they are not NULL could result in a panic, since
       
  4335 # they may not have been constructed. The pointers should be
       
  4336 # checked to determine whether they are owned objects. If they are
       
  4337 # not owned, they should really be references rather than pointers.
       
  4338 #
       
  4339 # #################################################################
       
  4340 
       
  4341 script = CScript("destructor")
       
  4342 script.iReString = r"""
       
  4343 	^\s*
       
  4344 	\w+
       
  4345 	\s*
       
  4346 	::~
       
  4347 	\s*
       
  4348 	\w+
       
  4349 	\(
       
  4350 	"""
       
  4351 script.iFileExts = ["cpp"]
       
  4352 script.iCategory = KCategoryCanPanic
       
  4353 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4354 script.iSeverity = KSeverityHigh
       
  4355 
       
  4356 remember = re.compile("(i[A-Z]\w*)(.+)")
       
  4357 reguard = re.compile("^\s*(if|while)(.*)({|$)")
       
  4358 
       
  4359 def findguard(lines, currentline, destructorstartline, membername):
       
  4360 	i = currentline
       
  4361 	line = lines[i]
       
  4362 
       
  4363 	while (i > destructorstartline):
       
  4364 		line = lines[i]
       
  4365 		m = reguard.search(line)
       
  4366 		if m:
       
  4367 			index = m.group(2).find(membername)
       
  4368 			if (index <> -1):
       
  4369 				if (line[index - 1:index] <> "*") and (line[index + len(membername):index + len(membername) + 2] <> "->"):
       
  4370 					return 1
       
  4371 		i = i - 1
       
  4372 
       
  4373 	return 0
       
  4374 
       
  4375 def destructorcompare(lines, currentline, rematch, filename):
       
  4376 	m = rematch.search(lines[currentline])
       
  4377 	if m:
       
  4378 		openbracecount = 0
       
  4379 		closebracecount = 0
       
  4380 		checkline = currentline
       
  4381 
       
  4382 		while (checkline < len(lines)):
       
  4383 			line = lines[checkline]
       
  4384 			openbracecount += line.count("{")
       
  4385 			closebracecount += line.count("}")
       
  4386 			member = remember.search(line)
       
  4387 			if member and ((member.group(2)[:2] == "->") or (line[member.start()-1:member.start()] == "*" and member.group(2)[:1] <> ".")):
       
  4388 				membername = member.group(1)
       
  4389 				if (membername.upper()[-3:] == "ENV") or findguard(lines, checkline, currentline, membername) <> 0:
       
  4390 					return 0
       
  4391 				else:
       
  4392 					return 1
       
  4393 
       
  4394 			if (openbracecount and (openbracecount - closebracecount == 0)):
       
  4395 				break
       
  4396 			checkline += 1
       
  4397 
       
  4398 	return 0
       
  4399 
       
  4400 script.iCompare	= destructorcompare
       
  4401 scanner.AddScript(script)
       
  4402 
       
  4403 # #################################################################
       
  4404 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4405 # All rights reserved.
       
  4406 # 
       
  4407 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4408 # 
       
  4409 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4410 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4411 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4412 # 
       
  4413 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4414 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4415 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4416 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4417 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4418 #
       
  4419 # #################################################################
       
  4420 # doubleSemiColon.py
       
  4421 #
       
  4422 # Checks : Use of double semicolon.
       
  4423 #
       
  4424 # Reason : Double semicolons at the end of a line are not necessary 
       
  4425 # and cause a CodeWarrior compiler error.
       
  4426 #
       
  4427 # #################################################################
       
  4428 
       
  4429 script = CScript("doubleSemiColon")
       
  4430 script.iReString = r"""
       
  4431 	;
       
  4432 	\s*
       
  4433 	;
       
  4434 	\s*
       
  4435 	$
       
  4436 	"""
       
  4437 script.iFileExts = ["cpp", "h", "inl"]
       
  4438 script.iCategory = KCategoryCodeReviewGuides
       
  4439 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4440 script.iSeverity = KSeverityLow
       
  4441 
       
  4442 scanner.AddScript(script)
       
  4443 
       
  4444 # #################################################################
       
  4445 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4446 # All rights reserved.
       
  4447 # 
       
  4448 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4449 # 
       
  4450 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4451 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4452 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4453 # 
       
  4454 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4455 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4456 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4457 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4458 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4459 #
       
  4460 # driveletters.py
       
  4461 #
       
  4462 # Checks : Hard-coded drive letters.
       
  4463 #
       
  4464 # Reason : Drive letters should not be hard-coded.
       
  4465 #
       
  4466 # #################################################################
       
  4467 
       
  4468 script = CScript("driveletters")
       
  4469 script.iReString = r"""[a-zA-Z]:\\\\"""
       
  4470 script.iFileExts = ["cpp", "h", "rss", "rls", "loc", "ra"]
       
  4471 script.iCategory = KCategoryCodingStandards
       
  4472 script.iIgnore = KIgnoreComments
       
  4473 script.iSeverity = KSeverityLow
       
  4474 
       
  4475 scanner.AddScript(script)
       
  4476 
       
  4477 # #################################################################
       
  4478 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4479 # All rights reserved.
       
  4480 # 
       
  4481 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4482 # 
       
  4483 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4484 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4485 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4486 # 
       
  4487 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4488 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4489 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4490 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4491 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4492 #
       
  4493 # eikbuttons.py
       
  4494 #
       
  4495 # Checks : Checks that the R_EIK_BUTTONS_* resources are not being 
       
  4496 # used.
       
  4497 #
       
  4498 # Reason : R_EIK_BUTTONS_* resources will not be internationalised, 
       
  4499 # and should not be used. Instead, create your own button resource. 
       
  4500 # No button resource (or indeed, rls string) should be used in 
       
  4501 # more than one location. Note: This issue is only relevant for 
       
  4502 # development on Nokia platforms.
       
  4503 #
       
  4504 # #################################################################
       
  4505 
       
  4506 script = CScript("eikbuttons")
       
  4507 script.iReString = "R_EIK_BUTTONS_.*?"
       
  4508 script.iFileExts = ["rss", "cpp"]
       
  4509 script.iCategory = KCategoryLocalisation
       
  4510 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4511 script.iSeverity = KSeverityMedium
       
  4512 
       
  4513 scanner.AddScript(script)
       
  4514 
       
  4515 # #################################################################
       
  4516 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4517 # All rights reserved.
       
  4518 # 
       
  4519 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4520 # 
       
  4521 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4522 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4523 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4524 # 
       
  4525 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4526 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4527 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4528 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4529 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4530 #
       
  4531 # eikonenvstatic.py
       
  4532 #
       
  4533 # Checks : Using CEikonEnv::Static.
       
  4534 #
       
  4535 # Reason : CEikonEnv::Static() calls should be kept to a minimum, 
       
  4536 # because this involves TLS. All applications, controls, and 
       
  4537 # dialogs already have a pointer to the singleton instance of 
       
  4538 # CEikonEnv as a member variable and so don't need to find it again. 
       
  4539 # If a class does not have access to a CEikonEnv and needs to use 
       
  4540 # it repeatedly, then it should store one.
       
  4541 #
       
  4542 # #################################################################
       
  4543 
       
  4544 script = CScript("eikonenvstatic")
       
  4545 script.iReString = "CEikonEnv::Static"
       
  4546 
       
  4547 script.iFileExts = ["cpp"]
       
  4548 script.iCategory = KCategoryPerformance
       
  4549 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4550 script.iSeverity = KSeverityMedium
       
  4551 
       
  4552 scanner.AddScript(script)
       
  4553 
       
  4554 # #################################################################
       
  4555 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4556 # All rights reserved.
       
  4557 # 
       
  4558 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4559 # 
       
  4560 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4561 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4562 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4563 # 
       
  4564 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4565 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4566 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4567 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4568 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4569 #
       
  4570 # enummembers.py
       
  4571 #
       
  4572 # Checks : Badly-named enum members.
       
  4573 #
       
  4574 # Reason : Badly-named enum members make the code harder to 
       
  4575 # maintain and may cause defects.
       
  4576 #
       
  4577 # #################################################################
       
  4578 
       
  4579 script = CScript("enummembers")
       
  4580 script.iReString = r"""
       
  4581 			^
       
  4582 			\s*
       
  4583 			enum
       
  4584 			((\s+\w+)|(\s+\w+\s*::\s*\w+))?
       
  4585 			\s*
       
  4586 			({|$)
       
  4587 			"""
       
  4588 script.iFileExts = ["h", "cpp"]
       
  4589 script.iCategory = KCategoryCodingStandards
       
  4590 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4591 script.iSeverity = KSeverityLow
       
  4592 
       
  4593 reMember = re.compile("^\s*(\w+)")
       
  4594 
       
  4595 def enummemberscompare(lines, currentline, rematch, filename):
       
  4596 	m = rematch.search(lines[currentline])
       
  4597 	if m:
       
  4598 		startline = currentline
       
  4599 		openbraceindex = lines[startline].find("{")
       
  4600 		while (openbraceindex == -1) and (startline < len(lines)) and (lines[startline].find(";") == -1):
       
  4601 			startline += 1
       
  4602 			openbraceindex = lines[startline].find("{")
       
  4603 
       
  4604 		if openbraceindex == -1:
       
  4605 			return 0
       
  4606 
       
  4607 		endline = currentline
       
  4608 		closebraceindex = lines[endline].find("}")
       
  4609 		while (closebraceindex == -1) and (endline < len(lines)):
       
  4610 			endline += 1
       
  4611 			closebraceindex = lines[endline].find("}")
       
  4612 
       
  4613 		enumcontents = ""
       
  4614 		if (startline == endline):
       
  4615 			enumcontents = lines[startline][openbraceindex + 1:closebraceindex - 1]
       
  4616 		else:
       
  4617 			enumcontents = lines[startline][openbraceindex + 1:]
       
  4618 			line = startline + 1
       
  4619 			while (line < len(lines)) and (line < endline):
       
  4620 				enumcontents = enumcontents + lines[line]
       
  4621 				line += 1
       
  4622 
       
  4623 			enumcontents = enumcontents + lines[endline][:closebraceindex - 1]
       
  4624 
       
  4625 		# check contents
       
  4626 		members = enumcontents.split("\n\r,")
       
  4627 		for member in members:
       
  4628 			m2 = reMember.search(member)
       
  4629 			if m2 and (m2.group(1)[:1] <> "E"):
       
  4630 				return 1
       
  4631 									
       
  4632 	return 0
       
  4633 
       
  4634 script.iCompare = enummemberscompare
       
  4635 scanner.AddScript(script)
       
  4636 
       
  4637 # #################################################################
       
  4638 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4639 # All rights reserved.
       
  4640 # 
       
  4641 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4642 # 
       
  4643 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4644 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4645 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4646 # 
       
  4647 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4648 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4649 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4650 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4651 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4652 #
       
  4653 # enumnames.py
       
  4654 #
       
  4655 # Checks : Badly-named enums.
       
  4656 #
       
  4657 # Reason : Badly-named enums make the code harder to maintain and 
       
  4658 # may cause defects.
       
  4659 #
       
  4660 # #################################################################
       
  4661 
       
  4662 script = CScript("enumnames")
       
  4663 script.iReString = r"""
       
  4664 			^
       
  4665 			\s*
       
  4666 			enum
       
  4667 			\s+
       
  4668 			(\w+\s*::\s*)?
       
  4669 			(\w+)
       
  4670 			\s*
       
  4671 			({|$)
       
  4672 			"""
       
  4673 script.iFileExts = ["h", "cpp"]
       
  4674 script.iCategory = KCategoryCodingStandards
       
  4675 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4676 script.iSeverity = KSeverityLow
       
  4677 
       
  4678 def enumnamescompare(lines, currentline, rematch, filename):
       
  4679 	m = rematch.search(lines[currentline])
       
  4680 	if m:
       
  4681 		if m.group(2)[:1] <> "T":
       
  4682 				return 1
       
  4683 
       
  4684 	return 0
       
  4685 
       
  4686 script.iCompare = enumnamescompare
       
  4687 scanner.AddScript(script)
       
  4688 
       
  4689 # #################################################################
       
  4690 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4691 # All rights reserved.
       
  4692 # 
       
  4693 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4694 # 
       
  4695 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4696 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4697 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4698 # 
       
  4699 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4700 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4701 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4702 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4703 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4704 #
       
  4705 # exportinline.py
       
  4706 #
       
  4707 # Checks : Exporting inline functions.
       
  4708 #
       
  4709 # Reason : Inline functions should not be exported because this can 
       
  4710 # cause those that link to the DLL to fail to build. Exporting 
       
  4711 # functions limits the changes that can be made in the future 
       
  4712 # due to considerations of binary-compatibility.
       
  4713 #
       
  4714 # #################################################################
       
  4715 
       
  4716 script = CScript("exportinline")
       
  4717 script.iReString = "IMPORT_C\s+.*inline\s+.+\("
       
  4718 script.iFileExts = ["cpp", "h", "hpp", "inl", "c"]
       
  4719 script.iCategory = KCategoryWrongFunctionality
       
  4720 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4721 script.iSeverity = KSeverityMedium
       
  4722 
       
  4723 scanner.AddScript(script)
       
  4724 
       
  4725 # #################################################################
       
  4726 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4727 # All rights reserved.
       
  4728 # 
       
  4729 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4730 # 
       
  4731 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4732 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4733 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4734 # 
       
  4735 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4736 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4737 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4738 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4739 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4740 #
       
  4741 # exportpurevirtual.py
       
  4742 #
       
  4743 # Checks : Exporting pure virtual functions.
       
  4744 #
       
  4745 # Reason : Symbian recommends against the exportation of 
       
  4746 # pure virtual functions.
       
  4747 #
       
  4748 # #################################################################
       
  4749 
       
  4750 script = CScript("exportpurevirtual")
       
  4751 script.iReString = "IMPORT_C\s+.*\)\s*=\s*0\s*;$"
       
  4752 script.iFileExts = ["cpp", "h", "hpp", "inl", "c"]
       
  4753 script.iCategory = KCategoryWrongFunctionality
       
  4754 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4755 script.iSeverity = KSeverityMedium
       
  4756 
       
  4757 scanner.AddScript(script)
       
  4758 
       
  4759 
       
  4760 
       
  4761 # This script is duplicate of driveletters.py
       
  4762 
       
  4763 # #################################################################
       
  4764 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4765 # All rights reserved.
       
  4766 # 
       
  4767 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4768 # 
       
  4769 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4770 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4771 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4772 # 
       
  4773 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4774 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4775 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4776 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4777 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4778 #
       
  4779 # externaldriveletters.py
       
  4780 #
       
  4781 # Checks : Hard-coded external drive letters.
       
  4782 #
       
  4783 # Reason : External drive letters should not be hard-coded as the 
       
  4784 # external drive may change between platforms and releases. 
       
  4785 # This may cause confusion over ownership leading to classes being 
       
  4786 # deleted erroneously and leaks occurring.
       
  4787 #
       
  4788 # #################################################################
       
  4789 
       
  4790 #script = CScript("externaldriveletters")
       
  4791 #script.iReString = """"[abd-yABD-Y]:\\\\"""
       
  4792 #script.iFileExts = ["cpp", "h", "rss", "rls", "loc", "ra"]
       
  4793 #script.iCategory = KCategoryCanPanic
       
  4794 #script.iIgnore = KIgnoreComments
       
  4795 #script.iSeverity = KSeverityHigh
       
  4796 
       
  4797 #scanner.AddScript(script)
       
  4798 
       
  4799 # #################################################################
       
  4800 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4801 # All rights reserved.
       
  4802 # 
       
  4803 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4804 # 
       
  4805 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4806 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4807 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4808 # 
       
  4809 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4810 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4811 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4812 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4813 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4814 #
       
  4815 # flags.py
       
  4816 #
       
  4817 # Checks : Use of R&D flags or feature flags.
       
  4818 #
       
  4819 # Reason : Independent application must not use R&D flags nor 
       
  4820 # feature flags via preprocessor statements in the source code.
       
  4821 # This means bld*.hrh and productvariant.hrh should not be used.
       
  4822 #
       
  4823 # #################################################################
       
  4824 
       
  4825 script = CScript("flags")
       
  4826 script.iReString = r"""
       
  4827     ^\s*
       
  4828     \#include
       
  4829     \s+
       
  4830     ("|<)
       
  4831     ((bld\w+|productvariant)\.hrh)
       
  4832     ("|>)
       
  4833     """
       
  4834 script.iFileExts = ["cpp", "h", "hrh", "mmp"]
       
  4835 script.iCategory = KCategoryOther
       
  4836 script.iIgnore = KIgnoreComments
       
  4837 script.iSeverity = KSeverityLow
       
  4838 
       
  4839 scanner.AddScript(script)
       
  4840 
       
  4841 # #################################################################
       
  4842 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4843 # All rights reserved.
       
  4844 # 
       
  4845 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4846 # 
       
  4847 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4848 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4849 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4850 # 
       
  4851 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4852 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4853 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4854 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4855 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4856 #
       
  4857 # foff.py
       
  4858 #
       
  4859 # Checks : Use of _FOFF.
       
  4860 #
       
  4861 # Reason : _FOFF allows access to data in classes that were not 
       
  4862 # intended for public access. This may cause problems, especially 
       
  4863 # when the location of the data changes.
       
  4864 #
       
  4865 # #################################################################
       
  4866 
       
  4867 script = CScript("foff")
       
  4868 script.iReString = "_FOFF"
       
  4869 script.iFileExts = ["cpp"]
       
  4870 script.iCategory = KCategoryCodeReviewGuides
       
  4871 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4872 script.iSeverity = KSeverityLow
       
  4873 
       
  4874 scanner.AddScript(script)
       
  4875 
       
  4876 # #################################################################
       
  4877 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4878 # All rights reserved.
       
  4879 # 
       
  4880 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4881 # 
       
  4882 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4883 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4884 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4885 # 
       
  4886 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4887 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4888 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4889 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4890 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4891 #
       
  4892 # forbiddenwords.py
       
  4893 #
       
  4894 # Checks : Use of forbidden words in header files.
       
  4895 #
       
  4896 # Reason : Some words should not be used in header files; 
       
  4897 # especially those header files destined for external release. 
       
  4898 # Some words may be forbidden for legal reasons or for platform 
       
  4899 # consistency. Where they exist, alternative allowed words should 
       
  4900 # be used. For example, \"NMP\" and \"Nokia Mobile Phones\" should 
       
  4901 # be replaced by \"Nokia\".
       
  4902 #
       
  4903 # #################################################################
       
  4904 
       
  4905 script = CScript("forbiddenwords")
       
  4906 script.iReString = ""
       
  4907 script.iFileExts = ["h"]
       
  4908 script.iCategory = KCategoryCodingStandards
       
  4909 script.iIgnore = KIgnoreNothing
       
  4910 script.iSeverity = KSeverityLow
       
  4911 
       
  4912 reForbiddenWordsStr = "(Typhoon|Hurricane|Calypso|Rubik|Epoc\\|Nokia Mobile Phones|NMP|Mobile Innovation|(^|\s)S90|(^|\s)S80)"
       
  4913 
       
  4914 scriptNode = script.ScriptConfig()
       
  4915 if (scriptNode <> None):
       
  4916 	for wordNode in scriptNode.getElementsByTagName("wordsRE"):
       
  4917 		reForbiddenWordsStr = wordNode.firstChild.nodeValue
       
  4918 		print "Note: 'forbidden words' pattern configured as: " + reForbiddenWordsStr
       
  4919 		break
       
  4920 reForbiddenWords = re.compile(reForbiddenWordsStr, re.IGNORECASE)
       
  4921 
       
  4922 def forbiddenwordcompare(lines, currentline, rematch, filename):
       
  4923 	return reForbiddenWords.search(lines[currentline])
       
  4924 
       
  4925 script.iCompare = forbiddenwordcompare
       
  4926 scanner.AddScript(script)
       
  4927 
       
  4928 # #################################################################
       
  4929 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  4930 # All rights reserved.
       
  4931 # 
       
  4932 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  4933 # 
       
  4934 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  4935 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  4936 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  4937 # 
       
  4938 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  4939 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  4940 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  4941 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  4942 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  4943 #
       
  4944 # forgottoputptroncleanupstack.py
       
  4945 #
       
  4946 # Checks : Neglected to put variable on cleanup stack.
       
  4947 #
       
  4948 # Reason : If a variable is not put on the cleanup stack and a 
       
  4949 # leaving function or ELeave is called, a memory leak occurs. 
       
  4950 # CodeScanner occasionally gives false positives for this issue. 
       
  4951 # Individual cases should be investigated.
       
  4952 #
       
  4953 # #################################################################
       
  4954 
       
  4955 script = CScript("forgottoputptroncleanupstack")
       
  4956 script.iReString = r"""
       
  4957 	\s+				# optional whitespace
       
  4958 	[b-hj-z]+		# must not be a member or parameter
       
  4959 	[A-Za-z0-9]+	# variable name
       
  4960 	\s*				# optional whitespace
       
  4961 	=				# assignment operator
       
  4962 	"""
       
  4963 script.iFileExts = ["cpp"]
       
  4964 script.iCategory = KCategoryCodeReviewGuides
       
  4965 script.iIgnore = KIgnoreCommentsAndQuotes
       
  4966 script.iSeverity = KSeverityLow
       
  4967 
       
  4968 forgottoputptroncleanupstackCleanup = re.compile("""Cleanup""", re.VERBOSE)
       
  4969 
       
  4970 forgottoputptroncleanupstackDeleteOp = re.compile("""
       
  4971 	\s+
       
  4972 	delete
       
  4973 	\s+
       
  4974 	""", re.VERBOSE)
       
  4975 
       
  4976 forgottoputptroncleanupstackReturnCmd = re.compile("""
       
  4977 	(\s*|\()
       
  4978 	return
       
  4979 	(\s*|\()
       
  4980 	""", re.VERBOSE)
       
  4981 
       
  4982 forgottoputptroncleanupstackSetFn = re.compile("""
       
  4983 	Set
       
  4984 	[A-Za-z0-9]+
       
  4985 	[A-KM-Za-z0-9]
       
  4986 	\s*
       
  4987 	\(
       
  4988 	""", re.VERBOSE)
       
  4989 
       
  4990 forgottoputptroncleanupstackBreak = re.compile("""
       
  4991 	\s+
       
  4992 	break
       
  4993 	\s*
       
  4994 	;
       
  4995 	""", re.VERBOSE)
       
  4996 
       
  4997 forgottoputptroncleanupstackIf = re.compile("""
       
  4998 	\s+
       
  4999 	if
       
  5000 	\s*
       
  5001 	\(
       
  5002 	""", re.VERBOSE)
       
  5003 	
       
  5004 forgottoputptroncleanupstackElse = re.compile("""
       
  5005 	\}*
       
  5006 	\s*
       
  5007 	else
       
  5008 	\s*
       
  5009 	\{*
       
  5010 	""", re.VERBOSE)
       
  5011 
       
  5012 forgottoputptroncleanupstackAssignToMember = re.compile("""
       
  5013 	i
       
  5014 	[A-Za-z0-9\[\]]+
       
  5015 	\s*
       
  5016 	=
       
  5017 	\s*
       
  5018 	.*
       
  5019 	\s*
       
  5020 	;
       
  5021 	""", re.VERBOSE)
       
  5022 
       
  5023 forgottoputptroncleanupstackTrapMacro = re.compile("""
       
  5024 	TRAP
       
  5025 	[D]*
       
  5026 	\s*
       
  5027 	\(
       
  5028 	""", re.VERBOSE)
       
  5029 
       
  5030 forgottoputptroncleanupstackLeavingFunction = re.compile("""
       
  5031 	[A-Za-z0-9]+
       
  5032 	L
       
  5033 	\s*
       
  5034 	\(
       
  5035 	""", re.VERBOSE)
       
  5036 
       
  5037 forgottoputptroncleanupstackLeave = re.compile("""
       
  5038 	User::Leave
       
  5039 	""", re.VERBOSE)
       
  5040 
       
  5041 forgottoputptroncleanupstackLeaveAndDelete = re.compile("""
       
  5042 	L
       
  5043 	[D]+
       
  5044 	\s*
       
  5045 	\(
       
  5046 	""", re.VERBOSE)
       
  5047 
       
  5048 forgottoputptroncleanupstackNewOperator = re.compile("""
       
  5049 	new
       
  5050 	\s*
       
  5051 	\(
       
  5052 	\s*
       
  5053 	ELeave
       
  5054 	""", re.VERBOSE)
       
  5055 
       
  5056 forgottoputptroncleanupstackNewFunction = re.compile("""
       
  5057 	::NewL
       
  5058 	\s*
       
  5059 	\(
       
  5060 	""", re.VERBOSE)
       
  5061 
       
  5062 forgottoputptroncleanupstackCreateFunction = re.compile("""
       
  5063 	Create
       
  5064 	[A-Za-z0-9]+
       
  5065 	L
       
  5066 	\s*
       
  5067 	\(
       
  5068 	""", re.VERBOSE)
       
  5069 
       
  5070 forgottoputptroncleanupstackAllocFunction = re.compile("""
       
  5071 	Alloc
       
  5072 	L*
       
  5073 	\s*
       
  5074 	\(
       
  5075 	""", re.VERBOSE)
       
  5076 
       
  5077 def findForgetCompare(lines, currentline, rematch, filename):
       
  5078 	line = lines[currentline]
       
  5079 	m = rematch.search(line)
       
  5080 
       
  5081 	if m:
       
  5082 		foundNew = 0
       
  5083 		equalPos = line.find("=")
       
  5084 		assignedSection = line[equalPos:]
       
  5085 	
       
  5086 		if forgottoputptroncleanupstackNewFunction.search(assignedSection):
       
  5087 			foundNew = 1
       
  5088 		if forgottoputptroncleanupstackNewOperator.search(assignedSection):
       
  5089 			foundNew = 1
       
  5090 		if forgottoputptroncleanupstackAllocFunction.search(assignedSection):
       
  5091 			foundNew = 1
       
  5092 		if forgottoputptroncleanupstackCreateFunction.search(assignedSection):
       
  5093 			foundNew = 1
       
  5094 
       
  5095 		# if this line contains a 'new', a 'NewL(', or an 'AllocL('
       
  5096 		if (foundNew == 1):	
       
  5097 			i = currentline
       
  5098 
       
  5099 		# move to next line ending if this line doesn't contain one
       
  5100 			while (lines[i].find(';') == -1):
       
  5101 				i = i + 1
       
  5102 
       
  5103 		# go to next line
       
  5104 			i = i + 1
       
  5105 			bracketdepth = GetBracketDepth(lines, i)
       
  5106 			
       
  5107 		# get the variable name, between the '*' and the '='
       
  5108 			startindex = line.find("*")
       
  5109 			if (startindex == -1):
       
  5110 				startindex = 0
       
  5111 			endindex = line.find("=")
       
  5112 			variable = line[startindex+1:endindex]
       
  5113 			if (len(variable) < 1):
       
  5114 				return 0
       
  5115 			variable = TrimVariableName(variable)
       
  5116 
       
  5117 			inAnIfOrSelectStatement = 1 # possibly
       
  5118 			
       
  5119 			while (i < len(lines)):
       
  5120 				line2 = lines[i]
       
  5121 
       
  5122 				if (line2.find('{') >= 0):
       
  5123 					bracketdepth = bracketdepth + 1
       
  5124 				if (line2.find('}') >= 0):
       
  5125 					bracketdepth = bracketdepth - 1
       
  5126 					inAnIfOrSelectStatement = 0
       
  5127 					if (bracketdepth == 0):
       
  5128 						return 0
       
  5129 
       
  5130 				varIndex = line2.find(variable)
       
  5131 		# if a later line contains the variable...
       
  5132 				while (varIndex <> -1):
       
  5133 					if (isNonAlpha(line2[varIndex-1])):
       
  5134 						if (isNonAlpha(line2[varIndex+len(variable)])):
       
  5135 		# ...and delete, exit
       
  5136 							if forgottoputptroncleanupstackDeleteOp.search(line2):
       
  5137 								return 0
       
  5138 	
       
  5139 		# ...and an xxxLD() function, exit
       
  5140 							if forgottoputptroncleanupstackLeaveAndDelete.search(line2):
       
  5141 								return 0
       
  5142 							
       
  5143 		# ...and the variable is assigned to a member variable, exit
       
  5144 							if forgottoputptroncleanupstackAssignToMember.search(line2):
       
  5145 								return 0
       
  5146 		
       
  5147 		# ...and it is a Set...() call, exit (e.g. SetArray, SetAppUi)
       
  5148 							if forgottoputptroncleanupstackSetFn.search(line2):
       
  5149 								return 0
       
  5150 
       
  5151 		# ...and a return command, exit 
       
  5152 							if forgottoputptroncleanupstackReturnCmd.search(line2):
       
  5153 								return 0
       
  5154 
       
  5155 		# search this line again incase there are similarly named variables
       
  5156 					line2 = line2[varIndex+1:]
       
  5157 					varIndex = line2.find(variable)
       
  5158 
       
  5159 				line2 = lines[i]
       
  5160 		# if a leaving function is called...
       
  5161 				if forgottoputptroncleanupstackLeavingFunction.search(line2):
       
  5162 		# ...if the leaving function is trapped, exit
       
  5163 					if forgottoputptroncleanupstackTrapMacro.search(line2):
       
  5164 						return 0
       
  5165 		# ...if a Cleanup function is called, exit
       
  5166 					if forgottoputptroncleanupstackCleanup.search(line2):
       
  5167 						return 0
       
  5168 		# ...otherwise this is a problem!
       
  5169 					return 1
       
  5170 
       
  5171 		# if a User::Leave is called, this is a problem
       
  5172 				if forgottoputptroncleanupstackLeave.search(line2):
       
  5173 					return 1
       
  5174 	
       
  5175 		# if the variable is initialised in a branch of an 'if' or 'switch' statement, ignore other branches
       
  5176 				if (inAnIfOrSelectStatement == 1):
       
  5177 					if forgottoputptroncleanupstackBreak.search(line2):
       
  5178 						atLine = i
       
  5179 						inAnIfOrSelectStatement = 0
       
  5180 						findSwitch = i
       
  5181 						line3 = lines[findSwitch]
       
  5182 						while (line3.find("switch") == -1):
       
  5183 							findSwitch = findSwitch - 1
       
  5184 							if (findSwitch <= 0):
       
  5185 								return 0
       
  5186 							line3 = lines[findSwitch]
       
  5187 						switchBracketDepth = GetBracketDepth(lines, findSwitch)
       
  5188 						i = atLine
       
  5189 						while (bracketdepth > switchBracketDepth):
       
  5190 							if (i >= len(lines)):
       
  5191 								return 0
       
  5192 							line2 = lines[i]
       
  5193 							if (line2.find('{') >= 0):
       
  5194 								bracketdepth = bracketdepth + 1
       
  5195 							if (line2.find('}') >= 0):
       
  5196 								bracketdepth = bracketdepth - 1
       
  5197 							i = i + 1
       
  5198 							
       
  5199 					if forgottoputptroncleanupstackElse.search(line2):
       
  5200 						inAnIfOrSelectStatement = 0
       
  5201 						elseBracketDepth = bracketdepth
       
  5202 						if (line2.find('{') >= 0):
       
  5203 							elseBracketDepth = elseBracketDepth - 1
       
  5204 						if (elseBracketDepth == GetBracketDepth(lines, currentline)):
       
  5205 							while (line2.find(';') == -1):
       
  5206 								i = i + 1
       
  5207 								if (i >= len(lines)):
       
  5208 									return 0
       
  5209 								line2 = lines[i]
       
  5210 						else:
       
  5211 							while (bracketdepth > elseBracketDepth):
       
  5212 								i = i + 1
       
  5213 								if (i >= len(lines)):
       
  5214 									return 0
       
  5215 								line2 = lines[i]
       
  5216 								if (line2.find('{') >= 0):
       
  5217 									bracketdepth = bracketdepth + 1
       
  5218 								if (line2.find('}') >= 0):
       
  5219 									bracketdepth = bracketdepth - 1
       
  5220 
       
  5221 					if forgottoputptroncleanupstackIf.search(line2):
       
  5222 						inAnIfOrSelectStatement = 0
       
  5223 				i = i + 1
       
  5224 			return 0
       
  5225 
       
  5226 	return 0
       
  5227 
       
  5228 script.iCompare	= findForgetCompare
       
  5229 scanner.AddScript(script)
       
  5230 
       
  5231 # #################################################################
       
  5232 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5233 # All rights reserved.
       
  5234 # 
       
  5235 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5236 # 
       
  5237 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5238 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5239 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5240 # 
       
  5241 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5242 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5243 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5244 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5245 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5246 #
       
  5247 # friend.py
       
  5248 #
       
  5249 # Checks : Use of friends.
       
  5250 #
       
  5251 # Reason : The friend directive is often misused and can indicate 
       
  5252 # problems in the OO design.
       
  5253 #
       
  5254 # #################################################################
       
  5255 
       
  5256 script = CScript("friend")
       
  5257 script.iReString = "^\s*friend\s"
       
  5258 script.iFileExts = ["cpp", "h", "hpp", "inl", "c"]
       
  5259 script.iCategory = KCategoryCodeReviewGuides
       
  5260 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5261 script.iSeverity = KSeverityLow
       
  5262 
       
  5263 scanner.AddScript(script)
       
  5264 
       
  5265 # #################################################################
       
  5266 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5267 # All rights reserved.
       
  5268 # 
       
  5269 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5270 # 
       
  5271 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5272 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5273 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5274 # 
       
  5275 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5276 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5277 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5278 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5279 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5280 #
       
  5281 # goto.py
       
  5282 #
       
  5283 # Checks : Use of goto.
       
  5284 #
       
  5285 # Reason : Goto should not be used if it can be avoided because 
       
  5286 # it makes the program flow more difficult to follow.
       
  5287 #
       
  5288 # #################################################################
       
  5289 
       
  5290 script = CScript("goto")
       
  5291 script.iReString = "(^|[^\w])goto\s+"	# a goto at the beginning of a line or after a non-alphanumeric char
       
  5292 script.iFileExts = ["cpp"]
       
  5293 script.iCategory = KCategoryCodingStandards
       
  5294 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5295 script.iSeverity = KSeverityLow
       
  5296 
       
  5297 scanner.AddScript(script)
       
  5298 
       
  5299 # #################################################################
       
  5300 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5301 # All rights reserved.
       
  5302 # 
       
  5303 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5304 # 
       
  5305 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5306 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5307 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5308 # 
       
  5309 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5310 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5311 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5312 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5313 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5314 #
       
  5315 # ifassignments.py
       
  5316 #
       
  5317 # Checks : Assignment in an If statement.
       
  5318 #
       
  5319 # Reason : Assignments inside an If statement often indicate that 
       
  5320 # the assignment was not intended. Even if the assignment was 
       
  5321 # intended, it is clearer to separate out the assignment from the 
       
  5322 # conditional. The script that detects such occurrences has a few 
       
  5323 # false positives when the action statements are on the same line 
       
  5324 # as the conditional check. However, this is also against the 
       
  5325 # coding standards and the action should be on a separate line.
       
  5326 #
       
  5327 # #################################################################
       
  5328 
       
  5329 script = CScript("ifassignments")
       
  5330 script.iReString = "^\s*if\s*\(\s*.*[A-Za-z0-9_]\s*=\s*[A-Za-z0-9_].*\)"
       
  5331 script.iFileExts = ["h", "cpp", "c"]
       
  5332 script.iCategory = KCategoryCodingStandards
       
  5333 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5334 script.iSeverity = KSeverityLow
       
  5335 
       
  5336 scanner.AddScript(script)
       
  5337 
       
  5338 # #################################################################
       
  5339 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5340 # All rights reserved.
       
  5341 # 
       
  5342 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5343 # 
       
  5344 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5345 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5346 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5347 # 
       
  5348 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5349 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5350 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5351 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5352 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5353 #
       
  5354 # ifpreprocessor.py
       
  5355 #
       
  5356 # Checks : Use of #if in .h files.
       
  5357 #
       
  5358 # Reason : #if in header files should only be used before the 
       
  5359 # main include guards and not around #include statements or around 
       
  5360 # functional blocks in class definitions. The reason for the latter 
       
  5361 # is to aid readability and to make BC breaks more difficult.
       
  5362 #
       
  5363 # #################################################################
       
  5364 
       
  5365 script = CScript("ifpreprocessor")
       
  5366 script.iReString = "^\s*\#if(.*)"
       
  5367 script.iFileExts = ["h"]
       
  5368 script.iCategory = KCategoryCodingStandards
       
  5369 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5370 script.iSeverity = KSeverityLow
       
  5371 
       
  5372 def ifpreprocessorcompare(lines, currentline, rematch, filename):
       
  5373 	m = rematch.search(lines[currentline])
       
  5374 	if m:
       
  5375 		text = m.group(1)
       
  5376 		slashindex = filename.rfind("/")
       
  5377 		if slashindex == -1 :
       
  5378 			slashindex = filename.rfind("\\")			
       
  5379 		if (slashindex <> -1) and (text.upper().find(filename[slashindex+1:-2].upper()) == -1):
       
  5380 			return 1
       
  5381 		else:
       
  5382 			return 0
       
  5383 
       
  5384 script.iCompare = ifpreprocessorcompare
       
  5385 scanner.AddScript(script)
       
  5386 
       
  5387 # #################################################################
       
  5388 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5389 # All rights reserved.
       
  5390 # 
       
  5391 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5392 # 
       
  5393 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5394 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5395 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5396 # 
       
  5397 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5398 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5399 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5400 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5401 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5402 #
       
  5403 # inheritaenceorder.py
       
  5404 #
       
  5405 # Checks : Incorrect inheritance order of M and C classes.
       
  5406 #
       
  5407 # Reason : If a C class inherits first from an M class and then a 
       
  5408 # C class, a panic can occur when trying to pop a CBase pointer 
       
  5409 # pointing to such a class from the cleanup stack when in fact a 
       
  5410 # pointer pointing to the first predecessor, the mixin class, was 
       
  5411 # popped instead.
       
  5412 #
       
  5413 # #################################################################
       
  5414 
       
  5415 script = CScript("inheritanceorder")
       
  5416 script.iReString = r"""
       
  5417     ^\s*         # optional whitespace
       
  5418     class
       
  5419     \s+          # whitespace
       
  5420     (\w+::)?
       
  5421     (\w+)        # class name
       
  5422     \s*          # optional whitespace
       
  5423     :
       
  5424     (.*)         # inheritance list
       
  5425     """
       
  5426 script.iFileExts = ["h", "cpp"]
       
  5427 script.iCategory = KCategoryCanPanic
       
  5428 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5429 script.iSeverity = KSeverityHigh
       
  5430 
       
  5431 def inheritancecompare(lines, currentline, rematch, filename):
       
  5432     m = rematch.search(lines[currentline])
       
  5433     if m:
       
  5434         className = m.group(2)
       
  5435         if className[0] <> "C" or (len(className) == 1) or not className[1].isupper():
       
  5436             return 0
       
  5437 
       
  5438         inheritanceString = m.group(3)
       
  5439 
       
  5440         # check for inheritance list spanning multiple lines
       
  5441         i = currentline + 1
       
  5442         while (inheritanceString.find("{") == -1) and i < len(lines):
       
  5443             if (inheritanceString.find(";") <> -1):
       
  5444                 return 0
       
  5445             inheritanceString += lines[i]
       
  5446             i += 1
       
  5447 
       
  5448         # construct inheritance class list
       
  5449         inheritancelist = inheritanceString.split(",")
       
  5450         reclass = re.compile("[\s:]*(public|protected|private)?\s*([\w:]+)")
       
  5451         classlist = []
       
  5452         for inheritance in inheritancelist:
       
  5453             match = reclass.search(inheritance)
       
  5454             if match:
       
  5455                 inheritclass = match.group(2)
       
  5456                 colonpos = inheritclass.rfind(":")
       
  5457                 if (colonpos <> -1):
       
  5458                     inheritclass = inheritclass[colonpos + 1:]
       
  5459                 classlist.append(inheritclass)
       
  5460 
       
  5461         # check the order of M and C classes in inheritance class list 
       
  5462         mclassIndex = -1
       
  5463         cclassIndex = -1
       
  5464         for classname in classlist:
       
  5465             if (len(classname) > 2):
       
  5466                 if classname[0] == "M" and classname[1].isupper() and mclassIndex == -1:
       
  5467                     mclassIndex = classlist.index(classname)
       
  5468                 if classname[0] == "C" and classname[1].isupper() and cclassIndex == -1:
       
  5469                     cclassIndex = classlist.index(classname)
       
  5470         if mclassIndex != -1 and cclassIndex != -1 and mclassIndex < cclassIndex:
       
  5471             return 1
       
  5472         else:
       
  5473             return 0
       
  5474 
       
  5475     return 0
       
  5476 
       
  5477 script.iCompare = inheritancecompare
       
  5478 scanner.AddScript(script)
       
  5479 
       
  5480 # #################################################################
       
  5481 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5482 # All rights reserved.
       
  5483 # 
       
  5484 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5485 # 
       
  5486 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5487 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5488 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5489 # 
       
  5490 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5491 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5492 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5493 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5494 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5495 #
       
  5496 # intleaves.py
       
  5497 #
       
  5498 # Checks : Methods that leave AND return a TInt error.
       
  5499 #
       
  5500 # Reason : Returning an error code as well as being able to leave 
       
  5501 # is problematical for the caller. It is preferable to adhere to 
       
  5502 # one method of returning the error. Note: CodeScanner is likely to 
       
  5503 # return false positives for this situation, because some returned 
       
  5504 # TInt values will not be error codes.
       
  5505 #
       
  5506 # #################################################################
       
  5507 
       
  5508 script = CScript("intleaves")
       
  5509 script.iReString = "TInt\s+\w+::\w+LC?\s*\("
       
  5510 script.iFileExts = ["h", "cpp"]
       
  5511 script.iCategory = KCategoryCodeReviewGuides
       
  5512 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5513 script.iSeverity = KSeverityLow
       
  5514 
       
  5515 scanner.AddScript(script)
       
  5516 
       
  5517 # #################################################################
       
  5518 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5519 # All rights reserved.
       
  5520 # 
       
  5521 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5522 # 
       
  5523 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5524 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5525 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5526 # 
       
  5527 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5528 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5529 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5530 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5531 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5532 #
       
  5533 # jmp.py
       
  5534 #
       
  5535 # Checks : Use of setjmp and/or longjmp.
       
  5536 #
       
  5537 # Reason : Using setjmp and/or longjmp makes code less maintainable.
       
  5538 #
       
  5539 # #################################################################
       
  5540 
       
  5541 script = CScript("jmp")
       
  5542 script.iReString = r"""
       
  5543 	(set|long)jmp
       
  5544 	"""
       
  5545 script.iFileExts = ["cpp", "h"]
       
  5546 script.iCategory = KCategoryCodingStandards
       
  5547 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5548 script.iSeverity = KSeverityLow
       
  5549 
       
  5550 scanner.AddScript(script)
       
  5551 
       
  5552 # #################################################################
       
  5553 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5554 # All rights reserved.
       
  5555 # 
       
  5556 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5557 # 
       
  5558 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5559 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5560 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5561 # 
       
  5562 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5563 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5564 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5565 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5566 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5567 #
       
  5568 # leave.py
       
  5569 #
       
  5570 # Checks : Leaving functions called in non-leaving functions.
       
  5571 #
       
  5572 # Reason : Non-leaving functions should not call leaving functions. 
       
  5573 # Note: Operator functions are considered to be able to leave when 
       
  5574 # scanning the code inside them.
       
  5575 #
       
  5576 # #################################################################
       
  5577 
       
  5578 script = CScript("leave")
       
  5579 script.iReString = KReStringLeavingLine
       
  5580 script.iFileExts = ["cpp"]
       
  5581 script.iCategory = KCategoryCanPanic
       
  5582 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5583 script.iSeverity = KSeverityHigh
       
  5584 
       
  5585 reLeavingMethod = re.compile("""
       
  5586 	(
       
  5587 	\s*operator
       
  5588 	|
       
  5589 	\w*
       
  5590 	[a-z]
       
  5591 	\w*
       
  5592 	L
       
  5593 	(C(C*|[2-9])|D|P|X)?
       
  5594 	$
       
  5595 	)
       
  5596 """, re.VERBOSE)
       
  5597 
       
  5598 def leavecompare(lines, currentline, rematch, filename):
       
  5599 	currentMethod = scanner.iCurrentMethodName
       
  5600 	if (currentMethod <> "") and (currentMethod[:5] <> "Leave"):
       
  5601 		m = rematch.search(lines[currentline])
       
  5602 		if m and not reLeavingMethod.search(currentMethod):
       
  5603 			line = lines[currentline]
       
  5604 			startline = currentline
       
  5605 			if (lines[currentline].find("TRAP") != -1):
       
  5606 				return 0
       
  5607 
       
  5608 			bracketCount = line.count("(") - line.count(")")
       
  5609 			startBracketCount = bracketCount
       
  5610 
       
  5611 			while (currentline > startline - 40) and (currentline >= 0):
       
  5612 				currentline -= 1
       
  5613 				line = lines[currentline]
       
  5614 				bracketCount += line.count("(") - line.count(")")
       
  5615 				if (lines[currentline].find("TRAP") != -1) and (bracketCount == startBracketCount + 1):
       
  5616 					return 0
       
  5617 			return 1
       
  5618 
       
  5619 	return 0
       
  5620 
       
  5621 script.iCompare = leavecompare
       
  5622 scanner.AddScript(script)
       
  5623 
       
  5624 # #################################################################
       
  5625 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5626 # All rights reserved.
       
  5627 # 
       
  5628 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5629 # 
       
  5630 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5631 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5632 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5633 # 
       
  5634 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5635 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5636 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5637 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5638 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5639 #
       
  5640 # LeaveNoError.py
       
  5641 #
       
  5642 # Checks : Leaving with KErrNone.
       
  5643 #
       
  5644 # Reason : Leaving with KErrNone usually indicates that there is a 
       
  5645 # makeshift way around a design issue rather than a true and proper 
       
  5646 # fix to the architecture.
       
  5647 #
       
  5648 # #################################################################
       
  5649 
       
  5650 script = CScript("LeaveNoError")
       
  5651 script.iReString = "User\s*::\s*Leave\(\s*KErrNone\s*\)"
       
  5652 script.iFileExts = ["cpp", "h", "c", "inl"]
       
  5653 script.iCategory = KCategoryWrongFunctionality
       
  5654 script.iIgnore = KIgnoreComments
       
  5655 script.iSeverity = KSeverityMedium
       
  5656 
       
  5657 scanner.AddScript(script)
       
  5658 
       
  5659 # #################################################################
       
  5660 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5661 # All rights reserved.
       
  5662 # 
       
  5663 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5664 # 
       
  5665 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5666 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5667 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5668 # 
       
  5669 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5670 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5671 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5672 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5673 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5674 #
       
  5675 # leavingoperators.py
       
  5676 #
       
  5677 # Checks : Leaving functions called in operator functions.
       
  5678 #
       
  5679 # Reason : It is not obvious that operator functions can leave. 
       
  5680 # Calling leaving functions in operator functions should be 
       
  5681 # considered carefully.
       
  5682 #
       
  5683 # #################################################################
       
  5684 
       
  5685 script = CScript("leavingoperators")
       
  5686 script.iReString = "(\w*[a-z]\w*L(C*|D|P))\s*\(|ELeave|User::Leave|tream\s+<<|tream\s+>>"
       
  5687 script.iFileExts = ["cpp"]
       
  5688 script.iCategory = KCategoryCodeReviewGuides
       
  5689 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5690 script.iSeverity = KSeverityLow
       
  5691 
       
  5692 reOperatorMethod = re.compile("""
       
  5693 	operator
       
  5694 	""", re.VERBOSE)
       
  5695 
       
  5696 def leavecompare(lines, currentline, rematch, filename):
       
  5697 	currentMethod = scanner.iCurrentMethodName
       
  5698 	if (currentMethod <> "") and (currentMethod[:5] <> "Leave"):
       
  5699 		m = rematch.search(lines[currentline])
       
  5700 		if m and reOperatorMethod.search(currentMethod):
       
  5701 			line = lines[currentline]
       
  5702 			startline = currentline
       
  5703 			if (lines[currentline].find("TRAP") != -1):
       
  5704 				return 0
       
  5705 
       
  5706 			bracketCount = line.count("(") - line.count(")")
       
  5707 			startBracketCount = bracketCount
       
  5708 
       
  5709 			while (currentline > startline - 20) and (currentline >= 0):
       
  5710 				currentline -= 1
       
  5711 				line = lines[currentline]
       
  5712 				bracketCount += line.count("(") - line.count(")")
       
  5713 				if (lines[currentline].find("TRAP") != -1) and (bracketCount == startBracketCount + 1):
       
  5714 					return 0
       
  5715 			return 1
       
  5716 
       
  5717 	return 0
       
  5718 
       
  5719 script.iCompare = leavecompare
       
  5720 scanner.AddScript(script)
       
  5721 
       
  5722 # #################################################################
       
  5723 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5724 # All rights reserved.
       
  5725 # 
       
  5726 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5727 # 
       
  5728 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5729 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5730 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5731 # 
       
  5732 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5733 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5734 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5735 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5736 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5737 #
       
  5738 # LFunctionCantLeave.py
       
  5739 #
       
  5740 # Checks : L-functions that cannot leave.
       
  5741 #
       
  5742 # Reason : A function should not be named with an 'L' if it cannot 
       
  5743 # leave. The only exception is in virtual functions where the 
       
  5744 # function name is defined in the base class so the L cannot be 
       
  5745 # emoved. For example, RunL().
       
  5746 #
       
  5747 # #################################################################
       
  5748 
       
  5749 script = CScript("LFunctionCantLeave")
       
  5750 script.iReString = r"""
       
  5751 	[A-Za-z0-9]+			# return type
       
  5752 	\s+
       
  5753 	[C|T|R][A-Za-z0-9]+		# class name
       
  5754 	::
       
  5755 	([A-Za-z0-9]+L(C|D)*)	# leaving function name (possible LC or LD function)
       
  5756 	\s*						# optional whitespace
       
  5757 	\(						# open bracket
       
  5758 	.*						# parameters
       
  5759 	\)						# close bracket
       
  5760 	\s*
       
  5761 	[^;]					# no semicolon after function definition
       
  5762 	"""
       
  5763 script.iFileExts = ["cpp"]
       
  5764 script.iCategory = KCategoryCodeReviewGuides
       
  5765 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5766 script.iSeverity = KSeverityLow
       
  5767 
       
  5768 lfunctioncantleaveLeavingMethod = re.compile("""
       
  5769 	[A-Za-z0-9]+
       
  5770 	L
       
  5771 	(C|D)*
       
  5772 	\(
       
  5773 """, re.VERBOSE)
       
  5774 
       
  5775 lfunctioncantleaveUserLeave = re.compile("""
       
  5776 	User::Leave
       
  5777 	""", re.VERBOSE)
       
  5778 
       
  5779 lfunctioncantleaveNewELeave = re.compile("""
       
  5780 	new
       
  5781 	\s*
       
  5782 	\(
       
  5783 	\s*
       
  5784 	ELeave
       
  5785 	\s*
       
  5786 	\)
       
  5787 """, re.VERBOSE)
       
  5788 
       
  5789 reLFunctionIgnoreStr = "RunL"
       
  5790 scriptNode = script.ScriptConfig()
       
  5791 if (scriptNode <> None):
       
  5792 	for wordNode in scriptNode.getElementsByTagName("LFunctionIgnoreRE"):
       
  5793 		reLFunctionIgnoreStr = wordNode.firstChild.nodeValue
       
  5794 		print "Note: ignoring the following functions when checking for L-functions that cannot leave: " + reLFunctionIgnoreStr
       
  5795 		break
       
  5796 if len(reLFunctionIgnoreStr) > 0:
       
  5797 	reLFunctionIgnores = re.compile(reLFunctionIgnoreStr, re.IGNORECASE)
       
  5798 else :
       
  5799 	reLFunctionIgnores = None
       
  5800 
       
  5801 def lfunctioncantleavecompare(lines, currentline, rematch, filename):
       
  5802 	line = lines[currentline]
       
  5803 	m = rematch.search(line)
       
  5804 
       
  5805 	if m:
       
  5806 		#ignore functions on the ignored list
       
  5807 		functionName = m.group(1)
       
  5808 		if reLFunctionIgnores:
       
  5809 			if reLFunctionIgnores.match(functionName):
       
  5810 				return 0
       
  5811 
       
  5812 		i = currentline
       
  5813 
       
  5814 		# find opening { in function
       
  5815 		while (line.count("{") == 0):
       
  5816 			i = i + 1
       
  5817 			if (i >= len(lines)):
       
  5818 				return 1
       
  5819 			line = lines[i]
       
  5820 
       
  5821 		# if empty function (or one-line function?)
       
  5822 		if (line.count("}") > 0):
       
  5823 			return 1
       
  5824 
       
  5825 		i = i + 1
       
  5826 		bracketDepth = 1
       
  5827 
       
  5828 		while (i < len(lines)):
       
  5829 			line = lines[i]
       
  5830 			if lfunctioncantleaveLeavingMethod.search(line):
       
  5831 				return 0
       
  5832 			if lfunctioncantleaveUserLeave.search(line):
       
  5833 				return 0
       
  5834 			if lfunctioncantleaveNewELeave.search(line):
       
  5835 				return 0 
       
  5836 
       
  5837 			bracketDepth += line.count("{") - line.count("}")
       
  5838 			if (bracketDepth == 0):
       
  5839 				return 1
       
  5840 			i = i + 1
       
  5841 	return 0
       
  5842 
       
  5843 script.iCompare = lfunctioncantleavecompare
       
  5844 scanner.AddScript(script)
       
  5845 
       
  5846 # #################################################################
       
  5847 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5848 # All rights reserved.
       
  5849 # 
       
  5850 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5851 # 
       
  5852 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5853 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5854 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5855 # 
       
  5856 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5857 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5858 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5859 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5860 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5861 #
       
  5862 # longlines.py
       
  5863 #
       
  5864 # Checks : Overly long lines of code.
       
  5865 #
       
  5866 # Reason : Lines longer than about 100 characters can indicate 
       
  5867 # messy or badly-structured code that is hard to maintain.
       
  5868 #
       
  5869 # #################################################################
       
  5870 
       
  5871 script = CScript("longlines")
       
  5872 # use configured line length, if available
       
  5873 scriptNode = script.ScriptConfig()
       
  5874 attrInt = 100
       
  5875 if (scriptNode <> None):
       
  5876 	attr = scriptNode.getAttribute("length")
       
  5877 	attrStr = str(attr)
       
  5878 	attrInt = 0
       
  5879 	if (attrStr.isdigit()):
       
  5880 		attrInt = int(attrStr)
       
  5881 	if (attrInt < 10):
       
  5882 		attrInt = 100
       
  5883 		print "Warning: Invalid line length configured; using default of 100: " + attr
       
  5884 	else:
       
  5885 		print "Note: 'long' line length configured as: " + str(attrInt)
       
  5886 script.iReString = r""".{"""+str(attrInt)+r"""}"""
       
  5887 
       
  5888 script.iFileExts = ["cpp", "h", "rss", "rls", "loc", "ra","mmp"]
       
  5889 script.iCategory = KCategoryCodingStandards
       
  5890 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5891 script.iSeverity = KSeverityLow
       
  5892 
       
  5893 scanner.AddScript(script)
       
  5894 
       
  5895 # #################################################################
       
  5896 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5897 # All rights reserved.
       
  5898 # 
       
  5899 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5900 # 
       
  5901 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5902 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5903 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5904 # 
       
  5905 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5906 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5907 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5908 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5909 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5910 #
       
  5911 # magicnumbers.py
       
  5912 #
       
  5913 # Checks : Use of magic numbers.
       
  5914 #
       
  5915 # Reason : Magic numbers - that is, numbers that are hard-coded 
       
  5916 # into the source code and instead of being presented as constants 
       
  5917 # - make code difficult to maintain and give no indication of why 
       
  5918 # a calculation is the way it is. Magic numbers should be replaced 
       
  5919 # with named constants.
       
  5920 #
       
  5921 # #################################################################
       
  5922 
       
  5923 script = CScript("magicnumbers")
       
  5924 script.iReString = "(.*[^a-zA-Z0-9_])([0-9]+)"
       
  5925 script.iFileExts = ["cpp"]
       
  5926 script.iCategory = KCategoryCodingStandards
       
  5927 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5928 script.iSeverity = KSeverityLow
       
  5929 
       
  5930 reEnum = re.compile("^\s*E\w+\s*=\s*");
       
  5931 
       
  5932 def magiccompare(lines, currentline, rematch, filename):
       
  5933 	m = rematch.search(lines[currentline])
       
  5934 	if m:
       
  5935 		pretext = m.group(1)
       
  5936 		number = m.group(2)
       
  5937 		if (number == "0") or (number == "1") or (number == '2'):
       
  5938 			return 0
       
  5939 		elif (pretext.find("const") <> -1):
       
  5940 			return 0
       
  5941 		else:
       
  5942 			m2 = reEnum.search(pretext)
       
  5943 			if m2:
       
  5944 				return 0
       
  5945 			else:
       
  5946 				return 1
       
  5947 
       
  5948 script.iCompare = magiccompare
       
  5949 scanner.AddScript(script)
       
  5950 
       
  5951 # #################################################################
       
  5952 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5953 # All rights reserved.
       
  5954 # 
       
  5955 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5956 # 
       
  5957 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5958 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5959 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5960 # 
       
  5961 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5962 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5963 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  5964 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  5965 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  5966 #
       
  5967 # mclassdestructor.py
       
  5968 #
       
  5969 # Checks : M class has destructor.
       
  5970 #
       
  5971 # Reason : M classes should not contain a destructor.
       
  5972 #
       
  5973 # #################################################################
       
  5974 
       
  5975 script = CScript("mclassdestructor")
       
  5976 script.iReString = r"""
       
  5977 	::
       
  5978 	\s*				# optional whitespace
       
  5979 	~M[A-Z]			# destructor
       
  5980 	"""
       
  5981 script.iFileExts = ["cpp", "h"]
       
  5982 script.iCategory = KCategoryCodingStandards
       
  5983 script.iIgnore = KIgnoreCommentsAndQuotes
       
  5984 script.iSeverity = KSeverityLow
       
  5985 
       
  5986 scanner.AddScript(script)
       
  5987 # #################################################################
       
  5988 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  5989 # All rights reserved.
       
  5990 # 
       
  5991 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  5992 # 
       
  5993 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  5994 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  5995 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  5996 # 
       
  5997 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  5998 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  5999 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6000 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6001 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6002 #
       
  6003 # memberlc.py
       
  6004 #
       
  6005 # Checks : Assigning LC methods to member variables.
       
  6006 #
       
  6007 # Reason : Objects on the cleanup stack should not be assigned to 
       
  6008 # member variables.
       
  6009 #
       
  6010 # #################################################################
       
  6011 
       
  6012 script = CScript("memberlc")
       
  6013 script.iReString = r"""
       
  6014 	^\s*
       
  6015 	i[A-Z]\w*
       
  6016 	\s*
       
  6017 	=
       
  6018 	\s*
       
  6019 	[\w:]+
       
  6020 	LC
       
  6021 	\s*
       
  6022 	\(
       
  6023 	"""
       
  6024 script.iFileExts = ["cpp"]
       
  6025 script.iCategory = KCategoryCanPanic
       
  6026 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6027 script.iSeverity = KSeverityHigh
       
  6028 
       
  6029 reMemberLCPop = re.compile("\s*CleanupStack::Pop\s*\(")
       
  6030 
       
  6031 def memberlccompare(lines, currentline, rematch, filename):
       
  6032 	if rematch.search(lines[currentline]):
       
  6033 		if (currentline + 1) < len(lines):
       
  6034 			if reMemberLCPop.search(lines[currentline + 1]):
       
  6035 				return 0	# next line is a Pop
       
  6036 			else:
       
  6037 				return 1
       
  6038 		else:					
       
  6039 			return 1
       
  6040 	else:
       
  6041 		return 0
       
  6042 
       
  6043 script.iCompare = memberlccompare
       
  6044 scanner.AddScript(script)
       
  6045 
       
  6046 # #################################################################
       
  6047 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6048 # All rights reserved.
       
  6049 # 
       
  6050 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6051 # 
       
  6052 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6053 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6054 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6055 # 
       
  6056 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6057 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6058 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6059 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6060 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6061 #
       
  6062 # membervariablecallld.py
       
  6063 #
       
  6064 # Checks : Calling LD function on member variable.
       
  6065 #
       
  6066 # Reason : LD functions should not be called on a member variable 
       
  6067 # because ownership can be unclear and may lead to double deletes.
       
  6068 #
       
  6069 # #################################################################
       
  6070 
       
  6071 script = CScript("membervariablecallld")
       
  6072 script.iReString = r"""
       
  6073 	i[A-Z]			# instance variable
       
  6074 	\w+				# rest of the instance variable name
       
  6075 	\s*				# optional whitespace
       
  6076 	(.|->)			# operator
       
  6077 	\s*				# optional whitespace
       
  6078 	[A-Z]			# classname
       
  6079 	\w+				# rest of the instance variable name
       
  6080 	LD\(			# LD function
       
  6081 	"""
       
  6082 script.iFileExts = ["cpp"]
       
  6083 script.iCategory = KCategoryCodingStandards
       
  6084 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6085 script.iSeverity = KSeverityLow
       
  6086 
       
  6087 scanner.AddScript(script)
       
  6088 
       
  6089 # #################################################################
       
  6090 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6091 # All rights reserved.
       
  6092 # 
       
  6093 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6094 # 
       
  6095 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6096 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6097 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6098 # 
       
  6099 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6100 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6101 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6102 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6103 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6104 #
       
  6105 # missingcancel.py
       
  6106 #
       
  6107 # Checks : Cancel() not called in active object's destructor.
       
  6108 # 
       
  6109 # Reason : Cancel() should always be called in active object's 
       
  6110 # destructor to cancel an outstanding request if there is one. 
       
  6111 # If there is no request pending then Cancel() just does nothing, 
       
  6112 # but if we do not call Cancel() when having an outstanding request 
       
  6113 # a panic will be raised. CodeScanner occasionally gives false 
       
  6114 # positives for this issue. Individual cases should be 
       
  6115 # investigated.
       
  6116 #
       
  6117 # #################################################################
       
  6118 
       
  6119 script = CScript("missingcancel")
       
  6120 script.iReString = r"""
       
  6121     ::
       
  6122     \s*        # optional whitespace
       
  6123     ~C(\w+)
       
  6124     """
       
  6125 script.iFileExts = ["cpp"]
       
  6126 script.iCategory = KCategoryCodingStandards
       
  6127 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6128 script.iSeverity = KSeverityLow
       
  6129 
       
  6130 # possible active and timer object types
       
  6131 activeObjectType = re.compile("\w+Active$")
       
  6132 timerObjectType = re.compile("\w+Timer$")
       
  6133 
       
  6134 cancelFunction = re.compile("""
       
  6135     Cancel
       
  6136     \s*
       
  6137     \(
       
  6138     """, re.VERBOSE)
       
  6139 
       
  6140 def isActiveDestructor(destructorType):
       
  6141     if (activeObjectType.match(destructorType)) or (timerObjectType.match(destructorType)):
       
  6142         return True
       
  6143     return False
       
  6144 
       
  6145 def cancelcompare(lines, currentline, rematch, filename):
       
  6146     line = lines[currentline]
       
  6147     m = rematch.search(line)
       
  6148 
       
  6149     if m:
       
  6150         destructorType = m.group(1)
       
  6151         # skip non-active types
       
  6152         if (not isActiveDestructor(destructorType)):
       
  6153             return 0
       
  6154 
       
  6155         i = currentline
       
  6156 
       
  6157         # find opening { in function
       
  6158         while (line.count("{") == 0):
       
  6159             i = i + 1
       
  6160             if (i >= len(lines)):
       
  6161                 return 1
       
  6162             line = lines[i]
       
  6163 
       
  6164         # if one-line or empty function
       
  6165         if (line.count("}") > 0):
       
  6166             if (cancelFunction.search(line)):
       
  6167                 return 0
       
  6168             else:
       
  6169                 return 1
       
  6170 
       
  6171         i = i + 1
       
  6172         bracketDepth = 1
       
  6173         while (i < len(lines)):
       
  6174             line = lines[i]
       
  6175             if (cancelFunction.search(line)):
       
  6176                 return 0
       
  6177 
       
  6178             bracketDepth += line.count("{") - line.count("}")
       
  6179             if (bracketDepth == 0):
       
  6180                 return 1
       
  6181             i = i + 1
       
  6182     return 0
       
  6183 
       
  6184 script.iCompare = cancelcompare
       
  6185 scanner.AddScript(script)
       
  6186 
       
  6187 # #################################################################
       
  6188 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6189 # All rights reserved.
       
  6190 # 
       
  6191 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6192 # 
       
  6193 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6194 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6195 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6196 # 
       
  6197 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6198 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6199 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6200 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6201 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6202 #
       
  6203 # missingcclass.py
       
  6204 #
       
  6205 # Checks : C class not inheriting from another C class.
       
  6206 #
       
  6207 # Reason : All C classes should inherit from another C class to 
       
  6208 # ensure that all data members are zeroed.
       
  6209 #
       
  6210 # #################################################################
       
  6211 
       
  6212 script = CScript("missingcclass")
       
  6213 script.iReString = r"""
       
  6214 	^\s*
       
  6215 	class
       
  6216 	\s+
       
  6217 	(\w+::)?
       
  6218 	(\w+)
       
  6219 	\s*
       
  6220 	(.*)"""
       
  6221 script.iFileExts = ["h", "cpp"]
       
  6222 script.iCategory = KCategoryCanPanic
       
  6223 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6224 script.iSeverity = KSeverityHigh
       
  6225 
       
  6226 reCClassIgnoreStr = ""
       
  6227 scriptNode = script.ScriptConfig()
       
  6228 if (scriptNode <> None):
       
  6229 	for wordNode in scriptNode.getElementsByTagName("cclassIgnoreRE"):
       
  6230 		reCClassIgnoreStr = wordNode.firstChild.nodeValue
       
  6231 		print "Note: ignoring the following classes when checking for C class not inheriting from another C class: " + reCClassIgnoreStr
       
  6232 		break
       
  6233 if len(reCClassIgnoreStr) > 0:
       
  6234 	reCClassIgnores = re.compile(reCClassIgnoreStr, re.IGNORECASE)
       
  6235 else :
       
  6236 	reCClassIgnores = None
       
  6237 
       
  6238 def missingcclasscompare(lines, currentline, rematch, filename):
       
  6239 	m = rematch.search(lines[currentline])
       
  6240 	if m:
       
  6241 		className = m.group(2)
       
  6242 		if className[0] <> "C" or (len(className) == 1) or not className[1].isupper():
       
  6243 			return 0
       
  6244 
       
  6245 		#ignore classes on the ignored list
       
  6246 		if reCClassIgnores:
       
  6247 			if reCClassIgnores.search(className):
       
  6248 				return 0
       
  6249 
       
  6250 		inheritanceString = m.group(3)
       
  6251 		i = currentline + 1
       
  6252 		while (inheritanceString.find("{") == -1) and i < len(lines):
       
  6253 			if (inheritanceString.find(";") <> -1):
       
  6254 				return 0
       
  6255 			inheritanceString += lines[i]
       
  6256 			i += 1
       
  6257 		
       
  6258 		inheritancelist = inheritanceString.split(",")
       
  6259 
       
  6260 		reclass = re.compile("[\s:]*(public|protected|private)?\s*([\w:]+)")
       
  6261 		classlist = []
       
  6262 		for inheritance in inheritancelist:
       
  6263 			match = reclass.search(inheritance)
       
  6264 			if match:
       
  6265 				inheritclass = match.group(2)
       
  6266 				colonpos = inheritclass.rfind(":")
       
  6267 				if (colonpos <> -1):
       
  6268 					inheritclass = inheritclass[colonpos + 1:]
       
  6269 				classlist.append(inheritclass)
       
  6270 
       
  6271 		ccount = 0
       
  6272 		for classname in classlist:
       
  6273 			if (len(classname) > 2) and classname[0] == "C" and classname[1].isupper():
       
  6274 				ccount += 1
       
  6275 				
       
  6276 		if ccount == 0:
       
  6277 			return 1
       
  6278 		else:
       
  6279 			return 0
       
  6280 	else:
       
  6281 		return 0
       
  6282 
       
  6283 script.iCompare = missingcclasscompare
       
  6284 scanner.AddScript(script)
       
  6285 
       
  6286 # #################################################################
       
  6287 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6288 # All rights reserved.
       
  6289 # 
       
  6290 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6291 # 
       
  6292 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6293 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6294 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6295 # 
       
  6296 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6297 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6298 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6299 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6300 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6301 #
       
  6302 # mmpsourcepath.py
       
  6303 #
       
  6304 # Checks : Use of absolute path names in MMP files.
       
  6305 #
       
  6306 # Reason : Use of absolute paths in MMP files makes it impossible 
       
  6307 # to relocate the source. Relative paths should be used instead.
       
  6308 #
       
  6309 # #################################################################
       
  6310 
       
  6311 script = CScript("mmpsourcepath")
       
  6312 script.iReString = "^\s*[Ss][Oo][Uu][Rr][Cc][Ee][Pp][Aa][Tt][Hh]\s*\\\\"
       
  6313 script.iFileExts = ["mmp"]
       
  6314 script.iCategory = KCategoryCodingStandards
       
  6315 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6316 script.iSeverity = KSeverityLow
       
  6317 
       
  6318 scanner.AddScript(script)
       
  6319 
       
  6320 # #################################################################
       
  6321 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6322 # All rights reserved.
       
  6323 # 
       
  6324 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6325 # 
       
  6326 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6327 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6328 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6329 # 
       
  6330 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6331 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6332 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6333 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6334 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6335 #
       
  6336 # multilangrsc.py
       
  6337 #
       
  6338 # Checks : Not using BaflUtils::NearestLanguageFile() when loading 
       
  6339 # a resource file.
       
  6340 #
       
  6341 # Reason : If AddResourceFileL() is used without first using 
       
  6342 # BaflUtils::NearestLanguageFile(), then not all language versions 
       
  6343 # of resources will be picked up.
       
  6344 #
       
  6345 # #################################################################
       
  6346 
       
  6347 script = CScript("multilangrsc")
       
  6348 script.iReString = """
       
  6349 	AddResourceFileL
       
  6350 	\s*
       
  6351 	\(
       
  6352 	\s*\w+.*
       
  6353 	\)
       
  6354 	"""
       
  6355 script.iFileExts = ["cpp"]
       
  6356 script.iCategory = KCategoryCodeReviewGuides
       
  6357 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6358 script.iSeverity = KSeverityLow
       
  6359 
       
  6360 reBaflNearestLanguage = re.compile("""
       
  6361 	\s*
       
  6362 	BaflUtils::NearestLanguageFile
       
  6363 	\s*
       
  6364 	\(
       
  6365 	\s*\w+.*
       
  6366 	\)
       
  6367 	""", re.VERBOSE)
       
  6368 
       
  6369 def multilangrsccompare(lines, currentline, rematch, filename):
       
  6370 	if (scanner.iCurrentMethodName <> ""):
       
  6371 		m = rematch.search(lines[currentline])
       
  6372 		if m:
       
  6373 			scanLineNum = currentline
       
  6374 			while (scanLineNum>scanner.iCurrentMethodStart):
       
  6375 				addResMatch = reBaflNearestLanguage.search(lines[scanLineNum])
       
  6376 				if addResMatch:
       
  6377 					return 0
       
  6378 				scanLineNum = scanLineNum - 1
       
  6379 			return 1
       
  6380 	return 0
       
  6381 
       
  6382 script.iCompare = multilangrsccompare
       
  6383 scanner.AddScript(script)
       
  6384 
       
  6385 # #################################################################
       
  6386 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6387 # All rights reserved.
       
  6388 # 
       
  6389 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6390 # 
       
  6391 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6392 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6393 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6394 # 
       
  6395 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6396 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6397 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6398 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6399 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6400 #
       
  6401 # multipledeclarations.py
       
  6402 #
       
  6403 # Checks : Multiple declarations on one line.
       
  6404 #
       
  6405 # Reason : Multiple declarations on one line can be confusing. 
       
  6406 # Separate them out so that each declaration is on its own separate 
       
  6407 # line.
       
  6408 #
       
  6409 # #################################################################
       
  6410 
       
  6411 script = CScript("multipledeclarations")
       
  6412 script.iReString = r"""
       
  6413 	\w+		# variable name
       
  6414 	\s*		# optional whitespace
       
  6415 	=
       
  6416 	\s*		# optional whitespace
       
  6417 	\w+		# variable value
       
  6418 	\s*		# optional whitespace
       
  6419 	,
       
  6420 	\s*		# optional whitespace
       
  6421 	\w+		# variable name
       
  6422 	\s*		# optional whitespace
       
  6423 	=
       
  6424 	\s*		# optional whitespace
       
  6425 	\w+		# variable value
       
  6426 	\s*		# optional whitespace
       
  6427 	;
       
  6428 	"""
       
  6429 script.iFileExts = ["h", "cpp"]
       
  6430 script.iCategory = KCategoryCodingStandards
       
  6431 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6432 script.iSeverity = KSeverityLow
       
  6433 
       
  6434 scanner.AddScript(script)
       
  6435 
       
  6436 # #################################################################
       
  6437 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6438 # All rights reserved.
       
  6439 # 
       
  6440 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6441 # 
       
  6442 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6443 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6444 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6445 # 
       
  6446 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6447 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6448 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6449 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6450 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6451 #
       
  6452 # multipleinheritance.py
       
  6453 #
       
  6454 # Checks : Non M-class multiple inheritance.
       
  6455 #
       
  6456 # Reason : It is bad Symbian OS practice to derive from two classes 
       
  6457 # that have implemented functions. Complex behaviour that was not 
       
  6458 # intended can result.
       
  6459 #
       
  6460 # #################################################################
       
  6461 
       
  6462 script = CScript("multipleinheritance")
       
  6463 script.iReString = r"""
       
  6464 	^\s*
       
  6465 	class
       
  6466 	\s+
       
  6467 	(\w+::)?
       
  6468 	(\w+)
       
  6469 	\s*
       
  6470 	:
       
  6471 	(.*)"""
       
  6472 script.iFileExts = ["h", "cpp"]
       
  6473 script.iCategory = KCategoryWrongFunctionality
       
  6474 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6475 script.iSeverity = KSeverityMedium
       
  6476 
       
  6477 def classcompare(lines, currentline, rematch, filename):
       
  6478 	m = rematch.search(lines[currentline])
       
  6479 	if m:
       
  6480 		className = m.group(2)
       
  6481 		if className[0] <> "C" or (len(className) == 1) or not className[1].isupper():
       
  6482 			return 0
       
  6483 
       
  6484 		inheritanceString = m.group(3)
       
  6485 		i = currentline + 1
       
  6486 		while (inheritanceString.find("{") == -1) and i < len(lines):
       
  6487 			if (inheritanceString.find(";") <> -1):
       
  6488 				return 0
       
  6489 			inheritanceString += lines[i]
       
  6490 			i += 1
       
  6491 		
       
  6492 		inheritancelist = inheritanceString.split(",")
       
  6493 
       
  6494 		reclass = re.compile("[\s:]*(public|protected|private)?\s*([\w:]+)")
       
  6495 		classlist = []
       
  6496 		for inheritance in inheritancelist:
       
  6497 			match = reclass.search(inheritance)
       
  6498 			if match:
       
  6499 				inheritclass = match.group(2)
       
  6500 				colonpos = inheritclass.rfind(":")
       
  6501 				if (colonpos <> -1):
       
  6502 					inheritclass = inheritclass[colonpos + 1:]
       
  6503 				classlist.append(inheritclass)
       
  6504 
       
  6505 		ccount = 0
       
  6506 		for classname in classlist:
       
  6507 			if (len(classname) > 2) and classname[0] == "C" and classname[1].isupper():
       
  6508 				ccount += 1
       
  6509 				
       
  6510 		if ccount > 1:
       
  6511 			return 1
       
  6512 		else:
       
  6513 			return 0
       
  6514 	else:
       
  6515 		return 0
       
  6516 
       
  6517 script.iCompare = classcompare
       
  6518 scanner.AddScript(script)
       
  6519 
       
  6520 # #################################################################
       
  6521 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6522 # All rights reserved.
       
  6523 # 
       
  6524 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6525 # 
       
  6526 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6527 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6528 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6529 # 
       
  6530 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6531 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6532 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6533 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6534 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6535 #
       
  6536 # mydocs.py
       
  6537 #
       
  6538 # Checks : Hard-coded mydocs directory strings.
       
  6539 # 
       
  6540 # Reason : The mydocs directory is subject to change so should not 
       
  6541 # be referenced directly. Note: @    This issue will only occur in 
       
  6542 # code developed for the Nokia Series 90 platform.
       
  6543 #
       
  6544 # #################################################################
       
  6545 
       
  6546 script = CScript("mydocs")
       
  6547 script.iReString = """".*[Mm][Yy][Dd][Oo][Cc][Ss]"""
       
  6548 script.iFileExts = ["cpp", "h", "rss", "rls", "loc", "ra"]
       
  6549 script.iCategory = KCategoryWrongFunctionality
       
  6550 script.iIgnore = KIgnoreComments
       
  6551 script.iSeverity = KSeverityMedium
       
  6552 
       
  6553 scanner.AddScript(script)
       
  6554 
       
  6555 # #################################################################
       
  6556 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6557 # All rights reserved.
       
  6558 # 
       
  6559 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6560 # 
       
  6561 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6562 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6563 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6564 # 
       
  6565 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6566 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6567 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6568 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6569 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6570 #
       
  6571 # namespace.py
       
  6572 #
       
  6573 # Checks : Use of namespace.
       
  6574 #
       
  6575 # Reason : Namespaces are often used to work around a poor naming 
       
  6576 # convention.
       
  6577 #
       
  6578 # #################################################################
       
  6579 
       
  6580 script = CScript("namespace")
       
  6581 script.iReString = "^\s*namespace\s*"
       
  6582 script.iFileExts = ["cpp", "h", "hpp"]
       
  6583 script.iCategory = KCategoryCodingStandards
       
  6584 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6585 script.iSeverity = KSeverityLow
       
  6586 
       
  6587 scanner.AddScript(script)
       
  6588 
       
  6589 # #################################################################
       
  6590 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6591 # All rights reserved.
       
  6592 # 
       
  6593 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6594 # 
       
  6595 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6596 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6597 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6598 # 
       
  6599 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6600 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6601 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6602 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6603 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6604 #
       
  6605 # newlreferences.py
       
  6606 #
       
  6607 # Checks : NewL() returning a reference.
       
  6608 #
       
  6609 # Reason : NewL() and NewLC() functions should return a pointer to 
       
  6610 # an object created on the heap.
       
  6611 #
       
  6612 # #################################################################
       
  6613 
       
  6614 script = CScript("newlreferences")
       
  6615 script.iReString = "&\s*NewL"
       
  6616 script.iFileExts = ["cpp", "h", "hpp", "inl", "c"]
       
  6617 script.iCategory = KCategoryCodingStandards
       
  6618 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6619 script.iSeverity = KSeverityLow
       
  6620 
       
  6621 scanner.AddScript(script)
       
  6622 
       
  6623 # #################################################################
       
  6624 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6625 # All rights reserved.
       
  6626 # 
       
  6627 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6628 # 
       
  6629 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6630 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6631 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6632 # 
       
  6633 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6634 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6635 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6636 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6637 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6638 #
       
  6639 # noleavetrap.py
       
  6640 #
       
  6641 # Checks : TRAP used with no leaving functions.
       
  6642 #
       
  6643 # Reason : A TRAP is unnecessary if there are no leaving functions.
       
  6644 #
       
  6645 # #################################################################
       
  6646 
       
  6647 script = CScript("noleavetrap")
       
  6648 script.iReString = "^\s*TRAPD?"
       
  6649 script.iFileExts = ["cpp"]
       
  6650 script.iCategory = KCategoryCodeReviewGuides
       
  6651 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6652 script.iSeverity = KSeverityLow
       
  6653 
       
  6654 reLeave = re.compile("(L[CDP]?\s*\(|ELeave|\)\s*\(|<<|>>)")
       
  6655 
       
  6656 def noleavetrapcompare(lines, currentline, rematch, filename):
       
  6657     line = lines[currentline]
       
  6658     m = rematch.search(line)
       
  6659     if m:
       
  6660     	if (line.find("(") == -1) and (currentline + 1 < len(lines)):
       
  6661     		currentline += 1
       
  6662     		line = lines[currentline]
       
  6663 
       
  6664         bracketCount = line.count("(") - line.count(")")
       
  6665         found = reLeave.search(line) 
       
  6666 
       
  6667         while (bracketCount > 0) and (currentline + 1 < len(lines)):
       
  6668             currentline += 1
       
  6669             line = lines[currentline]
       
  6670             bracketCount += line.count("(") - line.count(")")
       
  6671             if not found:
       
  6672                 found = reLeave.search(line) 
       
  6673 
       
  6674         if found:
       
  6675             return 0
       
  6676         else:
       
  6677         	return 1
       
  6678 
       
  6679     return 0
       
  6680 
       
  6681 script.iCompare = noleavetrapcompare
       
  6682 scanner.AddScript(script)
       
  6683 
       
  6684 # #################################################################
       
  6685 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6686 # All rights reserved.
       
  6687 # 
       
  6688 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6689 # 
       
  6690 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6691 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6692 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6693 # 
       
  6694 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6695 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6696 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6697 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6698 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6699 #
       
  6700 # nonconsthbufc.py
       
  6701 #
       
  6702 # Checks : Non-const HBufC* parameter passing.
       
  6703 #
       
  6704 # Reason : HBufC* parameters should almost always be passed as a 
       
  6705 # const pointer.
       
  6706 #
       
  6707 # #################################################################
       
  6708 
       
  6709 script = CScript("nonconsthbufc")
       
  6710 script.iReString = """
       
  6711     (\(|,)?        # open bracket or preceeding comma
       
  6712     \s*            # whitespace
       
  6713     (\w+)?
       
  6714     \s*            # whitespace
       
  6715     HBufC
       
  6716     \s*            # whitespace
       
  6717     \*
       
  6718     \s*            # whitespace
       
  6719     (\w+)          # parameter name
       
  6720     (=|\w|\s)*     # optional parameter initialization or whitespace
       
  6721     (\)|,)         # close bracket or trailing comma
       
  6722     """
       
  6723 script.iFileExts = ["cpp"]
       
  6724 script.iCategory = KCategoryCodingStandards
       
  6725 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6726 script.iSeverity = KSeverityLow
       
  6727 
       
  6728 def consthbufccompare(lines, currentline, rematch, filename):
       
  6729     # make sure const HBufC* parameters are skipped
       
  6730     line = lines[currentline]
       
  6731     m = rematch.search(line)
       
  6732     if m:
       
  6733         isConst = (m.group(0).find("const") <> -1)
       
  6734         while m and isConst:
       
  6735             line = line[m.end():]
       
  6736             m = rematch.search(line)
       
  6737             if m:
       
  6738                 isConst = (m.group(0).find("const") <> -1)
       
  6739         if isConst:
       
  6740             return 0
       
  6741         else:
       
  6742             return DefaultFuncParamCompare(lines, currentline, rematch, filename)
       
  6743     return 0
       
  6744 
       
  6745 script.iCompare = consthbufccompare
       
  6746 scanner.AddScript(script)
       
  6747 
       
  6748 # #################################################################
       
  6749 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6750 # All rights reserved.
       
  6751 # 
       
  6752 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6753 # 
       
  6754 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6755 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6756 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6757 # 
       
  6758 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6759 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6760 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6761 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6762 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6763 #
       
  6764 # nonconsttdesc.py
       
  6765 #
       
  6766 # Checks : Non-const TDesC& parameter passing.
       
  6767 #
       
  6768 # Reason : TDesC& parameters should be passed as a const. If it is 
       
  6769 # not, it may indicate that the coder does not understand 
       
  6770 # descriptors, for example, passing descriptors by value.
       
  6771 #
       
  6772 # #################################################################
       
  6773 
       
  6774 script = CScript("nonconsttdesc")
       
  6775 script.iReString = """
       
  6776     (\(|,)?        # open bracket or preceeding comma
       
  6777     \s*            # whitespace
       
  6778     (\w+)?
       
  6779     \s*            # whitespace
       
  6780     (TDesC)
       
  6781     \s*            # whitespace
       
  6782     &
       
  6783     \s*            # whitespace
       
  6784     (\w+)          # parameter name
       
  6785     (=|\w|\s)*     # optional parameter initialization or whitespace
       
  6786     (\)|,)         # close bracket or trailing comma
       
  6787     """
       
  6788 script.iFileExts = ["cpp"]
       
  6789 script.iCategory = KCategoryCodingStandards
       
  6790 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6791 script.iSeverity = KSeverityLow
       
  6792 
       
  6793 def consttdesccompare(lines, currentline, rematch, filename):
       
  6794     # make sure const TDesC& parameters are skipped
       
  6795     line = lines[currentline]
       
  6796     m = rematch.search(line)
       
  6797     if m:
       
  6798         isConst = (m.group(0).find("const") <> -1)
       
  6799         while m and isConst:
       
  6800             line = line[m.end():]
       
  6801             m = rematch.search(line)
       
  6802             if m:
       
  6803                 isConst = (m.group(0).find("const") <> -1)
       
  6804         if isConst:
       
  6805             return 0
       
  6806         else:
       
  6807             return DefaultFuncParamCompare(lines, currentline, rematch, filename)
       
  6808     return 0
       
  6809 
       
  6810 script.iCompare = consttdesccompare
       
  6811 scanner.AddScript(script)
       
  6812 
       
  6813 # #################################################################
       
  6814 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6815 # All rights reserved.
       
  6816 # 
       
  6817 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6818 # 
       
  6819 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6820 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6821 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6822 # 
       
  6823 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6824 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6825 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6826 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6827 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6828 #
       
  6829 # nonleavenew.py
       
  6830 #
       
  6831 # Checks : Use of new without (ELeave).
       
  6832 #
       
  6833 # Reason : Using new without (ELeave) is only used in special 
       
  6834 # circumstances. The leaving variant should typically be used in 
       
  6835 # preference. A common exception is for application creation, 
       
  6836 # where NULL is returned for failed creation.
       
  6837 #
       
  6838 # #################################################################
       
  6839 
       
  6840 script = CScript("nonleavenew")
       
  6841 script.iReString = r"""
       
  6842 	(=|\(|,)		# equals, open bracket or comma
       
  6843 	\s*				# optional whitespace
       
  6844 	new\s+			# "new" plus at least one whitespace char
       
  6845 	([^\(\s]		# a character other than a bracket
       
  6846 	.*)
       
  6847 	"""
       
  6848 script.iFileExts = ["cpp"]
       
  6849 script.iCategory = KCategoryCodeReviewGuides
       
  6850 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6851 script.iSeverity = KSeverityLow
       
  6852 
       
  6853 currentfilename = ""
       
  6854 iswindowsfile = 0
       
  6855 rewindows = re.compile("^\s*#include\s+<(windows|wchar).h>", re.IGNORECASE)
       
  6856 
       
  6857 def checkforwindowsinclude(lines, filename):
       
  6858 	global currentfilename
       
  6859 	global iswindowsfile
       
  6860 	global rewindows
       
  6861 
       
  6862 	if (currentfilename <> filename):
       
  6863 		currentfilename = filename
       
  6864 		iswindowsfile = 0
       
  6865 		for line in lines:
       
  6866 			m = rewindows.search(line)
       
  6867 			if m:
       
  6868 				iswindowsfile = 1
       
  6869 				break
       
  6870 
       
  6871 	return iswindowsfile
       
  6872 
       
  6873 def nonleavenewcompare(lines, currentline, rematch, filename):
       
  6874 	m = rematch.search(lines[currentline])
       
  6875 	if m:
       
  6876 		if (m.group(2).find("Application") <> -1):
       
  6877 			return 0
       
  6878 		else:				
       
  6879 			return not checkforwindowsinclude(lines, filename)
       
  6880 
       
  6881 	return 0
       
  6882 
       
  6883 script.iCompare = nonleavenewcompare
       
  6884 scanner.AddScript(script)
       
  6885 
       
  6886 # #################################################################
       
  6887 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6888 # All rights reserved.
       
  6889 # 
       
  6890 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6891 # 
       
  6892 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6893 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6894 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6895 # 
       
  6896 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6897 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6898 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6899 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6900 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6901 #
       
  6902 # nonunicodeskins.py
       
  6903 #
       
  6904 # Checks : Non-Unicode skins.
       
  6905 #
       
  6906 # Reason : Skin definition files (SKN, SKE) must be Unicode. 
       
  6907 # Note: Code that causes this issue only needs attention if it is 
       
  6908 # found in code developed for Nokia Series 90 code.
       
  6909 #
       
  6910 # #################################################################
       
  6911 
       
  6912 script = CScript("nonunicodeskins")
       
  6913 script.iReString = r"""
       
  6914 	^\s*
       
  6915 	(//|/\*|A-Z|a-z|\#|\[)
       
  6916 """
       
  6917 script.iFileExts = ["skn", "ske"]
       
  6918 script.iCategory = KCategoryCodeReviewGuides
       
  6919 script.iIgnore = KIgnoreNothing
       
  6920 script.iSeverity = KSeverityLow
       
  6921 
       
  6922 def nonunicodecompare(lines, currentline, rematch, filename):
       
  6923 	return (currentline == 0) and rematch.search(lines[currentline])
       
  6924 
       
  6925 script.iCompare = nonunicodecompare
       
  6926 scanner.AddScript(script)
       
  6927 
       
  6928 # #################################################################
       
  6929 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6930 # All rights reserved.
       
  6931 # 
       
  6932 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6933 # 
       
  6934 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6935 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6936 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6937 # 
       
  6938 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6939 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6940 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6941 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6942 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6943 #
       
  6944 # null.py
       
  6945 #
       
  6946 # Checks : NULL equality check.
       
  6947 #
       
  6948 # Reason : There is no need to compare pointer variables to NULL. 
       
  6949 # Use If(ptr).
       
  6950 #
       
  6951 # #################################################################
       
  6952 
       
  6953 script = CScript("null")
       
  6954 script.iReString = r"""
       
  6955 	[!=]=\s*NULL
       
  6956 	"""
       
  6957 script.iFileExts = ["cpp"]
       
  6958 script.iCategory = KCategoryCodingStandards
       
  6959 script.iIgnore = KIgnoreCommentsAndQuotes
       
  6960 script.iSeverity = KSeverityLow
       
  6961 
       
  6962 def nullcompare(lines, currentline, rematch, filename):
       
  6963     # It's OK to compare against NULL in return statement
       
  6964     line = lines[currentline]
       
  6965     m = rematch.search(line)
       
  6966     if m:
       
  6967     	if (line.find("return") > -1):
       
  6968     		return 0
       
  6969     	if (line.find("ASSERT") > -1):
       
  6970     		return 0
       
  6971     	return 1
       
  6972 
       
  6973     return 0
       
  6974 
       
  6975 script.iCompare = nullcompare
       
  6976 scanner.AddScript(script)
       
  6977 
       
  6978 # #################################################################
       
  6979 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  6980 # All rights reserved.
       
  6981 # 
       
  6982 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  6983 # 
       
  6984 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  6985 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  6986 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  6987 # 
       
  6988 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  6989 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  6990 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  6991 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  6992 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  6993 #
       
  6994 # open.py
       
  6995 #
       
  6996 # Checks : Ignoring Open() return value.
       
  6997 #
       
  6998 # Reason : Ignoring the return value from Open() functions 
       
  6999 # (due to OOM, etc.) means that when the resource is accessed next, 
       
  7000 # a panic will result.
       
  7001 #
       
  7002 # #################################################################
       
  7003 
       
  7004 script = CScript("open")
       
  7005 script.iReString = "^\s*(\w+)(\.|->)Open\s*\("
       
  7006 script.iFileExts = ["cpp"]
       
  7007 script.iCategory = KCategoryCanPanic
       
  7008 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7009 script.iSeverity = KSeverityHigh
       
  7010 
       
  7011 reOpenIgnoreStr = ""
       
  7012 scriptNode = script.ScriptConfig()
       
  7013 if (scriptNode <> None):
       
  7014 	for wordNode in scriptNode.getElementsByTagName("openIgnoreRE"):
       
  7015 		reOpenIgnoreStr = wordNode.firstChild.nodeValue
       
  7016 		print "Note: ignoring the following objects and classes when checking for open() return value: " + reOpenIgnoreStr
       
  7017 		break
       
  7018 if len(reOpenIgnoreStr) > 0:
       
  7019 	reOpenIgnores = re.compile(reOpenIgnoreStr, re.IGNORECASE)
       
  7020 else :
       
  7021 	reOpenIgnores = None
       
  7022 
       
  7023 reOpenAssignStr = "=\s+$"
       
  7024 reOpenAssign = re.compile(reOpenAssignStr, re.IGNORECASE)
       
  7025 
       
  7026 def streamcompare(lines, currentline, rematch, filename):
       
  7027 	m = rematch.search(lines[currentline])
       
  7028 	if m:
       
  7029 		# ignore objects with the word "tream" in object name or object type
       
  7030 		objectName = m.group(1)
       
  7031 		if (objectName.find("tream") <> -1):
       
  7032 			return 0
       
  7033 		objectType = GetLocalVariableType(lines, currentline, objectName)
       
  7034 		if (objectType.find("tream") <> -1):
       
  7035 			return 0
       
  7036 
       
  7037 		#ignore objects with either object name or object type on the ignored list
       
  7038 		if reOpenIgnores:
       
  7039 			if reOpenIgnores.search(objectName):
       
  7040 				return 0
       
  7041 			if reOpenIgnores.search(objectType):
       
  7042 				return 0
       
  7043 
       
  7044 		# look for handler of Open() return value on a different line
       
  7045 		i = currentline - 1
       
  7046 		if (i > 0) and (i >= scanner.iCurrentMethodStart):
       
  7047 			line = lines[i]
       
  7048 			bracketCount = line.count("(") - line.count(")")
       
  7049 			if (bracketCount > 0):
       
  7050 				return 0
       
  7051 			r = reOpenAssign.search(line)
       
  7052 			if r:
       
  7053 				return 0
       
  7054 		return 1
       
  7055 	else:
       
  7056 		return 0
       
  7057 
       
  7058 script.iCompare = streamcompare
       
  7059 scanner.AddScript(script)
       
  7060 
       
  7061 # #################################################################
       
  7062 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7063 # All rights reserved.
       
  7064 # 
       
  7065 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7066 # 
       
  7067 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7068 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7069 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7070 # 
       
  7071 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7072 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7073 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7074 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7075 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7076 #
       
  7077 # pointertoarrays.py
       
  7078 #
       
  7079 # Checks : Pointer to arrays as members of a C class.
       
  7080 #
       
  7081 # Reason : In C classes, there is no need to use pointers to arrays 
       
  7082 # as data members. Instead, use the arrays themselves. Using 
       
  7083 # pointers leads to obscure notation like \"(*array)[n]\" for the 
       
  7084 # more usual \"array[n]\". It also makes it necessary to explicitly 
       
  7085 # delete the arrays in the destructor. Using the arrays themselves 
       
  7086 # also simplifies notation, reduces indirection, and reduces heap 
       
  7087 # fragmentation.
       
  7088 #
       
  7089 # #################################################################
       
  7090 
       
  7091 script = CScript("pointertoarrays")
       
  7092 script.iReString = r"""
       
  7093 	^\s*				# start of line plus optional whitespace
       
  7094 	[CR]\w*Array\w*		# class name e.g. RPointerArray
       
  7095     (|<\w*>)			# optional "<Xxxx>" part
       
  7096 	\s*\*				# "*" (with optional whitespace)
       
  7097 	\s*i[A-Z]			# optional whitespace followed by the starting i of the member variable and then a capital letter
       
  7098 	"""
       
  7099 script.iFileExts = ["h", "cpp"]
       
  7100 script.iCategory = KCategoryPerformance
       
  7101 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7102 script.iSeverity = KSeverityMedium
       
  7103 
       
  7104 def pointerToArraysCompare(lines, currentline, rematch, filename):
       
  7105 	m = rematch.search(lines[currentline])
       
  7106 	if m:
       
  7107 		if (len(scanner.iCurrentClassName) > 1)  and (scanner.iCurrentClassName[0]=="C"):
       
  7108 			return 1    # only a problem with C classes
       
  7109 		else:
       
  7110 			return 0    
       
  7111 	else:
       
  7112 		return 0
       
  7113 
       
  7114 script.iCompare = pointerToArraysCompare
       
  7115 script.iDisplayMethodName = 0
       
  7116 script.iDisplayClassName = 1
       
  7117 
       
  7118 scanner.AddScript(script)
       
  7119 
       
  7120 # #################################################################
       
  7121 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7122 # All rights reserved.
       
  7123 # 
       
  7124 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7125 # 
       
  7126 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7127 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7128 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7129 # 
       
  7130 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7131 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7132 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7133 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7134 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7135 #
       
  7136 # pragmadisable.py
       
  7137 #
       
  7138 # Checks : Use of #pragma warning.
       
  7139 #
       
  7140 # Reason : Disabling warnings can lead to problems, because the 
       
  7141 # warnings are probably there for a reason.
       
  7142 #
       
  7143 # #################################################################
       
  7144 
       
  7145 script = CScript("pragmadisable")
       
  7146 script.iReString = "\#pragma\s+warning"
       
  7147 script.iFileExts = ["h","cpp"]
       
  7148 script.iCategory = KCategoryCodingStandards
       
  7149 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7150 script.iSeverity = KSeverityLow
       
  7151 
       
  7152 scanner.AddScript(script)
       
  7153 
       
  7154 # #################################################################
       
  7155 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7156 # All rights reserved.
       
  7157 # 
       
  7158 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7159 # 
       
  7160 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7161 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7162 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7163 # 
       
  7164 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7165 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7166 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7167 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7168 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7169 #
       
  7170 # pragmamessage.py
       
  7171 #
       
  7172 # Checks : Use of #pragma message.
       
  7173 #
       
  7174 # Reason : #pragma messages during the build stage can interfere 
       
  7175 # with the build log parsing.
       
  7176 #
       
  7177 # #################################################################
       
  7178 
       
  7179 script = CScript("pragmamessage")
       
  7180 script.iReString = "\#pragma\s+message"
       
  7181 script.iFileExts = ["h","cpp"]
       
  7182 script.iCategory = KCategoryCodingStandards
       
  7183 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7184 script.iSeverity = KSeverityLow
       
  7185 
       
  7186 scanner.AddScript(script)
       
  7187 
       
  7188 # #################################################################
       
  7189 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7190 # All rights reserved.
       
  7191 # 
       
  7192 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7193 # 
       
  7194 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7195 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7196 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7197 # 
       
  7198 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7199 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7200 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7201 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7202 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7203 #
       
  7204 # pragmaother.py
       
  7205 #
       
  7206 # Checks : Use of #pragma other than warning and message.
       
  7207 #
       
  7208 # Reason : #pragma directives should only be used in very edge 
       
  7209 # cases (for example, functions consisting of inline assembler 
       
  7210 # without explicit return statements) because, typically, their 
       
  7211 # usage masks valid build warnings and error messages.
       
  7212 #
       
  7213 # #################################################################
       
  7214 
       
  7215 script = CScript("pragmaother")
       
  7216 script.iReString = "\#pragma\s+[^warning|message]"
       
  7217 script.iFileExts = ["h","cpp", "c", "inl"]
       
  7218 script.iCategory = KCategoryCodeReviewGuides
       
  7219 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7220 script.iSeverity = KSeverityLow
       
  7221 
       
  7222 scanner.AddScript(script)
       
  7223 
       
  7224 # #################################################################
       
  7225 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7226 # All rights reserved.
       
  7227 # 
       
  7228 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7229 # 
       
  7230 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7231 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7232 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7233 # 
       
  7234 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7235 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7236 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7237 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7238 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7239 #
       
  7240 # privateinheritance.py
       
  7241 #
       
  7242 # Checks : Use of private inheritance.
       
  7243 #
       
  7244 # Reason : Classes should not be inherited privately. If public or 
       
  7245 # protected inheritance is not appropriate, consider using an 
       
  7246 # amalgamation; that is, have an object of that type as a 
       
  7247 # member variable.
       
  7248 #
       
  7249 # #################################################################
       
  7250 
       
  7251 script = CScript("privateinheritance")
       
  7252 script.iReString = r"""
       
  7253 	^\s*				# start of line plus optional whitespace
       
  7254 	class
       
  7255 	\s+					# whitespace
       
  7256 	\w+					# class name
       
  7257 	\s*					# optional whitespace
       
  7258 	:
       
  7259 	(.*)
       
  7260 	"""
       
  7261 script.iFileExts = ["cpp", "h"]
       
  7262 script.iCategory = KCategoryCodingStandards
       
  7263 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7264 script.iSeverity = KSeverityLow
       
  7265 
       
  7266 def privatecompare(lines, currentline, rematch, filename):
       
  7267 	m = rematch.search(lines[currentline])
       
  7268 	if m:
       
  7269 		searchtext = m.group(1)
       
  7270 		if (searchtext.find("private") == -1):
       
  7271 			return 0
       
  7272 		else:
       
  7273 			return 1
       
  7274 	else:
       
  7275 		return 0
       
  7276 
       
  7277 script.iCompare = privatecompare
       
  7278 scanner.AddScript(script)
       
  7279 
       
  7280 # #################################################################
       
  7281 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7282 # All rights reserved.
       
  7283 # 
       
  7284 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7285 # 
       
  7286 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7287 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7288 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7289 # 
       
  7290 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7291 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7292 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7293 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7294 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7295 #
       
  7296 # pushaddrvar.py
       
  7297 #
       
  7298 # Checks : Pushing address of a variable onto the cleanup stack.
       
  7299 #
       
  7300 # Reason : If the variable is owned by the code pushing it, it 
       
  7301 # should be stored as a pointer. If it is not, it should not be 
       
  7302 # pushed onto the cleanup stack.
       
  7303 #
       
  7304 # #################################################################
       
  7305 
       
  7306 script = CScript("pushaddrvar")
       
  7307 script.iReString = r"""
       
  7308 	::
       
  7309 	PushL\s*		# "PushL" plus optional whitespace
       
  7310 	\(				# open bracket
       
  7311 	\s*				# optional whitespace
       
  7312 	&				# taking the address?
       
  7313 	"""
       
  7314 script.iFileExts = ["cpp"]
       
  7315 script.iCategory = KCategoryCanPanic
       
  7316 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7317 script.iSeverity = KSeverityHigh
       
  7318 
       
  7319 scanner.AddScript(script)
       
  7320 
       
  7321 # #################################################################
       
  7322 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7323 # All rights reserved.
       
  7324 # 
       
  7325 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7326 # 
       
  7327 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7328 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7329 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7330 # 
       
  7331 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7332 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7333 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7334 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7335 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7336 #
       
  7337 # pushmember.py
       
  7338 #
       
  7339 # Checks : Pushing data members onto the cleanup stack.
       
  7340 #
       
  7341 # Reason : Pushing member variables is likely to lead to double 
       
  7342 # deletes or leakage in certain circumstances and so should be 
       
  7343 # avoided. Even if no panic can result, it is bad practice and 
       
  7344 # makes maintenance more difficult.
       
  7345 #
       
  7346 # #################################################################
       
  7347 
       
  7348 script = CScript("pushmember")
       
  7349 script.iReString = r"""
       
  7350 	::
       
  7351 	PushL\s*		# "PushL" plus optional whitespace
       
  7352 	\(				# open bracket
       
  7353 	\s*				# optional whitespace
       
  7354 	i[A-Z]			# i variable
       
  7355 	"""
       
  7356 script.iFileExts = ["cpp"]
       
  7357 script.iCategory = KCategoryCanPanic
       
  7358 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7359 script.iSeverity = KSeverityHigh
       
  7360 
       
  7361 scanner.AddScript(script)
       
  7362 
       
  7363 # #################################################################
       
  7364 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7365 # All rights reserved.
       
  7366 # 
       
  7367 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7368 # 
       
  7369 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7370 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7371 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7372 # 
       
  7373 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7374 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7375 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7376 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7377 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7378 #
       
  7379 # readresource.py
       
  7380 #
       
  7381 # Checks : Using ReadResource() instead of ReadResourceL().
       
  7382 #
       
  7383 # Reason : ReadResourceL() should always be used in preference to 
       
  7384 # ReadResource() because in an error scenario ReadResource() 
       
  7385 # effectively fails silently. If no check is performed on the 
       
  7386 # resulting descriptor afterwards, unexpected states can ensue. 
       
  7387 # These states are often characterized by buffer overflows.
       
  7388 #
       
  7389 # #################################################################
       
  7390 
       
  7391 script = CScript("readresource")
       
  7392 # matching against a line like this: iCoeEnv->ReadResource( buffer, R_RESOURCE_ID );
       
  7393 script.iReString = r"""
       
  7394 	^\s*				# start of line plus optional whitespace
       
  7395 	\w+					# variable name
       
  7396 	(\.|->)				# "." or "->"
       
  7397 	ReadResource\s*\(.*\)
       
  7398 	\s*;
       
  7399 	"""
       
  7400 script.iFileExts = ["cpp"]
       
  7401 script.iCategory = KCategoryCanPanic
       
  7402 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7403 script.iSeverity = KSeverityHigh
       
  7404 
       
  7405 scanner.AddScript(script)
       
  7406 
       
  7407 # #################################################################
       
  7408 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7409 # All rights reserved.
       
  7410 # 
       
  7411 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7412 # 
       
  7413 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7414 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7415 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7416 # 
       
  7417 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7418 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7419 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7420 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7421 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7422 #
       
  7423 # resourcenotoncleanupstack.py
       
  7424 #
       
  7425 # Checks : Neglected to put resource objects on cleanup stack.
       
  7426 #
       
  7427 # Reason : If a stack-based resource object is not put on the 
       
  7428 # cleanup stack with CleanupResetAndDestroyPushL() or 
       
  7429 # CleanupClosePushL(), and a leaving function or ELeave is called, 
       
  7430 # a memory leak occurs. CodeScanner occasionally gives false 
       
  7431 # positives for this issue. Individual cases should be investigated.
       
  7432 #
       
  7433 # #################################################################
       
  7434 
       
  7435 script = CScript("resourcenotoncleanupstack")
       
  7436 script.iReString = r"""
       
  7437 	^\s*					# start of line plus optional whitespace
       
  7438 	R\w+					# resource type
       
  7439 	\s*						# optional whitespace
       
  7440 	(<.*>)?					# optional class in angle brackets
       
  7441 	\s+						# whitespace
       
  7442 	(\w+)					# object name
       
  7443 	\s*						# optional whitespace
       
  7444 	;
       
  7445 	"""
       
  7446 script.iFileExts = ["cpp"]
       
  7447 script.iCategory = KCategoryCodeReviewGuides
       
  7448 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7449 script.iSeverity = KSeverityLow
       
  7450 
       
  7451 cleanupFunction = re.compile("""
       
  7452 	\s*						# optional whitespace
       
  7453 	(CleanupClosePushL|CleanupResetAndDestroyPushL)
       
  7454 	\s*						# optional whitespace
       
  7455 	\(
       
  7456 	\s*						# optional whitespace
       
  7457 	(\w+)					# object name
       
  7458 	\s*						# optional whitespace
       
  7459 	\)
       
  7460 	\s*						# optional whitespace
       
  7461 	;
       
  7462 	""", re.VERBOSE)
       
  7463 
       
  7464 def resourcecompare(lines, currentline, rematch, filename):
       
  7465     m = rematch.search(lines[currentline])
       
  7466     if m:
       
  7467     	objectName = m.group(2)
       
  7468     	bracketdepth = GetBracketDepth(lines, currentline)
       
  7469     	i = currentline
       
  7470 
       
  7471     	# search for CleanupClosePushL() or CleanupResetAndDestroyPushL() 
       
  7472     	# with the resource object at parameter
       
  7473     	while (i < len(lines)):
       
  7474     		nextLine = lines[i]
       
  7475     		
       
  7476     		match = cleanupFunction.search(nextLine)
       
  7477     		if (match):
       
  7478     			if objectName == match.group(2):
       
  7479     				return 0
       
  7480 
       
  7481     		if (nextLine.find('{') >= 0):
       
  7482     			bracketdepth = bracketdepth + 1
       
  7483     		if (nextLine.find('}') >= 0):
       
  7484     			bracketdepth = bracketdepth - 1
       
  7485     			if (bracketdepth == 0):
       
  7486     				return 1
       
  7487 
       
  7488     		i += 1
       
  7489 
       
  7490 	return 0
       
  7491 
       
  7492 script.iCompare = resourcecompare
       
  7493 scanner.AddScript(script)
       
  7494 
       
  7495 # #################################################################
       
  7496 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7497 # All rights reserved.
       
  7498 # 
       
  7499 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7500 # 
       
  7501 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7502 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7503 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7504 # 
       
  7505 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7506 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7507 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7508 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7509 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7510 #
       
  7511 # resourcesonheap.py
       
  7512 #
       
  7513 # Checks : Resource objects on the heap.
       
  7514 #
       
  7515 # Reason : There is very rarely any real need to put R classes on 
       
  7516 # the heap (unless they are not real R classes!).  Doing so can 
       
  7517 # lead to inefficiency and cleanup stack problems.
       
  7518 #
       
  7519 # #################################################################
       
  7520 
       
  7521 script = CScript("resourcesonheap")
       
  7522 script.iReString = "new\s*(|\(ELeave\))\s+R[A-Z]"
       
  7523 script.iFileExts = ["cpp"]
       
  7524 script.iCategory = KCategoryCodingStandards
       
  7525 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7526 script.iSeverity = KSeverityLow
       
  7527 
       
  7528 scanner.AddScript(script)
       
  7529 
       
  7530 # #################################################################
       
  7531 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7532 # All rights reserved.
       
  7533 # 
       
  7534 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7535 # 
       
  7536 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7537 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7538 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7539 # 
       
  7540 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7541 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7542 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7543 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7544 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7545 #
       
  7546 # returndescriptoroutofscope.py
       
  7547 #
       
  7548 # Checks : Return descriptor out of scope.
       
  7549 #
       
  7550 # Reason : Returning a TBuf descriptor that is declared locally 
       
  7551 # takes it out of scope. This can cause a crash on WINSCW, although 
       
  7552 # not on WINS.
       
  7553 #
       
  7554 # #################################################################
       
  7555 
       
  7556 script = CScript("returndescriptoroutofscope")
       
  7557 script.iReString = r"""
       
  7558 	TBuf
       
  7559 	\s*
       
  7560 	<
       
  7561 	[A-Za-z0-9]+
       
  7562 	>
       
  7563 	\s*
       
  7564 	"""
       
  7565 script.iFileExts = ["cpp"]
       
  7566 script.iCategory = KCategoryCanPanic
       
  7567 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7568 script.iSeverity = KSeverityHigh
       
  7569 
       
  7570 reReturnValue = re.compile("""
       
  7571 	return
       
  7572 	\s*
       
  7573 	""", re.VERBOSE)
       
  7574 
       
  7575 reOpenCurlyBracket = re.compile("""
       
  7576 	{
       
  7577 	""", re.VERBOSE)
       
  7578 
       
  7579 reCloseCurlyBracket = re.compile("""
       
  7580 	}
       
  7581 	""", re.VERBOSE)
       
  7582 
       
  7583 def finddescriptor(line, descriptor):
       
  7584 	startindex = line.find(descriptor)
       
  7585 	if (startindex <> -1):
       
  7586 		if (line[startindex] == " "):
       
  7587 			if (line[startindex + len(descriptor)] == ";"):
       
  7588 				return 1
       
  7589 	return 0
       
  7590 
       
  7591 def returnvaluecompare(lines, currentline, rematch, filename):
       
  7592 	line = lines[currentline]
       
  7593 	m = rematch.search(line)
       
  7594 
       
  7595 	if m:
       
  7596 		startindex = line.find(">");
       
  7597 		endindex = line.find(";");
       
  7598 
       
  7599 		if (startindex <> -1):
       
  7600 			descriptor = line[startindex+1:endindex]
       
  7601 
       
  7602 			i = currentline
       
  7603 			bracketdepth = 1
       
  7604 			while (i+1 < len(lines)):
       
  7605 				i = i + 1
       
  7606 				line2 = lines[i]
       
  7607 
       
  7608 				if reReturnValue.search(line2):
       
  7609 					if (finddescriptor(line2, descriptor)):
       
  7610 						return 1
       
  7611 
       
  7612 				if reOpenCurlyBracket.search(line2):
       
  7613 					bracketdepth = bracketdepth + 1
       
  7614 
       
  7615 				if reCloseCurlyBracket.search(line2):
       
  7616 					bracketdepth = bracketdepth - 1
       
  7617 					if (bracketdepth == 0):
       
  7618 						return 0
       
  7619 
       
  7620 	return 0
       
  7621 
       
  7622 script.iCompare	= returnvaluecompare
       
  7623 scanner.AddScript(script)
       
  7624 
       
  7625 # #################################################################
       
  7626 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7627 # All rights reserved.
       
  7628 # 
       
  7629 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7630 # 
       
  7631 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7632 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7633 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7634 # 
       
  7635 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7636 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7637 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7638 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7639 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7640 #
       
  7641 # rfs.py
       
  7642 #
       
  7643 # Checks : Use of non-pointer/reference RFs.
       
  7644 #
       
  7645 # Reason : Connecting to an RFs is a time-consuming operation. 
       
  7646 # (It can take approximately 0.1 seconds on some devices.) 
       
  7647 # To minimise wasted time and resources, use the already-connected 
       
  7648 # one in EikonEnv or elsewhere, if possible.
       
  7649 #
       
  7650 # #################################################################
       
  7651 
       
  7652 script = CScript("rfs")
       
  7653 script.iReString = r"""
       
  7654 	RFs
       
  7655 	\s+					# at least one whitespace char
       
  7656 	\w+					# variable name
       
  7657 	"""
       
  7658 script.iFileExts = ["cpp"]
       
  7659 script.iCategory = KCategoryCodeReviewGuides
       
  7660 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7661 script.iSeverity = KSeverityLow
       
  7662 
       
  7663 scanner.AddScript(script)
       
  7664 
       
  7665 # #################################################################
       
  7666 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7667 # All rights reserved.
       
  7668 # 
       
  7669 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7670 # 
       
  7671 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7672 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7673 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7674 # 
       
  7675 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7676 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7677 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7678 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7679 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7680 #
       
  7681 # rssnames.py
       
  7682 #
       
  7683 # Checks : Duplicate RSS names.
       
  7684 #
       
  7685 # Reason : Resource files with clashing NAME fields can cause the 
       
  7686 # wrong resource file to be accessed. This can lead to incorrect 
       
  7687 # functionality or panics.
       
  7688 #
       
  7689 # #################################################################
       
  7690 
       
  7691 script = CScript("rssnames")
       
  7692 script.iReString = "^\s*NAME\s+(\w+)"
       
  7693 script.iFileExts = ["rss"]
       
  7694 script.iCategory = KCategoryCodeReviewGuides
       
  7695 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7696 script.iSeverity = KSeverityLow
       
  7697 
       
  7698 rssnames = []
       
  7699 
       
  7700 def rsscompare(lines, currentline, rematch, filename):
       
  7701 	m = rematch.search(lines[currentline])
       
  7702 	if m:
       
  7703 		text = m.group(1).lower()
       
  7704 		shortfilename = filename[filename.rfind("/") + 1:].lower()
       
  7705 		for pair in rssnames:
       
  7706 			if (pair[0] == text):
       
  7707 			 	if (pair[1] == shortfilename):
       
  7708 					return 0
       
  7709 				else:
       
  7710 					scanner.iRendererManager.ReportAnnotation(pair[2])
       
  7711 					return 1
       
  7712 
       
  7713 		rssnames.append([text, shortfilename, filename])
       
  7714 		return 0
       
  7715 	else:
       
  7716 		return 0
       
  7717 
       
  7718 script.iCompare = rsscompare
       
  7719 scanner.AddScript(script)
       
  7720 
       
  7721 # #################################################################
       
  7722 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7723 # All rights reserved.
       
  7724 # 
       
  7725 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7726 # 
       
  7727 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7728 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7729 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7730 # 
       
  7731 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7732 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7733 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7734 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7735 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7736 #
       
  7737 # stringliterals.py
       
  7738 #
       
  7739 # Checks : Use of _L string literals.
       
  7740 #
       
  7741 # Reason : _L() string literals should be replaced by the _LIT() 
       
  7742 # macro.
       
  7743 #
       
  7744 # #################################################################
       
  7745 
       
  7746 script = CScript("stringliterals")
       
  7747 script.iReString = r"""
       
  7748 	_L
       
  7749 	(16|8)?			# optional "16" or "8"
       
  7750 	\(
       
  7751 	"""
       
  7752 script.iFileExts = ["h", "cpp"]
       
  7753 script.iCategory = KCategoryCodingStandards
       
  7754 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7755 script.iSeverity = KSeverityLow
       
  7756 
       
  7757 def stringliteralscompare(lines, currentline, rematch, filename):
       
  7758 	if (lines[currentline].find("RDebug::Print(") != -1):
       
  7759 		return 0
       
  7760 	else:
       
  7761 		m = rematch.search(lines[currentline])
       
  7762 		if m:
       
  7763 			return 1
       
  7764 		else:
       
  7765 			return 0
       
  7766 
       
  7767 script.iCompare = stringliteralscompare
       
  7768 scanner.AddScript(script)
       
  7769 
       
  7770 # #################################################################
       
  7771 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7772 # All rights reserved.
       
  7773 # 
       
  7774 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7775 # 
       
  7776 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7777 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7778 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7779 # 
       
  7780 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7781 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7782 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7783 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7784 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7785 #
       
  7786 # stringsinresourcefiles.py
       
  7787 #
       
  7788 # Checks : Strings in RSS or RA files.
       
  7789 #
       
  7790 # Reason : Strings should not be defined in RSS or RA files. 
       
  7791 # Instead, they should be put in RLS or other localisable files.
       
  7792 #
       
  7793 # #################################################################
       
  7794 
       
  7795 script = CScript("stringsinresourcefiles")
       
  7796 script.iReString = "=\s*\"[^\"]+\""
       
  7797 script.iFileExts = ["rss", "ra"]
       
  7798 script.iCategory = KCategoryCodeReviewGuides
       
  7799 script.iIgnore = KIgnoreComments
       
  7800 script.iSeverity = KSeverityLow
       
  7801 
       
  7802 scanner.AddScript(script)
       
  7803 
       
  7804 # #################################################################
       
  7805 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7806 # All rights reserved.
       
  7807 # 
       
  7808 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7809 # 
       
  7810 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7811 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7812 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7813 # 
       
  7814 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7815 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7816 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7817 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7818 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7819 #
       
  7820 # struct.py
       
  7821 #
       
  7822 # Checks : Use of struct.
       
  7823 #
       
  7824 # Reason : C-style structs should not generally be used. 
       
  7825 # The correct idiom is to use a class with public members. 
       
  7826 # A permissible use of a C-style struct is if it is used to group 
       
  7827 # non-semantically related entities together for convenience, and 
       
  7828 # if a class-related hierarchy would be too heavy-weight.
       
  7829 #
       
  7830 # #################################################################
       
  7831 
       
  7832 script = CScript("struct")
       
  7833 script.iReString = "^\s*struct\s*"
       
  7834 script.iFileExts = ["cpp", "h", "hpp"]
       
  7835 script.iCategory = KCategoryCodingStandards
       
  7836 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7837 script.iSeverity = KSeverityLow
       
  7838 
       
  7839 scanner.AddScript(script)
       
  7840 
       
  7841 # #################################################################
       
  7842 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7843 # All rights reserved.
       
  7844 # 
       
  7845 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7846 # 
       
  7847 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7848 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7849 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7850 # 
       
  7851 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7852 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7853 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7854 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7855 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7856 #
       
  7857 # tcclasses.py
       
  7858 #
       
  7859 # Checks : T classes inheriting from C classes.
       
  7860 #
       
  7861 # Reason : T classes that are derived from C classes may have a 
       
  7862 # complex constructor and so need to be handled differently. 
       
  7863 # It is better to make the T class into a C class, which will make 
       
  7864 # the code easier to maintain.
       
  7865 #
       
  7866 # #################################################################
       
  7867 
       
  7868 script = CScript("tcclasses")
       
  7869 script.iReString = r"""
       
  7870 	class
       
  7871 	\s+					# at least one whitespace char
       
  7872 	(\w+::)?
       
  7873 	(\w+)				# T class
       
  7874 	\s*					# optional whitespace
       
  7875 	:
       
  7876 	(.*)				# save inheritance text as group 1
       
  7877 	"""
       
  7878 script.iFileExts = ["h", "cpp"]
       
  7879 script.iCategory = KCategoryWrongFunctionality
       
  7880 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7881 script.iSeverity = KSeverityMedium
       
  7882 
       
  7883 def tcclasscompare(lines, currentline, rematch, filename):
       
  7884 	m = rematch.search(lines[currentline])
       
  7885 	if m:
       
  7886 		className = m.group(2)
       
  7887 		if className[0] <> "T" or (len(className) == 1) or not className[1].isupper():
       
  7888 			return 0
       
  7889 
       
  7890 		inheritanceString = m.group(3)
       
  7891 		i = currentline + 1
       
  7892 		while (inheritanceString.find("{") == -1) and i < len(lines):
       
  7893 			if (inheritanceString.find(";") <> -1):
       
  7894 				return 0
       
  7895 			inheritanceString += lines[i]
       
  7896 			i += 1	
       
  7897 
       
  7898 		inheritancelist = inheritanceString.split(",")
       
  7899 		reclass = re.compile("[\s:]*(public|protected|private)?\s*([\w:]+)")
       
  7900 		classlist = []
       
  7901 		for inheritance in inheritancelist:
       
  7902 			match = reclass.search(inheritance)
       
  7903 			if match:
       
  7904 				inheritclass = match.group(2)
       
  7905 				colonpos = inheritclass.rfind(":")
       
  7906 				if (colonpos <> -1):
       
  7907 					inheritclass = inheritclass[colonpos + 1:]
       
  7908 				classlist.append(inheritclass)
       
  7909 
       
  7910 		for classname in classlist:
       
  7911 			if (len(classname) > 2) and classname[0] == "C" and classname[1].isupper():
       
  7912 				return 1
       
  7913 	return 0
       
  7914 
       
  7915 script.iCompare = tcclasscompare
       
  7916 scanner.AddScript(script)
       
  7917 
       
  7918 # #################################################################
       
  7919 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7920 # All rights reserved.
       
  7921 # 
       
  7922 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7923 # 
       
  7924 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7925 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7926 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7927 # 
       
  7928 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7929 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7930 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7931 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7932 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7933 #
       
  7934 # tclassdestructor.py
       
  7935 #
       
  7936 # Checks : T class has destructor.
       
  7937 #
       
  7938 # Reason : T classes should not have a destructor.
       
  7939 #
       
  7940 # #################################################################
       
  7941 
       
  7942 script = CScript("tclassdestructor")
       
  7943 script.iReString = r"""
       
  7944 	::
       
  7945 	\s*				# optional whitespace
       
  7946 	~T[A-Z]			# destructor
       
  7947 	"""
       
  7948 script.iFileExts = ["cpp", "h"]
       
  7949 script.iCategory = KCategoryCodingStandards
       
  7950 script.iIgnore = KIgnoreCommentsAndQuotes
       
  7951 script.iSeverity = KSeverityLow
       
  7952 
       
  7953 scanner.AddScript(script)
       
  7954 
       
  7955 # #################################################################
       
  7956 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  7957 # All rights reserved.
       
  7958 # 
       
  7959 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  7960 # 
       
  7961 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  7962 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  7963 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  7964 # 
       
  7965 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  7966 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  7967 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  7968 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  7969 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  7970 #
       
  7971 # todocomments.py
       
  7972 #
       
  7973 # Checks : "To do" comments.
       
  7974 #
       
  7975 # Reason : "To do" comments in code suggest that it is not finished.
       
  7976 #
       
  7977 # #################################################################
       
  7978 
       
  7979 script = CScript("todocomments")
       
  7980 script.iReString = r"""
       
  7981 	/(/|\*)						# "//" or "/*"
       
  7982 	.*(t|T)(o|O)(d|D)(o|O)		# skip to Todo
       
  7983 	"""
       
  7984 script.iFileExts = ["h", "cpp", "c"]
       
  7985 script.iCategory = KCategoryCodeReviewGuides
       
  7986 script.iIgnore = KIgnoreQuotes
       
  7987 script.iSeverity = KSeverityLow
       
  7988 
       
  7989 def todocommentcodecompare(lines, currentline, rematch, filename):
       
  7990 	m = rematch.search(lines[currentline])
       
  7991 	if m:
       
  7992 		line = lines[currentline]
       
  7993 		i = 0
       
  7994 		inCommentBlock = 0
       
  7995 
       
  7996 		while i < len(line):
       
  7997 			if not inCommentBlock:
       
  7998 				if (line[i] == "/"):
       
  7999 					if (line[i + 1] == "/"):
       
  8000 						return 1
       
  8001 					elif (line[i + 1] == "*"):
       
  8002 						inCommentBlock = 1
       
  8003 						i += 2
       
  8004 						continue
       
  8005 			else:
       
  8006 				endIndex = line[i:].find("*/")
       
  8007 				if (endIndex <> -1):
       
  8008 					inCommentBlock = 0
       
  8009 					# note, that first character is ignored in comments as can be direction to the in-source documentation tool
       
  8010 					if (line[i+1:i + endIndex + 2].lower().find("todo") <> -1):
       
  8011 						return 1
       
  8012 					i += endIndex + 2
       
  8013 					continue
       
  8014 				else:
       
  8015 					return 1			
       
  8016 			i += 1		
       
  8017 	return 0
       
  8018 
       
  8019 script.iCompare = todocommentcodecompare
       
  8020 scanner.AddScript(script)
       
  8021 
       
  8022 # #################################################################
       
  8023 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8024 # All rights reserved.
       
  8025 # 
       
  8026 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8027 # 
       
  8028 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8029 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8030 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8031 # 
       
  8032 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8033 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8034 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8035 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8036 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8037 #
       
  8038 # trapcleanup.py
       
  8039 #
       
  8040 # Checks : Use of LC function in TRAPs.
       
  8041 #
       
  8042 # Reason : You cannot trap something that leaves something on the 
       
  8043 # cleanup stack because it will panic.
       
  8044 #
       
  8045 # #################################################################
       
  8046 
       
  8047 script = CScript("trapcleanup")
       
  8048 script.iReString = "^\s*TRAPD?"
       
  8049 script.iFileExts = ["cpp"]
       
  8050 script.iCategory = KCategoryDefinitePanic
       
  8051 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8052 script.iSeverity = KSeverityHigh
       
  8053 
       
  8054 reCMethod = re.compile("""
       
  8055 	\w*
       
  8056 	[a-z]
       
  8057 	\w*
       
  8058 	LC\(
       
  8059 """, re.VERBOSE)
       
  8060 
       
  8061 def trapcleanupcompare(lines, currentline, rematch, filename):
       
  8062 	line = lines[currentline]
       
  8063 	m = rematch.search(line)
       
  8064 	if m:
       
  8065 		bracketCount = line.count("(") - line.count(")")
       
  8066 		cMethod = reCMethod.search(line) 
       
  8067 		pop = line.find("Pop")			
       
  8068 						 
       
  8069 		while (bracketCount > 0) and (currentline + 1 < len(lines)):
       
  8070 			currentline += 1
       
  8071 			line = lines[currentline]
       
  8072 			bracketCount += line.count("(") - line.count(")")
       
  8073 			if not cMethod:
       
  8074 				cMethod = reCMethod.search(line) 
       
  8075 			if (pop == -1):
       
  8076 				pop = line.find("Pop")			
       
  8077 
       
  8078 		if cMethod and (pop == -1):
       
  8079 			return 1
       
  8080 	
       
  8081 	return 0
       
  8082 
       
  8083 script.iCompare = trapcleanupcompare
       
  8084 scanner.AddScript(script)
       
  8085 
       
  8086 # #################################################################
       
  8087 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8088 # All rights reserved.
       
  8089 # 
       
  8090 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8091 # 
       
  8092 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8093 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8094 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8095 # 
       
  8096 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8097 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8098 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8099 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8100 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8101 #
       
  8102 # trapeleave.py
       
  8103 #
       
  8104 # Checks : Trapping new(ELeave).
       
  8105 #
       
  8106 # Reason : The trapping of a "new(ELeave) CXxx" call is redundant 
       
  8107 # and wasteful as the code to support TRAP is surprisingly large. 
       
  8108 # If the instantiation process really needs not to leave, use 
       
  8109 # "new CXxx" and check for NULL.
       
  8110 #
       
  8111 # #################################################################
       
  8112 
       
  8113 script = CScript("trapeleave")
       
  8114 script.iReString = "^\s*TRAPD?"
       
  8115 script.iFileExts = ["cpp"]
       
  8116 script.iCategory = KCategoryPerformance
       
  8117 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8118 script.iSeverity = KSeverityMedium
       
  8119 
       
  8120 reELeave = re.compile("""
       
  8121     new
       
  8122     \s*        # whitespace
       
  8123     \(         # open bracket
       
  8124     \s*        # whitespace
       
  8125     ELeave
       
  8126     \s*        # whitespace
       
  8127     \)         # close bracket
       
  8128 """, re.VERBOSE)
       
  8129 
       
  8130 def trapeleavecompare(lines, currentline, rematch, filename):
       
  8131     line = lines[currentline]
       
  8132     m = rematch.search(line)
       
  8133     if m:
       
  8134         if (line.find("(") == -1) and (currentline + 1 < len(lines)):
       
  8135             currentline += 1
       
  8136             line = lines[currentline]
       
  8137 
       
  8138         bracketCount = line.count("(") - line.count(")")
       
  8139         found = reELeave.search(line) 
       
  8140 
       
  8141         while (bracketCount > 0) and (currentline + 1 < len(lines)):
       
  8142             currentline += 1
       
  8143             line = lines[currentline]
       
  8144             bracketCount += line.count("(") - line.count(")")
       
  8145             if not found:
       
  8146                 found = reELeave.search(line) 
       
  8147 
       
  8148         if found:
       
  8149             return 1
       
  8150 
       
  8151     return 0
       
  8152 
       
  8153 script.iCompare = trapeleavecompare
       
  8154 scanner.AddScript(script)
       
  8155 
       
  8156 # #################################################################
       
  8157 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8158 # All rights reserved.
       
  8159 # 
       
  8160 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8161 # 
       
  8162 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8163 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8164 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8165 # 
       
  8166 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8167 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8168 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8169 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8170 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8171 #
       
  8172 # traprunl.py
       
  8173 #
       
  8174 # Checks : Trapping of (Do)RunL() rather than using RunError().
       
  8175 #
       
  8176 # Reason : The RunError() function should be used rather than the 
       
  8177 # CActive derivative using its own TRAPD solution within a RunL().
       
  8178 #
       
  8179 # #################################################################
       
  8180 
       
  8181 script = CScript("traprunl")
       
  8182 script.iReString = "^\s*TRAPD?"
       
  8183 script.iFileExts = ["cpp"]
       
  8184 script.iCategory = KCategoryCodingStandards
       
  8185 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8186 script.iSeverity = KSeverityLow
       
  8187 
       
  8188 reRunL = re.compile("""
       
  8189     RunL
       
  8190     \s*        # whitespace
       
  8191     \(         # open bracket
       
  8192 """, re.VERBOSE)
       
  8193 
       
  8194 def traprunlcompare(lines, currentline, rematch, filename):
       
  8195     line = lines[currentline]
       
  8196     m = rematch.search(line)
       
  8197     if m:
       
  8198         if (line.find("(") == -1) and (currentline + 1 < len(lines)):
       
  8199             currentline += 1
       
  8200             line = lines[currentline]
       
  8201 
       
  8202         bracketCount = line.count("(") - line.count(")")
       
  8203         found = reRunL.search(line) 
       
  8204 
       
  8205         while (bracketCount > 0) and (currentline + 1 < len(lines)):
       
  8206             currentline += 1
       
  8207             line = lines[currentline]
       
  8208             bracketCount += line.count("(") - line.count(")")
       
  8209             if not found:
       
  8210                 found = reRunL.search(line) 
       
  8211 
       
  8212         if found:
       
  8213             return 1
       
  8214 
       
  8215     return 0
       
  8216 
       
  8217 script.iCompare = traprunlcompare
       
  8218 scanner.AddScript(script)
       
  8219 
       
  8220 # #################################################################
       
  8221 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8222 # All rights reserved.
       
  8223 # 
       
  8224 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8225 # 
       
  8226 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8227 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8228 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8229 # 
       
  8230 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8231 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8232 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8233 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8234 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8235 #
       
  8236 # trspassing.py
       
  8237 #
       
  8238 # Checks : Passing TRequestStatus parameters by value.
       
  8239 #
       
  8240 # Reason : TRequestStatus parameters should be passed by reference. 
       
  8241 # If TRequestStatus is just being used as an error code, then 
       
  8242 # convert it to a TInt.
       
  8243 #
       
  8244 # #################################################################
       
  8245 
       
  8246 script = CScript("trspassing")
       
  8247 script.iReString = r"""
       
  8248     (\(|,)?				# open bracket or preceeding comma
       
  8249     \s*					# whitespace
       
  8250 	TRequestStatus
       
  8251     \s*					# whitespace
       
  8252 	[^&*]				# matches any character except '&' and '*'
       
  8253     \s*					# whitespace
       
  8254 	(\w+)				# parameter name
       
  8255     (=|\w|\s)*          # optional parameter initialization or whitespace
       
  8256     (\)|,)				# close bracket or trailing comma
       
  8257 	"""
       
  8258 script.iFileExts = ["cpp"]
       
  8259 script.iCategory = KCategoryWrongFunctionality
       
  8260 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8261 script.iSeverity = KSeverityMedium
       
  8262 script.iCompare = DefaultFuncParamCompare
       
  8263 
       
  8264 scanner.AddScript(script)
       
  8265 
       
  8266 # #################################################################
       
  8267 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8268 # All rights reserved.
       
  8269 # 
       
  8270 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8271 # 
       
  8272 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8273 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8274 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8275 # 
       
  8276 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8277 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8278 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8279 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8280 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8281 #
       
  8282 # uids.py
       
  8283 #
       
  8284 # Checks : Duplicate UIDs.
       
  8285 #
       
  8286 # Reason : UIDs must be unique.
       
  8287 #
       
  8288 # #################################################################
       
  8289 
       
  8290 script = CScript("uids")
       
  8291 script.iReString = r"""
       
  8292 	^\s*			# whitespace
       
  8293 	[Uu][Ii][Dd]	# uid			
       
  8294 	\s+				# at least one whitespace char
       
  8295 	\w+
       
  8296 	\s+				# at least one whitespace char
       
  8297 	(\w+)
       
  8298 	"""
       
  8299 script.iFileExts = ["mmp"]
       
  8300 script.iCategory = KCategoryCodeReviewGuides
       
  8301 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8302 script.iSeverity = KSeverityLow
       
  8303 
       
  8304 uids = []
       
  8305 
       
  8306 def uidcompare(lines, currentline, rematch, filename):
       
  8307 	m = rematch.search(lines[currentline])
       
  8308 	if m:
       
  8309 		text = m.group(1).lower()
       
  8310 		shortfilename = filename[filename.rfind("/") + 1:].lower()
       
  8311 		for pair in uids:
       
  8312 			if (pair[0] == text):
       
  8313 			 	if (pair[1] == shortfilename):
       
  8314 					return 0
       
  8315 				else:
       
  8316 					scanner.iRendererManager.ReportAnnotation(pair[2])
       
  8317 					return 1
       
  8318 
       
  8319 		uids.append([text, shortfilename, filename])
       
  8320 		return 0
       
  8321 	else:
       
  8322 		return 0
       
  8323 
       
  8324 script.iCompare = uidcompare
       
  8325 scanner.AddScript(script)
       
  8326 
       
  8327 # #################################################################
       
  8328 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8329 # All rights reserved.
       
  8330 # 
       
  8331 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8332 # 
       
  8333 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8334 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8335 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8336 # 
       
  8337 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8338 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8339 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8340 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8341 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8342 #
       
  8343 # uncompressedaif.py
       
  8344 #
       
  8345 # Checks : Uncompressed AIFs in ROM.
       
  8346 #
       
  8347 # Reason : AIF files should be referenced as "AIF=" rather than 
       
  8348 # "data=" or "file=" otherwise they can bloat the ROM size and 
       
  8349 # slow down application loading.
       
  8350 #
       
  8351 # #################################################################
       
  8352 
       
  8353 script = CScript("uncompressedaif")
       
  8354 script.iReString = r"""
       
  8355 			(
       
  8356 			^
       
  8357 			\s*
       
  8358 			(data|file)
       
  8359 			\s*
       
  8360 			=
       
  8361 			.*
       
  8362 			\.aif
       
  8363 			)
       
  8364 			"""
       
  8365 script.iFileExts = ["iby", "hby", "oby"]
       
  8366 script.iCategory = KCategoryPerformance
       
  8367 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8368 script.iSeverity = KSeverityMedium
       
  8369 
       
  8370 scanner.AddScript(script)
       
  8371 
       
  8372 # #################################################################
       
  8373 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8374 # All rights reserved.
       
  8375 # 
       
  8376 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8377 # 
       
  8378 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8379 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8380 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8381 # 
       
  8382 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8383 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8384 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8385 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8386 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8387 #
       
  8388 # uncompressedbmp.py
       
  8389 #
       
  8390 # Checks : Uncompressed bitmaps in ROM.
       
  8391 #
       
  8392 # Reason : Using uncompressed bitmaps can significantly bloat the 
       
  8393 # size of ROM images. All occurrences of "bitmap=" in iby/hby files 
       
  8394 # should be replaced with "auto-bitmap=". Also, including bitmaps 
       
  8395 # using "data=" or "file=" causes bloat and load-speed reductions.
       
  8396 #
       
  8397 # #################################################################
       
  8398 
       
  8399 script = CScript("uncompressedbmp")
       
  8400 script.iReString = r"""
       
  8401 			(
       
  8402 
       
  8403 			^
       
  8404 			\s*
       
  8405 			bitmap
       
  8406 			\s*
       
  8407 			=
       
  8408 			
       
  8409 			|
       
  8410 
       
  8411 			^
       
  8412 			\s*
       
  8413 			(data|file)
       
  8414 			\s*
       
  8415 			=
       
  8416 			.*
       
  8417 			\.mbm
       
  8418 			)
       
  8419 			"""
       
  8420 script.iFileExts = ["iby", "hby", "oby"]
       
  8421 script.iCategory = KCategoryPerformance
       
  8422 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8423 script.iSeverity = KSeverityMedium
       
  8424 
       
  8425 scanner.AddScript(script)
       
  8426 
       
  8427 # #################################################################
       
  8428 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8429 # All rights reserved.
       
  8430 # 
       
  8431 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8432 # 
       
  8433 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8434 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8435 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8436 # 
       
  8437 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8438 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8439 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8440 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8441 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8442 #
       
  8443 # unicodesource.py
       
  8444 #
       
  8445 # Checks : Unicode source files.
       
  8446 #
       
  8447 # Reason : Having Unicode source files (CPP, H, RLS, LOC, RSS, and 
       
  8448 # RA) will break most build systems.
       
  8449 #
       
  8450 # #################################################################
       
  8451 
       
  8452 script = CScript("unicodesource")
       
  8453 script.iReString = r"""
       
  8454 	^
       
  8455 	\xFF\xFE	
       
  8456 	"""
       
  8457 script.iFileExts = ["cpp", "h", "rls", "loc", "rss", "ra"]
       
  8458 script.iCategory = KCategoryCodeReviewGuides
       
  8459 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8460 script.iSeverity = KSeverityLow
       
  8461 
       
  8462 def unicodesourcecompare(lines, currentline, rematch, filename):
       
  8463 	return (currentline == 0) and rematch.search(lines[currentline])
       
  8464 
       
  8465 script.iCompare = unicodesourcecompare
       
  8466 scanner.AddScript(script)
       
  8467 
       
  8468 # #################################################################
       
  8469 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8470 # All rights reserved.
       
  8471 # 
       
  8472 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8473 # 
       
  8474 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8475 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8476 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8477 # 
       
  8478 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8479 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8480 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8481 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8482 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8483 #
       
  8484 # userafter.py
       
  8485 #
       
  8486 # Checks : Use of User::After.
       
  8487 #
       
  8488 # Reason : Generally, User::After() functions are used to skirt 
       
  8489 # around timing problems. Typically, they should be removed and the 
       
  8490 # defects fixed properly: that is, by waiting for the correct event 
       
  8491 # to continue execution.
       
  8492 #
       
  8493 # #################################################################
       
  8494 
       
  8495 script = CScript("userafter")
       
  8496 script.iReString = "User::After\s*\("
       
  8497 script.iFileExts = ["cpp"]
       
  8498 script.iCategory = KCategoryPerformance
       
  8499 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8500 script.iSeverity = KSeverityMedium
       
  8501 
       
  8502 scanner.AddScript(script)
       
  8503 
       
  8504 # #################################################################
       
  8505 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8506 # All rights reserved.
       
  8507 # 
       
  8508 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8509 # 
       
  8510 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8511 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8512 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8513 # 
       
  8514 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8515 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8516 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8517 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8518 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8519 #
       
  8520 # userfree.py
       
  8521 #
       
  8522 # Checks : Using User::Free directly.
       
  8523 #
       
  8524 # Reason : User::Free() should never be called, because all objects 
       
  8525 # free their memory on deletion; their destructors are not called 
       
  8526 # and further resources cannot be freed or closed. This function 
       
  8527 # should be removed and replaced by explicit deletes.
       
  8528 #
       
  8529 # #################################################################
       
  8530 
       
  8531 script = CScript("userfree")
       
  8532 script.iReString = "User::Free\s*\("
       
  8533 script.iFileExts = ["cpp"]
       
  8534 script.iCategory = KCategoryCodeReviewGuides
       
  8535 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8536 script.iSeverity = KSeverityLow
       
  8537 
       
  8538 scanner.AddScript(script)
       
  8539 
       
  8540 # #################################################################
       
  8541 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8542 # All rights reserved.
       
  8543 # 
       
  8544 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8545 # 
       
  8546 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8547 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8548 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8549 # 
       
  8550 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8551 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8552 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8553 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8554 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8555 #
       
  8556 # userWaitForRequest.py
       
  8557 #
       
  8558 # Checks : Use of User::WaitForRequest.
       
  8559 #
       
  8560 # Reason : User::WaitForRequest() should not generally be used in 
       
  8561 # UI code because the UI will not respond to redraw events while 
       
  8562 # its thread is stopped.
       
  8563 #
       
  8564 # #################################################################
       
  8565 
       
  8566 script = CScript("userWaitForRequest")
       
  8567 script.iReString = "User::WaitForRequest\s*\(\s*"
       
  8568 script.iFileExts = ["cpp","inl"]
       
  8569 script.iCategory = KCategoryCodeReviewGuides
       
  8570 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8571 script.iSeverity = KSeverityLow
       
  8572 
       
  8573 scanner.AddScript(script)
       
  8574 
       
  8575 # #################################################################
       
  8576 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8577 # All rights reserved.
       
  8578 # 
       
  8579 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8580 # 
       
  8581 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8582 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8583 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8584 # 
       
  8585 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8586 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8587 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8588 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8589 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8590 #
       
  8591 # variablenames.py
       
  8592 #
       
  8593 # Checks : Local variables with member/argument names.
       
  8594 #
       
  8595 # Reason : Local variable names should be of the form localVariable 
       
  8596 # and not aLocalVar or iLocalVar. Badly-named variables can be 
       
  8597 # misleading and cause maintenance and coding errors.
       
  8598 #
       
  8599 # #################################################################
       
  8600 
       
  8601 script = CScript("variablenames")
       
  8602 script.iReString = r"""
       
  8603 	^\s*				# start of line plus optional whitespace
       
  8604 	[A-Z]\w*			# class name e.g. TInt, CActive
       
  8605 	\s*[\*&\s]\s*		# optional "*" or "&" plus at least one whitespace char
       
  8606 	[ai][A-Z]\w*\s*		# a or i variable name plus optional whitespace
       
  8607 	[;\(=]				# ";" or "(" or "="
       
  8608 	"""
       
  8609 script.iFileExts = ["cpp"]
       
  8610 script.iCategory = KCategoryCodingStandards
       
  8611 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8612 script.iSeverity = KSeverityLow
       
  8613 
       
  8614 def bracecompare(lines, currentline, rematch, filename):
       
  8615 	m = rematch.search(lines[currentline])
       
  8616 	if m:
       
  8617 		checkline = currentline - 1
       
  8618 		bracecount = 1
       
  8619 		while (bracecount > 0) and (checkline >= 0):
       
  8620 			bracecount -= lines[checkline].count("{")
       
  8621 			bracecount += lines[checkline].count("}")
       
  8622 			checkline -= 1
       
  8623 
       
  8624 		while (bracecount == 0) and (checkline >= 0):
       
  8625 			if (lines[checkline].upper().find("CLASS") <> -1) or (lines[checkline].upper().find("STRUCT") <> -1):
       
  8626 				return 0
       
  8627 			
       
  8628 			bracecount -= lines[checkline].count("{")
       
  8629 			bracecount += lines[checkline].count("}")
       
  8630 			checkline -= 1
       
  8631 
       
  8632 		return 1
       
  8633 	else:
       
  8634 		return 0
       
  8635 
       
  8636 script.iCompare = bracecompare
       
  8637 scanner.AddScript(script)
       
  8638 
       
  8639 # #################################################################
       
  8640 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8641 # All rights reserved.
       
  8642 # 
       
  8643 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8644 # 
       
  8645 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8646 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8647 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8648 # 
       
  8649 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8650 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8651 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8652 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8653 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8654 #
       
  8655 # voidparameter.py
       
  8656 #
       
  8657 # Checks : Void parameter explicitly declared.
       
  8658 #
       
  8659 # Reason : Declaring a void parameter is unnecessary. A function 
       
  8660 # declared as DoSomething(void) may as well be declared as 
       
  8661 # DoSomething(). Void casts are also unnecessary.
       
  8662 #
       
  8663 # #################################################################
       
  8664 
       
  8665 script = CScript("voidparameter")
       
  8666 script.iReString = r"""
       
  8667 	\(				# opening bracket
       
  8668 	\s*				# optional whitespace
       
  8669 	void			# void paramater declaration
       
  8670 	\s*				# optional whitespace
       
  8671 	\)				# closing bracket
       
  8672 	.*;				# skip to semicolon
       
  8673 	"""
       
  8674 script.iFileExts = ["h", "cpp"]
       
  8675 script.iCategory = KCategoryCodingStandards
       
  8676 script.iIgnore = KIgnoreCommentsAndQuotes
       
  8677 script.iSeverity = KSeverityLow
       
  8678 
       
  8679 scanner.AddScript(script)
       
  8680 
       
  8681 # #################################################################
       
  8682 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
  8683 # All rights reserved.
       
  8684 # 
       
  8685 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
       
  8686 # 
       
  8687 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
       
  8688 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
       
  8689 # * Neither the name of Nokia Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
       
  8690 # 
       
  8691 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
       
  8692 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
       
  8693 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
  8694 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
  8695 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
       
  8696 #
       
  8697 # worryingcomments.py
       
  8698 #
       
  8699 # Checks : Worrying comments.
       
  8700 #
       
  8701 # Reason : Typically, exclamation and question marks in comments 
       
  8702 # indicate that something odd is in the code or that it is 
       
  8703 # unfinished or not understood fully.
       
  8704 #
       
  8705 # #################################################################
       
  8706 
       
  8707 script = CScript("worryingcomments")
       
  8708 script.iFileExts = ["h", "cpp", "c"]
       
  8709 script.iCategory = KCategoryCodeReviewGuides
       
  8710 script.iIgnore = KIgnoreQuotes
       
  8711 script.iSeverity = KSeverityLow
       
  8712 
       
  8713 reWordsStr = r"""\!|\?|[Zz]{3}|kludge|workaround|\scrap|hack"""
       
  8714 scriptNode = script.ScriptConfig()
       
  8715 if (scriptNode <> None):
       
  8716 	for wordNode in scriptNode.getElementsByTagName("worryRE"):
       
  8717 		reWordsStr = wordNode.firstChild.nodeValue
       
  8718 		print "Note: 'worrying comments' pattern configured as: " + reWordsStr
       
  8719 		break
       
  8720 script.iReString = r"""
       
  8721 	/(/|\*)						# "//" or "/*"
       
  8722 	.*("""+reWordsStr+r""")		# skip to "!", "?", "zzz", "kludge", "workaround", " crap" or "hack"
       
  8723 	"""
       
  8724 
       
  8725 def worryingcommentcodecompare(lines, currentline, rematch, filename):
       
  8726 	m = rematch.search(lines[currentline])
       
  8727 	if m:
       
  8728 		line = lines[currentline]
       
  8729 		i = 0
       
  8730 		inCommentBlock = 0
       
  8731 
       
  8732 		while i < len(line):
       
  8733 			if not inCommentBlock:
       
  8734 				if (line[i] == "/"):
       
  8735 					if (line[i + 1] == "/"):
       
  8736 						# note i+3 to bypass the character after the start of the comment as can be an in-source documentation directive
       
  8737 						return (line[i+3:].find("!")<>-1) or (line[i+3:].find("?")<>-1)
       
  8738 					elif (line[i + 1] == "*"):
       
  8739 						inCommentBlock = 1
       
  8740 						i += 2
       
  8741 						continue
       
  8742 			else:
       
  8743 				endIndex = line[i:].find("*/")
       
  8744 				if (endIndex <> -1):
       
  8745 					inCommentBlock = 0
       
  8746 					# note, that first character is ignored in comments as can be direction to the in-source documentation tool
       
  8747 					if (line[i+1:i + endIndex + 2].find("!") <> -1) or (line[i+1:i + endIndex + 2].find("?") <> -1):
       
  8748 						return 1
       
  8749 					i += endIndex + 2
       
  8750 					continue
       
  8751 				else:
       
  8752 					return 1			
       
  8753 			i += 1		
       
  8754 	return 0
       
  8755 
       
  8756 script.iCompare = worryingcommentcodecompare
       
  8757 scanner.AddScript(script)
       
  8758 
       
  8759 #!PARSE
       
  8760 
       
  8761 if (scanner.iVerbose):
       
  8762 	scanner.iCategoriedScripts.PrintListOfTestScripts()
       
  8763 	scanner.iRendererManager.PrintListOfRenderers()
       
  8764 
       
  8765 print
       
  8766 print "Scanning inititated : " + scanner.iStartTime
       
  8767 
       
  8768 if scanner.iInputFilenames <> "":
       
  8769 	scanner.iComponentManager.iUseFullComponentPath = True
       
  8770 	#additional input files
       
  8771 	inputFiles = scanner.iInputFilenames.split("::")
       
  8772 	for inputFile in inputFiles:
       
  8773 		if inputFile <> "":
       
  8774 			ScanDirOrFile(inputFile)
       
  8775 
       
  8776 argument = args[0]
       
  8777 ScanDirOrFile(argument)
       
  8778 
       
  8779 print "Scanning finished   : " + scanner.iEndTime
       
  8780 scanner.iLog.Close()
       
  8781 
       
  8782 if (scanner.iDomConfig <> None):
       
  8783 	scanner.iDomConfig.unlink()
       
  8784 
       
  8785 sys.exit(0)