Incorporate ARI web page generator into GDB sources.
[external/binutils.git] / gdb / contrib / ari / update-web-ari.sh
1 #!/bin/sh -x
2
3 # GDB script to create GDB ARI web page.
4 #
5 # Copyright (C) 2001-2012 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 # TODO: setjmp.h, setjmp and longjmp.
23
24 # Direct stderr into stdout but still hang onto stderr (/dev/fd/3)
25 exec 3>&2 2>&1
26 ECHO ()
27 {
28 #   echo "$@" | tee /dev/fd/3 1>&2
29     echo "$@" 1>&2
30     echo "$@" 1>&3
31 }
32
33 # Really mindless usage
34 if test $# -ne 4
35 then
36     echo "Usage: $0 <snapshot/sourcedir> <tmpdir> <destdir> <project>" 1>&2
37     exit 1
38 fi
39 snapshot=$1 ; shift
40 tmpdir=$1 ; shift
41 wwwdir=$1 ; shift
42 project=$1 ; shift
43
44 # Try to create destination directory if it doesn't exist yet
45 if [ ! -d ${wwwdir} ]
46 then
47   mkdir -p ${wwwdir}
48 fi
49
50 # Fail if destination directory doesn't exist or is not writable
51 if [ ! -w ${wwwdir} -o ! -d ${wwwdir} ]
52 then
53   echo ERROR: Can not write to directory ${wwwdir} >&2
54   exit 2
55 fi
56
57 if [ ! -r ${snapshot} ]
58 then
59     echo ERROR: Can not read snapshot file 1>&2
60     exit 1
61 fi
62
63 # FILE formats
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}
68
69 unpack_source_p=true
70 delete_source_p=true
71
72 check_warning_p=false # broken
73 check_indent_p=false # too slow, too many fail
74 check_source_p=true
75 check_doschk_p=true
76 check_werror_p=true
77
78 update_doc_p=true
79 update_web_p=true
80
81 if awk --version 2>&1 </dev/null | grep -i gnu > /dev/null
82 then
83   AWK=awk
84 else
85   AWK=gawk
86 fi
87 export AWK
88
89 # Set up a few cleanups
90 if ${delete_source_p}
91 then
92     trap "cd /tmp; rm -rf ${tmpdir}; exit" 0 1 2 15
93 fi
94
95
96 # If the first parameter is a directory,
97 #we just use it as the extracted source
98 if [ -d ${snapshot} ]
99 then
100   module=${project}
101   srcdir=${snapshot}
102   aridir=${srcdir}/${module}/contrib/ari
103   unpack_source_p=false
104   delete_source_p=false
105   version_in=${srcdir}/${module}/version.in
106 else
107   # unpack the tar-ball
108   if ${unpack_source_p}
109   then
110     # Was it previously unpacked?
111     if ${delete_source_p} || test ! -d ${tmpdir}/${module}*
112     then
113         /bin/rm -rf "${tmpdir}"
114         /bin/mkdir -p ${tmpdir}
115         if [ ! -d ${tmpdir} ]
116         then
117             echo "Problem creating work directory"
118             exit 1
119         fi
120         cd ${tmpdir} || exit 1
121         echo `date`: Unpacking tar-ball ...
122         case ${snapshot} in
123             *.tar.bz2 ) bzcat ${snapshot} ;;
124             *.tar ) cat ${snapshot} ;;
125             * ) ECHO Bad file ${snapshot} ; exit 1 ;;
126         esac | tar xf -
127     fi
128   fi
129
130   module=`basename ${snapshot}`
131   module=`basename ${module} .bz2`
132   module=`basename ${module} .tar`
133   srcdir=`echo ${tmpdir}/${module}*`
134   aridir=${HOME}/ss
135   version_in=${srcdir}/gdb/version.in
136 fi
137
138 if [ ! -r ${version_in} ]
139 then
140     echo ERROR: missing version file 1>&2
141     exit 1
142 fi
143 version=`cat ${version_in}`
144
145
146 # THIS HAS SUFFERED BIT ROT
147 if ${check_warning_p} && test -d "${srcdir}"
148 then
149     echo `date`: Parsing compiler warnings 1>&2
150     cat ${root}/ari.compile | $AWK '
151 BEGIN {
152     FS=":";
153 }
154 /^[^:]*:[0-9]*: warning:/ {
155   file = $1;
156   #sub (/^.*\//, "", file);
157   warning[file] += 1;
158 }
159 /^[^:]*:[0-9]*: error:/ {
160   file = $1;
161   #sub (/^.*\//, "", file);
162   error[file] += 1;
163 }
164 END {
165   for (file in warning) {
166     print file ":warning:" level[file]
167   }
168   for (file in error) {
169     print file ":error:" level[file]
170   }
171 }
172 ' > ${root}/ari.warning.bug
173 fi
174
175 # THIS HAS SUFFERED BIT ROT
176 if ${check_indent_p} && test -d "${srcdir}"
177 then
178     printf "Analizing file indentation:" 1>&2
179     ( cd "${srcdir}" && /bin/sh ${aridir}/gdb_find.sh ${project} | while read f
180     do
181         if /bin/sh ${aridir}/gdb_indent.sh < ${f} 2>/dev/null | cmp -s - ${f}
182         then
183             :
184         else
185             # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
186             echo "${f}:0: info: indent: Indentation does not match GNU indent output"
187         fi
188     done ) > ${wwwdir}/ari.indent.bug
189     echo ""
190 fi
191
192 if ${check_source_p} && test -d "${srcdir}"
193 then
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
198
199     diff=${wwwdir}/ari.source.diff
200     diffin=${diff}-in
201     newf1=${bugf}1
202     oldf1=${oldf}1
203     oldpruned=${oldf1}-pruned
204     newpruned=${newf1}-pruned
205
206     cp -f ${bugf} ${oldf}
207     cp -f ${srcf} ${oldsrcf}
208     rm -f ${srcf}
209     node=`uname -n`
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}
214     ) > ${bugf}
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
225     # is reparsed after
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
240     sed -n \
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}"
248     else
249         email_suffix="`date`"
250     fi
251
252 fi
253
254
255
256
257 if ${check_doschk_p} && test -d "${srcdir}"
258 then
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
267
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.
272
273     sed -e 's;@[^@]*@[/]*\([^ ]*\) @[^@]*@[/]*\([^ ]*\);\$0 == "\1" { print "\2"\; next\; };' \
274         < "${fnchange_lst}" > "${fnchange_awk}"
275     echo '{ print }' >> "${fnchange_awk}"
276
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 \
283         -o -name tk -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}
290
291     # Start with a clean slate
292     rm -f ${doschk_bug}
293
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/'
299
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} '
303 BEGIN {
304     state = 1;
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";
310     state = 0;
311 }
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; }
318
319 NF == 0 { next }
320
321 NF == 3 { name = $1 ; file = $3 }
322 NF == 1 { file = $1 }
323 NF > 3 && $2 == "-" { file = $1 ; name = gensub(/^.* - /, "", 1) }
324
325 state == same_dos {
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" \
332         " fnchange.lst."
333     next
334 }
335 state == invalid_dos {
336     # ari.*.bug: <FILE>:<LINE>: <SEVERITY>: <CATEGORY>: <DOC>
337     print file ":0: " category[state] ": "  name ": DOSCHK - " name
338     next
339 }
340 state == internal {
341     # ari.*.bug: <FILE>:<LINE>: <SEVERITY>: <CATEGORY>: <DOC>
342     print file ":0: " category[state] ": "  bug[state] ": DOSCHK - a " \
343         bug[state] " problem"
344 }
345 '
346 fi
347
348
349
350 if ${check_werror_p} && test -d "${srcdir}"
351 then
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 '
355 BEGIN {
356     count = 0
357     cont_p = 0
358     full_line = ""
359 }
360 /^[-_[:alnum:]]+\.o:/ {
361     file = gensub(/.o:.*/, "", 1) ".c"
362 }
363
364 /[^\\]\\$/ { gsub (/\\$/, ""); full_line = full_line $0; cont_p = 1; next; }
365 cont_p { $0 = full_line $0; cont_p = 0; full_line = ""; }
366
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"
372     }
373 }
374 '
375 fi
376
377
378 # From the warnings, generate the doc and indexed bug files
379 if ${update_doc_p}
380 then
381     cd ${wwwdir}
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 '
386 BEGIN {
387     FS=": *"
388 }
389 {
390     # ari.*.bug: <FILE>:<LINE>: <CATEGORY>: <BUG>: <DOC>
391     file = $1
392     line = $2
393     category = $3
394     bug = $4
395     if (! (bug in cat)) {
396         cat[bug] = category
397         # strip any trailing .... (supplement)
398         doc[bug] = gensub(/ \([^\)]*\)$/, "", 1, $5)
399         count[bug] = 0
400     }
401     if (file != "") {
402         count[bug] += 1
403         # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
404         print bug ":" file ":" category
405     }
406     # Also accumulate some categories as obsolete
407     if (category == "deprecated") {
408         # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
409         if (file != "") {
410             print category ":" file ":" "obsolete"
411         }
412         #count[category]++
413         #doc[category] = "Contains " category " code"
414     }
415 }
416 END {
417     i = 0;
418     for (bug in count) {
419         # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
420         print bug ":" count[bug] ":" cat[bug] ":" doc[bug] >> "ari.doc"
421     }
422 }
423 '
424 fi
425
426
427 # print_toc BIAS MIN_COUNT CATEGORIES TITLE
428
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.
433
434 all=
435
436 print_toc ()
437 {
438     bias="$1" ; shift
439     min_count="$1" ; shift
440
441     all=" $all $1 "
442     categories=""
443     for c in $1; do
444         categories="${categories} categories[\"${c}\"] = 1 ;"
445     done
446     shift
447
448     title="$@" ; shift
449
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
454
455     cat >> ${newari} <<EOF
456 <p>
457 <table>
458 <tr><th align=left>BUG</th><th>Total</th><th align=left>Description</th></tr>
459 EOF
460     # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
461     cat ${wwwdir}/ari.doc \
462     | sort -t: +1rn -2 +0d \
463     | $AWK >> ${newari} '
464 BEGIN {
465     FS=":"
466     '"$categories"'
467     MIN_COUNT = '${min_count}'
468     BIAS = '${bias}'
469     total = 0
470     nr = 0
471 }
472 {
473     # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
474     bug = $1
475     count = $2
476     category = $3
477     doc = $4
478     if (count < MIN_COUNT) next
479     if (!(category in categories)) next
480     nr += 1
481     total += count
482     printf "<tr>"
483     printf "<th align=left valign=top><a name=\"%s\">", bug
484     printf "%s", gensub(/_/, " ", "g", bug)
485     printf "</a></th>"
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
489     } else {
490         printf "%d", count + BIAS
491     }
492     printf "</td>"
493     printf "<td align=left valign=top>%s</td>", doc
494     printf "</tr>"
495     print ""
496 }
497 END {
498     print "<tr><th align=right valign=top>" nr "</th><th align=right valign=top>" total "</th><td></td></tr>"
499 }
500 '
501 cat >> ${newari} <<EOF
502 </table>
503 <p>
504 EOF
505 }
506
507
508 print_table ()
509 {
510     categories=""
511     for c in $1; do
512         categories="${categories} categories[\"${c}\"] = 1 ;"
513     done
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) {
519     middle = ""
520     for (middle in table) { break; }
521     nr_left = 0;
522     nr_right = 0;
523     for (tmp in table) {
524         if (tolower(tmp) < tolower(middle)) {
525             nr_left++
526             left[tmp] = tmp
527         } else if (tolower(tmp) > tolower(middle)) {
528             nr_right++
529             right[tmp] = tmp
530         }
531     }
532     #print "qsort " nr_left " " middle " " nr_right > "/dev/stderr"
533     result = ""
534     if (nr_left > 0) {
535         result = qsort(left) SUBSEP
536     }
537     result = result middle
538     if (nr_right > 0) {
539         result = result SUBSEP qsort(right)
540     }
541     return result
542 }
543 function print_heading (where, bug_i) {
544     print ""
545     print "<tr border=1>"
546     print "<th align=left>File</th>"
547     print "<th align=left><em>Total</em></th>"
548     print "<th></th>"
549     for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
550         bug = i2bug[bug_i];
551         printf "<th>"
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\">&nbsp;</a>", bug
555         printf "<a name=\",%s\">&nbsp;</a>", i2bug[bug_i-1]
556         printf "<a href=\"#%s\">", bug
557         printf "%s", gensub(/_/, " ", "g", bug)
558         printf "</a>\n"
559         printf "</th>\n"
560     }
561     #print "<th></th>"
562     printf "<th><a name=\"%s,\">&nbsp;</a></th>\n", i2bug[bug_i-1]
563     print "<th align=left><em>Total</em></th>"
564     print "<th align=left>File</th>"
565     print "</tr>"
566 }
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
571     printf "&gt;"
572     printf "</th>\n"
573     print "<th></th>";
574     for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
575         bug = i2bug[bug_i];
576         printf "<th align=right>"
577         printf "<em>"
578         printf "<a href=\"#%s\">%d</a>", bug, bug_total[bug]
579         printf "</em>";
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\">&nbsp;</a>", where, bug
583         printf "</th>";
584         print ""
585     }
586     print "<th></th>"
587     printf "<th align=right>"
588     printf "<em>%s</em>", total
589     printf "&lt;"
590     printf "</th>\n"
591     print "<th align=left><em>Totals</em></th>"
592     print "</tr>"
593 }
594 BEGIN {
595     FS = ":"
596     '"${categories}"'
597     nr_file = 0;
598     nr_bug = 0;
599 }
600 {
601     # ari.*.idx: <BUG>:<FILE>:<CATEGORY>
602     bug = $1
603     file = $2
604     category = $3
605     # Interested in this
606     if (!(category in categories)) next
607     # Totals
608     db[bug, file] += 1
609     bug_total[bug] += 1
610     file_total[file] += 1
611     total += 1
612 }
613 END {
614
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);
618
619     # Dummy entries for first/last
620     i2file[0] = 0
621     i2file[-1] = -1
622     i2bug[0] = 0
623     i2bug[-1] = -1
624
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).
629
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++) {
632         bug = i2bug[bug_i]
633         prev = 0
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
641                 prev = file
642             }
643         }
644         prev_file[bug, -1] = prev
645         next_file[bug, prev] = -1
646     }
647
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]
651         prev = 0
652         prev_bug[file, 0] = -1
653         next_bug[file, -1] = 0
654         for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
655             bug = i2bug[bug_i]
656             if ((bug, file) in db) {
657                 prev_bug[file, bug] = prev
658                 next_bug[file, prev] = bug
659                 prev = bug
660             }
661         }
662         prev_bug[file, -1] = prev
663         next_bug[file, prev] = -1
664     }
665
666     print "<table border=1 cellspacing=0>"
667     print "<tr></tr>"
668     print_heading(0);
669     print "<tr></tr>"
670     print_totals(0);
671     print "<tr></tr>"
672
673     for (file_i = 1; file_i <= nr_file; file_i++) {
674         file = i2file[file_i];
675         pfile = gensub(/^'${project}'\//, "", 1, file)
676         print ""
677         print "<tr>"
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\">&gt;</a>", file, next_bug[file, 0]
682         printf "</th>\n"
683         print "<th></th>"
684         for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
685             bug = i2bug[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\">&nbsp;</a>", file, bug
692                 printf "</td>"
693                 print ""
694             } else {
695                 print "<td>&nbsp;</td>"
696                 #print "<td></td>"
697             }
698         }
699         print "<th></th>"
700         printf "<th align=right>"
701         printf "%s", file_total[file]
702         printf "<a href=\"#%s,%s\">&lt;</a>", file, prev_bug[file, -1]
703         printf "</th>\n"
704         print "<th align=left>" pfile "</th>"
705         print "</tr>"
706     }
707
708     print "<tr></tr>"
709     print_totals(-1)
710     print "<tr></tr>"
711     print_heading(-1);
712     print "<tr></tr>"
713     print ""
714     print "</table>"
715     print ""
716 }
717 '
718 }
719
720
721 # Make the scripts available
722 cp ${aridir}/gdb_*.sh ${wwwdir}
723
724 # Compute the ARI index - ratio of zero vs non-zero problems.
725 indexes=`${AWK} '
726 BEGIN {
727     FS=":"
728 }
729 {
730     # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
731     bug = $1; count = $2; category = $3; doc = $4
732
733     if (bug ~ /^legacy_/) legacy++
734     if (bug ~ /^deprecated_/) deprecated++
735
736     if (category !~ /^gdbarch$/) {
737         bugs += count
738     }
739     if (count == 0) {
740         oks++
741     }
742 }
743 END {
744     #print "tests/ok:", nr / ok
745     #print "bugs/tests:", bugs / nr
746     #print "bugs/ok:", bugs / ok
747     print bugs / ( oks + legacy + deprecated )
748 }
749 ' ${wwwdir}/ari.doc`
750
751 # Merge, generating the ARI tables.
752 if ${update_web_p}
753 then
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}
760 <html>
761 <head>
762 <title>A.R. Index for GDB version ${version}</title>
763 </head>
764 <body>
765
766 <center><h2>A.R. Index for GDB version ${version}<h2></center>
767
768 <!-- body, update above using ../index.sh -->
769
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.
777 -->
778
779 <center><h3>${indexes}</h3></center>
780 <center><h3>You can not take this seriously!</h3></center>
781
782 <center>
783 Also available:
784 <a href="../gdb/ari/">most recent branch</a>
785 |
786 <a href="../gdb/current/ari/">current</a>
787 |
788 <a href="../gdb/download/ari/">last release</a>
789 </center>
790
791 <center>
792 Last updated: `date -u`
793 </center>
794 EOF
795
796     print_toc 0 1 "internal regression" Critical <<EOF
797 Things previously eliminated but returned.  This should always be empty.
798 EOF
799
800     print_table "regression code comment obsolete gettext"
801
802     print_toc 0 0 code Code <<EOF
803 Coding standard problems, portability problems, readability problems.
804 EOF
805
806     print_toc 0 0 comment Comments <<EOF
807 Problems concerning comments in source files.
808 EOF
809
810     print_toc 0 0 gettext GetText <<EOF
811 Gettext related problems.
812 EOF
813
814     print_toc 0 -1 dos DOS 8.3 File Names <<EOF
815 File names with problems on 8.3 file systems.
816 EOF
817
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).
825 EOF
826
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.
830 EOF
831
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.
838 EOF
839
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).
844 EOF
845
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).
849 EOF
850
851     print_toc 0 -1 macro Macro <<EOF
852 Breakdown of macro definitions (and #undef) in configuration files.
853 EOF
854
855     print_toc 0 0 regression Fixed <<EOF
856 Problems that have been expunged from the source code.
857 EOF
858
859     # Check for invalid categories
860     for a in $all; do
861         alls="$alls all[$a] = 1 ;"
862     done
863     cat ari.*.doc | $AWK >> ${newari} '
864 BEGIN {
865     FS = ":"
866     '"$alls"'
867 }
868 {
869     # ari.*.doc: <BUG>:<COUNT>:<CATEGORY>:<DOC>
870     bug = $1
871     count = $2
872     category = $3
873     doc = $4
874     if (!(category in all)) {
875         print "<b>" category "</b>: no documentation<br>"
876     }
877 }
878 '
879
880     cat >> ${newari} <<EOF
881 <center>
882 Input files:
883 `( cd ${wwwdir} && ls ari.*.bug ari.idx ari.doc ) | while read f
884 do
885     echo "<a href=\"${f}\">${f}</a>"
886 done`
887 </center>
888
889 <center>
890 Scripts:
891 `( cd ${wwwdir} && ls *.sh ) | while read f
892 do
893     echo "<a href=\"${f}\">${f}</a>"
894 done`
895 </center>
896
897 <!-- /body, update below using ../index.sh -->
898 </body>
899 </html>
900 EOF
901
902     for i in . .. ../..; do
903         x=${wwwdir}/${i}/index.sh
904         if test -x $x; then
905             $x ${newari}
906             break
907         fi
908     done
909
910     gzip -c -v -9 ${newari} > ${newari}.gz
911
912     cp ${ari} ${oldari}
913     cp ${ari}.gz ${oldari}.gz
914     cp ${newari} ${ari}
915     cp ${newari}.gz ${ari}.gz
916
917 fi # update_web_p
918
919 # ls -l ${wwwdir}
920
921 exit 0