3 # GDB script to create GDB ARI web page.
5 # Copyright (C) 2001-2012 Free Software Foundation, Inc.
7 # This file is part of GDB.
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.
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.
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/>.
22 # TODO: setjmp.h, setjmp and longjmp.
24 # Direct stderr into stdout but still hang onto stderr (/dev/fd/3)
28 # echo "$@" | tee /dev/fd/3 1>&2
33 # Really mindless usage
36 echo "Usage: $0 <snapshot/sourcedir> <tmpdir> <destdir> <project>" 1>&2
44 # Try to create destination directory if it doesn't exist yet
50 # Fail if destination directory doesn't exist or is not writable
51 if [ ! -w ${wwwdir} -o ! -d ${wwwdir} ]
53 echo ERROR: Can not write to directory ${wwwdir} >&2
57 if [ ! -r ${snapshot} ]
59 echo ERROR: Can not read snapshot file 1>&2
64 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
65 # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
66 # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
67 # Where ``*'' is {source,warning,indent,doschk}
72 check_warning_p=false # broken
73 check_indent_p=false # too slow, too many fail
81 if awk --version 2>&1 </dev/null | grep -i gnu > /dev/null
89 # Set up a few cleanups
92 trap "cd /tmp; rm -rf ${tmpdir}; exit" 0 1 2 15
96 # If the first parameter is a directory,
97 #we just use it as the extracted source
102 aridir=${srcdir}/${module}/contrib/ari
103 unpack_source_p=false
104 delete_source_p=false
105 version_in=${srcdir}/${module}/version.in
107 # unpack the tar-ball
108 if ${unpack_source_p}
110 # Was it previously unpacked?
111 if ${delete_source_p} || test ! -d ${tmpdir}/${module}*
113 /bin/rm -rf "${tmpdir}"
114 /bin/mkdir -p ${tmpdir}
115 if [ ! -d ${tmpdir} ]
117 echo "Problem creating work directory"
120 cd ${tmpdir} || exit 1
121 echo `date`: Unpacking tar-ball ...
123 *.tar.bz2 ) bzcat ${snapshot} ;;
124 *.tar ) cat ${snapshot} ;;
125 * ) ECHO Bad file ${snapshot} ; exit 1 ;;
130 module=`basename ${snapshot}`
131 module=`basename ${module} .bz2`
132 module=`basename ${module} .tar`
133 srcdir=`echo ${tmpdir}/${module}*`
135 version_in=${srcdir}/gdb/version.in
138 if [ ! -r ${version_in} ]
140 echo ERROR: missing version file 1>&2
143 version=`cat ${version_in}`
146 # THIS HAS SUFFERED BIT ROT
147 if ${check_warning_p} && test -d "${srcdir}"
149 echo `date`: Parsing compiler warnings 1>&2
150 cat ${root}/ari.compile | $AWK '
154 /^[^:]*:[0-9]*: warning:/ {
156 #sub (/^.*\//, "", file);
159 /^[^:]*:[0-9]*: error:/ {
161 #sub (/^.*\//, "", file);
165 for (file in warning) {
166 print file ":warning:" level[file]
168 for (file in error) {
169 print file ":error:" level[file]
172 ' > ${root}/ari.warning.bug
175 # THIS HAS SUFFERED BIT ROT
176 if ${check_indent_p} && test -d "${srcdir}"
178 printf "Analizing file indentation:" 1>&2
179 ( cd "${srcdir}" && /bin/sh ${aridir}/gdb_find.sh ${project} | while read f
181 if /bin/sh ${aridir}/gdb_indent.sh < ${f} 2>/dev/null | cmp -s - ${f}
185 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
186 echo "${f}:0: info: indent: Indentation does not match GNU indent output"
188 done ) > ${wwwdir}/ari.indent.bug
192 if ${check_source_p} && test -d "${srcdir}"
194 bugf=${wwwdir}/ari.source.bug
195 oldf=${wwwdir}/ari.source.old
196 srcf=${wwwdir}/ari.source.lines
197 oldsrcf=${wwwdir}/ari.source.lines-old
199 diff=${wwwdir}/ari.source.diff
203 oldpruned=${oldf1}-pruned
204 newpruned=${newf1}-pruned
206 cp -f ${bugf} ${oldf}
207 cp -f ${srcf} ${oldsrcf}
210 echo "`date`: Using source lines ${srcf}" 1>&2
211 echo "`date`: Checking source code" 1>&2
212 ( cd "${srcdir}" && /bin/sh ${aridir}/gdb_find.sh "${project}" | \
213 xargs /bin/sh ${aridir}/gdb_ari.sh -Werror -Wall --print-idx --src=${srcf}
215 # Remove things we are not interested in to signal by email
216 # gdbarch changes are not important here
217 # Also convert ` into ' to avoid command substitution in script below
218 sed -e "/.*: gdbarch:.*/d" -e "s:\`:':g" ${oldf} > ${oldf1}
219 sed -e "/.*: gdbarch:.*/d" -e "s:\`:':g" ${bugf} > ${newf1}
220 # Remove line number info so that code inclusion/deletion
221 # has no impact on the result
222 sed -e "s/\([^:]*\):\([^:]*\):\(.*\)/\1:0:\3/" ${oldf1} > ${oldpruned}
223 sed -e "s/\([^:]*\):\([^:]*\):\(.*\)/\1:0:\3/" ${newf1} > ${newpruned}
224 # Use diff without option to get normal diff output that
226 diff ${oldpruned} ${newpruned} > ${diffin}
227 # Only keep new warnings
228 sed -n -e "/^>.*/p" ${diffin} > ${diff}
229 sedscript=${wwwdir}/sedscript
230 script=${wwwdir}/script
231 sed -n -e "s|\(^[0-9,]*\)a\(.*\)|echo \1a\2 \n \
232 sed -n \'\2s:\\\\(.*\\\\):> \\\\1:p\' ${newf1}|p" \
233 -e "s|\(^[0-9,]*\)d\(.*\)|echo \1d\2\n \
234 sed -n \'\1s:\\\\(.*\\\\):< \\\\1:p\' ${oldf1}|p" \
235 -e "s|\(^[0-9,]*\)c\(.*\)|echo \1c\2\n \
236 sed -n \'\1s:\\\\(.*\\\\):< \\\\1:p\' ${oldf1} \n \
237 sed -n \"\2s:\\\\(.*\\\\):> \\\\1:p\" ${newf1}|p" \
238 ${diffin} > ${sedscript}
239 ${SHELL} ${sedscript} > ${wwwdir}/message
241 -e "s;\(.*\);echo \\\"\1\\\";p" \
242 -e "s;.*< \([^:]*\):\([0-9]*\):.*;grep \"^\1:\2:\" ${oldsrcf};p" \
243 -e "s;.*> \([^:]*\):\([0-9]*\):.*;grep \"^\1:\2:\" ${srcf};p" \
244 ${wwwdir}/message > ${script}
245 ${SHELL} ${script} > ${wwwdir}/mail-message
246 if [ "x${branch}" != "x" ]; then
247 email_suffix="`date` in ${branch}"
249 email_suffix="`date`"
257 if ${check_doschk_p} && test -d "${srcdir}"
259 echo "`date`: Checking for doschk" 1>&2
260 rm -f "${wwwdir}"/ari.doschk.*
261 fnchange_lst="${srcdir}"/gdb/config/djgpp/fnchange.lst
262 fnchange_awk="${wwwdir}"/ari.doschk.awk
263 doschk_in="${wwwdir}"/ari.doschk.in
264 doschk_out="${wwwdir}"/ari.doschk.out
265 doschk_bug="${wwwdir}"/ari.doschk.bug
266 doschk_char="${wwwdir}"/ari.doschk.char
268 # Transform fnchange.lst into fnchange.awk. The program DJTAR
269 # does a textual substitution of each file name using the list.
270 # Generate an awk script that does the equivalent - matches an
271 # exact line and then outputs the replacement.
273 sed -e 's;@[^@]*@[/]*\([^ ]*\) @[^@]*@[/]*\([^ ]*\);\$0 == "\1" { print "\2"\; next\; };' \
274 < "${fnchange_lst}" > "${fnchange_awk}"
275 echo '{ print }' >> "${fnchange_awk}"
277 # Do the raw analysis - transform the list of files into the DJGPP
278 # equivalents putting it in the .in file
279 ( cd "${srcdir}" && find * \
280 -name '*.info-[0-9]*' -prune \
281 -o -name tcl -prune \
282 -o -name itcl -prune \
284 -o -name libgui -prune \
285 -o -name tix -prune \
286 -o -name dejagnu -prune \
287 -o -name expect -prune \
288 -o -type f -print ) \
289 | $AWK -f ${fnchange_awk} > ${doschk_in}
291 # Start with a clean slate
294 # Check for any invalid characters.
295 grep '[\+\,\;\=\[\]\|\<\>\\\"\:\?\*]' < ${doschk_in} > ${doschk_char}
296 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
297 sed < ${doschk_char} >> ${doschk_bug} \
298 -e s'/$/:0: dos: DOSCHK: Invalid DOS character/'
300 # Magic to map ari.doschk.out to ari.doschk.bug goes here
301 doschk < ${doschk_in} > ${doschk_out}
302 cat ${doschk_out} | $AWK >> ${doschk_bug} '
305 invalid_dos = state++; bug[invalid_dos] = "invalid DOS file name"; category[invalid_dos] = "dos";
306 same_dos = state++; bug[same_dos] = "DOS 8.3"; category[same_dos] = "dos";
307 same_sysv = state++; bug[same_sysv] = "SysV";
308 long_sysv = state++; bug[long_sysv] = "long SysV";
309 internal = state++; bug[internal] = "internal doschk"; category[internal] = "internal";
312 /^$/ { state = 0; next; }
313 /^The .* not valid DOS/ { state = invalid_dos; next; }
314 /^The .* same DOS/ { state = same_dos; next; }
315 /^The .* same SysV/ { state = same_sysv; next; }
316 /^The .* too long for SysV/ { state = long_sysv; next; }
317 /^The .* / { state = internal; next; }
321 NF == 3 { name = $1 ; file = $3 }
322 NF == 1 { file = $1 }
323 NF > 3 && $2 == "-" { file = $1 ; name = gensub(/^.* - /, "", 1) }
326 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
327 print file ":0: " category[state] ": " \
328 name " " bug[state] " " " dup: " \
329 " DOSCHK - the names " name " and " file " resolve to the same" \
330 " file on a " bug[state] \
331 " system.<br>For DOS, this can be fixed by modifying the file" \
335 state == invalid_dos {
336 # ari.*.bug: <FILE>:<LINE>: <SEVERITY>: <CATEGORY>: <DOC>
337 print file ":0: " category[state] ": " name ": DOSCHK - " name
341 # ari.*.bug: <FILE>:<LINE>: <SEVERITY>: <CATEGORY>: <DOC>
342 print file ":0: " category[state] ": " bug[state] ": DOSCHK - a " \
343 bug[state] " problem"
350 if ${check_werror_p} && test -d "${srcdir}"
352 echo "`date`: Checking Makefile.in for non- -Werror rules"
353 rm -f ${wwwdir}/ari.werror.*
354 cat "${srcdir}/${project}/Makefile.in" | $AWK > ${wwwdir}/ari.werror.bug '
360 /^[-_[:alnum:]]+\.o:/ {
361 file = gensub(/.o:.*/, "", 1) ".c"
364 /[^\\]\\$/ { gsub (/\\$/, ""); full_line = full_line $0; cont_p = 1; next; }
365 cont_p { $0 = full_line $0; cont_p = 0; full_line = ""; }
367 /\$\(COMPILE\.pre\)/ {
368 print file " has line " $0
369 if (($0 !~ /\$\(.*ERROR_CFLAGS\)/) && ($0 !~ /\$\(INTERNAL_CFLAGS\)/)) {
370 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
371 print "'"${project}"'/" file ":0: info: Werror: The file is not being compiled with -Werror"
378 # From the warnings, generate the doc and indexed bug files
382 rm -f ari.doc ari.idx ari.doc.bug
383 # Generate an extra file containing all the bugs that the ARI can detect.
384 /bin/sh ${aridir}/gdb_ari.sh -Werror -Wall --print-idx --print-doc >> ari.doc.bug
385 cat ari.*.bug | $AWK > ari.idx '
390 # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
395 if (! (bug in cat)) {
397 # strip any trailing .... (supplement)
398 doc[bug] = gensub(/ \([^\)]*\)$/, "", 1, $5)
403 # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
404 print bug ":" file ":" category
406 # Also accumulate some categories as obsolete
407 if (category == "deprecated") {
408 # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
410 print category ":" file ":" "obsolete"
413 #doc[category] = "Contains " category " code"
419 # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
420 print bug ":" count[bug] ":" cat[bug] ":" doc[bug] >> "ari.doc"
427 # print_toc BIAS MIN_COUNT CATEGORIES TITLE
429 # Print a table of contents containing the bugs CATEGORIES. If the
430 # BUG count >= MIN_COUNT print it in the table-of-contents. If
431 # MIN_COUNT is non -ve, also include a link to the table.Adjust the
432 # printed BUG count by BIAS.
439 min_count="$1" ; shift
444 categories="${categories} categories[\"${c}\"] = 1 ;"
450 echo "<p>" >> ${newari}
451 echo "<a name=${title}>" | tr '[A-Z]' '[a-z]' >> ${newari}
452 echo "<h3>${title}</h3>" >> ${newari}
453 cat >> ${newari} # description
455 cat >> ${newari} <<EOF
458 <tr><th align=left>BUG</th><th>Total</th><th align=left>Description</th></tr>
460 # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
461 cat ${wwwdir}/ari.doc \
462 | sort -t: +1rn -2 +0d \
463 | $AWK >> ${newari} '
467 MIN_COUNT = '${min_count}'
473 # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
478 if (count < MIN_COUNT) next
479 if (!(category in categories)) next
483 printf "<th align=left valign=top><a name=\"%s\">", bug
484 printf "%s", gensub(/_/, " ", "g", bug)
486 printf "<td align=right valign=top>"
487 if (count > 0 && MIN_COUNT >= 0) {
488 printf "<a href=\"#,%s\">%d</a></td>", bug, count + BIAS
490 printf "%d", count + BIAS
493 printf "<td align=left valign=top>%s</td>", doc
498 print "<tr><th align=right valign=top>" nr "</th><th align=right valign=top>" total "</th><td></td></tr>"
501 cat >> ${newari} <<EOF
512 categories="${categories} categories[\"${c}\"] = 1 ;"
514 # Remember to prune the dir prefix from projects files
515 # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
516 cat ${wwwdir}/ari.idx | $AWK >> ${newari} '
517 function qsort (table,
518 middle, tmp, left, nr_left, right, nr_right, result) {
520 for (middle in table) { break; }
524 if (tolower(tmp) < tolower(middle)) {
527 } else if (tolower(tmp) > tolower(middle)) {
532 #print "qsort " nr_left " " middle " " nr_right > "/dev/stderr"
535 result = qsort(left) SUBSEP
537 result = result middle
539 result = result SUBSEP qsort(right)
543 function print_heading (where, bug_i) {
545 print "<tr border=1>"
546 print "<th align=left>File</th>"
547 print "<th align=left><em>Total</em></th>"
549 for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
552 # The title names are offset by one. Otherwize, when the browser
553 # jumps to the name it leaves out half the relevant column.
554 #printf "<a name=\",%s\"> </a>", bug
555 printf "<a name=\",%s\"> </a>", i2bug[bug_i-1]
556 printf "<a href=\"#%s\">", bug
557 printf "%s", gensub(/_/, " ", "g", bug)
562 printf "<th><a name=\"%s,\"> </a></th>\n", i2bug[bug_i-1]
563 print "<th align=left><em>Total</em></th>"
564 print "<th align=left>File</th>"
567 function print_totals (where, bug_i) {
568 print "<th align=left><em>Totals</em></th>"
569 printf "<th align=right>"
570 printf "<em>%s</em>", total
574 for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
576 printf "<th align=right>"
578 printf "<a href=\"#%s\">%d</a>", bug, bug_total[bug]
580 printf "<a href=\"#%s,%s\">^</a>", prev_file[bug, where], bug
581 printf "<a href=\"#%s,%s\">v</a>", next_file[bug, where], bug
582 printf "<a name=\"%s,%s\"> </a>", where, bug
587 printf "<th align=right>"
588 printf "<em>%s</em>", total
591 print "<th align=left><em>Totals</em></th>"
601 # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
606 if (!(category in categories)) next
610 file_total[file] += 1
615 # Sort the files and bugs creating indexed lists.
616 nr_bug = split(qsort(bug_total), i2bug, SUBSEP);
617 nr_file = split(qsort(file_total), i2file, SUBSEP);
619 # Dummy entries for first/last
625 # Construct a cycle of next/prev links. The file/bug "0" and "-1"
626 # are used to identify the start/end of the cycle. Consequently,
627 # prev(0) = -1 (prev of start is the end) and next(-1) = 0 (next
628 # of end is the start).
630 # For all the bugs, create a cycle that goes to the prev / next file.
631 for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
634 prev_file[bug, 0] = -1
635 next_file[bug, -1] = 0
636 for (file_i = 1; file_i <= nr_file; file_i++) {
637 file = i2file[file_i]
638 if ((bug, file) in db) {
639 prev_file[bug, file] = prev
640 next_file[bug, prev] = file
644 prev_file[bug, -1] = prev
645 next_file[bug, prev] = -1
648 # For all the files, create a cycle that goes to the prev / next bug.
649 for (file_i = 1; file_i <= nr_file; file_i++) {
650 file = i2file[file_i]
652 prev_bug[file, 0] = -1
653 next_bug[file, -1] = 0
654 for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
656 if ((bug, file) in db) {
657 prev_bug[file, bug] = prev
658 next_bug[file, prev] = bug
662 prev_bug[file, -1] = prev
663 next_bug[file, prev] = -1
666 print "<table border=1 cellspacing=0>"
673 for (file_i = 1; file_i <= nr_file; file_i++) {
674 file = i2file[file_i];
675 pfile = gensub(/^'${project}'\//, "", 1, file)
678 print "<th align=left><a name=\"" file ",\">" pfile "</a></th>"
679 printf "<th align=right>"
680 printf "%s", file_total[file]
681 printf "<a href=\"#%s,%s\">></a>", file, next_bug[file, 0]
684 for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
686 if ((bug, file) in db) {
687 printf "<td align=right>"
688 printf "<a href=\"#%s\">%d</a>", bug, db[bug, file]
689 printf "<a href=\"#%s,%s\">^</a>", prev_file[bug, file], bug
690 printf "<a href=\"#%s,%s\">v</a>", next_file[bug, file], bug
691 printf "<a name=\"%s,%s\"> </a>", file, bug
695 print "<td> </td>"
700 printf "<th align=right>"
701 printf "%s", file_total[file]
702 printf "<a href=\"#%s,%s\"><</a>", file, prev_bug[file, -1]
704 print "<th align=left>" pfile "</th>"
721 # Make the scripts available
722 cp ${aridir}/gdb_*.sh ${wwwdir}
724 # Compute the ARI index - ratio of zero vs non-zero problems.
730 # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
731 bug = $1; count = $2; category = $3; doc = $4
733 if (bug ~ /^legacy_/) legacy++
734 if (bug ~ /^deprecated_/) deprecated++
736 if (category !~ /^gdbarch$/) {
744 #print "tests/ok:", nr / ok
745 #print "bugs/tests:", bugs / nr
746 #print "bugs/ok:", bugs / ok
747 print bugs / ( oks + legacy + deprecated )
751 # Merge, generating the ARI tables.
754 echo "Create the ARI table" 1>&2
755 oldari=${wwwdir}/old.html
756 ari=${wwwdir}/index.html
757 newari=${wwwdir}/new.html
758 rm -f ${newari} ${newari}.gz
759 cat <<EOF >> ${newari}
762 <title>A.R. Index for GDB version ${version}</title>
766 <center><h2>A.R. Index for GDB version ${version}<h2></center>
768 <!-- body, update above using ../index.sh -->
770 <!-- Navigation. This page contains the following anchors.
771 "BUG": The definition of the bug.
772 "FILE,BUG": The row/column containing FILEs BUG count
773 "0,BUG", "-1,BUG": The top/bottom total for BUGs column.
774 "FILE,O", "FILE,-1": The left/right total for FILEs row.
775 ",BUG": The top title for BUGs column.
776 "FILE,": The left title for FILEs row.
779 <center><h3>${indexes}</h3></center>
780 <center><h3>You can not take this seriously!</h3></center>
784 <a href="../gdb/ari/">most recent branch</a>
786 <a href="../gdb/current/ari/">current</a>
788 <a href="../gdb/download/ari/">last release</a>
792 Last updated: `date -u`
796 print_toc 0 1 "internal regression" Critical <<EOF
797 Things previously eliminated but returned. This should always be empty.
800 print_table "regression code comment obsolete gettext"
802 print_toc 0 0 code Code <<EOF
803 Coding standard problems, portability problems, readability problems.
806 print_toc 0 0 comment Comments <<EOF
807 Problems concerning comments in source files.
810 print_toc 0 0 gettext GetText <<EOF
811 Gettext related problems.
814 print_toc 0 -1 dos DOS 8.3 File Names <<EOF
815 File names with problems on 8.3 file systems.
818 print_toc -2 -1 deprecated Deprecated <<EOF
819 Mechanisms that have been replaced with something better, simpler,
820 cleaner; or are no longer required by core-GDB. New code should not
821 use deprecated mechanisms. Existing code, when touched, should be
822 updated to use non-deprecated mechanisms. See obsolete and deprecate.
823 (The declaration and definition are hopefully excluded from count so
824 zero should indicate no remaining uses).
827 print_toc 0 0 obsolete Obsolete <<EOF
828 Mechanisms that have been replaced, but have not yet been marked as
829 such (using the deprecated_ prefix). See deprecate and deprecated.
832 print_toc 0 -1 deprecate Deprecate <<EOF
833 Mechanisms that are a candidate for being made obsolete. Once core
834 GDB no longer depends on these mechanisms and/or there is a
835 replacement available, these mechanims can be deprecated (adding the
836 deprecated prefix) obsoleted (put into category obsolete) or deleted.
837 See obsolete and deprecated.
840 print_toc -2 -1 legacy Legacy <<EOF
841 Methods used to prop up targets using targets that still depend on
842 deprecated mechanisms. (The method's declaration and definition are
843 hopefully excluded from count).
846 print_toc -2 -1 gdbarch Gdbarch <<EOF
847 Count of calls to the gdbarch set methods. (Declaration and
848 definition hopefully excluded from count).
851 print_toc 0 -1 macro Macro <<EOF
852 Breakdown of macro definitions (and #undef) in configuration files.
855 print_toc 0 0 regression Fixed <<EOF
856 Problems that have been expunged from the source code.
859 # Check for invalid categories
861 alls="$alls all[$a] = 1 ;"
863 cat ari.*.doc | $AWK >> ${newari} '
869 # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
874 if (!(category in all)) {
875 print "<b>" category "</b>: no documentation<br>"
880 cat >> ${newari} <<EOF
883 `( cd ${wwwdir} && ls ari.*.bug ari.idx ari.doc ) | while read f
885 echo "<a href=\"${f}\">${f}</a>"
891 `( cd ${wwwdir} && ls *.sh ) | while read f
893 echo "<a href=\"${f}\">${f}</a>"
897 <!-- /body, update below using ../index.sh -->
902 for i in . .. ../..; do
903 x=${wwwdir}/${i}/index.sh
910 gzip -c -v -9 ${newari} > ${newari}.gz
913 cp ${ari}.gz ${oldari}.gz
915 cp ${newari}.gz ${ari}.gz