This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: Tools to generate the ARI bug lists
Just FYI, the breakdown of what came from where is in:
http://sources.redhat.com/gdb/current/ari/ari.source.bug
(I only very recently added a link to this). The script is attached.
Andrew
#!/bin/sh -x
# TODO: setjmp.h, setjmp and longjmp.
PATH=/bin:/usr/bin:/usr/local/bin:$HOME/bin
export PATH
# Direct stderr into stdout but still hang onto stderr (/dev/fd/3)
exec 3>&2 2>&1
ECHO ()
{
# echo "$@" | tee /dev/fd/3 1>&2
echo "$@" 1>&2
echo "$@" 1>&3
}
# Really mindless usage
if test $# -ne 4
then
echo "Usage: $0 <snapshot> <tmpdir> <destdir> <project>" 1>&2
exit 1
fi
snapshot=$1 ; shift
tmpdir=$1 ; shift
wwwdir=$1 ; shift
project=$1 ; shift
if [ ! -w ${wwwdir} -o ! -d ${wwwdir} ]
then
echo ERROR: Can not write to directory ${wwwdir} >&2
exit 2
fi
if [ ! -r ${snapshot} ]
then
echo ERROR: Can not read snapshot file 1>&2
exit 1
fi
# FILE formats
# ari.*.doc: <BUG>:<COUNT>:<LEVEL>:<DOC>
# ari.*.bug: <BUG>:<COUNT>:<LEVEL>:<FILE>:<LINE>
# Where ``*'' is {source,warning,format,doschk}
ARI_REGRESSION=0
ARI_DEPRECATED=1
ARI_CODE=2
ARI_WARNING=3
ARI_INFO=4
ARI_FIRST=$ARI_CODE
unpack_source_p=true
delete_source_p=true
check_warning_p=false # broken
check_format_p=false # broken
check_source_p=true
check_doschk_p=true
check_werror_p=true
update_web_p=true
if awk --version 2>&1 </dev/null | grep -i gnu > /dev/null
then
AWK=awk
else
AWK=gawk
fi
# Set up a few cleanups
if ${delete_source_p}
then
trap "cd /tmp; rm -rf ${tmpdir}; exit" 0 1 2 15
fi
# unpack the tar-ball
if ${unpack_source_p}
then
/bin/rm -rf ${tmpdir}
/bin/mkdir ${tmpdir}
if [ ! -d ${tmpdir} ]
then
echo "Problem creating work directory"
exit 1
fi
cd ${tmpdir} || exit 1
echo `date`: Unpacking tar-ball ...
case ${snapshot} in
*.tar.bz2 ) bzcat ${snapshot} ;;
*.tar ) cat ${snapshot} ;;
* ) ECHO Bad file ${snapshot} ; exit 1 ;;
esac | tar xf -
fi
module=`basename ${snapshot}`
module=`basename ${module} .bz2`
module=`basename ${module} .tar`
srcdir=`echo ${tmpdir}/${module}*`
version_in=${srcdir}/gdb/version.in
if [ ! -r ${version_in} ]
then
echo ERROR: missing version file 1>&2
exit 1
fi
version=`cat ${version_in}`
# THIS HAS SUFFERED BIT ROT
if ${check_warning_p} && test -d "${srcdir}"
then
echo `date`: Parsing compiler warnings 1>&2
$AWK < ${root}/ari.compile '
BEGIN {
FS=":";
}
/^[^:]*:[0-9]*: warning:/ {
file = $1;
#sub (/^.*\//, "", file);
warning[file] += 1;
}
/^[^:]*:[0-9]*: error:/ {
file = $1;
#sub (/^.*\//, "", file);
error[file] += 1;
}
END {
for (file in warning) {
print file ":warning:" level[file]
}
for (file in error) {
print file ":error:" level[file]
}
}
' > ${root}/ari.warning.bug
fi
# THIS HAS SUFFERED BIT ROT
if ${check_format_p} && test -d "${srcdir}"
then
printf "Analizing file formatting:" 1>&2
( cd "${srcdir}/${project}" && ls | sed -n -e '/\.[hc]$/p'
) | while read f
do
printf " $f" 1>&2
lines=`( indent < "${srcdir}/${project}/${f}" | diff -e - "${srcdir}/${project}/${f}" ) 2>&1 | wc -l`
if test $lines -gt 0
then
echo ${f}:format:`echo ${lines}`
fi
done > ${wwwdir}/ari.format.bug
echo ""
fi
if ${check_source_p} && test -d "${srcdir}"
then
echo "`date`: Checking source code" 1>&2
rm -f ${wwwdir}/ari.source.*
find "${srcdir}/${project}" \
-name 'testsuite' -prune \
-o -name 'stop-gdb.c' -prune \
-o -name 'stuff.c' -prune \
-o -name '*-stub.c' -prune \
-o -name '*-share' -prune \
-o -name 'tui' -prune \
-o -name 'nlm' -prune \
-o -name 'gnu-regex.c' -prune \
-o -name 'gnu-regex.h' -prune \
-o -name '*\.tab\.c' -prune \
-o -name 'gdbserver' -prune \
-o -name '*.[hc]' -type f -print \
| $AWK > ${wwwdir}/ari.source.bug '
BEGIN {
comment_p = 0
string_p = 0
}
function fail (bug) {
# ari.*.bug: <BUG>:<COUNT>:<LEVEL>:<FILE>:<LINE>
if (fixit[bug, file] > 0) {
fixit[bug, file] -= 1
} else {
print bug ":" 1 ":" level[bug] ":" file ":" FNR
total[bug] += 1
}
}
function fix(bug, file, count) {
# ari.*.bug: <BUG>:<COUNT>:<LEVEL>:<FILE>:<LINE>
# print bug ":" -count ":" level[bug] ":" file ":" 0
fixit[bug, file] = count
}
# Load the list of files into an initially empty argument list.
# While STDIN is being parsed, ARGIND will remain zero.
ARGIND == 0 {
ARGV[ARGC++] = $0;
next;
}
# Initialize the PARSER
FNR == 1 {
file = FILENAME;
sub (/^.*\/'"${project}"'\//, "", file);
file = "'"${project}"'/" file
#printf " %s", file > "/dev/stderr";
#fflush (/dev/stderr);
}
# Skip deprecated/obsolete lines
/(^|[^_[:alnum:]])OBSOLETE([^_[:alnum:]]|$)/ { next; }
# Things in comments
BEGIN { doc["GNU/Linux"] = "\
Use either ``GNU/Linux'\'\'' or ``Linux kernel'\'\'' in comments. \
This test assumes that the word ``Linux'\'\'' appears on the same line \
as the ``GNU'\'\'' or ``kernel'\'\''."
level["GNU/Linux"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])Linux([^_[:alnum:]]|$)/ \
&& !/(^|[^_[:alnum:]])GNU\/Linux([^_[:alnum:]]|$)/ \
&& !/(^|[^_[:alnum:]])Linux kernel([^_[:alnum:]]|$)/ {
fail("GNU/Linux")
}
# SNIP - Strip out comments - SNIP
FNR == 1 { comment_p = 0; }
comment_p && /\*\// { gsub (/^([^\*]|\*+[^\/\*])*\*+\//, " "); comment_p = 0; }
comment_p { next; }
!comment_p { gsub (/\/\*([^\*]|\*+[^\/\*])*\*+\//, " "); }
!comment_p && /\/\*/ { gsub (/\/\*.*$/, " "); comment_p = 1; }
BEGIN { doc["error capital"] = "\
An error message should start with a capital letter"
level["error capital"] = '$ARI_INFO'
}
/(^[^_[:alnum:]])error([^_[:alnum:]]|$)\([[:space:]]*"[^A-Z]*[^\/]"/ {
fail("error capital")
}
BEGIN { doc["error full-stop"] = "\
An error message should not have a trailing full-stop"
level["error full-stop"] = '$ARI_REGRESSION'
}
/(^[^_[:alnum:]])error([^_[:alnum:]]|$)\([[:space:]]*"[^"]\."/ {
fail("error full-stop")
}
# Include files for which GDB has a custom version.
BEGIN { doc["assert.h"] = "\
Instead of assert.h, use gdb_assert.h";
level["assert.h"] = '$ARI_REGRESSION'
fix("assert.h", "gdb/gdb_assert.h", 0) # it does not use it
}
/^#[[:blank:]]*include[[:blank:]]+.assert\.h./ {
fail("assert.h")
}
BEGIN { doc["dirent.h"] = "\
Instead of dirent.h, use gdb_dirent.h";
level["dirent.h"] = '$ARI_REGRESSION'
fix("dirent.h", "gdb/gdb_dirent.h", 1);
}
/^#[[:blank:]]*include[[:blank:]]*.dirent\.h./ {
fail("dirent.h")
}
BEGIN { doc["proc_service.h"] = "\
Instead of proc_service.h, use gdb_proc_service.h";
level["proc_service.h"] = '$ARI_CODE'
fix("proc_service.h", "gdb/gdb_proc_service.h", 1)
}
/^#[[:blank:]]*include[[:blank:]]*.proc_service\.h./ {
fail("proc_service.h")
}
BEGIN { doc["regex.h"] = "\
Instead of regex.h, use gdb_regex.h";
level["regex.h"] = '$ARI_REGRESSION'
fix("regex.h", "gdb/gdb_regex.h", 1)
}
/^#[[:blank:]]*include[[:blank:]]*.regex\.h./ {
fail("regex.h")
}
BEGIN { doc["xregex.h"] = "\
Instead of xregex.h, use gdb_regex.h";
level["xregex.h"] = '$ARI_REGRESSION'
fix("xregex.h", "gdb/gdb_regex.h", 1)
}
/^#[[:blank:]]*include[[:blank:]]*.xregex\.h./ {
fail("xregex.h")
}
BEGIN { doc["gnu-regex.h"] = "\
Instead of gnu-regex.h, use gdb_regex.h";
level["gnu-regex.h"] = '$ARI_REGRESSION'
}
/^#[[:blank:]]*include[[:blank:]]*.gnu-regex\.h./ {
fail("gnu regex.h")
}
BEGIN { doc["stat.h"] = "\
Instead of stat.h or sys/stat.h, use gdb_stat.h";
level["stat.h"] = '$ARI_CODE'
fix("stat.h", "gdb/gdb_stat.h", 1)
}
/^#[[:blank:]]*include[[:blank:]]*.stat\.h./ \
|| /^#[[:blank:]]*include[[:blank:]]*.sys\/stat\.h./ {
fail("stat.h")
}
BEGIN { doc["string.h"] = "\
Instead of string.h, strings.h or memory.h, use gdb_string.h";
level["string.h"] = '$ARI_REGRESSION'
fix("string.h", "gdb/gdb_string.h", 4)
}
/^#[[:blank:]]*include[[:blank:]]*.string\.h./ \
|| /^#[[:blank:]]*include[[:blank:]]*.strings\.h./ \
|| /^#[[:blank:]]*include[[:blank:]]*.memory\.h./ {
fail("string.h")
}
BEGIN { doc["thread_db.h"] = "\
Instead of thread_db.h, use gdb_thread_db.h";
fix("thread_db.h", "gdb/gdb_thread_db.h", 1);
level["thread_db.h"] = '$ARI_CODE'
}
/^#[[:blank:]]*include[[:blank:]]*.thread_db\.h./ {
fail("thread_db.h")
}
BEGIN { doc["wait.h"] = "\
Instead of wait.h or sys/wait.h, use gdb_wait.h";
fix("wait.h", "gdb/gdb_wait.h", 2);
level["wait.h"] = '$ARI_CODE'
}
/^#[[:blank:]]*include[[:blank:]]*.wait\.h./ \
|| /^#[[:blank:]]*include[[:blank:]]*.sys\/wait\.h./ {
fail("wait.h")
}
BEGIN { doc["vfork.h"] = "\
Instead of vfork.h, use gdb_vfork.h";
fix("vfork.h", "gdb/gdb_vfork.h", 1);
level["vfork.h"] = '$ARI_REGRESSION'
}
/^#[[:blank:]]*include[[:blank:]]*.vfork\.h./ {
fail("vfork.h")
}
BEGIN { doc["Xm-OS.h"] = "\
Some config/ARCH/Xm-OS.h files use #include \"Xm-OS.h\". To include the \
file \"config/Xm-OS.h\". They should use the latter path."
level["Xm-OS.h"] = '$ARI_REGRESSION'
}
/^#[[:blank:]]*include[[:blank:]]*.nm-[^\.]*\.h./ \
|| /^#[[:blank:]]*include[[:blank:]]*.tm[^\.]*-\.h./ \
|| /^#[[:blank:]]*include[[:blank:]]*.xm-[^\.]*\.h./ {
fail("Xm-OS.h")
}
BEGIN { doc["error printing internal error"] = "\
Code should call the internal_error() function rather than print an \
internal-error message directly";
level["error printing internal error"] = '$ARI_WARNING'
}
/error.*\"Internal error/ || /error.*\"internal error/ {
fail("error printing internal error")
}
BEGIN { doc["%p"] = "\
Use %s and paddr() to print target addresses, not %p.";
level["%p"] = '$ARI_CODE'
}
/%p/ && !/%prec/ {
fail("%p")
}
BEGIN { doc["%ll"] = "\
Use %s and phex() et.al. to print long long values, not %ll.";
level["%ll"] = '$ARI_CODE'
}
/%ll/ {
fail("%ll")
}
# SNIP - Strip out strings - SNIP
# awk
# Test on top.c, scm-valprint.c, remote-rdi.c, ada-lang.c
FNR == 1 { string_p = 0; }
# Strip escaped characters.
{ gsub(/\\./, "."); }
# Strip quoted quotes.
{ gsub(/'\''.'\''/, "'\''.'\''"); }
# End of multi-line string
string_p && /\"/ {
# print "EOS:", $0;
gsub (/^[^\"]*\"/, "'\''");
string_p = 0;
}
# Middle of multi-line string, discard line.
string_p {
# print "MOS:", $0;
$0 = ""
}
# Strip complete strings from the middle of the line
!string_p {
# print "COS:", $0;
gsub (/\"[^\"]*\"/, "'\'\''");
}
# Start of multi-line string
!string_p && /\"/ {
# print "SOS:", $0;
gsub (/\"[^\"]*$/, "'\''");
string_p = 1;
}
# { print }
# Accumulate continuation lines
FNR == 1 { cont_p = 0; }
!cont_p { full_line = ""; }
/[^\\]\\$/ { gsub (/\\$/, ""); full_line = full_line $0; cont_p = 1; next; }
cont_p { $0 = full_line $0; cont_p = 0; full_line = ""; }
# GDB uses ISO C. Check for any non pure ISO C code
BEGIN { doc["PARAMS"] = "\
Still uses the PARAMS macro.";
level["PARAMS"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])PARAMS([^_[:alnum:]]|$)/ {
fail("PARAMS")
}
BEGIN { doc["__STDC__"] = "\
GDB assumes ISO C, testing for __STDC__ makes little sense";
level["__STDC__"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])__STDC__([^_[:alnum:]]|$)/ {
fail("__STDC__")
}
BEGIN { doc["__func__"] = "\
__func__ is a post ISO C 90 extension. EGCS 1.1.2, for instance, does not \
support it."
level["__func__"] = '$ARI_REGRESSION'
fix("__func__", "gdb/gdb_assert.h", 1)
}
/(^|[^_[:alnum:]])__func__([^_[:alnum:]]|$)/ {
fail("__func__")
}
BEGIN { doc["__FUNCTION__"] = "\
__FUNCTION__ is a post ISO C 90 extension."
level["__FUNCTION__"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])__FUNCTION__([^_[:alnum:]]|$)/ {
fail("__FUNCTION__")
}
BEGIN { doc["__CYGWIN32__"] = "\
__CYGWIN32__ has been replaced by __CYGWIN__ or, better, explicit \
autoconf tests";
level["__CYGWIN32__"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])__CYGWIN32__([^_[:alnum:]]|$)/ {
fail("__CYGWIN32__")
}
BEGIN { doc["PTR"] = "\
Use ``void *'\'\''. PTR dates back to the days before ISO C.";
level["PTR"] = '$ARI_CODE'
}
/(^|[^_[:alnum:]])PTR([^_[:alnum:]]|$)/ {
fail("PTR")
}
BEGIN { doc["//"] = "\
C++ comments - // - are not valid ISO C."
level["//"] = '$ARI_REGRESSION'
}
/\/\// {
fail("//")
}
BEGIN { doc["CONST_PTR"] = "\
Use ``const void *'\'\''. PTR dates back to the days before ISO C.";
level["CONST_PTR"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])CONST_PTR([^_[:alnum:]]|$)/ {
fail("CONST_PTR")
}
BEGIN { doc["grep ^func"] = "\
A function declaration with the function name positioned at the very start \
of a line. Only as part of the function definition should the function \
name appear at the very start of a line. This is so that \
``grep ^func'\'\'' works";
level["grep ^func"] = '$ARI_CODE'
}
{ grep_func = 0; }
/^[[:alnum:]_]+[[:blank:]]*\([[:blank:]]*[^\*].*\);[[:blank:]]*/ {
# FYI, it matches:
#NAME (...);
# when a normal declaration would have:
#TYPE NAME (...);
fail("grep ^func")
grep_func = 1;
}
BEGIN { doc["K&R defn"] = "\
Still uses an old style K&R function definition (not declaration). \
This check also trips up on incorrectly indented function declarations \
(see ``grep ^func'\'\'')."
level["K&R defn"] = '$ARI_REGRESSION'
fix("K&R defn", "gdb/ser-go32.c", 2)
}
/^[[:alnum:]_]+[[:blank:]]*\([[:alnum:]_]*[[:blank:]]*[,\)]/ && \
! /\(void\)/ && ! /\);/ && !grep_func {
fail("K&R defn")
}
BEGIN { doc["hash"] = "\
Some compilers will only corectly parse a preprocessor directive when the \
``#'\'\'' is the first character on the line. \
"
level["hash"] = '$ARI_REGRESSION'
}
/^[[:blank:]]+#/ {
fail("hash")
}
BEGIN { doc["#define JB_..."] = "\
The system header <setjmp.h> is free to define macros with the JB_ prefix.\
level["#define JB_..."] = '$ARI_CODE'
}
/^#[[:space:]]*define[[:space:]]*JB_/ {
fail("#define JB_...")
}
BEGIN { doc["make_cleanup_func"] = "\
Type casting using make_cleanup_func is invalid ISO C";
level["make_cleanup_func"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])make_cleanup_func([^_[:alnum:]]|$)/ {
fail("make_cleanup_func")
}
BEGIN { doc["catch_errors_ftype"] = "\
Type casting using catch_errors_ftype is invalid ISO C";
level["catch_errors_ftype"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])catch_errors_ftype([^_[:alnum:]]|$)/ {
fail("catch_errors_ftype")
}
BEGIN { doc["catch_errors"] = "\
Use catch_exceptions() in preference to catch_errors().";
level["catch_errors"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])catch_errors[[:space:]]*\(/ {
fail("catch_errors")
}
BEGIN { doc["strerror"] = "\
Use safe_strerror() in preference to strerror().";
level["strerror"] = '$ARI_REGRESSION'
fix("strerror", "gdb/gdb_string.h", 2)
fix("strerror", "gdb/utils.c", 1)
}
/(^|[^_[:alnum:]])strerror[[:space:]]*\(/ {
fail("strerror")
}
BEGIN { doc["long long"] = "\
Change ``long long'\'\'' to ``LONGEST'\'\''.";
level["long long"] = '$ARI_CODE'
}
/(^|[^_[:alnum:]])long[[:space:]]+long([^_[:alnum:]]|$)/ {
fail("long long")
}
BEGIN { doc["ATTRIBUTE_UNUSED"] = "\
GDB is compiled with -Werror and, consequently, is not able to tolerate \
false warnings. Since -Wunused-param produces such warnings, neither \
that warning flag nor ATTRIBUTE_UNUSED are used in GDB."
level["ATTRIBUTE_UNUSED"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])ATTRIBUTE_UNUSED([^_[:alnum:]]|$)/ {
fail("ATTRIBUTE_UNUSED")
}
# General problems
BEGIN { doc["_func"] = "\
The suffixes ..._func and ..._ftype are used inconsistently in the source. \
Perhaps just ..._ftype should be used.";
level["_func"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])[[:alpha:]_][[:alnum:]_]*_func([^_[:alnum:]]|$)/ {
fail("_func")
}
BEGIN { doc["TARGET_BYTE_ORDER_SELECTABLE"] = "\
This macro is made redundant by multi-arch."
level["TARGET_BYTE_ORDER_SELECTABLE"] = '$ARI_REGRESSION'
}
/TARGET_BYTE_ORDER_SELECTABLE/ {
fail("TARGET_BYTE_ORDER_SELECTABLE")
}
BEGIN { doc["TARGET_BYTE_ORDER_DEFAULT"] = "\
This macro is made redundant by multi-arch."
level["TARGET_BYTE_ORDER_DEFAULT"] = '$ARI_REGRESSION'
}
/TARGET_BYTE_ORDER_DEFAULT/ {
fail("TARGET_BYTE_ORDER_DEFAULT")
}
# Correct use of initialized?
BEGIN {
doc["_initialize decl"] = "\
Declaration of _initialize*() missing. The declaration stops a -Wmissing-declarations \
warning from GCC.";
level["_initialize decl"] = '$ARI_INFO'
doc["_initialize ftype"] = "\
Declaration of _initialize*() does not use initialize_file_ftype, should it?";
level["_initialize ftype"] = '$ARI_INFO'
}
# Remember what type declaration, if any, we see
FNR == 1 {
initialize_decl = 0;
initialize_ftype = 0;
}
/^extern[[:space:]]+void[[:space:]]+_initialize_[_[:alnum:]]*/ {
initialize_decl = 1
}
/^extern[[:space:]]+initialize_file_ftype[[:space:]]+_initialize_[_[:alnum:]]*/ {
initialize_ftype = 1
}
# Check it against the definition
/^_initialize_[_[:alnum:]]*[[:space:]]+/ {
if (!initialize_decl && !initialize_ftype) {
fail("_initialize decl")
}
if (!initialize_ftype) {
fail("_initialize ftype")
}
}
BEGIN { doc["inline"] = "\
Using INLINE generally suggests a micro-optimization - a better \
algorithm will likely produce greater performance improvements. \
Instead let the compiler decide if/when something needs to be \
made inline."
level["inline"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])inline([^_[:alnum:]]|$)/ {
fail("inline")
}
BEGIN { doc["register"] = "\
Let the compiler decide if something needs to be made register"
level["register"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])register([^_[:alnum:]]|$)/ {
fail("register")
}
BEGIN { doc["return_to_top_level"] = "\
return_to_top_level() is deprecated in favor of the verror(), error_stream() \
et.al.";
level["return_to_top_level"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])return_to_top_level[[:blank:]]*\(/ {
fail("return_to_top_level")
}
BEGIN { doc["error_begin"] = "\
error_begin() is deprecated in favor of verror(), error_stream() et.al.";
level["error_begin"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])error_begin[[:blank:]]*\(/ {
fail("error_begin")
}
BEGIN { doc["warning_begin"] = "\
warning_begin() is deprecated in favor of vwarning(), warning_stream() \
et.al. (see error_begin())";
level["warning_begin"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])warning_begin[[:blank:]]*\(/ {
fail("warning_begin")
}
BEGIN { doc["sizeof CORE_ADDR"] = "\
Taking the sizeof a CORE_ADDR is wrong. CORE_ADDR is at \
least as big as the target pointer, _not_ the same size. Use \
TARGET_PTR_BIT or TARGET_ADDR_BIT.";
level["sizeof CORE_ADDR"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])sizeof[[:blank:]]*\(CORE_ADDR\)/ \
|| /(^|[^_[:alnum:]])sizeof[[:blank:]]*CORE_ADDR([^_[:alnum:]]|$)/ {
fail("sizeof CORE_ADDR")
}
BEGIN { doc["REGNO"] = "\
Use the ..._REGNUM instead of the ..._REGNO name suffix";
level["REGNO"] = '$ARI_INFO'
}
/_REGNO([^_[:alnum:]]|$)/ || /_regno([^_[:alnum:]]|$)/ {
fail("REGNO")
}
BEGIN { doc["abort"] = "\
GDB should never abort - use internal_error()";
level["abort"] = '$ARI_REGRESSION'
fix("abort", "gdb/utils.c", 3)
}
/(^|[^_[:alnum:]])abort[[:blank:]]*\(/ {
fail("abort")
}
BEGIN { doc["basename"] = "\
GDB should never basename - use ``const char *lbasename(const char *)'\'\''";
level["basename"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])basename[[:blank:]]*\(/ {
fail("basename")
}
BEGIN { doc["assert"] = "\
GDB should never use assert(). Assert() calls abort() and GDB should \
not abort. Use internal_error() or gdb_assert() instead.";
level["assert"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])assert[[:blank:]]*\(/ {
fail("assert")
}
BEGIN { doc["CORE_ADDR cast"] = "\
Casting something to a CORE_ADDR is typically dangerous and non-portable. \
(The data from this pattern may be wrong)";
level["CORE_ADDR cast"] = '$ARI_WARNING'
}
/\(CORE_ADDR\)[:blank:]*[^,);]/ {
fail("CORE_ADDR cast")
}
BEGIN { doc["QUIT"] = "\
Uses QUIT which could be unsafe. Should it instead use ``if (QUIT_P ()) \
return ...;'\'\'' (which does not yet exist)."
level["QUIT"] = '$ARI_INFO'
}
/QUIT[[:blank:]]*[^;]/ {
fail("QUIT")
}
BEGIN { doc["quit_flag"] = "\
Uses ``quit_flag'\'\''. Should it instead use ``if (QUIT_P ()) ...'\'\'' \
(which does not yet exist).";
level["quit_flag"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])quit_flag([^_[:alnum:]]|$)/ {
fail("quit_flag")
}
BEGIN { doc["extern"] = "\
An ``extern'\'\'' declaration appears in a .c file";
level["extern"] = '$ARI_WARNING'
fix("extern", "gdb/ser-go32.c", 1) # extern *environ;
}
/^[[:blank:]]*extern[[:blank:]]*/ && ! /_initialize_/ && file ~ /\.c$/ {
fail("extern")
}
BEGIN { doc["#define"] = "\
Delcare an enum in preference to define a macro. ???";
level["#define"] = '$ARI_INFO'
}
/^#[[:blank:]]*define[[:blank:]]+[[:alnum:]_]+[[:blank:]]+/ {
fail("#define")
}
BEGIN { doc["#if"] = "\
Use an if statement in preference to conditionally compiled code. ???";
level["#if"] = '$ARI_INFO'
}
/^#[[:blank:]]*if/ && ! / HAVE_/ {
fail("#if")
}
BEGIN { doc["GDBTK"] = "\
#ifdef GDBTK should not be needed.";
level["GDBTK"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])GDBTK([^_[:alnum:]]|$)/ {
fail("GDBTK")
}
BEGIN { doc["TUI"] = "\
#ifdef TUI should not be needed.";
level["TUI"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])TUI([^_[:alnum:]]|$)/ {
fail("TUI")
}
BEGIN { doc["HAVE_VFORK"] = "\
#ifdef HAVE_VFORK is redundant. Include \"gdb_vfork.h\" and call vfork() \
unconditionally.";
level["HAVE_VFORK"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])HAVE_VFORK([^_[:alnum:]]|$)/ {
fail("HAVE_VFORK")
}
BEGIN { doc["DEBUG"] = "\
Nothing should depend on a macro like DEBUG"
level["DEBUG"] = '$ARI_INFO'
}
/^#[[:blank:]]*if.*DEBUG/ {
fail("DEBUG")
}
BEGIN { doc["union"] = "\
The union construct always leads to problems...";
level["union"] = '$ARI_INFO'
}
/[[:blank:]]*union[[:blank:]]*/ {
fail("union")
}
BEGIN { doc["unsafe getpkt"] = "\
Function that can call longjmp.";
level["unsafe getpkt"] = '$ARI_INFO'
}
/^[^_[:alnum:]]getpkt([^_[:alnum:]]|$)/ {
fail("unsafe getpkt")
}
BEGIN { doc["unsafe error"] = "\
Function that can can call longjmp.";
level["unsafe error"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])error[[:blank:]]*\(/ {
fail("unsafe error")
}
BEGIN { doc["readchar"] = "\
Parameterise the remote serial read/write code with the serial device \
being read.";
level["readchar"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])readchar[[:blank:]]*\(/ {
fail("readchar")
}
BEGIN { doc["sigsetmask"] = "\
sigsetmask() should be replaced by sigprocmask().";
level["sigsetmask"] = '$ARI_CODE'
}
/(^|[^_[:alnum:]])sigsetmask[[:blank:]]*\(/ {
fail("sigsetmask")
}
BEGIN { doc["bcmp"] = "\
bcmp() is deprecated in favor of the ISO C function memcmp().";
level["bcmp"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])bcmp[[:blank:]]*\(/ {
fail("bcmp")
}
BEGIN { doc["bzero"] = "\
bzero() id deprecated in favour of the ISO C function memset().";
level["bzero"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])bzero[[:blank:]]*\(/ {
fail("bzero")
}
BEGIN { doc["bcopy"] = "\
bcopy() id deprecated in favour of the ISO C functions memcpy() and \
memmove().";
level["bcopy"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])bcopy[[:blank:]]*\(/ {
fail("bcopy")
}
BEGIN { doc["atoi"] = "\
GDB needs a string to LONGEST conversion function. Something like \
string_to_core_addr() but in the style of strtol(). The latter has a habit \
of accepting dud strings."
level["atoi"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])atoi[[:blank:]]*\(/ {
fail("atoi")
}
BEGIN { doc["strtol"] = "\
GDB needs a string to LONGEST conversion function. Something like \
string_to_core_addr() but in the style of strtol(). The latter has a habit \
of accepting dud strings."
level["strtol"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])strtol[[:blank:]]*\(/ {
fail("strtol")
}
BEGIN { doc["printf"] = "\
All GDB output should use the *printf*filtered() functions.";
level["printf"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])printf[[:blank:]]*\(/ {
fail("printf")
}
BEGIN { doc["extract_floating"] = "\
extract_floating() is deprecated in favour of extract_typed_floating().";
level["extract_floating"] = '$ARI_DEPRECATED'
fix("extract_floating", "gdb/floatformat.c", 1)
}
/(^|[^_[:alnum:]])extract_floating[[:blank:]]*\(/ {
fail("extract_floating")
}
BEGIN { doc["store_floating"] = "\
store_floating() is deprecated in favour of store_typed_floating().";
level["store_floating"] = '$ARI_DEPRECATED'
fix("store_floating", "gdb/floatformat.c", 1)
}
/(^|[^_[:alnum:]])store_floating[[:blank:]]*\(/ {
fail("store_floating")
}
BEGIN { doc["floatformat_to_double"] = "\
floatformat_to_double() is deprecated in favour of \
floatformat_to_doublest().";
level["floatformat_to_double"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])floatformat_to_double[[:blank:]]*\(/ {
fail("floatformat_to_double")
}
BEGIN { doc["floatformat_from_double"] = "\
floatformat_from_double() is deprecated in favour of \
floatformat_from_doublest().";
level["floatformat_from_double"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])floatformat_from_double[[:blank:]]*\(/ {
fail("floatformat_from_double")
}
BEGIN { doc["floatformat_arm_ext"] = "\
GDB should use floatformat_arm_big or floatformat_arm_littlebyte_bigword.";
level["floatformat_arm_ext"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])floatformat_arm_ext([^_[:alnum:]]|$)/ {
fail("floatformat_arm_ext")
}
BEGIN { doc["IEEE_FLOAT"] = "\
The macro IEEE_FLOAT is no longer needed.";
level["IEEE_FLOAT"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])IEEE_FLOAT([^_[:alnum:]]|$)/ {
fail("IEEE_FLOAT")
}
BEGIN { doc["address of builtin_type"] = "\
The builtin_type* defined in \"gdbtypes.h\" are going to be changed to either \
dynamic variables or functions. Taking their address - as is often done in \
c-lang.c - will no longer be possible";
level["address of builtin_type"] = '$ARI_WARNING'
}
/\&builtin_type/ {
fail("address of builtin_type")
}
BEGIN { doc["FLOAT_INFO"] = "\
The macro FLOAT_INFO is deprecated in favour of PRINT_FLOAT_INFO.";
level["FLOAT_INFO"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])FLOAT_INFO([^_[:alnum:]]|$)/ {
fail("FLOAT_INFO")
}
BEGIN { doc["PRINT_REGISTER_HOOK"] = "\
The macro PRINT_REGISTER_HOOK is redundant. The macro DO_REGISTERS_INFO \
and a helper function can do similar."
level["PRINT_REGISTER_HOOK"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])PRINT_REGISTER_HOOK([^_[:alnum:]]|$)/ {
fail("PRINT_REGISTER_HOOK")
}
BEGIN { doc["INVALID_FLOAT"] = "\
The macro INVALID_FLOAT was just just wierd.";
level["INVALID_FLOAT"] = '$ARI_REGRESSION'
fix("INVALID_FLOAT", "gdb/vax-tdep.c", 3);
}
/(^|[^_[:alnum:]])INVALID_FLOAT([^_[:alnum:]]|$)/ {
fail("INVALID_FLOAT")
}
BEGIN { doc["HOST_BYTE_ORDER"] = "\
The macro HOST_BYTE_ORDER is not used.";
level["HOST_BYTE_ORDER"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])HOST_BYTE_ORDER([^_[:alnum:]]|$)/ {
fail("HOST_BYTE_ORDER")
}
BEGIN { doc["BIG_ENDIAN"] = "\
The macro BIG_ENDIAN is being replaced with BFD_ENDIAN_BIG.";
level["BIG_ENDIAN"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])BIG_ENDIAN([^_[:alnum:]]|$)/ {
fail("BIG_ENDIAN")
}
BEGIN { doc["LITTLE_ENDIAN"] = "\
The macro LITTLE_ENDIAN is being replaced with BFD_ENDIAN_LITTLE.";
level["LITTLE_ENDIAN"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])LITTLE_ENDIAN([^_[:alnum:]]|$)/ {
fail("LITTLE_ENDIAN")
}
BEGIN { doc["report_transfer_performance"] = "\
?????";
level["report_transfer_performance"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])report_transfer_performance([^_[:alnum:]]|$)/ {
fail("report_transfer_performance")
}
BEGIN { doc["DECR_PC_AFTER_BREAK"] = "\
I wish this would just go away. An ISA has one or more hardware registers \
that define a processors current execution point in an instruction stream. \
Sometimes those registers specify the instruction about to be executed \
and sometimes one beyond that. None of this is of interest to core-gdb. \
Instead the architecture should provide a current instruction address \
method that always returns the address of the instruction about to be \
executed (as determined from the hardware registers).";
level["DECR_PC_AFTER_BREAK"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])DECR_PC_AFTER_BREAK([^_[:alnum:]]|$)/ {
fail("DECR_PC_AFTER_BREAK")
}
BEGIN { doc["USG"] = "\
What does USG even tell us?";
level["USG"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])USG([^_[:alnum:]]|$)/ {
fail("USG")
}
BEGIN { doc["EXTRA_FRAME_INFO"] = "\
The macro EXTRA_FRAME_INFO is replaced by ``struct frame_extra_info'\'\''.";
level["EXTRA_FRAME_INFO"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])EXTRA_FRAME_INFO([^_[:alnum:]]|$)/ {
fail("EXTRA_FRAME_INFO")
}
BEGIN { doc["FRAME_FIND_SAVED_REGS"] = "\
The macro FRAME_FIND_SAVED_REGS is replaced by FRAME_INIT_SAVED_REGS.";
level["FRAME_FIND_SAVED_REGS"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])FRAME_FIND_SAVED_REGS([^_[:alnum:]]|$)/ {
fail("FRAME_FIND_SAVED_REGS")
}
BEGIN { doc["SIZEOF_FRAME_SAVED_REGS"] = "\
The macro SIZEOF_FRAME_SAVED_REGS typically should not be needed.";
level["SIZEOF_FRAME_SAVED_REGS"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])SIZEOF_FRAME_SAVED_REGS([^_[:alnum:]]|$)/ {
fail("SIZEOF_FRAME_SAVED_REGS")
}
BEGIN { doc["strsignal"] = "\
GDB should be using the ABI to convert a signal into a string.";
level["strsignal"] = '$ARI_CODE'
}
/(^|[^_[:alnum:]])strsignal[[:blank:]]*\(/ {
fail("strsignal")
}
BEGIN { doc["target_signal"] = "\
This is really badly named. It should be called something like gdb_signal \
as it is GDBs internal representation of the target signal. It gets worse \
as target_signal_to_host() is actually translating to/from the true target \
signal.";
level["target_signal"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])target_signal([^_[:alnum:]]|$)/ {
fail("target_signal")
}
# The register cache and the addition of a frame argument.
BEGIN { doc["registers []"] = "\
Too many cases of code just blatting registers[]. Use existing interfaces \
and mechanisms.";
level["registers []"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])registers([^_[:alnum:]]|$)/ && ! /->registers([^_[:alnum:]]|$)/ {
fail("registers []")
}
BEGIN { doc["register_valid []"] = "\
Too many cases of code just blatting register_valid[]. Use existing \
interfaces and mechanisms.";
level["register_valid []"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])register_valid([^_[:alnum:]]|$)/ {
fail("register_valid []")
}
BEGIN { doc["read_register_gen in target"] = "\
Target and nat code should fetch values from the cache using \
regcache_collect()."
level["read_register_gen in target"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])read_register_gen([^_[:alnum:]]|$)/ && file ~ /.*-nat\.c/ {
fail("read_register_gen in target")
}
BEGIN { doc["read_register_bytes"] = "\
The function read_register_bytes() should be avoided. Typically \
read_register_gen() can be used. There are unfortunatly still one or \
two cases where read_register_bytes() is needed that need to be fixed \
and until that is done, it is not possible to make this an error."
level["read_register_bytes"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])read_register_bytes[[:blank:]]*\(/ {
fail("read_register_bytes")
}
BEGIN { doc["write_register_bytes"] = "\
The function write_register_bytes() should be avoided. Typically \
write_register_gen() can be used. There are unfortunatly still one or \
two cases where write_register_bytes() is needed that need to be fixed \
and until that is done, it is not possible to make this an error."
level["write_register_bytes"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])write_register_bytes[[:blank:]]*\(/ {
fail("write_register_bytes")
}
BEGIN { doc["registers_fetched"] = "\
registers_fetched() is replaced by supply_register().";
level["registers_fetched"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])registers_fetched[[:blank:]]*\(/ {
fail("registers_fetched")
}
BEGIN { doc["generic_get_saved_register"] = "\
generic_get_saved_register() is replaced by \
generic_unwind_get_saved_register() (which really should be made the \
default).";
level["generic_get_saved_register"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])generic_get_saved_register[[:blank:]]*\(/ {
fail("generic_get_saved_register")
}
BEGIN { doc["deprecated"] = "\
Uses a deprecated function or macro.";
level["DEPRECATED"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])DEPRECATED_/ || \
/(^|[^_[:alnum:]])deprecated_/ {
fail("deprecated")
}
BEGIN { doc["REGISTER_NAME_ALIAS_HOOK"] = "\
REGISTER_NAME_ALIAS_HOOK() is obsolete.";
level["REGISTER_NAME_ALIAS_HOOK"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])REGISTER_NAME_ALIAS_HOOK[[:blank:]]*\(/ \
|| /(^|[^_[:alnum:]])REGISTER_NAME_ALIAS_HOOK[[:blank:]]*\(/ {
fail("REGISTER_NAME_ALIAS_HOOK")
}
BEGIN { doc["STORE_PSEUDO_REGISTER"] = "\
STORE_PSEUDO_REGISTER() is replaced with gdbarch_register_write().";
level["STORE_PSEUDO_REGISTER"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])STORE_PSEUDO_REGISTER[[:blank:]]*\(/ \
|| /(^|[^_[:alnum:]])set_gdbarch_store_pseudo_register[[:blank:]]*\(/ {
fail("STORE_PSEUDO_REGISTER")
}
BEGIN { doc["FETCH_PSEUDO_REGISTER"] = "\
FETCH_PSEUDO_REGISTER() is replaced by gdbarch_register_read().";
level["FETCH_PSEUDO_REGISTER"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])FETCH_PSEUDO_REGISTER[[:blank:]]*\(/ || \
/(^|[^_[:alnum:]])set_gdbarch_fetch_pseudo_register[[:blank:]]*\(/ {
fail("FETCH_PSEUDO_REGISTER")
}
BEGIN { doc["IS_TRAPPED_INTERNALVAR"] = "\
IS_TRAPPED_INTERNALVAR() is replaced by gdbarch_register_read().";
level["IS_TRAPPED_INTERNALVAR"] = '$ARI_DEPRECATED'
}
/(^|[^_[:alnum:]])IS_TRAPPED_INTERNALVAR[[:blank:]]*\(/ {
fail("IS_TRAPPED_INTERNALVAR")
}
BEGIN { doc["REGISTER_BYTE"] = "\
REGISTER_BYTE and its co-conspirator, registers[] should both be deleted. \
The successor, computed at run-time, should be local to regcache.c.";
level["REGISTER_BYTE"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])REGISTER_BYTE[[:blank:]]*\(/ {
fail("REGISTER_BYTE")
}
BEGIN { doc["REGISTER_BYTES"] = "\
REGISTER_BYTES the size of the regcache can be computed at run time.";
level["REGISTER_BYTES"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])REGISTER_BYTES[[:blank:]]*\(/ {
fail("REGISTER_BYTES")
}
BEGIN { doc["REGISTER_VIRTUAL_TYPE"] = "\
REGISTER_VIRTUAL_TYPE() should be replaced by a single \
REGISTER_TYPE() function."
level["REGISTER_VIRTUAL_TYPE"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])REGISTER_VIRTUAL_TYPE[[:blank:]]*\(/ {
fail("REGISTER_VIRTUAL_TYPE")
}
BEGIN { doc["REGISTER_{RAW,VIRTUAL}_SIZE"] = "\
REGISTER_{RAW,VIRTUAL}_SIZE() should be replaced by a single \
REGISTER_SIZE() function that computes the size from \
REGISTER_VIRTUAL_TYPE().";
level["REGISTER_{RAW,VIRTUAL}_SIZE"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])REGISTER_RAW_SIZE[[:blank:]]*\(/ || \
/(^|[^_[:alnum:]])REGISTER_VIRTUAL_SIZE[[:blank:]]*\(/ {
fail("REGISTER_{RAW,VIRTUAL}_SIZE")
}
BEGIN { doc["MAX_REGISTER_{RAW,VIRTUAL}_SIZE"] = "\
MAX_REGISTER_{RAW,VIRTUAL}_SIZE can be computed at runtime from \
REGISTER_{RAW,VIRTUAL}_SIZE().";
level["MAX_REGISTER_{RAW,VIRTUAL}_SIZE"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])MAX_REGISTER_RAW_SIZE([^_[:alnum:]]|$)/ || \
/(^|[^_[:alnum:]])MAX_REGISTER_VIRTUAL_SIZE([^_[:alnum:]]|$)/ {
fail("MAX_REGISTER_{RAW,VIRTUAL}_SIZE")
}
BEGIN { doc["[MAX_REGISTER_{RAW,VIRTUAL}_SIZE]"] = "\
MAX_REGISTER_{RAW,VIRTUAL}_SIZE is a function and, hence, can not be \
used to specify the size of an array.";
level["[MAX_REGISTER_{RAW,VIRTUAL}_SIZE]"] = '$ARI_CODE'
}
/\[[[:blank:]]*MAX_REGISTER_RAW_SIZE[[:blank:]]*\]/ || \
/\[[[:blank:]]*MAX_REGISTER_VIRTUAL_SIZE[[:blank:]]*\]/ {
fail("[MAX_REGISTER_{RAW,VIRTUAL}_SIZE]")
}
BEGIN { doc["DO_REGISTERS_INFO"] = "\
DO_REGISTERS_INFO() should be replaced by FRAME_REGISTERS_INFO.";
level["DO_REGISTERS_INFO"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])DO_REGISTERS_INFO[[:blank:]]*\(/ {
fail("DO_REGISTERS_INFO")
}
BEGIN { doc["REGISTER_CONVERTIBLE"] = "\
REGISTER_CONVERTIBLE() has overloaded semantics.";
level["REGISTER_CONVERTIBLE"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])REGISTER_CONVERTIBLE[[:blank:]]*\(/ {
fail("REGISTER_CONVERTIBLE")
}
BEGIN { doc["REGISTER_CONVERT_TO_RAW"] = "\
REGISTER_CONVERT_TO_RAW() has overloaded semantics.";
level["REGISTER_CONVERT_TO_RAW"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])REGISTER_CONVERT_TO_RAW[[:blank:]]*\(/ {
fail("REGISTER_CONVERT_TO_RAW")
}
BEGIN { doc["REGISTER_CONVERT_TO_VIRTUAL"] = "\
REGISTER_CONVERT_TO_VIRTUAL() has overloaded semantics.";
level["REGISTER_CONVERT_TO_VIRTUAL"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])REGISTER_CONVERT_TO_VIRTUAL[[:blank:]]*\(/ {
fail("REGISTER_CONVERT_TO_VIRTUAL")
}
# The totally dreaded FP REGNUM code.
BEGIN { doc["FP_REGNUM"] = "\
FP_REGNUM() is going to be deleted.";
level["FP_REGNUM"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])FP_REGNUM[[:blank:]]*\(/ {
fail("FP_REGNUM")
}
BEGIN { doc["TARGET_WRITE_FP"] = "\
TARGET_WRITE_FP() has been deleted.";
level["TARGET_WRITE_FP"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])TARGET_WRITE_FP[[:blank:]]*\(/ {
fail("TARGET_WRITE_FP")
}
BEGIN { doc["write_fp"] = "\
write_fp() has been deleted.";
level["write_fp"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])write_fp[[:blank:]]*\(/ {
fail("write_fp")
}
BEGIN { doc["TARGET_READ_FP"] = "\
TARGET_READ_FP() might be deleted.";
level["TARGET_READ_FP"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])TARGET_READ_FP[[:blank:]]*\(/ {
fail("TARGET_READ_FP")
}
BEGIN { doc["read_fp"] = "\
read_fp() might be deleted.";
level["read_fp"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])read_fp[[:blank:]]*\(/ {
fail("read_fp")
}
# Print functions: Use versions that either check for buffer overflow
# or safely allocate a fresh buffer.
BEGIN { doc["sprintf"] = "\
sprintf() should be avoided. Use either xasprintf() or snprintf().";
level["sprintf"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])sprintf[[:blank:]]*\(/ {
fail("sprintf")
}
BEGIN { doc["vsprint"] = "\
vsprint() should be avoided. Use either xvasprint() or vsnprintf().";
level["vsprint"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])vsprint[[:blank:]]*\(/ {
fail("vsprint")
}
BEGIN { doc["asprintf"] = "\
asprintf() is deprecated in favour of xasprintf().";
level["asprintf"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])asprintf[[:blank:]]*\(/ {
fail("asprintf")
}
BEGIN { doc["vasprintf"] = "\
vasprintf() is deprecated in favour of xvasprintf().";
fix("vasprintf", "gdb/utils.c", 1)
level["vasprintf"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])vasprintf[[:blank:]]*\(/ {
fail("vasprintf")
}
# Memory allocation: malloc(): Use versions that check for NULL memory
# buffers. gdb/utils.c contains wrappers that call the underlying
# functions.
BEGIN { doc["malloc"] = "\
GDB uses xmalloc() and not malloc()";
level["malloc"] = '$ARI_REGRESSION';
fix("malloc", "gdb/utils.c", 2); # decl, use
}
/(^|[^_[:alnum:]])malloc[[:blank:]]*\(/ {
fail("malloc")
}
BEGIN { doc["calloc"] = "\
GDB uses xcalloc() and not calloc()";
level["calloc"] = '$ARI_REGRESSION';
fix("calloc", "gdb/utils.c", 1);
}
/(^|[^_[:alnum:]])calloc[[:blank:]]*\(/ {
fail("calloc")
}
BEGIN { doc["realloc"] = "\
GDB uses xrealloc() and not realloc()";
level["realloc"] = '$ARI_REGRESSION';
fix("realloc", "gdb/utils.c", 2); # decl, use
}
/(^|[^_[:alnum:]])realloc[[:blank:]]*\(/ {
fail("realloc")
}
BEGIN { doc["free"] = "\
GDB uses xfree() and not free(). xfree() can handle NULL.";
level["free"] = '$ARI_REGRESSION';
fix("free", "gdb/utils.c", 2); # decl, use
}
/(^|[^_[:alnum:]>\.])free[[:blank:]]*\(/ {
fail("free")
}
# Memory allocation: mmalloc(): Use versions that check for NULL memory
# buffers. gdb/utils.c contains wrappers that call the underlying
# functions.
BEGIN { doc["mmalloc"] = "\
GDB uses xmmalloc() and not mmalloc()";
level["mmalloc"] = '$ARI_REGRESSION'
fix("mmalloc", "gdb/utils.c", 4);
}
/(^|[^_[:alnum:]])mmalloc[[:blank:]]*\(/ {
fail("mmalloc")
}
BEGIN { doc["mcalloc"] = "\
GDB uses xmcalloc() and not mcalloc()";
level["mcalloc"] = '$ARI_REGRESSION'
fix("mcalloc", "gdb/utils.c", 2);
}
/(^|[^_[:alnum:]])mcalloc[[:blank:]]*\(/ {
fail("mcalloc")
}
BEGIN { doc["mrealloc"] = "\
GDB uses xmrealloc() and not mrealloc()";
level["mrealloc"] = '$ARI_REGRESSION'
fix("mrealloc", "gdb/utils.c", 2);
}
/(^|[^_[:alnum:]])mrealloc[[:blank:]]*\(/ {
fail("mrealloc")
}
BEGIN { doc["mfree"] = "\
GDB uses xmfree() and not mfree()";
level["mfree"] = '$ARI_REGRESSION'
fix("mfree", "gdb/utils.c", 3);
}
/(^|[^_[:alnum:]>\.])mfree[[:blank:]]*\(/ {
fail("mfree")
}
# Memory allocation: xmmalloc(): We are trying to eliminate these
# versions and just use simple xmalloc() and obstacks.
BEGIN { doc["xmmalloc"] = "\
GDB is trying to elminate the [x]mmalloc() family.";
level["xmmalloc"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])xmmalloc[[:blank:]]*\(/ {
fail("xmmalloc")
}
BEGIN { doc["xmcalloc"] = "\
GDB is trying to elminate the [x]mmalloc() family.";
level["xmcalloc"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])xmcalloc[[:blank:]]*\(/ {
fail("xmcalloc")
}
BEGIN { doc["xmrealloc"] = "\
GDB is trying to elminate the [x]mmalloc() family.";
level["xmrealloc"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])xmrealloc[[:blank:]]*\(/ {
fail("xmrealloc")
}
BEGIN { doc["xmfree"] = "\
GDB is trying to elminate the [x]mmalloc() family.";
level["xmfree"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]>\.])xmfree[[:blank:]]*\(/ {
fail("xmfree")
}
# More generic memory operations
BEGIN { doc["FREEIF"] = "\
GDB uses xfree() and not FREEIF()";
level["FREEIF"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])FREEIF[[:blank:]]*\(/ {
fail("FREEIF")
}
BEGIN { doc["MALLOC_INCOMPATIBLE"] = "\
MALLOC_INCOMPATIBLE should be handled by autoconf.";
level["MALLOC_INCOMPATIBLE"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])MALLOC_INCOMPATIBLE([^_[:alnum:]]|$)/ {
fail("MALLOC_INCOMPATIBLE")
}
BEGIN { doc["strdup"] = "\
GDB uses xstrdup() and not strdup()";
level["strdup"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])strdup[[:blank:]]*\(/ {
fail("strdup")
}
BEGIN { doc["strsave"] = "\
strsave() is deprecated in favour of xstrdup() et.al.";
level["strsave"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])strsave[[:blank:]]*\(/ {
fail("strsave")
}
BEGIN { doc["savestring"] = "\
savestring() needs a rethink. Should there be a xstrldup() (???).";
level["savestring"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])savestring[[:blank:]]*\(/ {
fail("savestring")
}
BEGIN { doc["alloca"] = "\
alloca() is non-portable but its use is tolerated";
level["alloca"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])alloca[[:blank:]]*\(/ {
fail("alloca")
}
# String compare functions
BEGIN { doc["STREQ"] = "\
Use ``strcmp() == 0'\'\'' instead of STREQ()."
level["STREQ"] = '$ARI_CODE'
}
/(^|[^_[:alnum:]])STREQ[[:blank:]]*\(/ {
fail("STREQ")
}
BEGIN { doc["STRCMP"] = "\
Use ``strcmp() == 0'\'\'' instead of STRCMP()"
level["STRCMP"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])STRCMP[[:blank:]]*\(/ {
fail("STRCMP")
}
BEGIN { doc["STREQN"] = "\
Use ``strncmp() == 0'\'\'' instead of STREQN()"
level["STREQN"] = '$ARI_CODE'
}
/(^|[^_[:alnum:]])STREQN[[:blank:]]*\(/ {
fail("STREQN")
}
BEGIN { doc["strncpy"] = "\
Uses strncpy instead of strlcpy (which does not yet exist)";
level["strncpy"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])strncpy[[:blank:]]*\(/ {
fail("strncpy")
}
BEGIN { doc["!strcmp"] = "\
Use ``strcmp() == 0'\'\'' rather than ``!strcmp()'\'\''. Correctly \
understanding ``string-compare equals ...'\'\'' is easier than the \
backward logic of ``Not string-compare'\'\''.";
level["!strcmp"] = '$ARI_INFO'
}
/\![[:blank:]]*str/ {
fail("!strcmp")
}
BEGIN { doc["strnicmp"] = "\
GDB uses strncasecmp() and not strnicmp()";
level["strnicmp"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])strnicmp[[:blank:]]*\(/ {
fail("strnicmp")
}
# Boolean expressions and conditionals
BEGIN { doc["FALSE"] = "\
Definitely do not use FALSE in boolean expressions.";
level["FALSE"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])FALSE([^_[:alnum:]]|$)/ {
fail("FALSE")
}
BEGIN { doc["TRUE"] = "\
Do not try to use TRUE in boolean expressions.";
level["TRUE"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])TRUE([^_[:alnum:]]|$)/ {
fail("TRUE")
}
BEGIN { doc["false"] = "\
Definitely do not use ``false'\'\'' in boolean expressions.";
level["false"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])false([^_[:alnum:]]|$)/ {
fail("false")
}
BEGIN { doc["true"] = "\
Do not try to use ``true'\'\'' in boolean expressions.";
level["true"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])true([^_[:alnum:]]|$)/ {
fail("true")
}
BEGIN { doc["if assignment"] = "\
An IF statement'\''s expression contains an assignment. The GNU coding \
standard discourages this.";
level["if assignment"] = '$ARI_WARNING'
}
/ if .* = / {
fail("if assignment")
}
# Typedefs that are either redundant or can be reduced to ``struct
# type *''.
BEGIN { doc["GDB_FILE"] = "\
GDB_FILE is deprecated in favor of ``struct ui_file'\'\''";
level["GDB_FILE"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])GDB_FILE([^_[:alnum:]]|$)/ {
fail("GDB_FILE")
}
BEGIN { doc["struct complaint"] = "\
``struct complaint'\'\'' is just nasty and over complex - hashing the \
format string would probably have done the trick";
level["struct complaint"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])struct complaint([^_[:alnum:]]|$)/ {
fail("struct complaint")
}
BEGIN { doc["serial_t"] = "\
Change serial_t to ``struct serial'\'\''.";
level["serial_t"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])serial_t([^_[:alnum:]]|$)/ {
fail("serial_t")
}
BEGIN { doc["value_ptr"] = "\
Change value_ptr to ``struct value *'\'\''.";
level["value_ptr"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])value_ptr([^_[:alnum:]]|$)/ {
fail("value_ptr")
}
BEGIN { doc["tm_print_insn"] = "\
tm_print_insn has been multi-arched.";
level["tm_print_insn"] = '$ARI_DEPRECATED'
}
/tm_print_insn[[:space:]]*=/ {
fail("tm_print_insn")
}
BEGIN { doc["goto"] = "\
Please do not use ``goto'\'\''.";
level["goto"] = '$ARI_INFO'
}
/(^|[^_[:alnum:]])goto([^_[:alnum:]]|$)/ {
fail("goto")
}
BEGIN { doc["label"] = "\
Please do not use labels.";
level["label"] = '$ARI_INFO'
}
/^[[:space:]]*[[:alpha:]_][[:alnum:]_]*[[:space:]]*:/ \
&& ! /^[[:space:]]*default[[:space:]]*:/ {
fail("label")
}
BEGIN { doc["codestream"] = "\
Several targets contain a codestream - aka instruction cache. More than anything \
is is probably caused by the broken target stack.";
level["codestream"] = '$ARI_INFO'
}
/codestream/ {
fail("codestream")
}
BEGIN { doc["wrap_"] = "\
Several targets are using a wrapper function found in wrapper.c. \
Unfortunatly, they are hard to debug and contain a bad cast."
level["wrap_"] = '$ARI_INFO'
}
/wrap_/ {
fail("wrap_")
}
BEGIN { doc["var_auto_boolean"] = "\
Use the function add_setshow_auto_boolean_cmd() instead of var_auto_boolean.";
fix("var_auto_boolean", "gdb/cli/cli-decode.c", 1)
fix("var_auto_boolean", "gdb/cli/cli-decode.h", 1)
fix("var_auto_boolean", "gdb/cli/cli-setshow.c", 2)
fix("var_auto_boolean", "gdb/command.h", 1)
level["var_auto_boolean"] = '$ARI_REGRESSION'
}
/(^|[^_[:alnum:]])var_auto_boolean([^_[:alnum:]]|$)/ {
fail("var_auto_boolean")
}
BEGIN { doc["var_boolean"] = "\
Use the function add_setshow_boolean_cmd() instead of var_boolean.";
level["var_boolean"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])var_boolean([^_[:alnum:]]|$)/ {
fail("var_boolean")
}
BEGIN { doc["add_show_from_set"] = "\
See gdb/434. \
The function add_show_from_set() is very i18n unfriendly. \
Create, and then use an equivalent add_setshow_...._cmd()."
level["add_show_from_set"] = '$ARI_WARNING'
}
/(^|[^_[:alnum:]])add_show_from_set([^_[:alnum:]]|$)/ {
fail("add_show_from_set")
}
END {
# Dump the documentation
for (bug in doc) {
if (! (bug in total)) {
total[bug] = 0
}
}
for (bug in doc) {
# ari.*.doc: <BUG>:<COUNT>:<LEVEL>:<DOC>
print bug ":" total[bug] ":" level[bug] ":" doc[bug] >> "'${wwwdir}'/ari.source.doc"
}
}'
fi
if ${check_doschk_p} && test -d "${srcdir}"
then
echo "`date`: Checking for doschk" 1>&2
rm -f "${wwwdir}"/ari.doschk.*
fnchange_lst="${srcdir}"/gdb/config/djgpp/fnchange.lst
fnchange_sed="${wwwdir}"/ari.doschk.sed
# Create fnchange.sed
sed -e 's;@[^@]*@[/]*\([^ ]*\) @[^@]*@[/]*\([^ ]*\);s,\1,\2,;' \
< "${fnchange_lst}" > "${fnchange_sed}"
# Do the raw analysis
( cd "${srcdir}" && find * \
-name '*.info-[0-9]*' -prune \
-o -name tcl -prune \
-o -name itcl -prune \
-o -name tk -prune \
-o -name libgui -prune \
-o -name tix -prune \
-o -name dejagnu -prune \
-o -name expect -prune \
-o -type f -print ) | sed -f ${fnchange_sed} \
| doschk > ${wwwdir}/ari.doschk.out
# Magic to map ari.doschk.out to ari.doschk.bug goes here
$AWK < ${wwwdir}/ari.doschk.out > ${wwwdir}/ari.doschk.bug '
BEGIN {
state = 1;
invalid_dos = state++; bug[invalid_dos] = "invalid dos"; level[invalid_dos] = '$ARI_INFO';
same_dos = state++; bug[same_dos] = "DOS"; level[same_dos] = '$ARI_REGRESSION';
same_sysv = state++; bug[same_sysv] = "SysV"; level[same_sysv] = '$ARI_INFO';
long_sysv = state++; bug[long_sysv] = "long SysV"; level[long_sysv] = '$ARI_INFO';
internal = state++; bug[internal] = "internal doschk"; level[internal] = '$ARI_INFO';
state = 0;
DOCFILE = "'"${wwwdir}/ari.doschk.doc"'"
}
/^$/ { state = 0; next; }
/^The .* not valid DOS/ { state = invalid_dos; next; }
/^The .* same DOS/ { state = same_dos; next; }
/^The .* same SysV/ { state = same_sysv; next; }
/^The .* too long for SysV/ { state = long_sysv; next; }
/^The .* / { state = internal; next; }
NF == 3 { name = $1 ; file = $3 }
NF == 1 { file = $1 }
NF == 0 { next }
state == same_dos || state == same_sysv {
BUG = bug[state] " dup " name
# ari.*.bug: <BUG>:<COUNT>:<LEVEL>:<FILE>:<LINE>
print BUG ":1:" level[state] ":" file ":0"
bug_count[BUG] += 1
bug_level[BUG] = level[state]
bug_doc[BUG] = "\
The name " name " resolves to duplicate files on a " bug[state] " system. \
For DOS, this can be fixed by modifying the file fnchange.lst."
next
}
{
# ari.*.bug: <BUG>:<COUNT>:<LEVEL>:<FILE>:<LINE>
BUG = bug[state]
print BUG ":1:" level[state] ":" file ":0"
bug_count[BUG] += 1
bug_level[BUG] = level[state]
bug_doc[BUG] = "DOSCHK reports a " bug[state] " problem"
}
END {
for (BUG in bug_count) {
# ari.*.doc: <BUG>:<COUNT>:<LEVEL>:<DOC>
print BUG ":" bug_count[BUG] ":" bug_level[BUG] ":" bug_doc[BUG] >> DOCFILE
}
}
'
fi
if ${check_werror_p} && test -d "${srcdir}"
then
echo "`date`: Checking Makefile.in for non- -Werror rules"
rm -f ${wwwdir}/ari.werror.*
$AWK < "${srcdir}/${project}/Makefile.in" > ${wwwdir}/ari.werror.bug '
BEGIN {
level = '$ARI_WARNING'
count = 0
}
/^[-_[:alnum:]]+\.o:/ {
file = gensub(/.o:.*/, "", 1) ".c"
}
/\$\(CC\).*\$\(INTERNAL_WARN_CFLAGS\)/ {
# ari.*.bug: <BUG>:<COUNT>:<LEVEL>:<FILE>:<LINE>
print "no -Werror:1:" level ":" file ":0"
count++
}
END {
# ari.*.doc: <BUG>:<COUNT>:<LEVEL>:<DOC>
print "no -Werror:" count ":" level ":\
The file has compiler warnings and is not being compiled with -Werror" \
>> "'"${wwwdir}/ari.werror.doc"'"
}
'
fi
# print_toc LEVEL LO_LEVEL HI_LEVEL TITLE [MIN_COUNT]
# Print a table of contents containing the bugs in the range [LO_LEVEL
# .. HI_LEVEL]. If the bug has an error-count >= MIN_COUNT include a
# link into the error table and include the error in the output. If
# MIN_COUNT is less than zero, don't bother printing any links but
# still print all errors. MIN_COUNT defaults to 0/-1 depending on
# LEVEL.
print_toc ()
{
level=$1 ; shift
lo_level="$1" ; shift
hi_level="$1" ; shift
echo "<p>" >> ${newari}
echo "<h3>$1</h3>" >> ${newari} ; shift
cat >> ${newari}
if [ $# -gt 0 ]
then
min_count=$1 ; shift
elif [ $level -ge $hi_level ]
then
min_count=0
else
min_count=-1
fi
cat >> ${newari} <<EOF
<p>
<table>
<tr><th align=left>BUG</th><th>Total</th><th align=left>Description</th></tr>
EOF
# ari.*.doc: <BUG>:<COUNT>:<LEVEL>:<DOC>
cat ${wwwdir}/ari.*.doc \
| sort -u \
| sort -t: +1rn -2 +0d \
| $AWK >> ${newari} '
BEGIN {
FS=":"
LO_LEVEL = '${lo_level}'
HI_LEVEL = '${hi_level}'
MIN_COUNT = '${min_count}'
}
{
# ari.*.doc: <BUG>:<COUNT>:<LEVEL>:<DOC>
bug = $1
count = $2
level = $3
doc = $4
if (level > HI_LEVEL) next
if (level < LO_LEVEL) next
if (count < MIN_COUNT) next
printf "<tr>"
printf "<th align=left valign=top><a name=\"%s\">", bug
printf "%s", gensub(/_/, " ", "g", bug)
printf "</a></th>"
printf "<td align=right valign=top>"
if (count > 0 && MIN_COUNT >= 0) {
printf "<a href=\"#%s,\">%d</a></td>", bug, count
} else {
printf "%d", count
}
printf "</td>"
printf "<td align=left valign=top>%s</td>", doc
printf "</tr>"
print ""
}'
cat >> ${newari} <<EOF
</table>
<p>
EOF
}
# Merge, generating the ARI tables.
if ${update_web_p}
then
for level in $ARI_FIRST $ARI_WARNING
do
echo "Create the ARI table (level ${level})" 1>&2
case ${level} in
$ARI_FIRST )
oldari=${wwwdir}/old.html
ari=${wwwdir}/index.html
newari=${wwwdir}/new.html
critical=$ARI_REGRESSION
;;
* )
oldari=${wwwdir}/old-ari.html
ari=${wwwdir}/ari.html
newari=${wwwdir}/new-ari.html
critical=${level}
;;
esac
rm -f ${newari} ${newari}.gz
cat <<EOF >> ${newari}
<html>
<head>
<title>A.R. Index for GDB version ${version}</title>
</head>
<body>
<center><h2>A.R. Index for GDB version ${version}<h2></center>
<!-- body, update above using ../index.sh -->
<center><h3>You can not take this seriously!</h3></center>
<center>
Also available:
<a href="../gdb/ari/">most recent branch</a>
|
<a href="../gdb/current/ari/">current</a>
|
<a href="../gdb/download/ari/">last release</a>
</center>
<center>
Last updated: `date -u`
</center>
<center>
Input files: `( cd ${wwwdir} && ls ari.*.bug ) | while read bug
do
echo "<a href=\"${bug}\">${bug}</a>"
done`
</center>
EOF
print_toc ${level} 0 ${critical} Critical 1 <<EOF
(or things that have been eliminated)
EOF
# Remember to prune the dir prefix from projects files
cat ${wwwdir}/ari.*.bug \
| sort -t: +3 \
| sed -e "s,:${project}/,:," \
| $AWK >> ${newari} '
function print_heading (where_i) {
print ""
print "<tr border=1>"
print "<th align=left>File</th>"
print "<th></th>"
print "<th align=left><em>Total</em></th>"
print "<th></th>"
for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
bug = i2bug[bug_i];
printf "<th>"
printf "<a name=\"%s,\"> </a>", bug
printf "<a href=\"#%s\">", bug
printf "%s", gensub(/_/, " ", "g", bug)
printf "</a>\n"
printf "</th>\n"
}
print "<th></th>"
print "<th align=left><em>Total</em></th>"
print "<th></th>"
print "<th align=left>File</th>"
print "</tr>"
}
function print_totals (where) {
print "<th align=left><em>Totals</em></th>"
print "<th></th>"
print "<th align=right><em>" total "</em></th>"
print "<th></th>";
for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
bug = i2bug[bug_i];
printf "<th align=right>"
printf "<a name=\"%s,%s\"> </a>", bug, where
printf "<em>"
printf "<a href=\"#%s\">%d</a>", bug, bug_total[bug]
printf "</em>";
printf "<a href=\"#%s,%s\">^</a>", bug, prev_file[bug, where]
printf "<a href=\"#%s,%s\">v</a>", bug, next_file[bug, where]
printf "</th>";
print ""
}
print "<th></th>"
print "<th align=right><em>" total "</em></th>";
print "<th></th>"
print "<th align=left><em>Totals</em></th>"
print "</tr>"
}
BEGIN {
FS = ":"
LEVEL = '${level}'
nr_file = 0;
nr_bug = 0;
# Dummy entries for first/last
i2file[0] = 0
i2file[-1] = -1
i2bug[0] = 0
i2bug[-1] = -1
}
{
# ari.*.bug: <BUG>:<COUNT>:<LEVEL>:<FILE>:<LINE>
bug = $1
count = $2
level = $3
file = $4
line = $5
# Interested in this
if (level > LEVEL) next
# Totals
if (count != 0) {
if (level < LEVEL) {
bold[bug, file] = "th"
} else {
bold[bug, file] = "td"
}
db[bug, file] += count
bug_total[bug] += count
file_total[file] += count
total += count
}
# Map file <-> index
if (! (file in file2i)) {
nr_file++;
i2file[nr_file] = file;
file2i[file] = nr_file;
};
# Map bug <-> index
if (! (bug in bug2i)) {
nr_bug++;
i2bug[nr_bug] = bug;
bug2i[bug] = nr_bug;
}
}
END {
# Construct a table of next/prev
# For all the bugs, create a cycle that goes to the prev / next file.
for (bug in bug2i) {
prev = 0
prev_file[bug, 0] = -1
next_file[bug, -1] = 0
for (file_i = 1; file_i <= nr_file; file_i++) {
file = i2file[file_i]
if ((bug, file) in db) {
prev_file[bug, file] = prev
next_file[bug, prev] = file
prev = file
}
}
prev_file[bug, -1] = prev
next_file[bug, prev] = -1
}
# For all the files, create a cycle that goes to the prev / next bug.
for (file in file2i) {
prev = 0
prev_bug[0, file] = -1
next_bug[-1, file] = 0
for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
bug = i2bug[bug_i]
if ((bug, file) in db) {
prev_bug[bug, file] = prev
next_bug[prev, bug] = bug
prev = bug
}
}
prev_bug[-1, file] = prev
next_bug[prev, file] = -1
}
print "<table border=1 cellspacing=0>"
print "<tr></tr>"
print_heading(0);
print "<tr></tr>"
print_totals(0);
print "<tr></tr>"
for (file_i = 1; file_i <= nr_file; file_i++) {
file = i2file[file_i];
print ""
print "<tr>"
print "<th align=left>" file "</th>"
print "<th></th>"
print "<th align=right>" file_total[file] "</th>"
print "<th></th>"
for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
bug = i2bug[bug_i];
if ((bug, file) in db) {
printf "<td align=right>"
printf "<a name=\"%s,%s\"> </a>", bug, file
#printf "<a href=\"#%s,%s\">", bug, next_file[bug, file]
printf "<a href=\"#%s\">%d</a>", bug, db[bug, file]
printf "<a href=\"#%s,%s\">^</a>", bug, prev_file[bug, file]
printf "<a href=\"#%s,%s\">v</a>", bug, next_file[bug, file]
printf "</td>"
print ""
} else {
print "<td> </td>"
#print "<td></td>"
}
}
print "<th></th>"
print "<th align=right>" file_total[file] "</th>"
print "<th></th>"
print "<th align=left>" file "</th>"
print "</tr>"
}
print "<tr></tr>"
print_totals(-1)
print "<tr></tr>"
print_heading(-1);
print "<tr></tr>"
print ""
print "</table>"
print ""
}
'
echo "<hr>" >> ${newari}
print_toc ${level} $ARI_DEPRECATED $ARI_DEPRECATED Deprecated <<EOF
(or mechanisms that have been replaced with something better,
simpler, cleaner)
EOF
echo "<hr>" >> ${newari}
print_toc ${level} $ARI_CODE $ARI_CODE Coding <<EOF
(or things that can cause portability, readability, or coding standard
problems)
EOF
echo "<hr>" >> ${newari}
print_toc ${level} $ARI_WARNING $ARI_WARNING Warnings <<EOF
(or things that are thought to a problem and will likely either be
added to Deprecated or Coding)
EOF
echo "<hr>" >> ${newari}
print_toc ${level} $ARI_INFO $ARI_INFO Info <<EOF
(or things that, er mostly, no one is even seriously considering)
EOF
echo "<hr>" >> ${newari}
print_toc ${level} $ARI_REGRESSION $ARI_REGRESSION Fixed <<EOF
(or things that have been eliminated - unless they regressed, sigh)
EOF
cat >> ${newari} <<EOF
<!-- /body, update below using ../index.sh -->
</body>
</html>
EOF
for i in . .. ../..
do
x=${wwwdir}/${i}/index.sh
if test -x $x
then
$x ${newari}
break
fi
done
gzip -c -v -9 ${newari} > ${newari}.gz
cp ${ari} ${oldari}
cp ${ari}.gz ${oldari}.gz
cp ${newari} ${ari}
cp ${newari}.gz ${ari}.gz
done # level
fi # update_web_p
# ls -l ${wwwdir}
exit 0