1#!/bin/sh 2 3# GDB script to list of problems using awk. 4# 5# Copyright (C) 2002-2014 Free Software Foundation, Inc. 6# 7# This file is part of GDB. 8# 9# This program is free software; you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation; either version 3 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program. If not, see <http://www.gnu.org/licenses/>. 21 22# Make certain that the script is not running in an internationalized 23# environment. 24 25LANG=C ; export LANG 26LC_ALL=C ; export LC_ALL 27 28# Permanent checks take the form: 29 30# Do not use XXXX, ISO C 90 implies YYYY 31# Do not use XXXX, instead use YYYY''. 32 33# and should never be removed. 34 35# Temporary checks take the form: 36 37# Replace XXXX with YYYY 38 39# and once they reach zero, can be eliminated. 40 41# FIXME: It should be able to override this on the command line 42error="regression" 43warning="regression" 44ari="regression eol code comment deprecated legacy obsolete gettext" 45all="regression eol code comment deprecated legacy obsolete gettext deprecate internal gdbarch macro" 46print_doc=0 47print_idx=0 48 49usage () 50{ 51 cat <<EOF 1>&2 52Error: $1 53 54Usage: 55 $0 --print-doc --print-idx -Wall -Werror -W<category> <file> ... 56Options: 57 --print-doc Print a list of all potential problems, then exit. 58 --print-idx Include the problems IDX (index or key) in every message. 59 --src=file Write source lines to file. 60 -Werror Treat all problems as errors. 61 -Wall Report all problems. 62 -Wari Report problems that should be fixed in new code. 63 -W<category> Report problems in the specifed category. Vaid categories 64 are: ${all} 65EOF 66 exit 1 67} 68 69 70# Parse the various options 71Woptions= 72srclines="" 73while test $# -gt 0 74do 75 case "$1" in 76 -Wall ) Woptions="${all}" ;; 77 -Wari ) Woptions="${ari}" ;; 78 -Werror ) Werror=1 ;; 79 -W* ) Woptions="${Woptions} `echo x$1 | sed -e 's/x-W//'`" ;; 80 --print-doc ) print_doc=1 ;; 81 --print-idx ) print_idx=1 ;; 82 --src=* ) srclines="`echo $1 | sed -e 's/--src=/srclines=\"/'`\"" ;; 83 -- ) shift ; break ;; 84 - ) break ;; 85 -* ) usage "$1: unknown option" ;; 86 * ) break ;; 87 esac 88 shift 89done 90if test -n "$Woptions" ; then 91 warning="$Woptions" 92 error= 93fi 94 95 96# -Werror implies treating all warnings as errors. 97if test -n "${Werror}" ; then 98 error="${error} ${warning}" 99fi 100 101 102# Validate all errors and warnings. 103for w in ${warning} ${error} 104do 105 case " ${all} " in 106 *" ${w} "* ) ;; 107 * ) usage "Unknown option -W${w}" ;; 108 esac 109done 110 111 112# make certain that there is at least one file. 113if test $# -eq 0 -a ${print_doc} = 0 114then 115 usage "Missing file." 116fi 117 118 119# Convert the errors/warnings into corresponding array entries. 120for a in ${all} 121do 122 aris="${aris} ari_${a} = \"${a}\";" 123done 124for w in ${warning} 125do 126 warnings="${warnings} warning[ari_${w}] = 1;" 127done 128for e in ${error} 129do 130 errors="${errors} error[ari_${e}] = 1;" 131done 132 133if [ "$AWK" = "" ] ; then 134 AWK=awk 135fi 136 137${AWK} -- ' 138BEGIN { 139 # NOTE, for a per-file begin use "FNR == 1". 140 '"${aris}"' 141 '"${errors}"' 142 '"${warnings}"' 143 '"${srclines}"' 144 print_doc = '$print_doc' 145 print_idx = '$print_idx' 146 PWD = "'`pwd`'" 147} 148 149# Print the error message for BUG. Append SUPLEMENT if non-empty. 150function print_bug(file,line,prefix,category,bug,doc,supplement, suffix,idx) { 151 if (print_idx) { 152 idx = bug ": " 153 } else { 154 idx = "" 155 } 156 if (supplement) { 157 suffix = " (" supplement ")" 158 } else { 159 suffix = "" 160 } 161 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC> 162 print file ":" line ": " prefix category ": " idx doc suffix 163 if (srclines != "") { 164 print file ":" line ":" $0 >> srclines 165 } 166} 167 168function fix(bug,file,count) { 169 skip[bug, file] = count 170 skipped[bug, file] = 0 171} 172 173function fail(bug,supplement) { 174 if (doc[bug] == "") { 175 print_bug("", 0, "internal: ", "internal", "internal", "Missing doc for bug " bug) 176 exit 177 } 178 if (category[bug] == "") { 179 print_bug("", 0, "internal: ", "internal", "internal", "Missing category for bug " bug) 180 exit 181 } 182 183 if (ARI_OK == bug) { 184 return 185 } 186 # Trim the filename down to just DIRECTORY/FILE so that it can be 187 # robustly used by the FIX code. 188 189 if (FILENAME ~ /^\//) { 190 canonicalname = FILENAME 191 } else { 192 canonicalname = PWD "/" FILENAME 193 } 194 shortname = gensub (/^.*\/([^\\]*\/[^\\]*)$/, "\\1", 1, canonicalname) 195 196 skipped[bug, shortname]++ 197 if (skip[bug, shortname] >= skipped[bug, shortname]) { 198 # print FILENAME, FNR, skip[bug, FILENAME], skipped[bug, FILENAME], bug 199 # Do nothing 200 } else if (error[category[bug]]) { 201 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC> 202 print_bug(FILENAME, FNR, "", category[bug], bug, doc[bug], supplement) 203 } else if (warning[category[bug]]) { 204 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC> 205 print_bug(FILENAME, FNR, "warning: ", category[bug], bug, doc[bug], supplement) 206 } 207} 208 209FNR == 1 { 210 seen[FILENAME] = 1 211 if (match(FILENAME, "\\.[ly]$")) { 212 # FILENAME is a lex or yacc source 213 is_yacc_or_lex = 1 214 } 215 else { 216 is_yacc_or_lex = 0 217 } 218} 219END { 220 if (print_idx) { 221 idx = bug ": " 222 } else { 223 idx = "" 224 } 225 # Did we do only a partial skip? 226 for (bug_n_file in skip) { 227 split (bug_n_file, a, SUBSEP) 228 bug = a[1] 229 file = a[2] 230 if (seen[file] && (skipped[bug_n_file] < skip[bug_n_file])) { 231 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC> 232 b = file " missing " bug 233 print_bug(file, 0, "", "internal", file " missing " bug, "Expecting " skip[bug_n_file] " occurances of bug " bug " in file " file ", only found " skipped[bug_n_file]) 234 } 235 } 236} 237 238 239# Skip OBSOLETE lines 240/(^|[^_[:alnum:]])OBSOLETE([^_[:alnum:]]|$)/ { next; } 241 242# Skip ARI lines 243 244BEGIN { 245 ARI_OK = "" 246} 247 248/\/\* ARI:[[:space:]]*(.*)[[:space:]]*\*\// { 249 ARI_OK = gensub(/^.*\/\* ARI:[[:space:]]*(.*[^[:space:]])[[:space:]]*\*\/.*$/, "\\1", 1, $0) 250 # print "ARI line found \"" $0 "\"" 251 # print "ARI_OK \"" ARI_OK "\"" 252} 253! /\/\* ARI:[[:space:]]*(.*)[[:space:]]*\*\// { 254 ARI_OK = "" 255} 256 257 258# Things in comments 259 260BEGIN { doc["ARGSUSED"] = "\ 261Do not use ARGSUSED, unnecessary" 262 category["ARGSUSED"] = ari_regression 263} 264/(^|[^_[:alnum:]])ARGSUSED([^_[:alnum:]]|$)/ { 265 fail("ARGSUSED") 266} 267 268 269# SNIP - Strip out comments - SNIP 270 271FNR == 1 { 272 comment_p = 0 273} 274comment_p && /\*\// { gsub (/^([^\*]|\*+[^\/\*])*\*+\//, " "); comment_p = 0; } 275comment_p { next; } 276!comment_p { gsub (/\/\*([^\*]|\*+[^\/\*])*\*+\//, " "); } 277!comment_p && /(^|[^"])\/\*/ { gsub (/\/\*.*$/, " "); comment_p = 1; } 278 279 280BEGIN { doc["_ markup"] = "\ 281All messages should be marked up with _." 282 category["_ markup"] = ari_gettext 283} 284/^[^"]*[[:space:]](warning|error|error_no_arg|query|perror_with_name)[[:space:]]*\([^_\(a-z]/ { 285 if (! /\("%s"/) { 286 fail("_ markup") 287 } 288} 289 290BEGIN { doc["trailing new line"] = "\ 291A message should not have a trailing new line" 292 category["trailing new line"] = ari_gettext 293} 294/(^|[^_[:alnum:]])(warning|error)[[:space:]]*\(_\(".*\\n"\)[\),]/ { 295 fail("trailing new line") 296} 297 298# Include files for which GDB has a custom version. 299 300BEGIN { doc["assert.h"] = "\ 301Do not include assert.h, instead include \"gdb_assert.h\""; 302 category["assert.h"] = ari_regression 303 fix("assert.h", "gdb/gdb_assert.h", 0) # it does not use it 304} 305/^#[[:space:]]*include[[:space:]]+.assert\.h./ { 306 fail("assert.h") 307} 308 309BEGIN { doc["regex.h"] = "\ 310Do not include regex.h, instead include gdb_regex.h" 311 category["regex.h"] = ari_regression 312 fix("regex.h", "gdb/gdb_regex.h", 1) 313} 314/^#[[:space:]]*include[[:space:]]*.regex\.h./ { 315 fail("regex.h") 316} 317 318BEGIN { doc["xregex.h"] = "\ 319Do not include xregex.h, instead include gdb_regex.h" 320 category["xregex.h"] = ari_regression 321 fix("xregex.h", "gdb/gdb_regex.h", 1) 322} 323/^#[[:space:]]*include[[:space:]]*.xregex\.h./ { 324 fail("xregex.h") 325} 326 327BEGIN { doc["gnu-regex.h"] = "\ 328Do not include gnu-regex.h, instead include gdb_regex.h" 329 category["gnu-regex.h"] = ari_regression 330} 331/^#[[:space:]]*include[[:space:]]*.gnu-regex\.h./ { 332 fail("gnu regex.h") 333} 334 335BEGIN { doc["wait.h"] = "\ 336Do not include wait.h or sys/wait.h, instead include gdb_wait.h" 337 fix("wait.h", "common/gdb_wait.h", 2); 338 category["wait.h"] = ari_regression 339} 340/^#[[:space:]]*include[[:space:]]*.wait\.h./ \ 341|| /^#[[:space:]]*include[[:space:]]*.sys\/wait\.h./ { 342 fail("wait.h") 343} 344 345BEGIN { doc["vfork.h"] = "\ 346Do not include vfork.h, instead include gdb_vfork.h" 347 fix("vfork.h", "gdb/gdb_vfork.h", 1); 348 category["vfork.h"] = ari_regression 349} 350/^#[[:space:]]*include[[:space:]]*.vfork\.h./ { 351 fail("vfork.h") 352} 353 354BEGIN { doc["error not internal-warning"] = "\ 355Do not use error(\"internal-warning\"), instead use internal_warning" 356 category["error not internal-warning"] = ari_regression 357} 358/error.*\"[Ii]nternal.warning/ { 359 fail("error not internal-warning") 360} 361 362BEGIN { doc["%p"] = "\ 363Do not use printf(\"%p\"), instead use printf(\"%s\",paddr()) to dump a \ 364target address, or host_address_to_string() for a host address" 365 category["%p"] = ari_code 366} 367/%p/ && !/%prec/ { 368 fail("%p") 369} 370 371BEGIN { doc["%ll"] = "\ 372Do not use printf(\"%ll\"), instead use printf(\"%s\",phex()) to dump a \ 373`long long'\'' value" 374 category["%ll"] = ari_code 375} 376# Allow %ll in scanf 377/%[0-9]*ll/ && !/scanf \(.*%[0-9]*ll/ { 378 fail("%ll") 379} 380 381 382# SNIP - Strip out strings - SNIP 383 384# Test on top.c, scm-valprint.c, remote-rdi.c, ada-lang.c 385FNR == 1 { 386 string_p = 0 387 trace_string = 0 388} 389# Strip escaped characters. 390{ gsub(/\\./, "."); } 391# Strip quoted quotes. 392{ gsub(/'\''.'\''/, "'\''.'\''"); } 393# End of multi-line string 394string_p && /\"/ { 395 if (trace_string) print "EOS:" FNR, $0; 396 gsub (/^[^\"]*\"/, "'\''"); 397 string_p = 0; 398} 399# Middle of multi-line string, discard line. 400string_p { 401 if (trace_string) print "MOS:" FNR, $0; 402 $0 = "" 403} 404# Strip complete strings from the middle of the line 405!string_p && /\"[^\"]*\"/ { 406 if (trace_string) print "COS:" FNR, $0; 407 gsub (/\"[^\"]*\"/, "'\''"); 408} 409# Start of multi-line string 410BEGIN { doc["multi-line string"] = "\ 411Multi-line string must have the newline escaped" 412 category["multi-line string"] = ari_regression 413} 414!string_p && /\"/ { 415 if (trace_string) print "SOS:" FNR, $0; 416 if (/[^\\]$/) { 417 fail("multi-line string") 418 } 419 gsub (/\"[^\"]*$/, "'\''"); 420 string_p = 1; 421} 422# { print } 423 424# Multi-line string 425string_p && 426 427# Accumulate continuation lines 428FNR == 1 { 429 cont_p = 0 430} 431!cont_p { full_line = ""; } 432/[^\\]\\$/ { gsub (/\\$/, ""); full_line = full_line $0; cont_p = 1; next; } 433cont_p { $0 = full_line $0; cont_p = 0; full_line = ""; } 434 435 436# GDB uses ISO C 90. Check for any non pure ISO C 90 code 437 438BEGIN { doc["PARAMS"] = "\ 439Do not use PARAMS(), ISO C 90 implies prototypes" 440 category["PARAMS"] = ari_regression 441} 442/(^|[^_[:alnum:]])PARAMS([^_[:alnum:]]|$)/ { 443 fail("PARAMS") 444} 445 446BEGIN { doc["__func__"] = "\ 447Do not use __func__, ISO C 90 does not support this macro" 448 category["__func__"] = ari_regression 449 fix("__func__", "common/gdb_assert.h", 1) 450} 451/(^|[^_[:alnum:]])__func__([^_[:alnum:]]|$)/ { 452 fail("__func__") 453} 454 455BEGIN { doc["__FUNCTION__"] = "\ 456Do not use __FUNCTION__, ISO C 90 does not support this macro" 457 category["__FUNCTION__"] = ari_regression 458} 459/(^|[^_[:alnum:]])__FUNCTION__([^_[:alnum:]]|$)/ { 460 fail("__FUNCTION__") 461} 462 463BEGIN { doc["__CYGWIN32__"] = "\ 464Do not use __CYGWIN32__, instead use __CYGWIN__ or, better, an explicit \ 465autoconf tests" 466 category["__CYGWIN32__"] = ari_regression 467} 468/(^|[^_[:alnum:]])__CYGWIN32__([^_[:alnum:]]|$)/ { 469 fail("__CYGWIN32__") 470} 471 472BEGIN { doc["PTR"] = "\ 473Do not use PTR, ISO C 90 implies `void *'\''" 474 category["PTR"] = ari_regression 475 #fix("PTR", "gdb/utils.c", 6) 476} 477/(^|[^_[:alnum:]])PTR([^_[:alnum:]]|$)/ { 478 fail("PTR") 479} 480 481BEGIN { doc["UCASE function"] = "\ 482Function name is uppercase." 483 category["UCASE function"] = ari_code 484 possible_UCASE = 0 485 UCASE_full_line = "" 486} 487(possible_UCASE) { 488 if (ARI_OK == "UCASE function") { 489 possible_UCASE = 0 490 } 491 # Closing brace found? 492 else if (UCASE_full_line ~ \ 493 /^[A-Z][[:alnum:]_]*[[:space:]]*\([^()]*\).*$/) { 494 if ((UCASE_full_line ~ \ 495 /^[A-Z][[:alnum:]_]*[[:space:]]*\([^()]*\)[[:space:]]*$/) \ 496 && ($0 ~ /^\{/) && (is_yacc_or_lex == 0)) { 497 store_FNR = FNR 498 FNR = possible_FNR 499 store_0 = $0; 500 $0 = UCASE_full_line; 501 fail("UCASE function") 502 FNR = store_FNR 503 $0 = store_0; 504 } 505 possible_UCASE = 0 506 UCASE_full_line = "" 507 } else { 508 UCASE_full_line = UCASE_full_line $0; 509 } 510} 511/^[A-Z][[:alnum:]_]*[[:space:]]*\([^()]*(|\))[[:space:]]*$/ { 512 possible_UCASE = 1 513 if (ARI_OK == "UCASE function") { 514 possible_UCASE = 0 515 } 516 possible_FNR = FNR 517 UCASE_full_line = $0 518} 519 520 521BEGIN { doc["editCase function"] = "\ 522Function name starts lower case but has uppercased letters." 523 category["editCase function"] = ari_code 524 possible_editCase = 0 525 editCase_full_line = "" 526} 527(possible_editCase) { 528 if (ARI_OK == "editCase function") { 529 possible_editCase = 0 530 } 531 # Closing brace found? 532 else if (editCase_full_line ~ \ 533/^[a-z][a-z0-9_]*[A-Z][a-z0-9A-Z_]*[[:space:]]*\([^()]*\).*$/) { 534 if ((editCase_full_line ~ \ 535/^[a-z][a-z0-9_]*[A-Z][a-z0-9A-Z_]*[[:space:]]*\([^()]*\)[[:space:]]*$/) \ 536 && ($0 ~ /^\{/) && (is_yacc_or_lex == 0)) { 537 store_FNR = FNR 538 FNR = possible_FNR 539 store_0 = $0; 540 $0 = editCase_full_line; 541 fail("editCase function") 542 FNR = store_FNR 543 $0 = store_0; 544 } 545 possible_editCase = 0 546 editCase_full_line = "" 547 } else { 548 editCase_full_line = editCase_full_line $0; 549 } 550} 551/^[a-z][a-z0-9_]*[A-Z][a-z0-9A-Z_]*[[:space:]]*\([^()]*(|\))[[:space:]]*$/ { 552 possible_editCase = 1 553 if (ARI_OK == "editCase function") { 554 possible_editCase = 0 555 } 556 possible_FNR = FNR 557 editCase_full_line = $0 558} 559 560# Only function implementation should be on first column 561BEGIN { doc["function call in first column"] = "\ 562Function name in first column should be restricted to function implementation" 563 category["function call in first column"] = ari_code 564} 565/^[a-z][a-z0-9_]*[[:space:]]*\((|[^*][^()]*)\)[[:space:]]*[^ \t]+/ { 566 fail("function call in first column") 567} 568 569 570# Functions without any parameter should have (void) 571# after their name not simply (). 572BEGIN { doc["no parameter function"] = "\ 573Function having no parameter should be declared with funcname (void)." 574 category["no parameter function"] = ari_code 575} 576/^[a-zA-Z][a-z0-9A-Z_]*[[:space:]]*\(\)/ { 577 fail("no parameter function") 578} 579 580BEGIN { doc["hash"] = "\ 581Do not use ` #...'\'', instead use `#...'\''(some compilers only correctly \ 582parse a C preprocessor directive when `#'\'' is the first character on \ 583the line)" 584 category["hash"] = ari_regression 585} 586/^[[:space:]]+#/ { 587 fail("hash") 588} 589 590BEGIN { doc["OP eol"] = "\ 591Do not use &&, or || at the end of a line" 592 category["OP eol"] = ari_code 593} 594# * operator needs a special treatment as it can be a 595# valid end of line for a pointer type definition 596# Only catch case where an assignment or an opening brace is present 597/(\|\||\&\&|==|!=|[[:space:]][+\-\/])[[:space:]]*$/ \ 598|| /(\(|=)[[:space:]].*[[:space:]]\*[[:space:]]*$/ { 599 fail("OP eol") 600} 601 602BEGIN { doc["strerror"] = "\ 603Do not use strerror(), instead use safe_strerror()" 604 category["strerror"] = ari_regression 605 fix("strerror", "gdb/gdb_string.h", 1) 606 fix("strerror", "gdb/mingw-hdep.c", 1) 607 fix("strerror", "gdb/posix-hdep.c", 1) 608} 609/(^|[^_[:alnum:]])strerror[[:space:]]*\(/ { 610 fail("strerror") 611} 612 613BEGIN { doc["long long"] = "\ 614Do not use `long long'\'', instead use LONGEST" 615 category["long long"] = ari_code 616 # defs.h needs two such patterns for LONGEST and ULONGEST definitions 617 fix("long long", "gdb/defs.h", 2) 618} 619/(^|[^_[:alnum:]])long[[:space:]]+long([^_[:alnum:]]|$)/ { 620 fail("long long") 621} 622 623BEGIN { doc["ATTRIBUTE_UNUSED"] = "\ 624Do not use ATTRIBUTE_UNUSED, do not bother (GDB is compiled with -Werror and, \ 625consequently, is not able to tolerate false warnings. Since -Wunused-param \ 626produces such warnings, neither that warning flag nor ATTRIBUTE_UNUSED \ 627are used by GDB" 628 category["ATTRIBUTE_UNUSED"] = ari_regression 629} 630/(^|[^_[:alnum:]])ATTRIBUTE_UNUSED([^_[:alnum:]]|$)/ { 631 fail("ATTRIBUTE_UNUSED") 632} 633 634BEGIN { doc["ATTR_FORMAT"] = "\ 635Do not use ATTR_FORMAT, use ATTRIBUTE_PRINTF instead" 636 category["ATTR_FORMAT"] = ari_regression 637} 638/(^|[^_[:alnum:]])ATTR_FORMAT([^_[:alnum:]]|$)/ { 639 fail("ATTR_FORMAT") 640} 641 642BEGIN { doc["ATTR_NORETURN"] = "\ 643Do not use ATTR_NORETURN, use ATTRIBUTE_NORETURN instead" 644 category["ATTR_NORETURN"] = ari_regression 645} 646/(^|[^_[:alnum:]])ATTR_NORETURN([^_[:alnum:]]|$)/ { 647 fail("ATTR_NORETURN") 648} 649 650BEGIN { doc["NORETURN"] = "\ 651Do not use NORETURN, use ATTRIBUTE_NORETURN instead" 652 category["NORETURN"] = ari_regression 653} 654/(^|[^_[:alnum:]])NORETURN([^_[:alnum:]]|$)/ { 655 fail("NORETURN") 656} 657 658 659# General problems 660 661BEGIN { doc["multiple messages"] = "\ 662Do not use multiple calls to warning or error, instead use a single call" 663 category["multiple messages"] = ari_gettext 664} 665FNR == 1 { 666 warning_fnr = -1 667} 668/(^|[^_[:alnum:]])(warning|error)[[:space:]]*\(/ { 669 if (FNR == warning_fnr + 1) { 670 fail("multiple messages") 671 } else { 672 warning_fnr = FNR 673 } 674} 675 676# Commented out, but left inside sources, just in case. 677# BEGIN { doc["inline"] = "\ 678# Do not use the inline attribute; \ 679# since the compiler generally ignores this, better algorithm selection \ 680# is needed to improved performance" 681# category["inline"] = ari_code 682# } 683# /(^|[^_[:alnum:]])inline([^_[:alnum:]]|$)/ { 684# fail("inline") 685# } 686 687# This test is obsolete as this type 688# has been deprecated and finally suppressed from GDB sources 689#BEGIN { doc["obj_private"] = "\ 690#Replace obj_private with objfile_data" 691# category["obj_private"] = ari_obsolete 692#} 693#/(^|[^_[:alnum:]])obj_private([^_[:alnum:]]|$)/ { 694# fail("obj_private") 695#} 696 697BEGIN { doc["abort"] = "\ 698Do not use abort, instead use internal_error; GDB should never abort" 699 category["abort"] = ari_regression 700 fix("abort", "gdb/utils.c", 3) 701} 702/(^|[^_[:alnum:]])abort[[:space:]]*\(/ { 703 fail("abort") 704} 705 706BEGIN { doc["basename"] = "\ 707Do not use basename, instead use lbasename" 708 category["basename"] = ari_regression 709} 710/(^|[^_[:alnum:]])basename[[:space:]]*\(/ { 711 fail("basename") 712} 713 714BEGIN { doc["assert"] = "\ 715Do not use assert, instead use gdb_assert or internal_error; assert \ 716calls abort and GDB should never call abort" 717 category["assert"] = ari_regression 718} 719/(^|[^_[:alnum:]])assert[[:space:]]*\(/ { 720 fail("assert") 721} 722 723BEGIN { doc["TARGET_HAS_HARDWARE_WATCHPOINTS"] = "\ 724Replace TARGET_HAS_HARDWARE_WATCHPOINTS with nothing, not needed" 725 category["TARGET_HAS_HARDWARE_WATCHPOINTS"] = ari_regression 726} 727/(^|[^_[:alnum:]])TARGET_HAS_HARDWARE_WATCHPOINTS([^_[:alnum:]]|$)/ { 728 fail("TARGET_HAS_HARDWARE_WATCHPOINTS") 729} 730 731BEGIN { doc["ADD_SHARED_SYMBOL_FILES"] = "\ 732Replace ADD_SHARED_SYMBOL_FILES with nothing, not needed?" 733 category["ADD_SHARED_SYMBOL_FILES"] = ari_regression 734} 735/(^|[^_[:alnum:]])ADD_SHARED_SYMBOL_FILES([^_[:alnum:]]|$)/ { 736 fail("ADD_SHARED_SYMBOL_FILES") 737} 738 739BEGIN { doc["SOLIB_ADD"] = "\ 740Replace SOLIB_ADD with nothing, not needed?" 741 category["SOLIB_ADD"] = ari_regression 742} 743/(^|[^_[:alnum:]])SOLIB_ADD([^_[:alnum:]]|$)/ { 744 fail("SOLIB_ADD") 745} 746 747BEGIN { doc["SOLIB_CREATE_INFERIOR_HOOK"] = "\ 748Replace SOLIB_CREATE_INFERIOR_HOOK with nothing, not needed?" 749 category["SOLIB_CREATE_INFERIOR_HOOK"] = ari_regression 750} 751/(^|[^_[:alnum:]])SOLIB_CREATE_INFERIOR_HOOK([^_[:alnum:]]|$)/ { 752 fail("SOLIB_CREATE_INFERIOR_HOOK") 753} 754 755BEGIN { doc["SOLIB_LOADED_LIBRARY_PATHNAME"] = "\ 756Replace SOLIB_LOADED_LIBRARY_PATHNAME with nothing, not needed?" 757 category["SOLIB_LOADED_LIBRARY_PATHNAME"] = ari_regression 758} 759/(^|[^_[:alnum:]])SOLIB_LOADED_LIBRARY_PATHNAME([^_[:alnum:]]|$)/ { 760 fail("SOLIB_LOADED_LIBRARY_PATHNAME") 761} 762 763BEGIN { doc["REGISTER_U_ADDR"] = "\ 764Replace REGISTER_U_ADDR with nothing, not needed?" 765 category["REGISTER_U_ADDR"] = ari_regression 766} 767/(^|[^_[:alnum:]])REGISTER_U_ADDR([^_[:alnum:]]|$)/ { 768 fail("REGISTER_U_ADDR") 769} 770 771BEGIN { doc["PROCESS_LINENUMBER_HOOK"] = "\ 772Replace PROCESS_LINENUMBER_HOOK with nothing, not needed?" 773 category["PROCESS_LINENUMBER_HOOK"] = ari_regression 774} 775/(^|[^_[:alnum:]])PROCESS_LINENUMBER_HOOK([^_[:alnum:]]|$)/ { 776 fail("PROCESS_LINENUMBER_HOOK") 777} 778 779BEGIN { doc["PC_SOLIB"] = "\ 780Replace PC_SOLIB with nothing, not needed?" 781 category["PC_SOLIB"] = ari_regression 782} 783/(^|[^_[:alnum:]])PC_SOLIB([^_[:alnum:]]|$)/ { 784 fail("PC_SOLIB") 785} 786 787BEGIN { doc["IN_SOLIB_DYNSYM_RESOLVE_CODE"] = "\ 788Replace IN_SOLIB_DYNSYM_RESOLVE_CODE with nothing, not needed?" 789 category["IN_SOLIB_DYNSYM_RESOLVE_CODE"] = ari_regression 790} 791/(^|[^_[:alnum:]])IN_SOLIB_DYNSYM_RESOLVE_CODE([^_[:alnum:]]|$)/ { 792 fail("IN_SOLIB_DYNSYM_RESOLVE_CODE") 793} 794 795BEGIN { doc["GCC_COMPILED_FLAG_SYMBOL"] = "\ 796Replace GCC_COMPILED_FLAG_SYMBOL with nothing, not needed?" 797 category["GCC_COMPILED_FLAG_SYMBOL"] = ari_deprecate 798} 799/(^|[^_[:alnum:]])GCC_COMPILED_FLAG_SYMBOL([^_[:alnum:]]|$)/ { 800 fail("GCC_COMPILED_FLAG_SYMBOL") 801} 802 803BEGIN { doc["GCC2_COMPILED_FLAG_SYMBOL"] = "\ 804Replace GCC2_COMPILED_FLAG_SYMBOL with nothing, not needed?" 805 category["GCC2_COMPILED_FLAG_SYMBOL"] = ari_deprecate 806} 807/(^|[^_[:alnum:]])GCC2_COMPILED_FLAG_SYMBOL([^_[:alnum:]]|$)/ { 808 fail("GCC2_COMPILED_FLAG_SYMBOL") 809} 810 811BEGIN { doc["FUNCTION_EPILOGUE_SIZE"] = "\ 812Replace FUNCTION_EPILOGUE_SIZE with nothing, not needed?" 813 category["FUNCTION_EPILOGUE_SIZE"] = ari_regression 814} 815/(^|[^_[:alnum:]])FUNCTION_EPILOGUE_SIZE([^_[:alnum:]]|$)/ { 816 fail("FUNCTION_EPILOGUE_SIZE") 817} 818 819BEGIN { doc["HAVE_VFORK"] = "\ 820Do not use HAVE_VFORK, instead include \"gdb_vfork.h\" and call vfork() \ 821unconditionally" 822 category["HAVE_VFORK"] = ari_regression 823} 824/(^|[^_[:alnum:]])HAVE_VFORK([^_[:alnum:]]|$)/ { 825 fail("HAVE_VFORK") 826} 827 828BEGIN { doc["bcmp"] = "\ 829Do not use bcmp(), ISO C 90 implies memcmp()" 830 category["bcmp"] = ari_regression 831} 832/(^|[^_[:alnum:]])bcmp[[:space:]]*\(/ { 833 fail("bcmp") 834} 835 836BEGIN { doc["setlinebuf"] = "\ 837Do not use setlinebuf(), ISO C 90 implies setvbuf()" 838 category["setlinebuf"] = ari_regression 839} 840/(^|[^_[:alnum:]])setlinebuf[[:space:]]*\(/ { 841 fail("setlinebuf") 842} 843 844BEGIN { doc["bcopy"] = "\ 845Do not use bcopy(), ISO C 90 implies memcpy() and memmove()" 846 category["bcopy"] = ari_regression 847} 848/(^|[^_[:alnum:]])bcopy[[:space:]]*\(/ { 849 fail("bcopy") 850} 851 852BEGIN { doc["get_frame_base"] = "\ 853Replace get_frame_base with get_frame_id, get_frame_base_address, \ 854get_frame_locals_address, or get_frame_args_address." 855 category["get_frame_base"] = ari_obsolete 856} 857/(^|[^_[:alnum:]])get_frame_base([^_[:alnum:]]|$)/ { 858 fail("get_frame_base") 859} 860 861BEGIN { doc["floatformat_to_double"] = "\ 862Do not use floatformat_to_double() from libierty, \ 863instead use floatformat_to_doublest()" 864 fix("floatformat_to_double", "gdb/doublest.c", 1) 865 category["floatformat_to_double"] = ari_regression 866} 867/(^|[^_[:alnum:]])floatformat_to_double[[:space:]]*\(/ { 868 fail("floatformat_to_double") 869} 870 871BEGIN { doc["floatformat_from_double"] = "\ 872Do not use floatformat_from_double() from libierty, \ 873instead use floatformat_from_doublest()" 874 category["floatformat_from_double"] = ari_regression 875} 876/(^|[^_[:alnum:]])floatformat_from_double[[:space:]]*\(/ { 877 fail("floatformat_from_double") 878} 879 880BEGIN { doc["BIG_ENDIAN"] = "\ 881Do not use BIG_ENDIAN, instead use BFD_ENDIAN_BIG" 882 category["BIG_ENDIAN"] = ari_regression 883} 884/(^|[^_[:alnum:]])BIG_ENDIAN([^_[:alnum:]]|$)/ { 885 fail("BIG_ENDIAN") 886} 887 888BEGIN { doc["LITTLE_ENDIAN"] = "\ 889Do not use LITTLE_ENDIAN, instead use BFD_ENDIAN_LITTLE"; 890 category["LITTLE_ENDIAN"] = ari_regression 891} 892/(^|[^_[:alnum:]])LITTLE_ENDIAN([^_[:alnum:]]|$)/ { 893 fail("LITTLE_ENDIAN") 894} 895 896BEGIN { doc["BIG_ENDIAN"] = "\ 897Do not use BIG_ENDIAN, instead use BFD_ENDIAN_BIG" 898 category["BIG_ENDIAN"] = ari_regression 899} 900/(^|[^_[:alnum:]])BIG_ENDIAN([^_[:alnum:]]|$)/ { 901 fail("BIG_ENDIAN") 902} 903 904BEGIN { doc["sec_ptr"] = "\ 905Instead of sec_ptr, use struct bfd_section"; 906 category["sec_ptr"] = ari_regression 907} 908/(^|[^_[:alnum:]])sec_ptr([^_[:alnum:]]|$)/ { 909 fail("sec_ptr") 910} 911 912BEGIN { doc["frame_unwind_unsigned_register"] = "\ 913Replace frame_unwind_unsigned_register with frame_unwind_register_unsigned" 914 category["frame_unwind_unsigned_register"] = ari_regression 915} 916/(^|[^_[:alnum:]])frame_unwind_unsigned_register([^_[:alnum:]]|$)/ { 917 fail("frame_unwind_unsigned_register") 918} 919 920BEGIN { doc["frame_register_read"] = "\ 921Replace frame_register_read() with get_frame_register(), or \ 922possibly introduce a new method safe_get_frame_register()" 923 category["frame_register_read"] = ari_obsolete 924} 925/(^|[^_[:alnum:]])frame_register_read([^_[:alnum:]]|$)/ { 926 fail("frame_register_read") 927} 928 929BEGIN { doc["read_register"] = "\ 930Replace read_register() with regcache_read() et.al." 931 category["read_register"] = ari_regression 932} 933/(^|[^_[:alnum:]])read_register([^_[:alnum:]]|$)/ { 934 fail("read_register") 935} 936 937BEGIN { doc["write_register"] = "\ 938Replace write_register() with regcache_read() et.al." 939 category["write_register"] = ari_regression 940} 941/(^|[^_[:alnum:]])write_register([^_[:alnum:]]|$)/ { 942 fail("write_register") 943} 944 945function report(name) { 946 # Drop any trailing _P. 947 name = gensub(/(_P|_p)$/, "", 1, name) 948 # Convert to lower case 949 name = tolower(name) 950 # Split into category and bug 951 cat = gensub(/^([[:alpha:]]+)_([_[:alnum:]]*)$/, "\\1", 1, name) 952 bug = gensub(/^([[:alpha:]]+)_([_[:alnum:]]*)$/, "\\2", 1, name) 953 # Report it 954 name = cat " " bug 955 doc[name] = "Do not use " cat " " bug ", see declaration for details" 956 category[name] = cat 957 fail(name) 958} 959 960/(^|[^_[:alnum:]])(DEPRECATED|deprecated|set_gdbarch_deprecated|LEGACY|legacy|set_gdbarch_legacy)_/ { 961 line = $0 962 # print "0 =", $0 963 while (1) { 964 name = gensub(/^(|.*[^_[:alnum:]])((DEPRECATED|deprecated|LEGACY|legacy)_[_[:alnum:]]*)(.*)$/, "\\2", 1, line) 965 line = gensub(/^(|.*[^_[:alnum:]])((DEPRECATED|deprecated|LEGACY|legacy)_[_[:alnum:]]*)(.*)$/, "\\1 \\4", 1, line) 966 # print "name =", name, "line =", line 967 if (name == line) break; 968 report(name) 969 } 970} 971 972# Count the number of times each architecture method is set 973/(^|[^_[:alnum:]])set_gdbarch_[_[:alnum:]]*([^_[:alnum:]]|$)/ { 974 name = gensub(/^.*set_gdbarch_([_[:alnum:]]*).*$/, "\\1", 1, $0) 975 doc["set " name] = "\ 976Call to set_gdbarch_" name 977 category["set " name] = ari_gdbarch 978 fail("set " name) 979} 980 981# Count the number of times each tm/xm/nm macro is defined or undefined 982/^#[[:space:]]*(undef|define)[[:space:]]+[[:alnum:]_]+.*$/ \ 983&& !/^#[[:space:]]*(undef|define)[[:space:]]+[[:alnum:]_]+_H($|[[:space:]])/ \ 984&& FILENAME ~ /(^|\/)config\/(|[^\/]*\/)(tm-|xm-|nm-).*\.h$/ { 985 basename = gensub(/(^|.*\/)([^\/]*)$/, "\\2", 1, FILENAME) 986 type = gensub(/^(tm|xm|nm)-.*\.h$/, "\\1", 1, basename) 987 name = gensub(/^#[[:space:]]*(undef|define)[[:space:]]+([[:alnum:]_]+).*$/, "\\2", 1, $0) 988 if (type == basename) { 989 type = "macro" 990 } 991 doc[type " " name] = "\ 992Do not define macros such as " name " in a tm, nm or xm file, \ 993in fact do not provide a tm, nm or xm file" 994 category[type " " name] = ari_macro 995 fail(type " " name) 996} 997 998BEGIN { doc["deprecated_registers"] = "\ 999Replace deprecated_registers with nothing, they have reached \ 1000end-of-life" 1001 category["deprecated_registers"] = ari_eol 1002} 1003/(^|[^_[:alnum:]])deprecated_registers([^_[:alnum:]]|$)/ { 1004 fail("deprecated_registers") 1005} 1006 1007BEGIN { doc["read_pc"] = "\ 1008Replace READ_PC() with frame_pc_unwind; \ 1009at present the inferior function call code still uses this" 1010 category["read_pc"] = ari_deprecate 1011} 1012/(^|[^_[:alnum:]])read_pc[[:space:]]*\(/ || \ 1013/(^|[^_[:alnum:]])set_gdbarch_read_pc[[:space:]]*\(/ || \ 1014/(^|[^_[:alnum:]])TARGET_READ_PC[[:space:]]*\(/ { 1015 fail("read_pc") 1016} 1017 1018BEGIN { doc["write_pc"] = "\ 1019Replace write_pc() with get_frame_base_address or get_frame_id; \ 1020at present the inferior function call code still uses this when doing \ 1021a DECR_PC_AFTER_BREAK" 1022 category["write_pc"] = ari_deprecate 1023} 1024/(^|[^_[:alnum:]])write_pc[[:space:]]*\(/ || \ 1025/(^|[^_[:alnum:]])TARGET_WRITE_PC[[:space:]]*\(/ { 1026 fail("write_pc") 1027} 1028 1029BEGIN { doc["generic_target_write_pc"] = "\ 1030Replace generic_target_write_pc with a per-architecture implementation, \ 1031this relies on PC_REGNUM which is being eliminated" 1032 category["generic_target_write_pc"] = ari_regression 1033} 1034/(^|[^_[:alnum:]])generic_target_write_pc([^_[:alnum:]]|$)/ { 1035 fail("generic_target_write_pc") 1036} 1037 1038BEGIN { doc["read_sp"] = "\ 1039Replace read_sp() with frame_sp_unwind" 1040 category["read_sp"] = ari_regression 1041} 1042/(^|[^_[:alnum:]])read_sp[[:space:]]*\(/ || \ 1043/(^|[^_[:alnum:]])set_gdbarch_read_sp[[:space:]]*\(/ || \ 1044/(^|[^_[:alnum:]])TARGET_READ_SP[[:space:]]*\(/ { 1045 fail("read_sp") 1046} 1047 1048BEGIN { doc["register_cached"] = "\ 1049Replace register_cached() with nothing, does not have a regcache parameter" 1050 category["register_cached"] = ari_regression 1051} 1052/(^|[^_[:alnum:]])register_cached[[:space:]]*\(/ { 1053 fail("register_cached") 1054} 1055 1056BEGIN { doc["set_register_cached"] = "\ 1057Replace set_register_cached() with nothing, does not have a regcache parameter" 1058 category["set_register_cached"] = ari_regression 1059} 1060/(^|[^_[:alnum:]])set_register_cached[[:space:]]*\(/ { 1061 fail("set_register_cached") 1062} 1063 1064# Print functions: Use versions that either check for buffer overflow 1065# or safely allocate a fresh buffer. 1066 1067BEGIN { doc["sprintf"] = "\ 1068Do not use sprintf, instead use xsnprintf or xstrprintf" 1069 category["sprintf"] = ari_code 1070} 1071/(^|[^_[:alnum:]])sprintf[[:space:]]*\(/ { 1072 fail("sprintf") 1073} 1074 1075BEGIN { doc["vsprintf"] = "\ 1076Do not use vsprintf(), instead use xstrvprintf" 1077 category["vsprintf"] = ari_regression 1078} 1079/(^|[^_[:alnum:]])vsprintf[[:space:]]*\(/ { 1080 fail("vsprintf") 1081} 1082 1083BEGIN { doc["asprintf"] = "\ 1084Do not use asprintf(), instead use xstrprintf()" 1085 category["asprintf"] = ari_regression 1086} 1087/(^|[^_[:alnum:]])asprintf[[:space:]]*\(/ { 1088 fail("asprintf") 1089} 1090 1091BEGIN { doc["vasprintf"] = "\ 1092Do not use vasprintf(), instead use xstrvprintf" 1093 fix("vasprintf", "common/common-utils.c", 1) 1094 category["vasprintf"] = ari_regression 1095} 1096/(^|[^_[:alnum:]])vasprintf[[:space:]]*\(/ { 1097 fail("vasprintf") 1098} 1099 1100# More generic memory operations 1101 1102BEGIN { doc["bzero"] = "\ 1103Do not use bzero(), instead use memset()" 1104 category["bzero"] = ari_regression 1105} 1106/(^|[^_[:alnum:]])bzero[[:space:]]*\(/ { 1107 fail("bzero") 1108} 1109 1110BEGIN { doc["strdup"] = "\ 1111Do not use strdup(), instead use xstrdup()"; 1112 category["strdup"] = ari_regression 1113} 1114/(^|[^_[:alnum:]])strdup[[:space:]]*\(/ { 1115 fail("strdup") 1116} 1117 1118BEGIN { doc["strsave"] = "\ 1119Do not use strsave(), instead use xstrdup() et.al." 1120 category["strsave"] = ari_regression 1121} 1122/(^|[^_[:alnum:]])strsave[[:space:]]*\(/ { 1123 fail("strsave") 1124} 1125 1126# String compare functions 1127 1128BEGIN { doc["strnicmp"] = "\ 1129Do not use strnicmp(), instead use strncasecmp()" 1130 category["strnicmp"] = ari_regression 1131} 1132/(^|[^_[:alnum:]])strnicmp[[:space:]]*\(/ { 1133 fail("strnicmp") 1134} 1135 1136# Boolean expressions and conditionals 1137 1138BEGIN { doc["boolean"] = "\ 1139Do not use `boolean'\'', use `int'\'' instead" 1140 category["boolean"] = ari_regression 1141} 1142/(^|[^_[:alnum:]])boolean([^_[:alnum:]]|$)/ { 1143 if (is_yacc_or_lex == 0) { 1144 fail("boolean") 1145 } 1146} 1147 1148BEGIN { doc["false"] = "\ 1149Definitely do not use `false'\'' in boolean expressions" 1150 category["false"] = ari_regression 1151} 1152/(^|[^_[:alnum:]])false([^_[:alnum:]]|$)/ { 1153 if (is_yacc_or_lex == 0) { 1154 fail("false") 1155 } 1156} 1157 1158BEGIN { doc["true"] = "\ 1159Do not try to use `true'\'' in boolean expressions" 1160 category["true"] = ari_regression 1161} 1162/(^|[^_[:alnum:]])true([^_[:alnum:]]|$)/ { 1163 if (is_yacc_or_lex == 0) { 1164 fail("true") 1165 } 1166} 1167 1168# Typedefs that are either redundant or can be reduced to `struct 1169# type *''. 1170# Must be placed before if assignment otherwise ARI exceptions 1171# are not handled correctly. 1172 1173BEGIN { doc["d_namelen"] = "\ 1174Do not use dirent.d_namelen, instead use NAMELEN" 1175 category["d_namelen"] = ari_regression 1176} 1177/(^|[^_[:alnum:]])d_namelen([^_[:alnum:]]|$)/ { 1178 fail("d_namelen") 1179} 1180 1181BEGIN { doc["strlen d_name"] = "\ 1182Do not use strlen dirent.d_name, instead use NAMELEN" 1183 category["strlen d_name"] = ari_regression 1184} 1185/(^|[^_[:alnum:]])strlen[[:space:]]*\(.*[^_[:alnum:]]d_name([^_[:alnum:]]|$)/ { 1186 fail("strlen d_name") 1187} 1188 1189BEGIN { doc["var_boolean"] = "\ 1190Replace var_boolean with add_setshow_boolean_cmd" 1191 category["var_boolean"] = ari_regression 1192 fix("var_boolean", "gdb/command.h", 1) 1193 # fix only uses the last directory level 1194 fix("var_boolean", "cli/cli-decode.c", 2) 1195} 1196/(^|[^_[:alnum:]])var_boolean([^_[:alnum:]]|$)/ { 1197 if (($0 !~ /(^|[^_[:alnum:]])case *var_boolean:/) \ 1198 && ($0 !~ /(^|[^_[:alnum:]])[=!]= *var_boolean/)) { 1199 fail("var_boolean") 1200 } 1201} 1202 1203BEGIN { doc["generic_use_struct_convention"] = "\ 1204Replace generic_use_struct_convention with nothing, \ 1205EXTRACT_STRUCT_VALUE_ADDRESS is a predicate" 1206 category["generic_use_struct_convention"] = ari_regression 1207} 1208/(^|[^_[:alnum:]])generic_use_struct_convention([^_[:alnum:]]|$)/ { 1209 fail("generic_use_struct_convention") 1210} 1211 1212BEGIN { doc["if assignment"] = "\ 1213An IF statement'\''s expression contains an assignment (the GNU coding \ 1214standard discourages this)" 1215 category["if assignment"] = ari_code 1216} 1217BEGIN { doc["if clause more than 50 lines"] = "\ 1218An IF statement'\''s expression expands over 50 lines" 1219 category["if clause more than 50 lines"] = ari_code 1220} 1221# 1222# Accumulate continuation lines 1223FNR == 1 { 1224 in_if = 0 1225} 1226 1227/(^|[^_[:alnum:]])if / { 1228 in_if = 1; 1229 if_brace_level = 0; 1230 if_cont_p = 0; 1231 if_count = 0; 1232 if_brace_end_pos = 0; 1233 if_full_line = ""; 1234} 1235(in_if) { 1236 # We want everything up to closing brace of same level 1237 if_count++; 1238 if (if_count > 50) { 1239 print "multiline if: " if_full_line $0 1240 fail("if clause more than 50 lines") 1241 if_brace_level = 0; 1242 if_full_line = ""; 1243 } else { 1244 if (if_count == 1) { 1245 i = index($0,"if "); 1246 } else { 1247 i = 1; 1248 } 1249 for (i=i; i <= length($0); i++) { 1250 char = substr($0,i,1); 1251 if (char == "(") { if_brace_level++; } 1252 if (char == ")") { 1253 if_brace_level--; 1254 if (!if_brace_level) { 1255 if_brace_end_pos = i; 1256 after_if = substr($0,i+1,length($0)); 1257 # Do not parse what is following 1258 break; 1259 } 1260 } 1261 } 1262 if (if_brace_level == 0) { 1263 $0 = substr($0,1,i); 1264 in_if = 0; 1265 } else { 1266 if_full_line = if_full_line $0; 1267 if_cont_p = 1; 1268 next; 1269 } 1270 } 1271} 1272# if we arrive here, we need to concatenate, but we are at brace level 0 1273 1274(if_brace_end_pos) { 1275 $0 = if_full_line substr($0,1,if_brace_end_pos); 1276 if (if_count > 1) { 1277 # print "IF: multi line " if_count " found at " FILENAME ":" FNR " \"" $0 "\"" 1278 } 1279 if_cont_p = 0; 1280 if_full_line = ""; 1281} 1282/(^|[^_[:alnum:]])if .* = / { 1283 # print "fail in if " $0 1284 fail("if assignment") 1285} 1286(if_brace_end_pos) { 1287 $0 = $0 after_if; 1288 if_brace_end_pos = 0; 1289 in_if = 0; 1290} 1291 1292# Printout of all found bug 1293 1294BEGIN { 1295 if (print_doc) { 1296 for (bug in doc) { 1297 fail(bug) 1298 } 1299 exit 1300 } 1301}' "$@" 1302 1303