| 1 | #!/usr/bin/perl |
|---|
| 2 | # (c)2003-2008 Broadcom Corporation |
|---|
| 3 | # |
|---|
| 4 | # This program is the proprietary software of Broadcom Corporation and/or its licensors, |
|---|
| 5 | # and may only be used, duplicated, modified or distributed pursuant to the terms and |
|---|
| 6 | # conditions of a separate, written license agreement executed between you and Broadcom |
|---|
| 7 | # (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants |
|---|
| 8 | # no license (express or implied), right to use, or waiver of any kind with respect to the |
|---|
| 9 | # Software, and Broadcom expressly reserves all rights in and to the Software and all |
|---|
| 10 | # intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU |
|---|
| 11 | # HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY |
|---|
| 12 | # NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. |
|---|
| 13 | # |
|---|
| 14 | # Except as expressly set forth in the Authorized License, |
|---|
| 15 | # |
|---|
| 16 | # 1. This program, including its structure, sequence and organization, constitutes the valuable trade |
|---|
| 17 | # secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, |
|---|
| 18 | # and to use this information only in connection with your use of Broadcom integrated circuit products. |
|---|
| 19 | # |
|---|
| 20 | # 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" |
|---|
| 21 | # AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR |
|---|
| 22 | # WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO |
|---|
| 23 | # THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES |
|---|
| 24 | # OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, |
|---|
| 25 | # LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION |
|---|
| 26 | # OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF |
|---|
| 27 | # USE OR PERFORMANCE OF THE SOFTWARE. |
|---|
| 28 | # |
|---|
| 29 | # 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS |
|---|
| 30 | # LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR |
|---|
| 31 | # EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR |
|---|
| 32 | # USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF |
|---|
| 33 | # THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT |
|---|
| 34 | # ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE |
|---|
| 35 | # LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF |
|---|
| 36 | # ANY LIMITED REMEDY. |
|---|
| 37 | # |
|---|
| 38 | # $brcm_Workfile: nexus_codecheck.pl $ |
|---|
| 39 | # $brcm_Revision: 4 $ |
|---|
| 40 | # $brcm_Date: 3/31/08 1:41p $ |
|---|
| 41 | # |
|---|
| 42 | # File Description: |
|---|
| 43 | # |
|---|
| 44 | # Revision History: |
|---|
| 45 | # |
|---|
| 46 | # $brcm_Log: /nexus/build/tools/common/nexus_codecheck.pl $ |
|---|
| 47 | # |
|---|
| 48 | # 4 3/31/08 1:41p erickson |
|---|
| 49 | # PR41077: added check for NEXUS_ASSERT_MODULE |
|---|
| 50 | # |
|---|
| 51 | # 3 3/31/08 1:13p erickson |
|---|
| 52 | # PR41075: added BDBG_OBJECT check |
|---|
| 53 | # |
|---|
| 54 | # 2 3/31/08 12:32p erickson |
|---|
| 55 | # PR41073: check result of malloc and fail graciously |
|---|
| 56 | # |
|---|
| 57 | # 1 1/18/08 2:15p jgarrett |
|---|
| 58 | # PR 38808: Merging to main branch |
|---|
| 59 | # |
|---|
| 60 | # Nexus_Devel/4 11/30/07 11:12a erickson |
|---|
| 61 | # PR35457: api update |
|---|
| 62 | # |
|---|
| 63 | # Nexus_Devel/3 10/5/07 3:21p erickson |
|---|
| 64 | # PR35746: update |
|---|
| 65 | # |
|---|
| 66 | # Nexus_Devel/2 10/5/07 9:33a erickson |
|---|
| 67 | # PR35746: update |
|---|
| 68 | # |
|---|
| 69 | # Nexus_Devel/1 10/4/07 4:41p erickson |
|---|
| 70 | # PR35746: first rev |
|---|
| 71 | # |
|---|
| 72 | ############################################################################# |
|---|
| 73 | use strict; |
|---|
| 74 | |
|---|
| 75 | my $totalerrors = 0; |
|---|
| 76 | |
|---|
| 77 | sub printerror |
|---|
| 78 | { |
|---|
| 79 | my $linenum = shift; |
|---|
| 80 | my $line = shift; |
|---|
| 81 | my $message = shift; |
|---|
| 82 | print "Line $linenum: $line\n"; |
|---|
| 83 | print " ERROR: $message\n"; |
|---|
| 84 | $totalerrors++; |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | sub check_source_file |
|---|
| 88 | { |
|---|
| 89 | local *FILE; |
|---|
| 90 | my $filename = shift; |
|---|
| 91 | open FILE, $filename; |
|---|
| 92 | my $text = join '',<FILE>; |
|---|
| 93 | |
|---|
| 94 | # convert DOS to unix |
|---|
| 95 | $text =~ s/\r\n/\n/sg; |
|---|
| 96 | # convert \r to \n |
|---|
| 97 | $text =~ s/\r/\n/sg; |
|---|
| 98 | |
|---|
| 99 | my @lines = split /\n/, $text; |
|---|
| 100 | |
|---|
| 101 | my $malloc = 0; |
|---|
| 102 | my $linenum = 1; |
|---|
| 103 | my $line; |
|---|
| 104 | my $in_comment = 0; |
|---|
| 105 | my $looking_for_dbg_object = 0; |
|---|
| 106 | my $in_priv = 0; |
|---|
| 107 | |
|---|
| 108 | for $line (@lines) { |
|---|
| 109 | if (!$in_comment) { |
|---|
| 110 | if ($line =~ s/(.*)\/\*.*\*\/(.*)/$1 $2/) { |
|---|
| 111 | $in_comment = 0; |
|---|
| 112 | } |
|---|
| 113 | elsif ($line =~ s/(.*)\/\*.*/$1/) { |
|---|
| 114 | $in_comment = 1; |
|---|
| 115 | } |
|---|
| 116 | } |
|---|
| 117 | else { |
|---|
| 118 | if ($line =~ s/.*\*\/(.*)/$1/) { |
|---|
| 119 | $in_comment = 0; |
|---|
| 120 | } |
|---|
| 121 | else { |
|---|
| 122 | goto nextline; |
|---|
| 123 | } |
|---|
| 124 | } |
|---|
| 125 | |
|---|
| 126 | if ($line =~ /^\s*$/) { |
|---|
| 127 | # if the line is all whitespace, skip it |
|---|
| 128 | goto nextline; |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | if ($malloc) { |
|---|
| 132 | if (!($line =~ /^\s*if/)) { |
|---|
| 133 | printerror $linenum, $line, "No check on result of Malloc"; |
|---|
| 134 | } |
|---|
| 135 | $malloc = 0; |
|---|
| 136 | } |
|---|
| 137 | if ($looking_for_dbg_object) { |
|---|
| 138 | if ($line =~ /^\}/) { |
|---|
| 139 | printerror $looking_for_dbg_object, $line, "Never found BDBG_OBJECT_SET or BDBG_OBJECT_INIT for Malloc. Might be needed."; |
|---|
| 140 | $looking_for_dbg_object = 0; |
|---|
| 141 | } |
|---|
| 142 | if (($line =~ /BDBG_OBJECT_SET/) || ($line =~ /BDBG_OBJECT_INIT/)) { |
|---|
| 143 | $looking_for_dbg_object = 0; |
|---|
| 144 | } |
|---|
| 145 | } |
|---|
| 146 | if ($in_priv) { |
|---|
| 147 | if ($line =~ /^\}/) { |
|---|
| 148 | printerror $in_priv, $line, "Never found NEXUS_ASSERT_MODULE in _priv function."; |
|---|
| 149 | $in_priv = 0; |
|---|
| 150 | } |
|---|
| 151 | if ($line =~ /NEXUS_ASSERT_MODULE/) { |
|---|
| 152 | $in_priv = 0; |
|---|
| 153 | } |
|---|
| 154 | } |
|---|
| 155 | |
|---|
| 156 | if ($line =~ /Malloc/) { |
|---|
| 157 | $malloc = 1; |
|---|
| 158 | $looking_for_dbg_object = $linenum; |
|---|
| 159 | } |
|---|
| 160 | if (($line =~ /_priv\s*\(/) && !($line =~ /;/)) { |
|---|
| 161 | $in_priv = $linenum; |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | nextline: |
|---|
| 165 | $linenum++; |
|---|
| 166 | } |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | sub check_header_file |
|---|
| 170 | { |
|---|
| 171 | local *FILE; |
|---|
| 172 | my $filename = shift; |
|---|
| 173 | open FILE, $filename; |
|---|
| 174 | my $text = join '',<FILE>; |
|---|
| 175 | |
|---|
| 176 | # convert DOS to unix |
|---|
| 177 | $text =~ s/\r\n/\n/sg; |
|---|
| 178 | # convert \r to \n |
|---|
| 179 | $text =~ s/\r/\n/sg; |
|---|
| 180 | |
|---|
| 181 | my @lines = split /\n/, $text; |
|---|
| 182 | my $line; |
|---|
| 183 | my $linenum = 1; |
|---|
| 184 | my $in_enum = 0; |
|---|
| 185 | my $in_struct = 0; |
|---|
| 186 | my $in_func = 0; |
|---|
| 187 | my $current_name; |
|---|
| 188 | my $struct_depth = 0; |
|---|
| 189 | my $in_comment = 0; |
|---|
| 190 | |
|---|
| 191 | for $line (@lines) { |
|---|
| 192 | if ($line =~ /^\#/) { |
|---|
| 193 | # skip preprocessor |
|---|
| 194 | goto nextline; |
|---|
| 195 | } |
|---|
| 196 | |
|---|
| 197 | if (!$in_comment) { |
|---|
| 198 | if ($line =~ s/(.*)\/\*.*\*\/(.*)/$1 $2/) { |
|---|
| 199 | $in_comment = 0; |
|---|
| 200 | } |
|---|
| 201 | elsif ($line =~ s/(.*)\/\*.*/$1/) { |
|---|
| 202 | $in_comment = 1; |
|---|
| 203 | } |
|---|
| 204 | } |
|---|
| 205 | else { |
|---|
| 206 | if ($line =~ s/.*\*\/(.*)/$1/) { |
|---|
| 207 | $in_comment = 0; |
|---|
| 208 | } |
|---|
| 209 | else { |
|---|
| 210 | goto nextline; |
|---|
| 211 | } |
|---|
| 212 | } |
|---|
| 213 | #print "$line\n"; |
|---|
| 214 | |
|---|
| 215 | if ($line =~ /^\s*$/) { |
|---|
| 216 | # if the line is all whitespace, skip it |
|---|
| 217 | goto nextline; |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | if ($line =~ /\t/) { |
|---|
| 221 | printerror $linenum, $line, "hard tabs not allowed"; |
|---|
| 222 | goto nextline; |
|---|
| 223 | } |
|---|
| 224 | if (!$in_struct) { |
|---|
| 225 | #TODO: deal with nested structs later |
|---|
| 226 | if (!($line =~ /^ \S/ || $line =~ /^\S/)) { |
|---|
| 227 | printerror $linenum, $line, "indentation must be 4 spaces"; |
|---|
| 228 | goto nextline; |
|---|
| 229 | } |
|---|
| 230 | } |
|---|
| 231 | if ($in_enum || $in_struct) { |
|---|
| 232 | if ($line =~ /^\}/) { |
|---|
| 233 | $in_enum = $in_struct = 0; |
|---|
| 234 | if (!($line =~ /^\} $current_name\;/)) { |
|---|
| 235 | printerror $linenum, $line, "name of typedef must match struct/enum name"; |
|---|
| 236 | goto nextline; |
|---|
| 237 | } |
|---|
| 238 | } |
|---|
| 239 | elsif ($line =~ /^\{/) { |
|---|
| 240 | # ok |
|---|
| 241 | } |
|---|
| 242 | elsif ($in_enum) { |
|---|
| 243 | if (!($line =~ / ${current_name}_e[A-Z0-9]\w*/)) { |
|---|
| 244 | printerror $linenum, $line, "invalid enum: ${current_name}_eName"; |
|---|
| 245 | goto nextline; |
|---|
| 246 | } |
|---|
| 247 | } |
|---|
| 248 | } |
|---|
| 249 | else { |
|---|
| 250 | if ($line =~ /enum/) { |
|---|
| 251 | ($current_name) = $line =~ /^typedef enum (NEXUS_\w+)\s*$/; |
|---|
| 252 | if (!$current_name) { |
|---|
| 253 | printerror $linenum, $line, "invalid enum typedef"; |
|---|
| 254 | goto nextline; |
|---|
| 255 | } |
|---|
| 256 | else { |
|---|
| 257 | $in_enum = 1; |
|---|
| 258 | } |
|---|
| 259 | } |
|---|
| 260 | elsif ($line =~ /struct/) { |
|---|
| 261 | ($current_name) = $line =~ /^typedef struct (NEXUS_\w+)\s*$/; |
|---|
| 262 | if (!$current_name) { |
|---|
| 263 | # could be a handle |
|---|
| 264 | ($current_name) = $line =~ /^typedef struct (NEXUS_\w+) \*\w+\;$/; |
|---|
| 265 | if (!$current_name) { |
|---|
| 266 | printerror $linenum, $line, "invalid struct typedef"; |
|---|
| 267 | goto nextline; |
|---|
| 268 | } |
|---|
| 269 | } |
|---|
| 270 | else { |
|---|
| 271 | $in_struct = 1; |
|---|
| 272 | } |
|---|
| 273 | } |
|---|
| 274 | } |
|---|
| 275 | if ($line =~ /\(/) { |
|---|
| 276 | my $returnval; |
|---|
| 277 | # function name |
|---|
| 278 | ($returnval,$current_name) = $line =~ /^(\w+) (NEXUS_\w+)\(\s*$/; |
|---|
| 279 | if (!$returnval || !$current_name) { |
|---|
| 280 | ($returnval,$current_name) = $line =~ /^(\w+) (NEXUS_\w+)\(void\)\;$/; |
|---|
| 281 | if (!$returnval || !$current_name) { |
|---|
| 282 | printerror $linenum, $line, "invalid function prototype"; |
|---|
| 283 | goto nextline; |
|---|
| 284 | } |
|---|
| 285 | |
|---|
| 286 | # returnval must be NEXUS_Error, NEXUS_XxxxHandle or void |
|---|
| 287 | if (!($returnval =~ /NEXUS_Error/ || $returnval =~ /void/ || $returnval =~ /NEXUS_\w+Handle/)) { |
|---|
| 288 | printerror $linenum, $line, "invalid function return type"; |
|---|
| 289 | goto nextline; |
|---|
| 290 | } |
|---|
| 291 | } |
|---|
| 292 | $in_func = 1; |
|---|
| 293 | } |
|---|
| 294 | if ($in_func) { |
|---|
| 295 | if ($line =~ /\)/) { |
|---|
| 296 | $in_func = 0; |
|---|
| 297 | if (!($line =~ / \);/) && !($line =~ /\(void\);/)) { |
|---|
| 298 | printerror $linenum, $line, "invalid close of function prototype"; |
|---|
| 299 | goto nextline; |
|---|
| 300 | } |
|---|
| 301 | } |
|---|
| 302 | if ($line =~ /\*/) { |
|---|
| 303 | # this doesn't work yet because we stripped comments |
|---|
| 304 | if (0) { |
|---|
| 305 | if ($line =~ /const/) { |
|---|
| 306 | if (($line =~ /\[out\]/)) { |
|---|
| 307 | printerror $linenum, $line, "in param should be const, out param should have [out] in comment"; |
|---|
| 308 | goto nextline; |
|---|
| 309 | } |
|---|
| 310 | } |
|---|
| 311 | else { |
|---|
| 312 | if (!($line =~ /\[out\]/)) { |
|---|
| 313 | printerror $linenum, $line, "in param should be const, out param should have [out] in comment"; |
|---|
| 314 | goto nextline; |
|---|
| 315 | } |
|---|
| 316 | } |
|---|
| 317 | } |
|---|
| 318 | # search for "Type *pName" |
|---|
| 319 | if (!($line =~ /\w+ \*?\*p[A-Z]\w*/)) { |
|---|
| 320 | printerror $linenum, $line, "reference param should be called pName"; |
|---|
| 321 | goto nextline; |
|---|
| 322 | } |
|---|
| 323 | } |
|---|
| 324 | } |
|---|
| 325 | |
|---|
| 326 | # Ideas: |
|---|
| 327 | # camel case in structure members |
|---|
| 328 | # indenting into sub-structures |
|---|
| 329 | # comments before prototype |
|---|
| 330 | # cplusplus defines |
|---|
| 331 | # const pointers or [out] |
|---|
| 332 | |
|---|
| 333 | nextline: |
|---|
| 334 | $linenum++; |
|---|
| 335 | } |
|---|
| 336 | # print $text; |
|---|
| 337 | } |
|---|
| 338 | |
|---|
| 339 | |
|---|
| 340 | ############### |
|---|
| 341 | # main |
|---|
| 342 | ############### |
|---|
| 343 | print "Nexus Code Check\n"; |
|---|
| 344 | print "Revision: 10/4/2007\n"; |
|---|
| 345 | my $file; |
|---|
| 346 | if ($#ARGV == -1) { |
|---|
| 347 | print "Usage: nexus_codecheck.pl file1.h file2.h ...\n"; |
|---|
| 348 | exit; |
|---|
| 349 | } |
|---|
| 350 | for $file (@ARGV) { |
|---|
| 351 | print "Checking $file\n"; |
|---|
| 352 | print "------------------------------------------\n"; |
|---|
| 353 | if ($file =~ /\.h$/) { |
|---|
| 354 | check_header_file $file; |
|---|
| 355 | } |
|---|
| 356 | elsif ($file =~ /\.c$/) { |
|---|
| 357 | check_source_file $file; |
|---|
| 358 | } |
|---|
| 359 | print "------------------------------------------\n"; |
|---|
| 360 | } |
|---|
| 361 | |
|---|
| 362 | print "Total errors: $totalerrors\n"; |
|---|
| 363 | $totalerrors; |
|---|