diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2003-11-29 13:06:32 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2003-11-29 13:06:32 +0000 |
commit | 00c543d4bc94ba42c08148a482abed06fd5b3217 (patch) | |
tree | 2054ce101c21a46ef544752667b9c1a787b11225 /gnu | |
parent | 4e3f9ef7392ad8de0e3664361961b6abe573d0b3 (diff) |
also import this dir.
Diffstat (limited to 'gnu')
22 files changed, 6004 insertions, 0 deletions
diff --git a/gnu/usr.bin/gcc/contrib/ChangeLog b/gnu/usr.bin/gcc/contrib/ChangeLog new file mode 100644 index 00000000000..536735b39d9 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/ChangeLog @@ -0,0 +1,810 @@ +2003-10-16 Release Manager + + * GCC 3.3.2 Released. + +2003-10-16 Mark Mitchell <mark@codesourcery.com> + + * gennews (files): Add GCC 3.3 files. + +2003-08-21 Mark Mitchell <mark@codesourcery.com> + + * gcc_build: Fix handling of -t option. Add -x option. + +2003-08-04 Release Manager + + * GCC 3.3.1 Released. + +2003-08-04 Release Manager + + * GCC 3.3.1 Released. + +2003-06-13 Jason Thorpe <thorpej@wasabisystems.com> + + * gcc_update (files_and_dependencies): Add + gcc/testsuite/gcc.dg/cpp/_Pragma3.c depends on + gcc/testsuite/gcc.dg/cpp/mi1c.h. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2003-04-12 Matthias Klose <doko@debian.org> + + * test_installed: Add options to run objc tests. + In generated site.exp, initialize rootme, CFLAGS, CXXFLAGS. + +2003-01-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * gcc_update (files_and_dependencies): Add gcc/cp/cfns.h depends + on gcc/cp/cfns.gperf and gcc/java/keyword.h depends on + gcc/java/keyword.gperf + +2002-12-29 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gcc_update (files_and_dependencies): Add gcc/intl/plural.c as + depending on gcc/intl/plural.y. + +2002-12-28 Joseph S. Myers <jsm@polyomino.org.uk> + + * texi2pod.pl: Skip contents of @copying. + +2002-10-21 Richard Henderson <rth@redhat.com> + + * paranoia.cc (real_c_float::image): Accomodate size of + real_internal format. + (main): Unbuffer stdio. Add real_internal format. + (floor_log2_wide): New. + +2002-10-16 Richard Henderson <rth@redhat.com> + + * paranoia.cc (ENUM_BITFIELD): New. + (class): Define as klass around real.h. + (real_c_float): Not a template any longer; define MODE as a + class static constant; use real_format elements for SIZE. + Update uses of real_to_decimal and real_to_hexadecimal. + (main): Change -g argument to use a format name. + (mode_for_size): Remove. + +2002-09-16 Richard Henderson <rth@redhat.com> + + * paranoia.cc: New file. + +2002-09-04 Richard Henderson <rth@redhat.com> + + * enquire.c: Remove. + +2002-08-14 Mark Mitchell <mark@codesourcery.com> + + * gennews (files): Add GCC 3.2 files. + +2002-07-22 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gennews (files): Add proper files for the GCC 3.1 release series. + Simplify and reformat introductory wording. + +2002-07-16 Nathanael Nerode <neroden@gcc.gnu.org> + + * enquire.c: Move from gcc. + +2002-07-16 H.J. Lu <hjl@gnu.org> + + * gcc_update (touch_files): Pass -s to ${MAKE}. + +2002-06-26 Zack Weinberg <zack@codesourcery.com> + + * texi2pod.pl: Correct handling of the internal R<> sequence. + +2002-05-31 Florian Weimer <fw@deneb.enyo.de> + + * gcc_update (files_and_dependencies): Add generated Texinfo files + for Ada. + +2002-05-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> + + * test_installed: Allow for PWDCMD to override hardcoded pwd. + * test_summary: Likewise. + +2002-04-18 Geoffrey Keating <geoffk@redhat.com> + + * gcc_update (touch_files): Don't have empty for loop. + +2002-04-16 Richard Henderson <rth@redhat.com> + + * gcc_update: Remove libchill. + +2002-03-25 Zack Weinberg <zack@codesourcery.com> + + * texi2pod.pl: Handle @end ftable and @end vtable. + +2002-03-11 Zack Weinberg <zack@codesourcery.com> + + * texi2pod.pl: Handle @include, @ftable, @vtable. + Reformat some code for clarity. + +2002-02-24 Christian Jönsson <c.christian.joensson@telia.com> + + * test_summary: Additional to XPASS and FAIL, add UNRESOLVED, + WARNING and ERROR output from the *.sum files. + +2002-01-26 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gennews (files): Replace gcc-2.95/gcc-2.95.html, + gcc-2.95/gcc-2.95.1.html, gcc-2.95/gcc-2.95.2.html, + and gcc-2.95/gcc-2.95.3.html by gcc-2.95/index.html. + +2002-01-16 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gennews (files): Replace egcs-1.1/egcs-1.1.2.html, + egcs-1.1/egcs-1.1.1.html, and egcs-1.1/egcs-1.1.html by + egcs-1.1/index.html. + +2002-01-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * warn_summary: Add -ada subdirectory flag. + +2001-12-12 Matthias Klose <doko@debian.org> + + * texi2pod.pl: Merge changes from binutils' texi2pod.pl. Allows + generation of more than one man page from one source. + Add '-' to set of valid chars for an identifier. + Let -D option accept flags of the form <flag>=<value>. + Use \s+ for whitespace detection in '@c man' lines. + Handle @set and @clear independent of $output. + Substitute all @value{}'s in a line. + +2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk> + + * texi2pod.pl: Handle @ifnottex, @iftex and @display. Handle @var + in verbatim blocks specially. Handle @unnumbered, @unnumberedsec + and @center. Allow [a-z] after @enumerate. Handle 0 and numbers + greater than 9 in enumerations. + +2001-11-07 Laurent Guerby <guerby@acm.org> + + * gcc_update (files_and_dependencies): Add Ada dependencies. + +2001-10-08 Joseph S. Myers <jsm28@cam.ac.uk> + + * snapshot: Remove. + +2001-09-07 Richard Sandiford <rsandifo@redhat.com> + + Revert: + * gcc_update: (files_and_dependencies) Add gcc/java/parse.c + gcc/java/parse-scan.c and gcc/java/keyword.h to list of files to + touch. + +2001-09-04 David.Billinghurst <David.Billinghurst@riotinto.com> + + * gcc_update: (files_and_dependencies) Add gcc/java/parse.c + gcc/java/parse-scan.c and gcc/java/keyword.h to list of files to + touch. + +Mon Aug 13 02:29:08 CEST 2001 Jan Hubicka <jh@suse.cz> + + * analyze_brprob: Update for changes in gcc debug output. + +Sat Jul 28 22:37:49 CEST 2001 Jan Hubicka <jh@suse.cz> + + * analyze_brprob: Avoid more overflows. + +2001-07-27 Richard Henderson <rth@redhat.com> + + * test_summary: Copy LAST_UPDATED UTC time to head of summary. + +Fri Jul 27 18:01:21 CEST 2001 Jan Hubicka <jh@suse.cz> + + * analyze_brprob: Avoid overflows. + +2001-07-27 Richard Henderson <rth@redhat.com> + + * gcc_update: Dump timestamp in LAST_UPDATED. + +2001-07-26 Andreas Jaeger <aj@suse.de>, + Hans-Peter Nilsson <hp@bitrange.com> + + * analyze_brprob: Fix documentation. + +Mon Jul 23 15:47:19 CEST 2001 Jan Hubicka <jh@suse.cz> + + * analyze_brprob: Fix awk compatibility problems; update comment. + +2001-07-23 Andreas Jaeger <aj@suse.de> + + * analyze_brprob: Fix more typos. + +2001-07-23 Andreas Jaeger <aj@suse.de> + + * analyze_brprob: Fix typos. + +2001-07-03 Joseph S. Myers <jsm28@cam.ac.uk> + + * texi2pod.pl: Handle @r inside @item. + +2001-07-02 Zack Weinberg <zackw@stanford.edu> + + * gcc_update: Remove entries for gcc.1, cpp.1, gcov.1. + +2001-07-01 Zoltan Felleg <zfelleg@telnet.hu> + + * warn_summary: Fix typo in a comment. + +2001-06-14 Albert Chin-A-Young <china@thewrittenword.com> + + * contrib/gcc_update: Fix timestamp on gcc/f/intdoc.texi. + +2001-06-13 Mark Mitchell <mark@codesourcery.com> + + * gennews: Set TERM to vt100 for Lynx. + +2001-06-13 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * release: Remove. + +Tue Jun 12 12:21:40 CEST 2001 Jan Hubicka <jh@suse.cz> + + * analyze_brprob: New file. + +2001-06-11 Mark Mitchell <mark@codesourcery.com> + + * gcc_build: Output information about the commands used to + configure the compiler. + +2001-06-07 Joseph S. Myers <jsm28@cam.ac.uk> + + * gennews: Update for GCC 3.0. + +2001-06-02 Joseph S. Myers <jsm28@cam.ac.uk> + + * gcc_update: Update for move of documentation to gcc/doc. + +2001-05-28 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> + + * contrib/test_summary (files): Sort before evaluating. + +2001-05-23 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gcc_update (UPDATE_OPTIONS): Add -d to the default settings. + +2001-05-21 Mark Mitchell <mark@codesourcery.com> + + * gcc_build: Use -d when invoking gcc_update. + +2001-05-18 Andreas Jaeger <aj@suse.de> + + * gcc_update: Add rules for libf2c/libI77. + +2001-05-17 Alexandre Oliva <aoliva@redhat.com> + + * gcc_update (touch_files): Use simpler, yet as portable, syntax. + +2001-05-14 Loren J. Rittle <ljrittle@acm.org> + + * gcc_update (touch_files): Enhance make portability. + +2001-05-14 Alexandre Oliva <aoliva@redhat.com> + + * gcc_update (touch_files): Use a Makefile to touch files. + +2001-05-03 Joseph S. Myers <jsm28@cam.ac.uk> + + * texi2pod.pl: Add copyright and GPL notices. + +2001-01-24 Joseph S. Myers <jsm28@cam.ac.uk> + + * texi2pod.pl: Handle "\,". + +2001-01-15 Joseph S. Myers <jsm28@cam.ac.uk> + + * texi2pod.pl: Fix regular expression for @r to avoid exponential + recursion. From Russ Allbery <rra@stanford.edu>. Remove perl + version check. + +2001-01-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * warn_summary (stageNfilter): Update for recent changes in + bootstrap logic. + +2001-01-14 Joseph S. Myers <jsm28@cam.ac.uk> + + * texi2pod.pl: Require at least perl 5.6.0. + +2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk> + + * gcc_update: Add gcc/gcc.1 to generated files. + * texi2pod.pl: Handle @r and @gccoptlist. Handle @gol. Handle + discarding to end of sentence with @xref where the sentence has an + interior "." in markup, and handle discarding parentheses around + such a sentence. + +2001-01-11 Bernd Schmidt <bernds@redhat.com> + + * gennews: Add gcc-2.95.3. + +2001-01-10 Joseph S. Myers <jsm28@cam.ac.uk> + + * texi2pod.pl: Handle @gcctabopt and @env in tables. Handle + @command. Format URLs and email addresses in bold. + +2001-01-03 Joseph S. Myers <jsm28@cam.ac.uk> + + * gcc_update: Add cpp.1 to the list of generated files. + + * texi2pod.pl: Handle @option and @env. + +2001-01-03 Mike Stump <mrs@wrs.com> + + * snapshot: Update to account for java libraries. + +2000-12-28 Jeffrey Oldham <oldham@codesourcery.com> + + * test_summary: Export filesuffix, not fileprefix. + +2000-12-22 Joseph S. Myers <jsm28@cam.ac.uk> + + * release: Change some EGCS references to GCC. + +2000-12-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * warn_summary: Fix subdirectory filtering. Add -intl and -fixinc + subdirectory flags. Add source directory prefix filtering. + Redirect diagnostic output to stderr. + +2000-12-07 Zack Weinberg <zack@wolery.stanford.edu> + + * texi2pod.pl: If multiple @c man sections with the same tag + appear, concatenate them in the final output. When skipping, + ignore block commands that can't cause skipping, and honor + those that can. Ensure that verbatim blocks are separate + paragraphs. + +2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk> + + * gcc_update: Don't touch tradcif.c or java/parse.h. + +2000-12-05 Zack Weinberg <zack@wolery.stanford.edu> + + * texi2pod.pl: Restructure for comprehensibility, add + comments. Merge handling of @ignore and @ifxxx. Handle a + whole bunch more Texinfo commands. Use consistent formatting + style. + +2000-12-04 Joseph S. Myers <jsm28@cam.ac.uk> + + * gennews: New script. + +2000-11-22 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gcc_update: Update a comment as we now require bison for CVS users. + +2000-11-22 Joseph S. Myers <jsm28@cam.ac.uk> + + * gcc_update: Add gcov.1 to the list of generated files. + +2000-11-21 Mark Mitchell <mark@codesourcery.com> + + * gcc_build: Remove code to put information in a log file. + +2000-11-19 Zack Weinberg <zackw@stanford.edu> + + * texi2pod.pl: + - Add real command line parsing. + - Support @ifset, @ifclear, @set, @value, -D switch. + - Support @sc. Improve handling of @ref and friends. + - Discard @subsection, @need, @node lines. + - Un-nest font changes to match texinfo semantics. + - Handle @{ and @}. Oops. + - Don't emit E<> directives inside verbatim blocks. + +2000-11-12 Bruce Korb <bkorb@gnu.org> + + * release: generalize the release script a bit. + +Sat Nov 11 17:29:03 2000 Mark P Mitchell <mark@codesourcery.com> + + * gcc_build: Add -o option for setting the objdir to use. + +2000-11-11 Jeff Law <law@redhat.com>, + + * release: New file. + +2000-11-08 Jeff Law <law@redhat.com>, + Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * snapshot: New file. + +2000-11-08 Jeffrey Oldham <oldham@oz.codesourcery.com> + + * gcc_build (bootstrap_gcc): New function. + (configure_gcc): Likewise. + (build_gcc): Rewritten to use configure and bootstrap. + (MAKE_BOOTSTRAP_OPTIONS): Replaced MAKE_OPTIONS. + +2000-10-31 Mark Mitchell <mark@codesourcery.com> + + * gcc_build (MAKE): New variable. + (build_gcc): Use it. Fix logging of errors. + (install_gcc): Likewise. + +2000-10-29 Mark Mitchell <mark@codesourcery.com> + + * gcc_build: Save the output from CVS into the logfile as well. + +2000-10-25 Mark Mitchell <mark@codesourcery.com> + + * gcc_build: Fix typos. + +2000-10-14 Joseph S. Myers <jsm28@cam.ac.uk> + + * gperf-2.7-19981006.pat: Remove. + +2000-10-08 Joseph S. Myers <jsm28@cam.ac.uk> + + * test_installed: Change EGCS references to refer to GCC. + +2000-09-28 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gcc_update (touch_files): Add some informative output. + +2000-09-16 Andreas Jaeger <aj@suse.de> + + * gcc_update: Remove gcc/c-parse.gperf. + +2000-08-30 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>, + Alexandre Oliva <aoliva@redhat.com> + + * gcc_update: Execute touch_files_reexec even if `cvs update` + failed. + +2000-08-09 Alexandre Oliva <aoliva@redhat.com> + + * test_summary: AWK breaks with filenames containing `='. + +Sun Jul 16 12:04:33 2000 Mark P Mitchell <mark@codesourcery.com> + + * gcc_build: New script. + +2000-07-13 Mark Mitchell <mark@codesourcery.com> + + * gcc_update (files_and_dependencies): Remove generated YACC files. + +2000-07-12 Mark Mitchell <mark@codesourcery.com> + + * gcc_update (files_and_dependencies): Remove generated YACC files. + +2000-06-04 Mark Mitchell <mark@codesourcery.com> + + * newcvsroot: Handle filenames that contain spaces. + +2000-06-03 Zack Weinberg <zack@wolery.cumb.org> + + * test_summary: In generated script, use cat <<'EOF' not cat <<\EOF. + Elide --with-gcc-version-trigger and --norecursion from + configure flags. Remove code to report status of haifa scheduler. + +2000-05-18 Alexandre Oliva <aoliva@cygnus.com> + + * gcc_update (self): Set to `$0'. + (touch_files_reexec): Use `$self' instead of `$0'. + +2000-05-12 Alexandre Oliva <aoliva@cygnus.com> + + * gcc_update (touch_files_reexec): New function, run after the + tree is modified. + +2000-05-08 Richard Hendeson <rth@cygnus.com> + + * gcc_update: Remove references to inclhack.tpl. + +2000-04-28 Jason Merrill <jason@casey.cygnus.com> + + * index-prop: Use a single pattern. Also support *** cdiffs. + +2000-04-28 Pavel Roskin <pavel_roskin@geocities.com> + + * index-prop: Don't change /dev/null. + +2000-04-27 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gcc_update: Refer to GCC and gcc_update instead of egcs and + egcs_update. + +2000-04-26 Jonathan Larmour <jlarmour@redhat.co.uk> + + * index-prop: Fix occasional problem when using cvs diff -p. + +2000-04-18 Zack Weinberg <zack@wolery.cumb.org> + + * gcc_update: Remove references to cexp.c/cexp.y. + +1999-12-18 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * newcvsroot: Add check on the number of command-line arguments. + Add usage. + +Sun Nov 28 00:41:44 1999 William Bader (william@nscs.fast.net) + + * gcc_update: Allow patches compressed by bzip2. + +1999-10-11 Martin v. Löwis <loewis@informatik.hu-berlin.de> + + * newcvsroot: New file. + +1999-09-11 Craig Burley <craig@jcb-sc.com> + + * convert_to_f2c, convert_to_g2c, download_f2c: New file. + +1999-08-16 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * gcc_update: New file. + * egcs_update: Renamed to gcc_update. + +1999-08-09 Robert Lipe <robertlipe@usa.net> + + * test_summary: Quote curly braces in 1999-07-03 change. + +1999-07-28 Alexandre Oliva <oliva@dcc.unicamp.br> + + * egcs_update (files_and_dependencies): Fixed typo in + gcc/cstamp-h.in. Added gcc/config.in. + +1999-07-27 Alexandre Oliva <oliva@dcc.unicamp.br> + + * egcs_update (files_and_dependencies): New function, with + complete list of files to be updated, as well as their + dependencies. + (touch_files): Check the timestamp of each generated file against + its dependencies'. + (main): New flags --touch, --list and --help. Remove the + pre-update step. + +1999-07-17 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary: Replace egcs with gcc. Update e-mail address. + +1999-07-05 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + Jerry Quinn <jquinn@nortelnetworks.com> + + * egcs_update (touch_files, apply_patch): New functions. + Use them. New command-line option --patch. Split test of local + tree into two parts. Add comments. + +1999-07-03 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary: If Target is `unix{*}', append the Target variants + to Host. + +1999-06-12 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary: Set default mail-address and version for egcs + instead of relying on unpredictable pathnames. + Reported by Andreas Jaeger <aj@arthur.rhein-neckar.de> + +Fri Apr 2 16:09:02 1999 Jeffrey A Law (law@cygnus.com) + + * fixinc/*: Delete obsolete files. + +1999-02-04 Robert Lipe <robertlipe@usa.net> + + * egcs_update: Test return values of 'cvs update'. Propogate + to caller as exit values. + +1999-01-25 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * egcs_update: Use "if" instead of "&&". Touch generated files + only after the corresponding *.y files. + +1999-01-19 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * egcs_update: Do not use xargs, but a backquote construct. + +1999-01-07 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary (version): Remove carriage return that gawk inserts + in the version string for some reason. + +1998-11-30 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * egcs_update: Only touch files that already exist. + +1998-11-29 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary (EOF): Remove double backslash. + Reported by Franz Sirl <Franz.Sirl-kernel@lauterbach.com> + +1998-11-28 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary (address): Set to egcs-testresults mailing list. + +1998-11-27 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary (address): Added Marc Lehmann's testsuite-results + to the default e-mail address. + +1998-11-25 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary (-p, prepend_logs): Add these before the summary. + (Compiler, Platform): Print these just before configflags. + +Sat Oct 31 10:53:40 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * warn_summary (longLineFilter): New shell function to encapsulate + this functionality. It is off by default, only active if -llf + flag is specified. + (subdirectoryFilter): Fix bug in filtering which made some + subdirectory warnings erroneously appear in the toplevel set. + (stageNfilter): Renamed from `stageNwarns'. Updated to collect + warnings from stage1 as well as stage0, which means warnings from + outside the bootstrap directory. Eg, the libraries, etc. + (warningFilter): New shell function to encapsulate this + functionality. + (keywordFilter): New shell function to encapsulate this + functionality. + + Store data in a temp file rather than calculating it 3x. Arrange + to remove it on exit and signals. + + Add -pass/-wpass flags to do "pass through" (i.e. manual + inspection) of bootstrap output from a particular stageN as well + as language subdirs. + + Add better comments/documentation. + +Sat Oct 31 16:39:31 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * egcs_update: Add comment about keeping the FAQ synchronized. + +Fri Oct 30 00:39:27 1998 Jeffrey A Law (law@cygnus.com) + + * egcs_update: Do touch java/parse.c and java/parse-scan.c. They're + in the repo again. + +Fri Oct 16 07:35:00 1998 Bruce Korb <korb@datadesign.com> + + * egcs_update: Added gcc/fixinc/* generated files to touch list. + +Tue Oct 13 23:28:33 1998 Jeffrey A Law (law@cygnus.com) + + * egcs_update: Remove gcc/java/parse.c from list of files to + touch. + +Wed Oct 7 13:00:40 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * gperf-2.7-19981006.pat: New file, patch for egcs-local gperf. + +Mon Oct 5 14:19:48 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * warn_summary (subdirectoryFilter): New shell function to + optionally filter in/out gcc subdirectories when summarizing + warnings. Add new flags to support subdirectory filtering. + + Also, ensure the bootstrap stage is a number. Add some more C + keywords that are preserved in the "warning type" summary and + tighten up the "arg ???" regexp. + +Tue Sep 22 07:30 Bruce Korb <korb@datadesign.com> + + * fixinc/inclhack.def: Not all C++ comments in C headers + were treated alike. They are now. Also fixed syntax + of sed expression in "systypes" fix. + + * fixinc/inclhack.def: Removed SVR4.2-ism from shell invocation + + * egcs_update: Added fixinc/* generated files to touch list. + +Wed Sep 16 16:06:51 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * egcs_update: Additionally touch gcc/java/parse.[ch]. + +Thu Sep 9 16:48 Bruce Korb <korb@datadesign.com> + + * fixinc/inclhack.def: Added two files required by + SCO's Open Server 5's avoid_bool fix. + Regenerated fixinc.x and inclhack.sh to incorporate + the update. + +Thu Sep 3 10:11:32 1998 Robert Lipe <robertl@dgii.com> + + * egcs_update: Do the pass 1 CVS update only for files that + may reasonably be under CVS control. + +1998-08-14 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_installed: New script for testing already-installed + gcc/g++/g77. + +Wed Aug 12 19:59:36 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * egcs_update: Assigned copyright to FSF. + +Tue Aug 11 17:55:53 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + Alexandre Oliva <oliva@dcc.unicamp.br> + + * egcs_update: New switch --nostdflags and documentation + enhancements. + +Tue Aug 11 17:33:19 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * egcs_update: New script. + +1998-08-05 Bruce Korb <korbb@datadesign.com> + + * fixinc/Makefile + Added define for target machine so machine-specific tests + can be selected for or against. + + * fixinc/fixincl.c + Added an array of string pointers to machines to select + or avoid, depending on a FD_MACH_IFNOT bit flag. + Used a shell script to match the defined TARGET_MACHINE + with any of the given match patterns. + + * fixinc/fixincl.tpl + Generate the array of strings and bit flag, as needed, + depending on "mach" and "not_machine" attributes for a fix. + + * fixinc/mkfixinc.sh + Invoke the make with TARGET assigned the value of the + machine name argument. + +Mon Jul 27 22:08:12 1998 Mike Stump (mrs@wrs.com) + + * compare_tests: New script. + +1998-07-28 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary: Assigned copyright to FSF. + +Mon Jul 27 20:33:02 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> + + * test_summary: Corrected script name in comments providing + documentation. Added linebreaks for lines with > 80 characters. + +Fri Jun 19 02:36:59 1998 Alexandre Oliva <oliva@dcc.unicamp.br> + + * test_summary: New switch, -i, and environment variable, + append_logs, for including files in the report. + +1998-06-01 Manfred Hollstein <manfred@s-direktnet.de> + + * warn_summary: Update to Kaveh's latest version allowing to + specify the last stage built. + +1998-05-29 Bruce Korb <korbb@datadesign.com> + + * fixinc/mkfixinc.sh + Changes to make it easier to invoke on platforms that + normally do not invoke fixincludes. + + * fixinc/inclhack.def + Applied fixes from egcs/gcc/fixincludes from the past several + months. + +1998-05-28 Bruce Korb <korbb@datadesign.com> + + * fixinc/*: Updated most everything for a first real + try at getting "fast_fixincludes" working. + +1998-05-28 Jason Merrill <jason@yorick.cygnus.com> + + * index-prop: New file. + +Sat May 23 23:38:49 1998 Matthias Klose <doko@cs.tu-berlin.de> + + * test_summary: find good awk (copied from warn_summary). + +Sat May 23 23:38:33 1998 Jeffrey A Law (law@cygnus.com) + + * test_summary, warn_summary: New files diff --git a/gnu/usr.bin/gcc/contrib/analyze_brprob b/gnu/usr.bin/gcc/contrib/analyze_brprob new file mode 100755 index 00000000000..3650e60c075 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/analyze_brprob @@ -0,0 +1,146 @@ +#!/usr/bin/awk -f +# Script to analyze experimental results of our branch prediction heuristics +# Contributed by Jan Hubicka, SuSE Inc. +# Copyright (C) 2001 Free Software Foundation, Inc. +# +# This file is part of GNU CC. +# +# GNU CC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU CC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU CC; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# +# This script is used to calculate two basic properties of the branch prediction +# heuristics - coverage and hitrate. Coverage is number of executions of a given +# branch matched by the heuristics and hitrate is probability that once branch is +# predicted as taken it is really taken. +# +# These values are useful to determine the quality of given heuristics. Hitrate +# may be directly used in predict.c. +# +# Usage: +# Step 1: Compile and profile your program. You need to use -fprofile-arcs +# flag to get the profiles +# Step 2: Generate log files. The information about given heuristics are +# saved into *.life dumps. You need to pass the -df switch to the compiler as well +# as -fbranch-probabilities to get the results of profiling noted in the dumps. +# Ensure that there are no "Arc profiling: some edge counts were bad." warnings. +# Step 3: Run this script to concatenate all *.life files: +# analyze_brprob `find . -name *.life` +# the information is collected and print once all files are parsed. This +# may take a while. +# Note that the script does use bc to perform long arithmetic. +# Step 4: Read the results. Basically the following table is printed: +# (this is just an example from a very early stage of branch prediction pass +# development, so please don't take these numbers seriously) +# +#HEURISTICS BRANCHES (REL) HITRATE COVERAGE (REL) +#opcode 2889 83.7% 94.96%/ 97.62% 7516383 75.3% +#pointer 246 7.1% 99.69%/ 99.86% 118791 1.2% +#loop header 449 13.0% 98.32%/ 99.07% 43553 0.4% +#first match 3450 100.0% 89.92%/ 97.27% 9979782 100.0% +#loop exit 924 26.8% 88.95%/ 95.58% 9026266 90.4% +#error return 150 4.3% 64.48%/ 86.81% 453542 4.5% +#call 803 23.3% 51.66%/ 98.61% 3614037 36.2% +#loop branch 51 1.5% 99.26%/ 99.27% 26854 0.3% +#noreturn call 951 27.6% 100.00%/100.00% 1759809 17.6% +# +# The heuristic called "first match" is a heuristic used by GCC branch +# prediction pass and it predicts 89.92% branches correctly. +# +# The quality of heuristics can be rated using both, coverage and hitrate +# parameters. For example "loop branch" heuristics (predicting loopback edge +# as taken) have both very high hitrate and coverage, so it is very useful. +# On the other hand, "exit block" heuristics (predicting exit edges as not +# taken) have good hitrate, but poor coverage, so only 3 branches have been +# predicted. The "loop header" heuristic has problems, since it tends to +# misspredict. +# +# The implementation of this script is somewhat brute force. My awk skills +# are limited. + +function longeval(e) +{ + e = "echo \"scale = 2 ;"e"\" | bc" + e | getline res + close (e) + return res +} + +BEGIN {nnames = 0} + +/^ .* heuristics: .*.$/ { + name=$0 + sub (/^ /,"",name) + sub (/ heuristics: .*.$/,"",name) + if (!(name in branches)) + { + names[nnames] = name + branches[name]=0 + counts[name]=0 + hits[name]=0 + phits[name]=0 + nnames++ + } + branches[name]+=1 + } + +/^ .* heuristics: .*. exec [0-9]* hit [0-9]* (.*.)$/ { + name=$0 + sub (/^ /,"",name) + sub (/ heuristics: .*. exec [0-9]* hit [0-9]* (.*.)$/,"",name) + pred=$0 + sub (/^ .* heuristics: /,"",pred) + sub (/. exec [0-9]* hit [0-9]* (.*.)$/,"",pred) + count=$0 + sub (/^ .* heuristics: .*. exec /,"",count) + sub (/ hit [0-9]* (.*.)$/,"",count) + hit=$0 + sub (/^ .* heuristics: .*. exec [0-9]* hit /,"",hit) + sub (/ (.*.)$/,"",hit) + + if (int(pred) < 50.0) + { + hit = count"-"hit; + } + counts[name]=counts[name] "+" count + hits[name]=hits[name] "+" hit + phits[name]=phits[name] "+(("hit")<"count"/2)*("count"-("hit"))+(("hit")>="count"/2)*("hit")" + + #BC crashes on long strings. Irritating. + if (length(counts[name]) > 2000) + counts[name] = longeval(counts[name]) + if (length(hits[name]) > 2000) + hits[name] = longeval(hits[name]) + if (length(phits[name]) > 2000) + phits[name] = longeval(phits[name]) + } +END { + # Heuristics called combined predicts just everything. + maxcounts = longeval(counts["combined"]) + maxbranches = branches["combined"] + max = names["combined"] + printf("HEURISTICS BRANCHES (REL) HITRATE COVERAGE (REL)\n") + for (i = 0; i < nnames ; i++) + { + name = names[i] + counts[name] = longeval(counts[name]) + printf ("%-27s %8i %5.1f%% %6s%%/%6s%% %12s %5.1f%%\n", + name, + branches[name], branches[name] * 100 / maxbranches, + longeval("("hits[name]") * 100 /(" counts[name]"-0.00001)"), + longeval("("phits[name]") * 100 /(" counts[name]"-0.00001)"), + counts[name], longeval(counts[name]" * 100 / ("maxcounts"-0.00001)")) + } +} diff --git a/gnu/usr.bin/gcc/contrib/compare_tests b/gnu/usr.bin/gcc/contrib/compare_tests new file mode 100755 index 00000000000..7a1d76cb827 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/compare_tests @@ -0,0 +1,98 @@ +#!/bin/sh +# This script automatically test the given tool with the tool's test cases, +# reporting anything of interest. + +# exits with 1 if there is nothing of interest +# exits with 0 if there is something interesting +# exits with 2 if an error occurred + +# Give two .sum files to compare them + +# Written by Mike Stump <mrs@cygnus.com> + +tmp1=/tmp/$tool-testing.$$a +tmp2=/tmp/$tool-testing.$$b +now_s=/tmp/$tool-testing.$$d +before_s=/tmp/$tool-testing.$$e + +if [ "$2" = "" ]; then + echo "Usage: $0 previous current" >&2 + exit 2 +fi + +sed 's/^XFAIL/FAIL/; s/^XPASS/PASS/' < "$1" >$tmp1 +sed 's/^XFAIL/FAIL/; s/^XPASS/PASS/' < "$2" >$tmp2 + +before=$tmp1 +now=$tmp2 + +trap "rm -f $tmp1 $tmp2 $now_s $before_s" 0 1 2 3 5 9 13 15 + +sort +0.4 "$now" > "$now_s" +sort +0.4 "$before" > "$before_s" + +grep '^FAIL' "$now_s" | sed 's/^....: //' >$tmp1 +grep '^PASS' "$before_s" | sed 's/^....: //' | comm -12 $tmp1 - >$tmp2 + +grep -s . $tmp2 >/dev/null +if [ $? = 0 ]; then + echo "Tests that now fail, but worked before:" + echo + cat $tmp2 + echo +fi + +grep '^PASS' "$now_s" | sed 's/^....: //' >$tmp1 +grep '^FAIL' "$before_s" | sed 's/^....: //' | comm -12 $tmp1 - >$tmp2 + +grep -s . $tmp2 >/dev/null +if [ $? = 0 ]; then + echo "Tests that now work, but didn't before:" + echo + cat $tmp2 + echo +fi + +grep '^FAIL' "$now_s" | sed 's/^....: //' >$tmp1 +grep '^[PF]A[SI][SL]' "$before_s" | sed 's/^....: //' | comm -23 $tmp1 - >$tmp2 + +grep -s . $tmp2 >/dev/null +if [ $? = 0 ]; then + echo "New tests that FAIL:" + echo + cat $tmp2 + echo +fi + +grep '^PASS' "$now_s" | sed 's/^....: //' >$tmp1 +grep '^[PF]A[SI][SL]' "$before_s" | sed 's/^....: //' | comm -23 $tmp1 - >$tmp2 + +grep -s . $tmp2 >/dev/null +if [ $? = 0 ]; then + echo "New tests that PASS:" + echo + cat $tmp2 + echo +fi + +grep '^[PF]A[SI][SL]' "$now_s" | sed 's/^....: //' >$tmp1 +grep '^PASS' "$before_s" | sed 's/^....: //' | comm -13 $tmp1 - >$tmp2 + +grep -s . $tmp2 >/dev/null +if [ $? = 0 ]; then + echo "Old tests that passed, that have disappeared: (Eeek!)" + echo + cat $tmp2 + echo +fi + +grep '^[PF]A[SI][SL]' "$now_s" | sed 's/^....: //' >$tmp1 +grep '^FAIL' "$before_s" | sed 's/^....: //' | comm -13 $tmp1 - >$tmp2 + +grep -s . $tmp2 >/dev/null +if [ $? = 0 ]; then + echo "Old tests that failed, that have disappeared: (Eeek!)" + echo + cat $tmp2 + echo +fi diff --git a/gnu/usr.bin/gcc/contrib/convert_to_f2c b/gnu/usr.bin/gcc/contrib/convert_to_f2c new file mode 100755 index 00000000000..9a499fcf14c --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/convert_to_f2c @@ -0,0 +1,48 @@ +#!/bin/sh +# +# convert_to_f2c [g2c-dir] +# +# Renames certain files in a g2c (libg2c) directory so they no longer have the +# `.netlib' suffix, a la netlib's f2c distribution. If `g2c-dir' is not +# specified, `g2c-YYYYMMDD' is the default, where YYYYMMDD is the current +# date. The directory is renamed such that the first `g' becomes an `f', +# usually `g2c-YYYYMMDD' -> `f2c-YYYYMMDD'. +# +# (C) 1999 Free Software Foundation +# Originally by James Craig Burley <craig@jcb-sc.com>, September 1999. +# +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html + +set -e + +if [ x$1 = x ] +then + dir=g2c-`date +%Y%m%d` +else + dir=$1 +fi + +newdir=`echo $dir | sed -e "s:g:f:"` + +cd $dir + +set +e + +mv -i changes.netlib changes +mv -i disclaimer.netlib disclaimer +mv -i g2c.hin f2c.h +mv -i permission.netlib permission +mv -i readme.netlib readme +cd libF77 +mv -i README.netlib README +mv -i makefile.netlib makefile +cd ../libI77 +mv -i README.netlib README +mv -i makefile.netlib makefile +cd .. + +cd .. + +mv -iv $dir $newdir diff --git a/gnu/usr.bin/gcc/contrib/convert_to_g2c b/gnu/usr.bin/gcc/contrib/convert_to_g2c new file mode 100755 index 00000000000..5d05f84e393 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/convert_to_g2c @@ -0,0 +1,48 @@ +#!/bin/sh +# +# convert_to_g2c [f2c-dir] +# +# Renames certain files in a netlib f2c directory so they have the `.netlib' +# suffix, a la g77's version of f2c (libg2c). If `f2c-dir' is not specified, +# `f2c-YYYYMMDD' is the default, where YYYYMMDD is the current date. +# The directory is renamed such that the first `f' becomes a `g', +# usually `f2c-YYYYMMDD' -> `g2c-YYYYMMDD'. +# +# (C) 1999 Free Software Foundation +# Originally by James Craig Burley <craig@jcb-sc.com>, September 1999. +# +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html + +set -e + +if [ x$1 = x ] +then + dir=f2c-`date +%Y%m%d` +else + dir=$1 +fi + +newdir=`echo $dir | sed -e "s:f:g:"` + +cd $dir + +set +e + +mv -i changes changes.netlib +mv -i disclaimer disclaimer.netlib +mv -i f2c.h g2c.hin +mv -i permission permission.netlib +mv -i readme readme.netlib +cd libF77 +mv -i README README.netlib +mv -i makefile makefile.netlib +cd ../libI77 +mv -i README README.netlib +mv -i makefile makefile.netlib +cd .. + +cd .. + +mv -iv $dir $newdir diff --git a/gnu/usr.bin/gcc/contrib/download_f2c b/gnu/usr.bin/gcc/contrib/download_f2c new file mode 100755 index 00000000000..159c52e7d87 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/download_f2c @@ -0,0 +1,77 @@ +#!/bin/sh +# +# download_f2c +# +# Unpacks a directory full of f2c stuff obtained from netlib, naming +# the directory f2c-YYYYMMDD (YYYYMMDD being the current date), +# leaving it in current working directory. +# +# This shell script downloads the tarball from netlib, unpacks everything, +# and strips off the redundant files, leaving a bare-bones (but fully +# reproducible) f2c source directory. (You must have yacc/bison to rebuild +# gram.c, by the way.) +# +# (C) 1999 Free Software Foundation +# Originally by James Craig Burley <craig@jcb-sc.com>, September 1999. +# +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html +# +# FIXME: Replace WHOAMI with whatever is the canonical way to +# obtain the user's email address these days. + +dir=f2c-`date +%Y%m%d` +if [ ! -d $dir ] +then + mkdir $dir +fi +cd $dir + +echo Preparing $dir... + +if [ ! -d tmp ] +then + mkdir tmp +fi + +if [ ! -f tmp/f2c.tar ] +then + cd tmp + echo Downloading f2c.tar via ftp... + ftp -n netlib.bell-labs.com <<EOF + user ftp WHOAMI + type binary + cd netlib + get f2c.tar + quit +EOF + cd .. +fi + +echo Unpacking f2c.tar... + +tar xf tmp/f2c.tar +cd f2c +find . -name "*.gz" -print | sed -e "s:^\(.*\).gz:rm -f \1.Z:g" | sh +mv src libf77.gz libi77.gz f2c.1t.gz f2c.h.gz changes.gz disclaimer.gz readme.gz permission.gz .. +cd .. +rm -fr f2c +gunzip *.gz +(cd src; rm -f MD5 MD5.gz gram.c.gz .depend .depend.gz f2c.1.gz index.html index.html.gz; gunzip *.gz) +sh libf77 > /dev/null && rm libf77 +rm -f libF77/xsum0.out libF77/libF77.xsum +sh libi77 > /dev/null && rm libi77 +rm -f libI77/xsum0.out libI77/libI77.xsum +rm -f src/xsum0.out +touch src/xsum.out +cmp f2c.h src/f2c.h && rm -fv src/f2c.h +cmp src/readme src/README && rm -fv src/readme + +echo Deleting f2c.tar... +rm tmp/f2c.tar +rmdir tmp + +cd .. + +echo Latest f2c now in $dir. diff --git a/gnu/usr.bin/gcc/contrib/gcc_build b/gnu/usr.bin/gcc/contrib/gcc_build new file mode 100755 index 00000000000..416835c2ccc --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/gcc_build @@ -0,0 +1,320 @@ +#! /bin/sh + +######################################################################## +# +# File: gcc_build +# Author: Mark Mitchell +# Date: 07/10/2000 +# +# Contents: +# Script to automatically download and build GCC. +# +# Copyright (c) 2000, 2001 Free Software Foundation. +# +# This file is part of GNU CC. +# +# GNU CC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU CC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU CC; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +######################################################################## + +######################################################################## +# Notes +######################################################################## + +# If you are using password-based CVS, you must manually log in, and +# not log out from, the CVS server before running this script. + +# You can set the following variables in the environment. They +# have no corresponding command-line options because they should +# only be needed infrequently: +# +# MAKE The path to `make'. + +######################################################################## +# Functions +######################################################################## + +# Issue the error message given by $1 and exit with a non-zero +# exit code. + +error() { + echo "gcc_build: error: $1" + exit 1 +} + +# Issue a usage message explaining how to use this script. + +usage() { +cat <<EOF +gcc_build [-c configure_options] + [-d destination_directory] + [-m make_boot_options] + [-o objdir] + [-u username] + [-p protocol] + [-t tarfile] + [-x make_check_options] + [bootstrap] + [build] + [checkout] + [configure] + [export] + [install] + [test] + [update] +EOF + exit 1 +} + +# Change to the directory given by $1. + +changedir() { + cd $1 || \ + error "Could not change directory to $1" +} + +# Set up CVS environment variables + +cvs_setup() { + CVSROOT=":${CVS_PROTOCOL}:${CVS_USERNAME}@" + CVSROOT="${CVSROOT}${CVS_SERVER}:${CVS_REPOSITORY}" + export CVSROOT +} + +# Checkout a fresh copy of the GCC build tree. + +checkout_gcc() { + # Tell CVS where to find everything. + cvs_setup + + # If the destination already exists, don't risk destroying it. + test -e ${DESTINATION} && \ + error "${DESTINATION} already exists" + + # CVS doesn't allow an absolute path for the destination directory. + DESTINATION_PARENT=`dirname ${DESTINATION}` + test -d ${DESTINATION_PARENT} || \ + error "${DESTINATION_PARENT} is not a directory" + changedir ${DESTINATION_PARENT} + + # Checkout the tree + cvs -z 9 co -d `basename ${DESTINATION}` gcc || \ + error "Could not check out GCC" +} + +# Update GCC. + +update_gcc() { + # Tell CVS where to find everything + cvs_setup + + # If the destination does not already exist, complain. + test -d ${DESTINATION} || \ + error "{$DESTINATION} does not exist" + # Enter the destination directory. + changedir ${DESTINATION} + + # Update the tree + ./contrib/gcc_update -d || \ + error "Could not update GCC" +} + +# Configure for a build of GCC. + +configure_gcc() { + # Go to the source directory. + changedir ${DESTINATION} + + # Remove the object directory. + rm -rf ${OBJDIR} + # Create it again. + mkdir ${OBJDIR} || \ + error "Could not create ${OBJDIR}" + # Enter it. + changedir ${OBJDIR} + + # Configure the tree. + echo "Configuring: ${DESTINATION}/configure ${CONFIGURE_OPTIONS}" + eval ${DESTINATION}/configure ${CONFIGURE_OPTIONS} || \ + error "Could not configure the compiler" +} + +# Bootstrap GCC. Assume configuration has already occurred. + +bootstrap_gcc() { + # Go to the source directory. + changedir ${DESTINATION} + # Go to the object directory. + changedir ${OBJDIR} + + # Bootstrap the compiler + echo "Building: ${MAKE} ${MAKE_BOOTSTRAP_OPTIONS} bootstrap" + eval ${MAKE} ${MAKE_BOOTSTRAP_OPTIONS} bootstrap || \ + error "Could not bootstrap the compiler" +} + +# Test GCC. + +test_gcc() { + # Go to the source directory. + changedir ${DESTINATION} + # Go to the object directory. + changedir ${OBJDIR} + + echo "Running tests... This will take a while." + eval \${MAKE} -k ${MAKE_CHECK_OPTIONS} check + ${DESTINATION}/contrib/test_summary +} + +# Export the GCC source tree. + +export_gcc() { + # Go to the source directory. + changedir ${DESTINATION} + # Go up one level. + changedir .. + # Build a tarball of the source directory. + tar czf ${TARFILE} \ + --exclude=${OBJDIR} \ + --exclude=CVS \ + --exclude='.#*' \ + --exclude='*~' \ + `basename ${DESTINATION}` +} + +# Install GCC. + +install_gcc() { + # Go to the source directory. + changedir ${DESTINATION} + # Go to the object directory. + changedir ${OBJDIR} + + ${MAKE} install || error "Installation failed" +} + +######################################################################## +# Initialization +######################################################################## + +# The CVS server containing the GCC repository. +CVS_SERVER="gcc.gnu.org" +# The path to the repository on that server. +CVS_REPOSITORY="/cvs/gcc" +# The CVS protocol to use. +CVS_PROTOCOL="pserver" +# The username to use when connecting to the server. +CVS_USERNAME="anoncvs" + +# The directory where the checked out GCC will be placed. +DESTINATION="${HOME}/dev/gcc" +# The relative path from the top of the source tree to the +# object directory. +OBJDIR="objdir" + +# The file where the tarred up sources will be placed. +TARFILE="${HOME}/dev/gcc.tgz" + +# Options to pass to configure. +CONFIGURE_OPTIONS= +# The `make' program. +MAKE=${MAKE:-make} +# Options to pass to "make bootstrap". +MAKE_BOOTSTRAP_OPTIONS= +# Options to pass to "make check". +MAKE_CHECK_OPTIONS= + +# Modes of operation +BOOTSTRAP=0 +CHECKOUT=0 +CONFIGURE=0 +EXPORT=0 +INSTALL=0 +TEST=0 +UPDATE=0 + +######################################################################## +# Main Program +######################################################################## + +# Parse the options. +while getopts "c:d:m:o:p:t:u:x:" ARG; do + case $ARG in + c) CONFIGURE_OPTIONS="${OPTARG}";; + d) DESTINATION="${OPTARG}";; + m) MAKE_BOOTSTRAP_OPTIONS="${OPTARG}";; + o) OBJDIR="${OPTARG}";; + p) CVS_PROTOCOL="${OPTARG}";; + t) TARFILE="${OPTARG}";; + x) MAKE_CHECK_OPTIONS="${OPTARG}";; + u) CVS_USERNAME="${OPTARG}";; + \?) usage;; + esac +done +shift `expr ${OPTIND} - 1` + +# Handle the major modes. +while [ $# -ne 0 ]; do + case $1 in + bootstrap) BOOTSTRAP=1;; + build) CONFIGURE=1; BOOTSTRAP=1;; + checkout) CHECKOUT=1;; + configure) CONFIGURE=1;; + export) EXPORT=1;; + install) INSTALL=1;; + test) TEST=1;; + update) UPDATE=1;; + *) usage;; + esac + shift +done + +# Check the arguments for sanity. +if [ ${CHECKOUT} -ne 0 ] && [ ${UPDATE} -ne 0 ]; then + error "Cannot checkout and update simultaneously" +fi + +# Checkout the tree. +if [ ${CHECKOUT} -ne 0 ]; then + checkout_gcc +elif [ ${UPDATE} -ne 0 ]; then + update_gcc +fi + +# Configure to build the tree. +if [ ${CONFIGURE} -ne 0 ]; then + configure_gcc +fi + +# Bootstrap the compiler. +if [ ${BOOTSTRAP} -ne 0 ]; then + bootstrap_gcc +fi + +# Test the compiler +if [ ${TEST} -ne 0 ]; then + test_gcc +fi + +# Install the compiler. +if [ ${INSTALL} -ne 0 ]; then + install_gcc +fi + +# Export the sources +if [ ${EXPORT} -ne 0 ]; then + export_gcc +fi diff --git a/gnu/usr.bin/gcc/contrib/gcc_update b/gnu/usr.bin/gcc/contrib/gcc_update new file mode 100755 index 00000000000..d5ffc5e4a45 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/gcc_update @@ -0,0 +1,237 @@ +#! /bin/sh +# +# Update a local CVS tree from the GCC repository, with an emphasis +# on treating generated files correctly, so that autoconf, gperf et +# al are not required for the ``end'' user. +# +# By default all command-line options are passed to `cvs update` in +# addition to $UPDATE_OPTIONS (defined below). If the first parameter +# reads --nostdflags, $UPDATE_OPTIONS as well as this parameter itself +# are omitted. +# +# If the first parameter reads --patch, the second parameter is considered +# a patch file. +# +# If the first parameter is --touch, no cvs operation will be performed, +# only generated files that appear to be out of date in the local tree +# will be touched. +# +# If the first parameter is --list, a list of the generated files and +# their dependencies will be printed; --help prints this message. +# +# Examples: +# +# contrib/gcc_update -r gcc_latest_snapshot +# contrib/gcc_update -A +# contrib/gcc_update --nostdflags -P -r gcc-2_95-branch gcc/testsuite +# contrib/gcc_update --patch some-patch +# contrib/gcc_update --touch +# contrib/gcc_update --list +# +# +# (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation +# Originally by Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>, August 1998. +# +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html + + +# Default options used when updating via CVS. +UPDATE_OPTIONS=-Pd +# Use -P to prune empty directories. +# Use -d to create any directories that exist in the repository but not +# locally. +# Use -A to reset any sticky tags, dates, or `-k' options. + +######## Anything below shouldn't be changed by regular users. + +# Arrange for the value of $0 to be available for functions +self=$0 + +# This function prints a list of all generated files, along with their +# dependencies. Note that only one target is supported per line: the +# colon is stripped from the output. +files_and_dependencies () { + sed -e 's/ *#.*//' -e '/^$/d' -e 's/://' <<\EOF +# All automake dependencies within texinfo +# In fact, not all, since we do not care about sub-directories that +# we do not build. In particular, *.po and *.gmo are not touched. +texinfo/aclocal.m4: texinfo/configure.in texinfo/acinclude.m4 +texinfo/Makefile.in: texinfo/Makefile.am texinfo/configure.in texinfo/aclocal.m4 +texinfo/configure: texinfo/configure.in texinfo/aclocal.m4 +texinfo/stamp-h.in: texinfo/configure.in texinfo/aclocal.m4 texinfo/acconfig.h +texinfo/lib/Makefile.in: texinfo/lib/Makefile.am texinfo/configure.in texinfo/aclocal.m4 +texinfo/makeinfo/Makefile.in: texinfo/makeinfo/Makefile.am texinfo/configure.in texinfo/aclocal.m4 +texinfo/util/Makefile.in: texinfo/util/Makefile.am texinfo/configure.in texinfo/aclocal.m4 +# Now, proceed to gcc automatically generated files +gcc/configure: gcc/configure.in +gcc/cstamp-h.in: gcc/configure.in gcc/acconfig.h +gcc/config.in: gcc/cstamp-h.in +gcc/fixinc/fixincl.x: gcc/fixinc/fixincl.tpl gcc/fixinc/inclhack.def +gcc/intl/plural.c: gcc/intl/plural.y +# And then, language-specific files +gcc/f/intdoc.texi: gcc/f/intdoc.in gcc/f/intdoc.c gcc/f/intrin.h gcc/f/intrin.def +gcc/cp/cfns.h: gcc/cp/cfns.gperf +gcc/java/keyword.h: gcc/java/keyword.gperf +gcc/ada/treeprs.ads: gcc/ada/treeprs.adt gcc/ada/sinfo.ads gcc/ada/xtreeprs.adb +gcc/ada/einfo.h: gcc/ada/einfo.ads gcc/ada/einfo.adb gcc/ada/xeinfo.adb +gcc/ada/sinfo.h: gcc/ada/sinfo.ads gcc/ada/xsinfo.adb +gcc/ada/nmake.adb: gcc/ada/sinfo.ads gcc/ada/nmake.adt gcc/ada/xnmake.adb +gcc/ada/nmake.ads: gcc/ada/sinfo.ads gcc/ada/nmake.adt gcc/ada/xnmake.adb +gcc/ada/gnat_ug_unx.texi: gcc/ada/gnat_ug.texi gcc/ada/xgnatug.adb gcc/ada/ug_words +gcc/ada/gnat_ug_vms.texi: gcc/ada/gnat_ug.texi gcc/ada/xgnatug.adb gcc/ada/ug_words +gcc/ada/gnat_ug_vxw.texi: gcc/ada/gnat_ug.texi gcc/ada/xgnatug.adb gcc/ada/ug_words +gcc/ada/gnat_ug_w32.texi: gcc/ada/gnat_ug.texi gcc/ada/xgnatug.adb gcc/ada/ug_words +# testsuite +# Without this, _Pragma3.c can have a false negative. +gcc/testsuite/gcc.dg/cpp/_Pragma3.c: gcc/testsuite/gcc.dg/cpp/mi1c.h +# And libraries, at last +libf2c/configure: libf2c/configure.in +libf2c/libF77/configure: libf2c/libF77/configure.in +libf2c/libI77/configure: libf2c/libI77/configure.in +libf2c/libI77/stamp-h.in: libf2c/libI77/configure.in +libf2c/libI77/config.h.in: libf2c/libI77/configure.in libf2c/libI77/stamp-h.in +libf2c/libU77/configure: libf2c/libU77/configure.in +libf2c/libU77/stamp-h.in: libf2c/libU77/configure.in libf2c/libU77/acconfig.h +libobjc/configure: libobjc/configure.in +# fastjar +fastjar/aclocal.m4: fastjar/configure.in +fastjar/Makefile.in: fastjar/Makefile.am fastjar/configure.in fastjar/aclocal.m4 +fastjar/configure: fastjar/configure.in fastjar/aclocal.m4 +fastjar/stamp-h.in: fastjar/configure.in fastjar/aclocal.m4 +boehm-gc/aclocal.m4: boehm-gc/configure.in boehm-gc/acinclude.m4 +boehm-gc/Makefile.in: boehm-gc/Makefile.am boehm-gc/configure.in boehm-gc/aclocal.m4 +boehm-gc/configure: boehm-gc/configure.in boehm-gc/aclocal.m4 +libjava/aclocal.m4: libjava/configure.in libjava/acinclude.m4 +libjava/Makefile.in: libjava/Makefile.am libjava/configure.in libjava/aclocal.m4 +libjava/configure: libjava/configure.in libjava/aclocal.m4 +libjava/libltdl/aclocal.m4: libjava/libltdl/configure.in libjava/libltdl/acinclude.m4 +libjava/libltdl/Makefile.in: libjava/libltdl/Makefile.am libjava/libltdl/configure.in libjava/libltdl/aclocal.m4 +libjava/libltdl/configure: libjava/libltdl/configure.in libjava/libltdl/aclocal.m4 +libjava/libltdl/stamp-h.in: libjava/libltdl/configure.in libjava/libltdl/aclocal.m4 libjava/libltdl/acconfig.h +# Top level +Makefile.in: Makefile.tpl Makefile.def +EOF +} + + +# This function touches generated files such that the ``end'' user does +# not have to rebuild them. +touch_files () { + rm -f Makefile.$$ + echo 'all: \' > Makefile.$$ + files_and_dependencies | sed 's, .*, \\,' >> Makefile.$$ + echo '; @true' >> Makefile.$$ + files_and_dependencies | sed 's, ,: ,' >> Makefile.$$ + files_and_dependencies | sed 's, .*, \\,' >> Makefile.$$ + echo ':' >> Makefile.$$ + echo ' @for f in $? $@; do test -f $$f || exit 0; done; \' >> Makefile.$$ + echo ' echo Touching $@...; \' >> Makefile.$$ + echo ' echo Touching $@... 1>&2; \' >> Makefile.$$ + echo ' touch $@' >> Makefile.$$ + files_and_dependencies | sed 's,[^ ]* ,,;s,$, :,' >> Makefile.$$ + while ${MAKE-make} -s -f Makefile.$$ all | grep . > /dev/null; do + sleep 1 + done 2>&1 + rm -f Makefile.$$ +} + + +# Whenever we update the tree or install a patch, we may be modifying +# this script. By re-execing it, we ensure that the appropriate +# dependencies and rules will be used. +touch_files_reexec () { + echo "Adjusting file timestamps" + exec ${CONFIG_SHELL-/bin/sh} $self --touch +} + +# This functions applies a patch to an existing tree. +apply_patch () { + if [ -f $1 ]; then + echo "Applying patch file $1" + case "$1" in + *gz) + gzip -d -c $1 | patch -p1 ;; + *bz2) + bzip2 -d -c $1 | patch -p1 ;; + *) + cat $1 | patch -p1 ;; + esac + fi + touch_files_reexec +} + +# Check whether this indeed looks like a local tree. +if [ ! -f gcc/version.c ]; then + echo "This does not seem to be a GCC tree!" + exit +fi + +case "$1" in +# First of all, check whether we are going to process a patch. +--patch) + if test "$#" != 2; then + echo "$1" expects only one argument >&2 + exit 1 + fi + apply_patch "${2}" + exit $? + ;; + +--touch) + if test "$#" != 1; then + echo "$1" does not expect any argument >&2 + exit 1 + fi + touch_files + exit $? + ;; + +--list) + if test "$#" != 1; then + echo "$1" does not expect any argument >&2 + exit 1 + fi + files_and_dependencies | sed 's/ /: /' + exit $? + ;; + +--help) + sed -e '1,2d' -e '/^UPDATE_OPTIONS=/{i\ +\ + +p +}' \ + -e '/^$/,$d' -e 's/#//' -e 's/^ //' < $0 + exit $? + ;; + +esac + +# Check whether this indeed looks like a local CVS tree. +if [ ! -d CVS ]; then + echo "This does not seem to be a GCC CVS tree!" + exit +fi + +# Check command-line options +if [ x"${1}"x = x"--nostdflags"x ]; then + shift +else + set -- $UPDATE_OPTIONS ${1+"$@"} +fi + +echo "Updating CVS tree" +cvs -q update ${1+"$@"} +if [ $? -ne 0 ]; then + (touch_files_reexec) + echo "CVS update of full tree failed." >&2 + exit 1 +fi + +{ + date + TZ=UTC date +} > LAST_UPDATED +touch_files_reexec diff --git a/gnu/usr.bin/gcc/contrib/gccbug.el b/gnu/usr.bin/gcc/contrib/gccbug.el new file mode 100644 index 00000000000..55821e5e6c5 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/gccbug.el @@ -0,0 +1,84 @@ +;;; gccbug.el --- forward bug reports to gnats +;; (C) 2000 Free Software Foundation +;; Written by Martin v. Löwis +;; Usage: +;; In rmail, bind a key to rmail-gccbug-reply, e.g. +;; (require 'rmail) +;; (require 'gccbug) +;; (define-key rmail-mode-map "R" 'rmail-gccbug-reply) +;; Then, when reviewing a report, type R to create a gnats-formatted +;; message. + +(provide 'gccbug) + +(defun gccbug-reply () + (interactive) + (let ((orig-yank-prefix mail-yank-prefix)) + (insert ">Submitter-Id: net\n") + (insert ">Originator: \n") + (insert ">Confidential: no\n") + (insert ">Synopsis: ") + (save-excursion + (mail-subject) + (let ((stop (point))) + (re-search-backward "Re: ") + (copy-region-as-kill (match-end 0) stop))) + (yank) + (insert "\n") + (insert ">Severity: serious\n") + (insert ">Priority: medium\n") + (insert ">Category: \n") + (insert ">Class: \n") + ;(insert ">State: analyzed\n") + (insert ">Release: 2.95.2\n") + (insert ">Environment:\n") + (insert ">Description:\n") + (set 'mail-yank-prefix nil) + (set 'mail-yank-ignored-headers + "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:\\|^X-.*:\\|^User-Agent:\\|^MIME-Version:\\|^Content-.*:\\|^List-.*:\\|C[Cc]:\\|^Precedence:\\|^Sender:\\|^Mailing-List:\\|^Delivered-To:\\|^>From") + (mail-yank-original t) + (set 'mail-yank-prefix orig-yank-prefix) + ; Copy From: field to Originator: + (re-search-backward "From: ") + (let ((beg (match-end 0))) + (end-of-line) + (kill-region beg (point))) + (re-search-backward ">Originator: ") + (goto-char (match-end 0)) + (yank) + ; Kill From: line + (re-search-forward "From:") + (beginning-of-line) + (kill-line 1) + ; Replace Message-ID: with Original-Message-ID + (beginning-of-buffer) + (re-search-forward "Message-ID: .*") + (replace-match "Original-\\&") + ; Replace To: line, adding recipient to Notify list + (mail-to) + (re-search-backward "To: ") + (replace-match "To: gcc-gnats@gcc.gnu.org\nX-GNATS-Notify: ") + ; add additional fields + (end-of-buffer) + (insert ">How-To-Repeat: \n>Fix: \n") + ; See whether an Organization: is present + (let ((org (re-search-backward "Organization:.*" nil t))) + (if org + (progn + (kill-region (point) (match-end 0)) + (re-search-backward ">Confidential") + (insert ">") + (yank) + (insert "\n")))) +; This kills CC: lines, but rmail-reply below won't create any +; (mail-cc) +; (beginning-of-line) +; (kill-line 1) + )) + +(defun rmail-gccbug-reply () + (interactive) + (rmail-toggle-header 0) + (rmail-reply t) + (gccbug-reply)) + diff --git a/gnu/usr.bin/gcc/contrib/gennews b/gnu/usr.bin/gcc/contrib/gennews new file mode 100755 index 00000000000..2dcb3442df2 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/gennews @@ -0,0 +1,57 @@ +#! /bin/sh +# +# Script to generate the NEWS file from online release notes. +# Contributed by Joseph Myers <jsm28@cam.ac.uk>. +# +# Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +# This file is part of GNU CC. +# +# GNU CC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU CC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU CC; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +website=http://gcc.gnu.org/ +files="gcc-3.3/index.html gcc-3.3/changes.html + gcc-3.2/index.html gcc-3.2/changes.html + gcc-3.1/index.html gcc-3.1/changes.html + gcc-3.0/gcc-3.0.html gcc-3.0/features.html gcc-3.0/caveats.html + gcc-2.95/index.html gcc-2.95/features.html gcc-2.95/caveats.html + egcs-1.1/index.html egcs-1.1/features.html egcs-1.1/caveats.html + egcs-1.0/egcs-1.0.3.html egcs-1.0/egcs-1.0.2.html egcs-1.0/egcs-1.0.1.html + egcs-1.0/egcs-1.0.html egcs-1.0/features.html egcs-1.0/caveats.html" + +set -e + +cat <<EOF +This file contains information about GCC releases which has been generated +automatically from the online release notes. It covers releases of GCC +(and the former EGCS project) since EGCS 1.0, on the line of development +that led to GCC 3. For information on GCC 2.8.1 and older releases of GCC 2, +see ONEWS. + +EOF + +header="======================================================================" + +echo $header + +for file in $files; do + wfile=$website$file + echo $wfile + # We lie to Lynx about the kind of terminal in use because we + # want to get consistent output everywhere, and we want this + # script to work even when it is not run interactively. + env TERM=vt100 lynx -dump $wfile + echo $header +done diff --git a/gnu/usr.bin/gcc/contrib/index-prop b/gnu/usr.bin/gcc/contrib/index-prop new file mode 100755 index 00000000000..1ea648989f6 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/index-prop @@ -0,0 +1,26 @@ +#! /usr/bin/perl -wi +# Fix up the output of cvs diff -c so that it works with patch. +# We do this by propagating the full pathname from the Index: line +# into the diff itself. +# +# Thrown together by Jason Merrill <jason@cygnus.com> + +while (<>) +{ + if (/^Index: (.*)/) + { + $full = $1; + print; + for (1..7) + { + $_ = <>; + s/^([-+*]{3}) [^\t]+\t/$1 $full\t/ + unless m{ /dev/null\t}; + print; + } + } + else + { + print; + } +} diff --git a/gnu/usr.bin/gcc/contrib/newcvsroot b/gnu/usr.bin/gcc/contrib/newcvsroot new file mode 100755 index 00000000000..43e8e079c0b --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/newcvsroot @@ -0,0 +1,34 @@ +#! /usr/bin/env bash +# Written by Roland McGrath <roland@gnu.org> + +# Replaces all CVS/Root and CVS/Repository files in a checked-out CVS +# tree. Requires shell with # and % variable substitution (e.g. bash). + +# Usage: newcvsroot <newroot> <modulename> <toplevel directory> + +if [ $# != 3 ]; then + echo "usage: `basename $0` <newroot> <modulename> <toplevel directory>" + exit 1 +fi + +root=$1; shift +module=$1; shift +topdir=$1; shift + +rep=${root##*:} + +case "$topdir" in +/*|./*|../*) echo >&2 "$0 wants relative path from top of checkout"; exit 1;; +esac + +find $topdir \( -name Repository -o -name Root \) -print | while read f; do + +case "$f" in +*/CVS/Root) echo $root > "$f" ;; +*/CVS/Repository) + r=${module}${f#${topdir}} + echo > "$f" $rep/${r%/CVS/Repository} + ;; +esac + +done diff --git a/gnu/usr.bin/gcc/contrib/paranoia.cc b/gnu/usr.bin/gcc/contrib/paranoia.cc new file mode 100644 index 00000000000..694d3d4509b --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/paranoia.cc @@ -0,0 +1,2716 @@ +/* A C version of Kahan's Floating Point Test "Paranoia" + +Thos Sumner, UCSF, Feb. 1985 +David Gay, BTL, Jan. 1986 + +This is a rewrite from the Pascal version by + +B. A. Wichmann, 18 Jan. 1985 + +(and does NOT exhibit good C programming style). + +Adjusted to use Standard C headers 19 Jan. 1992 (dmg); + +(C) Apr 19 1983 in BASIC version by: +Professor W. M. Kahan, +567 Evans Hall +Electrical Engineering & Computer Science Dept. +University of California +Berkeley, California 94720 +USA + +converted to Pascal by: +B. A. Wichmann +National Physical Laboratory +Teddington Middx +TW11 OLW +UK + +converted to C by: + +David M. Gay and Thos Sumner +AT&T Bell Labs Computer Center, Rm. U-76 +600 Mountain Avenue University of California +Murray Hill, NJ 07974 San Francisco, CA 94143 +USA USA + +with simultaneous corrections to the Pascal source (reflected +in the Pascal source available over netlib). +[A couple of bug fixes from dgh = sun!dhough incorporated 31 July 1986.] + +Reports of results on various systems from all the versions +of Paranoia are being collected by Richard Karpinski at the +same address as Thos Sumner. This includes sample outputs, +bug reports, and criticisms. + +You may copy this program freely if you acknowledge its source. +Comments on the Pascal version to NPL, please. + +The following is from the introductory commentary from Wichmann's work: + +The BASIC program of Kahan is written in Microsoft BASIC using many +facilities which have no exact analogy in Pascal. The Pascal +version below cannot therefore be exactly the same. Rather than be +a minimal transcription of the BASIC program, the Pascal coding +follows the conventional style of block-structured languages. Hence +the Pascal version could be useful in producing versions in other +structured languages. + +Rather than use identifiers of minimal length (which therefore have +little mnemonic significance), the Pascal version uses meaningful +identifiers as follows [Note: A few changes have been made for C]: + + +BASIC C BASIC C BASIC C + +A J S StickyBit +A1 AInverse J0 NoErrors T +B Radix [Failure] T0 Underflow +B1 BInverse J1 NoErrors T2 ThirtyTwo +B2 RadixD2 [SeriousDefect] T5 OneAndHalf +B9 BMinusU2 J2 NoErrors T7 TwentySeven +C [Defect] T8 TwoForty +C1 CInverse J3 NoErrors U OneUlp +D [Flaw] U0 UnderflowThreshold +D4 FourD K PageNo U1 +E0 L Milestone U2 +E1 M V +E2 Exp2 N V0 +E3 N1 V8 +E5 MinSqEr O Zero V9 +E6 SqEr O1 One W +E7 MaxSqEr O2 Two X +E8 O3 Three X1 +E9 O4 Four X8 +F1 MinusOne O5 Five X9 Random1 +F2 Half O8 Eight Y +F3 Third O9 Nine Y1 +F6 P Precision Y2 +F9 Q Y9 Random2 +G1 GMult Q8 Z +G2 GDiv Q9 Z0 PseudoZero +G3 GAddSub R Z1 +H R1 RMult Z2 +H1 HInverse R2 RDiv Z9 +I R3 RAddSub +IO NoTrials R4 RSqrt +I3 IEEE R9 Random9 + +SqRWrng + +All the variables in BASIC are true variables and in consequence, +the program is more difficult to follow since the "constants" must +be determined (the glossary is very helpful). The Pascal version +uses Real constants, but checks are added to ensure that the values +are correctly converted by the compiler. + +The major textual change to the Pascal version apart from the +identifiersis that named procedures are used, inserting parameters +wherehelpful. New procedures are also introduced. The +correspondence is as follows: + + +BASIC Pascal +lines + +90- 140 Pause +170- 250 Instructions +380- 460 Heading +480- 670 Characteristics +690- 870 History +2940-2950 Random +3710-3740 NewD +4040-4080 DoesYequalX +4090-4110 PrintIfNPositive +4640-4850 TestPartialUnderflow + +*/ + + /* This version of paranoia has been modified to work with GCC's internal + software floating point emulation library, as a sanity check of same. + + I'm doing this in C++ so that I can do operator overloading and not + have to modify so damned much of the existing code. */ + + extern "C" { +#include <stdio.h> +#include <stddef.h> +#include <limits.h> +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <unistd.h> +#include <float.h> + + /* This part is made all the more awful because many gcc headers are + not prepared at all to be parsed as C++. The biggest stickler + here is const structure members. So we include exactly the pieces + that we need. */ + +#define GTY(x) + +#include "ansidecl.h" +#include "auto-host.h" +#include "hwint.h" + +#undef EXTRA_MODES_FILE + + struct rtx_def; + typedef struct rtx_def *rtx; + struct rtvec_def; + typedef struct rtvec_def *rtvec; + union tree_node; + typedef union tree_node *tree; + +#define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM, + enum tree_code { +#include "tree.def" + LAST_AND_UNUSED_TREE_CODE + }; +#undef DEFTREECODE + +#define ENUM_BITFIELD(X) enum X +#define class klass + +#include "real.h" + +#undef class + } + +/* We never produce signals from the library. Thus setjmp need do nothing. */ +#undef setjmp +#define setjmp(x) (0) + +static bool verbose = false; +static int verbose_index = 0; + +/* ====================================================================== */ +/* The implementation of the abstract floating point class based on gcc's + real.c. I.e. the object of this excersize. Templated so that we can + all fp sizes. */ + +class real_c_float +{ + public: + static const enum machine_mode MODE = SFmode; + + private: + static const int external_max = 128 / 32; + static const int internal_max + = (sizeof (REAL_VALUE_TYPE) + sizeof (long) + 1) / sizeof (long); + long image[external_max < internal_max ? internal_max : external_max]; + + void from_long(long); + void from_str(const char *); + void binop(int code, const real_c_float&); + void unop(int code); + bool cmp(int code, const real_c_float&) const; + + public: + real_c_float() + { } + real_c_float(long l) + { from_long(l); } + real_c_float(const char *s) + { from_str(s); } + real_c_float(const real_c_float &b) + { memcpy(image, b.image, sizeof(image)); } + + const real_c_float& operator= (long l) + { from_long(l); return *this; } + const real_c_float& operator= (const char *s) + { from_str(s); return *this; } + const real_c_float& operator= (const real_c_float &b) + { memcpy(image, b.image, sizeof(image)); return *this; } + + const real_c_float& operator+= (const real_c_float &b) + { binop(PLUS_EXPR, b); return *this; } + const real_c_float& operator-= (const real_c_float &b) + { binop(MINUS_EXPR, b); return *this; } + const real_c_float& operator*= (const real_c_float &b) + { binop(MULT_EXPR, b); return *this; } + const real_c_float& operator/= (const real_c_float &b) + { binop(RDIV_EXPR, b); return *this; } + + real_c_float operator- () const + { real_c_float r(*this); r.unop(NEGATE_EXPR); return r; } + real_c_float abs () const + { real_c_float r(*this); r.unop(ABS_EXPR); return r; } + + bool operator < (const real_c_float &b) const { return cmp(LT_EXPR, b); } + bool operator <= (const real_c_float &b) const { return cmp(LE_EXPR, b); } + bool operator == (const real_c_float &b) const { return cmp(EQ_EXPR, b); } + bool operator != (const real_c_float &b) const { return cmp(NE_EXPR, b); } + bool operator >= (const real_c_float &b) const { return cmp(GE_EXPR, b); } + bool operator > (const real_c_float &b) const { return cmp(GT_EXPR, b); } + + const char * str () const; + const char * hex () const; + long integer () const; + int exp () const; + void ldexp (int); +}; + +void +real_c_float::from_long (long l) +{ + REAL_VALUE_TYPE f; + + real_from_integer (&f, MODE, l, l < 0 ? -1 : 0, 0); + real_to_target (image, &f, MODE); +} + +void +real_c_float::from_str (const char *s) +{ + REAL_VALUE_TYPE f; + const char *p = s; + + if (*p == '-' || *p == '+') + p++; + if (strcasecmp(p, "inf") == 0) + { + real_inf (&f); + if (*s == '-') + real_arithmetic (&f, NEGATE_EXPR, &f, NULL); + } + else if (strcasecmp(p, "nan") == 0) + real_nan (&f, "", 1, MODE); + else + real_from_string (&f, s); + + real_to_target (image, &f, MODE); +} + +void +real_c_float::binop (int code, const real_c_float &b) +{ + REAL_VALUE_TYPE ai, bi, ri; + + real_from_target (&ai, image, MODE); + real_from_target (&bi, b.image, MODE); + real_arithmetic (&ri, code, &ai, &bi); + real_to_target (image, &ri, MODE); + + if (verbose) + { + char ab[64], bb[64], rb[64]; + const real_format *fmt = real_format_for_mode[MODE - QFmode]; + const int digits = (fmt->p * fmt->log2_b + 3) / 4; + char symbol_for_code; + + real_from_target (&ri, image, MODE); + real_to_hexadecimal (ab, &ai, sizeof(ab), digits, 0); + real_to_hexadecimal (bb, &bi, sizeof(bb), digits, 0); + real_to_hexadecimal (rb, &ri, sizeof(rb), digits, 0); + + switch (code) + { + case PLUS_EXPR: + symbol_for_code = '+'; + break; + case MINUS_EXPR: + symbol_for_code = '-'; + break; + case MULT_EXPR: + symbol_for_code = '*'; + break; + case RDIV_EXPR: + symbol_for_code = '/'; + break; + default: + abort (); + } + + fprintf (stderr, "%6d: %s %c %s = %s\n", verbose_index++, + ab, symbol_for_code, bb, rb); + } +} + +void +real_c_float::unop (int code) +{ + REAL_VALUE_TYPE ai, ri; + + real_from_target (&ai, image, MODE); + real_arithmetic (&ri, code, &ai, NULL); + real_to_target (image, &ri, MODE); + + if (verbose) + { + char ab[64], rb[64]; + const real_format *fmt = real_format_for_mode[MODE - QFmode]; + const int digits = (fmt->p * fmt->log2_b + 3) / 4; + const char *symbol_for_code; + + real_from_target (&ri, image, MODE); + real_to_hexadecimal (ab, &ai, sizeof(ab), digits, 0); + real_to_hexadecimal (rb, &ri, sizeof(rb), digits, 0); + + switch (code) + { + case NEGATE_EXPR: + symbol_for_code = "-"; + break; + case ABS_EXPR: + symbol_for_code = "abs "; + break; + default: + abort (); + } + + fprintf (stderr, "%6d: %s%s = %s\n", verbose_index++, + symbol_for_code, ab, rb); + } +} + +bool +real_c_float::cmp (int code, const real_c_float &b) const +{ + REAL_VALUE_TYPE ai, bi; + bool ret; + + real_from_target (&ai, image, MODE); + real_from_target (&bi, b.image, MODE); + ret = real_compare (code, &ai, &bi); + + if (verbose) + { + char ab[64], bb[64]; + const real_format *fmt = real_format_for_mode[MODE - QFmode]; + const int digits = (fmt->p * fmt->log2_b + 3) / 4; + const char *symbol_for_code; + + real_to_hexadecimal (ab, &ai, sizeof(ab), digits, 0); + real_to_hexadecimal (bb, &bi, sizeof(bb), digits, 0); + + switch (code) + { + case LT_EXPR: + symbol_for_code = "<"; + break; + case LE_EXPR: + symbol_for_code = "<="; + break; + case EQ_EXPR: + symbol_for_code = "=="; + break; + case NE_EXPR: + symbol_for_code = "!="; + break; + case GE_EXPR: + symbol_for_code = ">="; + break; + case GT_EXPR: + symbol_for_code = ">"; + break; + default: + abort (); + } + + fprintf (stderr, "%6d: %s %s %s = %s\n", verbose_index++, + ab, symbol_for_code, bb, (ret ? "true" : "false")); + } + + return ret; +} + +const char * +real_c_float::str() const +{ + REAL_VALUE_TYPE f; + const real_format *fmt = real_format_for_mode[MODE - QFmode]; + const int digits = int(fmt->p * fmt->log2_b * .30102999566398119521 + 1); + + real_from_target (&f, image, MODE); + char *buf = new char[digits + 10]; + real_to_decimal (buf, &f, digits+10, digits, 0); + + return buf; +} + +const char * +real_c_float::hex() const +{ + REAL_VALUE_TYPE f; + const real_format *fmt = real_format_for_mode[MODE - QFmode]; + const int digits = (fmt->p * fmt->log2_b + 3) / 4; + + real_from_target (&f, image, MODE); + char *buf = new char[digits + 10]; + real_to_hexadecimal (buf, &f, digits+10, digits, 0); + + return buf; +} + +long +real_c_float::integer() const +{ + REAL_VALUE_TYPE f; + real_from_target (&f, image, MODE); + return real_to_integer (&f); +} + +int +real_c_float::exp() const +{ + REAL_VALUE_TYPE f; + real_from_target (&f, image, MODE); + return real_exponent (&f); +} + +void +real_c_float::ldexp (int exp) +{ + REAL_VALUE_TYPE ai; + + real_from_target (&ai, image, MODE); + real_ldexp (&ai, &ai, exp); + real_to_target (image, &ai, MODE); +} + +/* ====================================================================== */ +/* An implementation of the abstract floating point class that uses native + arithmetic. Exists for reference and debugging. */ + +template<typename T> +class native_float +{ + private: + // Force intermediate results back to memory. + volatile T image; + + static T from_str (const char *); + static T do_abs (T); + static T verbose_binop (T, char, T, T); + static T verbose_unop (const char *, T, T); + static bool verbose_cmp (T, const char *, T, bool); + + public: + native_float() + { } + native_float(long l) + { image = l; } + native_float(const char *s) + { image = from_str(s); } + native_float(const native_float &b) + { image = b.image; } + + const native_float& operator= (long l) + { image = l; return *this; } + const native_float& operator= (const char *s) + { image = from_str(s); return *this; } + const native_float& operator= (const native_float &b) + { image = b.image; return *this; } + + const native_float& operator+= (const native_float &b) + { + image = verbose_binop(image, '+', b.image, image + b.image); + return *this; + } + const native_float& operator-= (const native_float &b) + { + image = verbose_binop(image, '-', b.image, image - b.image); + return *this; + } + const native_float& operator*= (const native_float &b) + { + image = verbose_binop(image, '*', b.image, image * b.image); + return *this; + } + const native_float& operator/= (const native_float &b) + { + image = verbose_binop(image, '/', b.image, image / b.image); + return *this; + } + + native_float operator- () const + { + native_float r; + r.image = verbose_unop("-", image, -image); + return r; + } + native_float abs () const + { + native_float r; + r.image = verbose_unop("abs ", image, do_abs(image)); + return r; + } + + bool operator < (const native_float &b) const + { return verbose_cmp(image, "<", b.image, image < b.image); } + bool operator <= (const native_float &b) const + { return verbose_cmp(image, "<=", b.image, image <= b.image); } + bool operator == (const native_float &b) const + { return verbose_cmp(image, "==", b.image, image == b.image); } + bool operator != (const native_float &b) const + { return verbose_cmp(image, "!=", b.image, image != b.image); } + bool operator >= (const native_float &b) const + { return verbose_cmp(image, ">=", b.image, image >= b.image); } + bool operator > (const native_float &b) const + { return verbose_cmp(image, ">", b.image, image > b.image); } + + const char * str () const; + const char * hex () const; + long integer () const + { return long(image); } + int exp () const; + void ldexp (int); +}; + +template<typename T> +inline T +native_float<T>::from_str (const char *s) +{ + return strtold (s, NULL); +} + +template<> +inline float +native_float<float>::from_str (const char *s) +{ + return strtof (s, NULL); +} + +template<> +inline double +native_float<double>::from_str (const char *s) +{ + return strtod (s, NULL); +} + +template<typename T> +inline T +native_float<T>::do_abs (T image) +{ + return fabsl (image); +} + +template<> +inline float +native_float<float>::do_abs (float image) +{ + return fabsf (image); +} + +template<> +inline double +native_float<double>::do_abs (double image) +{ + return fabs (image); +} + +template<typename T> +T +native_float<T>::verbose_binop (T a, char symbol, T b, T r) +{ + if (verbose) + { + const int digits = int(sizeof(T) * CHAR_BIT / 4) - 1; +#ifdef NO_LONG_DOUBLE + fprintf (stderr, "%6d: %.*a %c %.*a = %.*a\n", verbose_index++, + digits, (double)a, symbol, + digits, (double)b, digits, (double)r); +#else + fprintf (stderr, "%6d: %.*La %c %.*La = %.*La\n", verbose_index++, + digits, (long double)a, symbol, + digits, (long double)b, digits, (long double)r); +#endif + } + return r; +} + +template<typename T> +T +native_float<T>::verbose_unop (const char *symbol, T a, T r) +{ + if (verbose) + { + const int digits = int(sizeof(T) * CHAR_BIT / 4) - 1; +#ifdef NO_LONG_DOUBLE + fprintf (stderr, "%6d: %s%.*a = %.*a\n", verbose_index++, + symbol, digits, (double)a, digits, (double)r); +#else + fprintf (stderr, "%6d: %s%.*La = %.*La\n", verbose_index++, + symbol, digits, (long double)a, digits, (long double)r); +#endif + } + return r; +} + +template<typename T> +bool +native_float<T>::verbose_cmp (T a, const char *symbol, T b, bool r) +{ + if (verbose) + { + const int digits = int(sizeof(T) * CHAR_BIT / 4) - 1; +#ifndef NO_LONG_DOUBLE + fprintf (stderr, "%6d: %.*a %s %.*a = %s\n", verbose_index++, + digits, (double)a, symbol, + digits, (double)b, (r ? "true" : "false")); +#else + fprintf (stderr, "%6d: %.*La %s %.*La = %s\n", verbose_index++, + digits, (long double)a, symbol, + digits, (long double)b, (r ? "true" : "false")); +#endif + } + return r; +} + +template<typename T> +const char * +native_float<T>::str() const +{ + char *buf = new char[50]; + const int digits = int(sizeof(T) * CHAR_BIT * .30102999566398119521 + 1); +#ifndef NO_LONG_DOUBLE + sprintf (buf, "%.*e", digits - 1, (double) image); +#else + sprintf (buf, "%.*Le", digits - 1, (long double) image); +#endif + return buf; +} + +template<typename T> +const char * +native_float<T>::hex() const +{ + char *buf = new char[50]; + const int digits = int(sizeof(T) * CHAR_BIT / 4); +#ifndef NO_LONG_DOUBLE + sprintf (buf, "%.*a", digits - 1, (double) image); +#else + sprintf (buf, "%.*La", digits - 1, (long double) image); +#endif + return buf; +} + +template<typename T> +int +native_float<T>::exp() const +{ + int e; + frexp (image, &e); + return e; +} + +template<typename T> +void +native_float<T>::ldexp (int exp) +{ + image = ldexpl (image, exp); +} + +template<> +void +native_float<float>::ldexp (int exp) +{ + image = ldexpf (image, exp); +} + +template<> +void +native_float<double>::ldexp (int exp) +{ + image = ::ldexp (image, exp); +} + +/* ====================================================================== */ +/* Some libm routines that Paranoia expects to be available. */ + +template<typename FLOAT> +inline FLOAT +FABS (const FLOAT &f) +{ + return f.abs(); +} + +template<typename FLOAT, typename RHS> +inline FLOAT +operator+ (const FLOAT &a, const RHS &b) +{ + return FLOAT(a) += FLOAT(b); +} + +template<typename FLOAT, typename RHS> +inline FLOAT +operator- (const FLOAT &a, const RHS &b) +{ + return FLOAT(a) -= FLOAT(b); +} + +template<typename FLOAT, typename RHS> +inline FLOAT +operator* (const FLOAT &a, const RHS &b) +{ + return FLOAT(a) *= FLOAT(b); +} + +template<typename FLOAT, typename RHS> +inline FLOAT +operator/ (const FLOAT &a, const RHS &b) +{ + return FLOAT(a) /= FLOAT(b); +} + +template<typename FLOAT> +FLOAT +FLOOR (const FLOAT &f) +{ + /* ??? This is only correct when F is representable as an integer. */ + long i = f.integer(); + FLOAT r; + + r = i; + if (i < 0 && f != r) + r = i - 1; + + return r; +} + +template<typename FLOAT> +FLOAT +SQRT (const FLOAT &f) +{ +#if 0 + FLOAT zero = long(0); + FLOAT two = 2; + FLOAT one = 1; + FLOAT diff, diff2; + FLOAT z, t; + + if (f == zero) + return zero; + if (f < zero) + return zero / zero; + if (f == one) + return f; + + z = f; + z.ldexp (-f.exp() / 2); + + diff2 = FABS (z * z - f); + if (diff2 > zero) + while (1) + { + t = (f / (two * z)) + (z / two); + diff = FABS (t * t - f); + if (diff >= diff2) + break; + z = t; + diff2 = diff; + } + + return z; +#elif defined(NO_LONG_DOUBLE) + double d; + char buf[64]; + + d = strtod (f.hex(), NULL); + d = sqrt (d); + sprintf(buf, "%.35a", d); + + return FLOAT(buf); +#else + long double ld; + char buf[64]; + + ld = strtold (f.hex(), NULL); + ld = sqrtl (ld); + sprintf(buf, "%.35La", ld); + + return FLOAT(buf); +#endif +} + +template<typename FLOAT> +FLOAT +LOG (FLOAT x) +{ +#if 0 + FLOAT zero = long(0); + FLOAT one = 1; + + if (x <= zero) + return zero / zero; + if (x == one) + return zero; + + int exp = x.exp() - 1; + x.ldexp(-exp); + + FLOAT xm1 = x - one; + FLOAT y = xm1; + long n = 2; + + FLOAT sum = xm1; + while (1) + { + y *= xm1; + FLOAT term = y / FLOAT (n); + FLOAT next = sum + term; + if (next == sum) + break; + sum = next; + if (++n == 1000) + break; + } + + if (exp) + sum += FLOAT (exp) * FLOAT(".69314718055994530941"); + + return sum; +#elif defined (NO_LONG_DOUBLE) + double d; + char buf[64]; + + d = strtod (x.hex(), NULL); + d = log (d); + sprintf(buf, "%.35a", d); + + return FLOAT(buf); +#else + long double ld; + char buf[64]; + + ld = strtold (x.hex(), NULL); + ld = logl (ld); + sprintf(buf, "%.35La", ld); + + return FLOAT(buf); +#endif +} + +template<typename FLOAT> +FLOAT +EXP (const FLOAT &x) +{ + /* Cheat. */ +#ifdef NO_LONG_DOUBLE + double d; + char buf[64]; + + d = strtod (x.hex(), NULL); + d = exp (d); + sprintf(buf, "%.35a", d); + + return FLOAT(buf); +#else + long double ld; + char buf[64]; + + ld = strtold (x.hex(), NULL); + ld = expl (ld); + sprintf(buf, "%.35La", ld); + + return FLOAT(buf); +#endif +} + +template<typename FLOAT> +FLOAT +POW (const FLOAT &base, const FLOAT &exp) +{ + /* Cheat. */ +#ifdef NO_LONG_DOUBLE + double d1, d2; + char buf[64]; + + d1 = strtod (base.hex(), NULL); + d2 = strtod (exp.hex(), NULL); + d1 = pow (d1, d2); + sprintf(buf, "%.35a", d1); + + return FLOAT(buf); +#else + long double ld1, ld2; + char buf[64]; + + ld1 = strtold (base.hex(), NULL); + ld2 = strtold (exp.hex(), NULL); + ld1 = powl (ld1, ld2); + sprintf(buf, "%.35La", ld1); + + return FLOAT(buf); +#endif +} + +/* ====================================================================== */ +/* Real Paranoia begins again here. We wrap the thing in a template so + that we can instantiate it for each floating point type we care for. */ + +int NoTrials = 20; /*Number of tests for commutativity. */ +bool do_pause = false; + +enum Guard { No, Yes }; +enum Rounding { Other, Rounded, Chopped }; +enum Class { Failure, Serious, Defect, Flaw }; + +template<typename FLOAT> +struct Paranoia +{ + FLOAT Radix, BInvrse, RadixD2, BMinusU2; + + /* Small floating point constants. */ + FLOAT Zero; + FLOAT Half; + FLOAT One; + FLOAT Two; + FLOAT Three; + FLOAT Four; + FLOAT Five; + FLOAT Eight; + FLOAT Nine; + FLOAT TwentySeven; + FLOAT ThirtyTwo; + FLOAT TwoForty; + FLOAT MinusOne; + FLOAT OneAndHalf; + + /* Declarations of Variables. */ + int Indx; + char ch[8]; + FLOAT AInvrse, A1; + FLOAT C, CInvrse; + FLOAT D, FourD; + FLOAT E0, E1, Exp2, E3, MinSqEr; + FLOAT SqEr, MaxSqEr, E9; + FLOAT Third; + FLOAT F6, F9; + FLOAT H, HInvrse; + int I; + FLOAT StickyBit, J; + FLOAT MyZero; + FLOAT Precision; + FLOAT Q, Q9; + FLOAT R, Random9; + FLOAT T, Underflow, S; + FLOAT OneUlp, UfThold, U1, U2; + FLOAT V, V0, V9; + FLOAT W; + FLOAT X, X1, X2, X8, Random1; + FLOAT Y, Y1, Y2, Random2; + FLOAT Z, PseudoZero, Z1, Z2, Z9; + int ErrCnt[4]; + int Milestone; + int PageNo; + int M, N, N1; + Guard GMult, GDiv, GAddSub; + Rounding RMult, RDiv, RAddSub, RSqrt; + int Break, Done, NotMonot, Monot, Anomaly, IEEE, SqRWrng, UfNGrad; + + /* Computed constants. */ + /*U1 gap below 1.0, i.e, 1.0-U1 is next number below 1.0 */ + /*U2 gap above 1.0, i.e, 1.0+U2 is next number above 1.0 */ + + int main (); + + FLOAT Sign (FLOAT); + FLOAT Random (); + void Pause (); + void BadCond (int, const char *); + void SqXMinX (int); + void TstCond (int, int, const char *); + void notify (const char *); + void IsYeqX (); + void NewD (); + void PrintIfNPositive (); + void SR3750 (); + void TstPtUf (); + + // Pretend we're bss. + Paranoia() { memset(this, 0, sizeof (*this)); } +}; + +template<typename FLOAT> +int +Paranoia<FLOAT>::main() +{ + /* First two assignments use integer right-hand sides. */ + Zero = long(0); + One = long(1); + Two = long(2); + Three = long(3); + Four = long(4); + Five = long(5); + Eight = long(8); + Nine = long(9); + TwentySeven = long(27); + ThirtyTwo = long(32); + TwoForty = long(240); + MinusOne = long(-1); + Half = "0x1p-1"; + OneAndHalf = "0x3p-1"; + ErrCnt[Failure] = 0; + ErrCnt[Serious] = 0; + ErrCnt[Defect] = 0; + ErrCnt[Flaw] = 0; + PageNo = 1; + /*=============================================*/ + Milestone = 7; + /*=============================================*/ + printf ("Program is now RUNNING tests on small integers:\n"); + + TstCond (Failure, (Zero + Zero == Zero), "0+0 != 0"); + TstCond (Failure, (One - One == Zero), "1-1 != 0"); + TstCond (Failure, (One > Zero), "1 <= 0"); + TstCond (Failure, (One + One == Two), "1+1 != 2"); + + Z = -Zero; + if (Z != Zero) + { + ErrCnt[Failure] = ErrCnt[Failure] + 1; + printf ("Comparison alleges that -0.0 is Non-zero!\n"); + U2 = "0.001"; + Radix = 1; + TstPtUf (); + } + + TstCond (Failure, (Three == Two + One), "3 != 2+1"); + TstCond (Failure, (Four == Three + One), "4 != 3+1"); + TstCond (Failure, (Four + Two * (-Two) == Zero), "4 + 2*(-2) != 0"); + TstCond (Failure, (Four - Three - One == Zero), "4-3-1 != 0"); + + TstCond (Failure, (MinusOne == (Zero - One)), "-1 != 0-1"); + TstCond (Failure, (MinusOne + One == Zero), "-1+1 != 0"); + TstCond (Failure, (One + MinusOne == Zero), "1+(-1) != 0"); + TstCond (Failure, (MinusOne + FABS (One) == Zero), "-1+abs(1) != 0"); + TstCond (Failure, (MinusOne + MinusOne * MinusOne == Zero), + "-1+(-1)*(-1) != 0"); + + TstCond (Failure, Half + MinusOne + Half == Zero, "1/2 + (-1) + 1/2 != 0"); + + /*=============================================*/ + Milestone = 10; + /*=============================================*/ + + TstCond (Failure, (Nine == Three * Three), "9 != 3*3"); + TstCond (Failure, (TwentySeven == Nine * Three), "27 != 9*3"); + TstCond (Failure, (Eight == Four + Four), "8 != 4+4"); + TstCond (Failure, (ThirtyTwo == Eight * Four), "32 != 8*4"); + TstCond (Failure, (ThirtyTwo - TwentySeven - Four - One == Zero), + "32-27-4-1 != 0"); + + TstCond (Failure, Five == Four + One, "5 != 4+1"); + TstCond (Failure, TwoForty == Four * Five * Three * Four, "240 != 4*5*3*4"); + TstCond (Failure, TwoForty / Three - Four * Four * Five == Zero, + "240/3 - 4*4*5 != 0"); + TstCond (Failure, TwoForty / Four - Five * Three * Four == Zero, + "240/4 - 5*3*4 != 0"); + TstCond (Failure, TwoForty / Five - Four * Three * Four == Zero, + "240/5 - 4*3*4 != 0"); + + if (ErrCnt[Failure] == 0) + { + printf ("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n"); + printf ("\n"); + } + printf ("Searching for Radix and Precision.\n"); + W = One; + do + { + W = W + W; + Y = W + One; + Z = Y - W; + Y = Z - One; + } + while (MinusOne + FABS (Y) < Zero); + /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ... */ + Precision = Zero; + Y = One; + do + { + Radix = W + Y; + Y = Y + Y; + Radix = Radix - W; + } + while (Radix == Zero); + if (Radix < Two) + Radix = One; + printf ("Radix = %s .\n", Radix.str()); + if (Radix != One) + { + W = One; + do + { + Precision = Precision + One; + W = W * Radix; + Y = W + One; + } + while ((Y - W) == One); + } + /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1 + ... */ + U1 = One / W; + U2 = Radix * U1; + printf ("Closest relative separation found is U1 = %s .\n\n", U1.str()); + printf ("Recalculating radix and precision\n "); + + /*save old values */ + E0 = Radix; + E1 = U1; + E9 = U2; + E3 = Precision; + + X = Four / Three; + Third = X - One; + F6 = Half - Third; + X = F6 + F6; + X = FABS (X - Third); + if (X < U2) + X = U2; + + /*... now X = (unknown no.) ulps of 1+... */ + do + { + U2 = X; + Y = Half * U2 + ThirtyTwo * U2 * U2; + Y = One + Y; + X = Y - One; + } + while (!((U2 <= X) || (X <= Zero))); + + /*... now U2 == 1 ulp of 1 + ... */ + X = Two / Three; + F6 = X - Half; + Third = F6 + F6; + X = Third - Half; + X = FABS (X + F6); + if (X < U1) + X = U1; + + /*... now X == (unknown no.) ulps of 1 -... */ + do + { + U1 = X; + Y = Half * U1 + ThirtyTwo * U1 * U1; + Y = Half - Y; + X = Half + Y; + Y = Half - X; + X = Half + Y; + } + while (!((U1 <= X) || (X <= Zero))); + /*... now U1 == 1 ulp of 1 - ... */ + if (U1 == E1) + printf ("confirms closest relative separation U1 .\n"); + else + printf ("gets better closest relative separation U1 = %s .\n", U1.str()); + W = One / U1; + F9 = (Half - U1) + Half; + + Radix = FLOOR (FLOAT ("0.01") + U2 / U1); + if (Radix == E0) + printf ("Radix confirmed.\n"); + else + printf ("MYSTERY: recalculated Radix = %s .\n", Radix.str()); + TstCond (Defect, Radix <= Eight + Eight, + "Radix is too big: roundoff problems"); + TstCond (Flaw, (Radix == Two) || (Radix == 10) + || (Radix == One), "Radix is not as good as 2 or 10"); + /*=============================================*/ + Milestone = 20; + /*=============================================*/ + TstCond (Failure, F9 - Half < Half, + "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?"); + X = F9; + I = 1; + Y = X - Half; + Z = Y - Half; + TstCond (Failure, (X != One) + || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0"); + X = One + U2; + I = 0; + /*=============================================*/ + Milestone = 25; + /*=============================================*/ + /*... BMinusU2 = nextafter(Radix, 0) */ + BMinusU2 = Radix - One; + BMinusU2 = (BMinusU2 - U2) + One; + /* Purify Integers */ + if (Radix != One) + { + X = -TwoForty * LOG (U1) / LOG (Radix); + Y = FLOOR (Half + X); + if (FABS (X - Y) * Four < One) + X = Y; + Precision = X / TwoForty; + Y = FLOOR (Half + Precision); + if (FABS (Precision - Y) * TwoForty < Half) + Precision = Y; + } + if ((Precision != FLOOR (Precision)) || (Radix == One)) + { + printf ("Precision cannot be characterized by an Integer number\n"); + printf + ("of significant digits but, by itself, this is a minor flaw.\n"); + } + if (Radix == One) + printf + ("logarithmic encoding has precision characterized solely by U1.\n"); + else + printf ("The number of significant digits of the Radix is %s .\n", + Precision.str()); + TstCond (Serious, U2 * Nine * Nine * TwoForty < One, + "Precision worse than 5 decimal figures "); + /*=============================================*/ + Milestone = 30; + /*=============================================*/ + /* Test for extra-precise subexpressions */ + X = FABS (((Four / Three - One) - One / Four) * Three - One / Four); + do + { + Z2 = X; + X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One; + } + while (!((Z2 <= X) || (X <= Zero))); + X = Y = Z = FABS ((Three / Four - Two / Three) * Three - One / Four); + do + { + Z1 = Z; + Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1)) + + One / Two)) + One / Two; + } + while (!((Z1 <= Z) || (Z <= Zero))); + do + { + do + { + Y1 = Y; + Y = + (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half)) + + Half; + } + while (!((Y1 <= Y) || (Y <= Zero))); + X1 = X; + X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9; + } + while (!((X1 <= X) || (X <= Zero))); + if ((X1 != Y1) || (X1 != Z1)) + { + BadCond (Serious, "Disagreements among the values X1, Y1, Z1,\n"); + printf ("respectively %s, %s, %s,\n", X1.str(), Y1.str(), Z1.str()); + printf ("are symptoms of inconsistencies introduced\n"); + printf ("by extra-precise evaluation of arithmetic subexpressions.\n"); + notify ("Possibly some part of this"); + if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) + printf ("That feature is not tested further by this program.\n"); + } + else + { + if ((Z1 != U1) || (Z2 != U2)) + { + if ((Z1 >= U1) || (Z2 >= U2)) + { + BadCond (Failure, ""); + notify ("Precision"); + printf ("\tU1 = %s, Z1 - U1 = %s\n", U1.str(), (Z1 - U1).str()); + printf ("\tU2 = %s, Z2 - U2 = %s\n", U2.str(), (Z2 - U2).str()); + } + else + { + if ((Z1 <= Zero) || (Z2 <= Zero)) + { + printf ("Because of unusual Radix = %s", Radix.str()); + printf (", or exact rational arithmetic a result\n"); + printf ("Z1 = %s, or Z2 = %s ", Z1.str(), Z2.str()); + notify ("of an\nextra-precision"); + } + if (Z1 != Z2 || Z1 > Zero) + { + X = Z1 / U1; + Y = Z2 / U2; + if (Y > X) + X = Y; + Q = -LOG (X); + printf ("Some subexpressions appear to be calculated " + "extra precisely\n"); + printf ("with about %s extra B-digits, i.e.\n", + (Q / LOG (Radix)).str()); + printf ("roughly %s extra significant decimals.\n", + (Q / LOG (FLOAT (10))).str()); + } + printf + ("That feature is not tested further by this program.\n"); + } + } + } + Pause (); + /*=============================================*/ + Milestone = 35; + /*=============================================*/ + if (Radix >= Two) + { + X = W / (Radix * Radix); + Y = X + One; + Z = Y - X; + T = Z + U2; + X = T - Z; + TstCond (Failure, X == U2, + "Subtraction is not normalized X=Y,X+Z != Y+Z!"); + if (X == U2) + printf ("Subtraction appears to be normalized, as it should be."); + } + printf ("\nChecking for guard digit in *, /, and -.\n"); + Y = F9 * One; + Z = One * F9; + X = F9 - Half; + Y = (Y - Half) - X; + Z = (Z - Half) - X; + X = One + U2; + T = X * Radix; + R = Radix * X; + X = T - Radix; + X = X - Radix * U2; + T = R - Radix; + T = T - Radix * U2; + X = X * (Radix - One); + T = T * (Radix - One); + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) + GMult = Yes; + else + { + GMult = No; + TstCond (Serious, false, "* lacks a Guard Digit, so 1*X != X"); + } + Z = Radix * U2; + X = One + Z; + Y = FABS ((X + Z) - X * X) - U2; + X = One - U2; + Z = FABS ((X - U2) - X * X) - U1; + TstCond (Failure, (Y <= Zero) + && (Z <= Zero), "* gets too many final digits wrong.\n"); + Y = One - U2; + X = One + U2; + Z = One / Y; + Y = Z - X; + X = One / Three; + Z = Three / Nine; + X = X - Z; + T = Nine / TwentySeven; + Z = Z - T; + TstCond (Defect, X == Zero && Y == Zero && Z == Zero, + "Division lacks a Guard Digit, so error can exceed 1 ulp\n" + "or 1/3 and 3/9 and 9/27 may disagree"); + Y = F9 / One; + X = F9 - Half; + Y = (Y - Half) - X; + X = One + U2; + T = X / One; + X = T - X; + if ((X == Zero) && (Y == Zero) && (Z == Zero)) + GDiv = Yes; + else + { + GDiv = No; + TstCond (Serious, false, "Division lacks a Guard Digit, so X/1 != X"); + } + X = One / (One + U2); + Y = X - Half - Half; + TstCond (Serious, Y < Zero, "Computed value of 1/1.000..1 >= 1"); + X = One - U2; + Y = One + Radix * U2; + Z = X * Radix; + T = Y * Radix; + R = Z / Radix; + StickyBit = T / Radix; + X = R - X; + Y = StickyBit - Y; + TstCond (Failure, X == Zero && Y == Zero, + "* and/or / gets too many last digits wrong"); + Y = One - U1; + X = One - F9; + Y = One - Y; + T = Radix - U2; + Z = Radix - BMinusU2; + T = Radix - T; + if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) + GAddSub = Yes; + else + { + GAddSub = No; + TstCond (Serious, false, + "- lacks Guard Digit, so cancellation is obscured"); + } + if (F9 != One && F9 - One >= Zero) + { + BadCond (Serious, "comparison alleges (1-U1) < 1 although\n"); + printf (" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n"); + printf (" such precautions against division by zero as\n"); + printf (" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n"); + } + if (GMult == Yes && GDiv == Yes && GAddSub == Yes) + printf + (" *, /, and - appear to have guard digits, as they should.\n"); + /*=============================================*/ + Milestone = 40; + /*=============================================*/ + Pause (); + printf ("Checking rounding on multiply, divide and add/subtract.\n"); + RMult = Other; + RDiv = Other; + RAddSub = Other; + RadixD2 = Radix / Two; + A1 = Two; + Done = false; + do + { + AInvrse = Radix; + do + { + X = AInvrse; + AInvrse = AInvrse / A1; + } + while (!(FLOOR (AInvrse) != AInvrse)); + Done = (X == One) || (A1 > Three); + if (!Done) + A1 = Nine + One; + } + while (!(Done)); + if (X == One) + A1 = Radix; + AInvrse = One / A1; + X = A1; + Y = AInvrse; + Done = false; + do + { + Z = X * Y - Half; + TstCond (Failure, Z == Half, "X * (1/X) differs from 1"); + Done = X == Radix; + X = Radix; + Y = One / X; + } + while (!(Done)); + Y2 = One + U2; + Y1 = One - U2; + X = OneAndHalf - U2; + Y = OneAndHalf + U2; + Z = (X - U2) * Y2; + T = Y * Y1; + Z = Z - X; + T = T - X; + X = X * Y2; + Y = (Y + U2) * Y1; + X = X - OneAndHalf; + Y = Y - OneAndHalf; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) + { + X = (OneAndHalf + U2) * Y2; + Y = OneAndHalf - U2 - U2; + Z = OneAndHalf + U2 + U2; + T = (OneAndHalf - U2) * Y1; + X = X - (Z + U2); + StickyBit = Y * Y1; + S = Z * Y2; + T = T - Y; + Y = (U2 - Y) + StickyBit; + Z = S - (Z + U2 + U2); + StickyBit = (Y2 + U2) * Y1; + Y1 = Y2 * Y1; + StickyBit = StickyBit - Y2; + Y1 = Y1 - Half; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && (StickyBit == Zero) && (Y1 == Half)) + { + RMult = Rounded; + printf ("Multiplication appears to round correctly.\n"); + } + else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero) + && (T < Zero) && (StickyBit + U2 == Zero) && (Y1 < Half)) + { + RMult = Chopped; + printf ("Multiplication appears to chop.\n"); + } + else + printf ("* is neither chopped nor correctly rounded.\n"); + if ((RMult == Rounded) && (GMult == No)) + notify ("Multiplication"); + } + else + printf ("* is neither chopped nor correctly rounded.\n"); + /*=============================================*/ + Milestone = 45; + /*=============================================*/ + Y2 = One + U2; + Y1 = One - U2; + Z = OneAndHalf + U2 + U2; + X = Z / Y2; + T = OneAndHalf - U2 - U2; + Y = (T - U2) / Y1; + Z = (Z + U2) / Y2; + X = X - OneAndHalf; + Y = Y - T; + T = T / Y1; + Z = Z - (OneAndHalf + U2); + T = (U2 - OneAndHalf) + T; + if (!((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) + { + X = OneAndHalf / Y2; + Y = OneAndHalf - U2; + Z = OneAndHalf + U2; + X = X - Y; + T = OneAndHalf / Y1; + Y = Y / Y1; + T = T - (Z + U2); + Y = Y - Z; + Z = Z / Y2; + Y1 = (Y2 + U2) / Y2; + Z = Z - OneAndHalf; + Y2 = Y1 - Y2; + Y1 = (F9 - U1) / F9; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && (Y2 == Zero) && (Y2 == Zero) && (Y1 - Half == F9 - Half)) + { + RDiv = Rounded; + printf ("Division appears to round correctly.\n"); + if (GDiv == No) + notify ("Division"); + } + else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero) + && (Y2 < Zero) && (Y1 - Half < F9 - Half)) + { + RDiv = Chopped; + printf ("Division appears to chop.\n"); + } + } + if (RDiv == Other) + printf ("/ is neither chopped nor correctly rounded.\n"); + BInvrse = One / Radix; + TstCond (Failure, (BInvrse * Radix - Half == Half), + "Radix * ( 1 / Radix ) differs from 1"); + /*=============================================*/ + Milestone = 50; + /*=============================================*/ + TstCond (Failure, ((F9 + U1) - Half == Half) + && ((BMinusU2 + U2) - One == Radix - One), + "Incomplete carry-propagation in Addition"); + X = One - U1 * U1; + Y = One + U2 * (One - U2); + Z = F9 - Half; + X = (X - Half) - Z; + Y = Y - One; + if ((X == Zero) && (Y == Zero)) + { + RAddSub = Chopped; + printf ("Add/Subtract appears to be chopped.\n"); + } + if (GAddSub == Yes) + { + X = (Half + U2) * U2; + Y = (Half - U2) * U2; + X = One + X; + Y = One + Y; + X = (One + U2) - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) + { + X = (Half + U2) * U1; + Y = (Half - U2) * U1; + X = One - X; + Y = One - Y; + X = F9 - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) + { + RAddSub = Rounded; + printf ("Addition/Subtraction appears to round correctly.\n"); + if (GAddSub == No) + notify ("Add/Subtract"); + } + else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + } + else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + } + else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + S = One; + X = One + Half * (One + Half); + Y = (One + U2) * Half; + Z = X - Y; + T = Y - X; + StickyBit = Z + T; + if (StickyBit != Zero) + { + S = Zero; + BadCond (Flaw, "(X - Y) + (Y - X) is non zero!\n"); + } + StickyBit = Zero; + if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes) + && (RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (FLOOR (RadixD2) == RadixD2)) + { + printf ("Checking for sticky bit.\n"); + X = (Half + U1) * U2; + Y = Half * U2; + Z = One + Y; + T = One + X; + if ((Z - One <= Zero) && (T - One >= U2)) + { + Z = T + Y; + Y = Z - X; + if ((Z - T >= U2) && (Y - T == Zero)) + { + X = (Half + U1) * U1; + Y = Half * U1; + Z = One - Y; + T = One - X; + if ((Z - One == Zero) && (T - F9 == Zero)) + { + Z = (Half - U1) * U1; + T = F9 - Z; + Q = F9 - Y; + if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) + { + Z = (One + U2) * OneAndHalf; + T = (OneAndHalf + U2) - Z + U2; + X = One + Half / Radix; + Y = One + Radix * U2; + Z = X * Y; + if (T == Zero && X + Radix * U2 - Z == Zero) + { + if (Radix != Two) + { + X = Two + U2; + Y = X / Two; + if ((Y - One == Zero)) + StickyBit = S; + } + else + StickyBit = S; + } + } + } + } + } + } + if (StickyBit == One) + printf ("Sticky bit apparently used correctly.\n"); + else + printf ("Sticky bit used incorrectly or not at all.\n"); + TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No || + RMult == Other || RDiv == Other || RAddSub == Other), + "lack(s) of guard digits or failure(s) to correctly round or chop\n\ +(noted above) count as one flaw in the final tally below"); + /*=============================================*/ + Milestone = 60; + /*=============================================*/ + printf ("\n"); + printf ("Does Multiplication commute? "); + printf ("Testing on %d random pairs.\n", NoTrials); + Random9 = SQRT (FLOAT (3)); + Random1 = Third; + I = 1; + do + { + X = Random (); + Y = Random (); + Z9 = Y * X; + Z = X * Y; + Z9 = Z - Z9; + I = I + 1; + } + while (!((I > NoTrials) || (Z9 != Zero))); + if (I == NoTrials) + { + Random1 = One + Half / Three; + Random2 = (U2 + U1) + One; + Z = Random1 * Random2; + Y = Random2 * Random1; + Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half / + Three) * ((U2 + U1) + + One); + } + if (!((I == NoTrials) || (Z9 == Zero))) + BadCond (Defect, "X * Y == Y * X trial fails.\n"); + else + printf (" No failures found in %d integer pairs.\n", NoTrials); + /*=============================================*/ + Milestone = 70; + /*=============================================*/ + printf ("\nRunning test of square root(x).\n"); + TstCond (Failure, (Zero == SQRT (Zero)) + && (-Zero == SQRT (-Zero)) + && (One == SQRT (One)), "Square root of 0.0, -0.0 or 1.0 wrong"); + MinSqEr = Zero; + MaxSqEr = Zero; + J = Zero; + X = Radix; + OneUlp = U2; + SqXMinX (Serious); + X = BInvrse; + OneUlp = BInvrse * U1; + SqXMinX (Serious); + X = U1; + OneUlp = U1 * U1; + SqXMinX (Serious); + if (J != Zero) + Pause (); + printf ("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials); + J = Zero; + X = Two; + Y = Radix; + if ((Radix != One)) + do + { + X = Y; + Y = Radix * Y; + } + while (!((Y - X >= NoTrials))); + OneUlp = X * U2; + I = 1; + while (I <= NoTrials) + { + X = X + One; + SqXMinX (Defect); + if (J > Zero) + break; + I = I + 1; + } + printf ("Test for sqrt monotonicity.\n"); + I = -1; + X = BMinusU2; + Y = Radix; + Z = Radix + Radix * U2; + NotMonot = false; + Monot = false; + while (!(NotMonot || Monot)) + { + I = I + 1; + X = SQRT (X); + Q = SQRT (Y); + Z = SQRT (Z); + if ((X > Q) || (Q > Z)) + NotMonot = true; + else + { + Q = FLOOR (Q + Half); + if (!(I > 0 || Radix == Q * Q)) + Monot = true; + else if (I > 0) + { + if (I > 1) + Monot = true; + else + { + Y = Y * BInvrse; + X = Y - U1; + Z = Y + U1; + } + } + else + { + Y = Q; + X = Y - U2; + Z = Y + U2; + } + } + } + if (Monot) + printf ("sqrt has passed a test for Monotonicity.\n"); + else + { + BadCond (Defect, ""); + printf ("sqrt(X) is non-monotonic for X near %s .\n", Y.str()); + } + /*=============================================*/ + Milestone = 110; + /*=============================================*/ + printf ("Seeking Underflow thresholds UfThold and E0.\n"); + D = U1; + if (Precision != FLOOR (Precision)) + { + D = BInvrse; + X = Precision; + do + { + D = D * BInvrse; + X = X - One; + } + while (X > Zero); + } + Y = One; + Z = D; + /* ... D is power of 1/Radix < 1. */ + do + { + C = Y; + Y = Z; + Z = Y * Y; + } + while ((Y > Z) && (Z + Z > Z)); + Y = C; + Z = Y * D; + do + { + C = Y; + Y = Z; + Z = Y * D; + } + while ((Y > Z) && (Z + Z > Z)); + if (Radix < Two) + HInvrse = Two; + else + HInvrse = Radix; + H = One / HInvrse; + /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */ + CInvrse = One / C; + E0 = C; + Z = E0 * H; + /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */ + do + { + Y = E0; + E0 = Z; + Z = E0 * H; + } + while ((E0 > Z) && (Z + Z > Z)); + UfThold = E0; + E1 = Zero; + Q = Zero; + E9 = U2; + S = One + E9; + D = C * S; + if (D <= C) + { + E9 = Radix * U2; + S = One + E9; + D = C * S; + if (D <= C) + { + BadCond (Failure, + "multiplication gets too many last digits wrong.\n"); + Underflow = E0; + Y1 = Zero; + PseudoZero = Z; + Pause (); + } + } + else + { + Underflow = D; + PseudoZero = Underflow * H; + UfThold = Zero; + do + { + Y1 = Underflow; + Underflow = PseudoZero; + if (E1 + E1 <= E1) + { + Y2 = Underflow * HInvrse; + E1 = FABS (Y1 - Y2); + Q = Y1; + if ((UfThold == Zero) && (Y1 != Y2)) + UfThold = Y1; + } + PseudoZero = PseudoZero * H; + } + while ((Underflow > PseudoZero) + && (PseudoZero + PseudoZero > PseudoZero)); + } + /* Comment line 4530 .. 4560 */ + if (PseudoZero != Zero) + { + printf ("\n"); + Z = PseudoZero; + /* ... Test PseudoZero for "phoney- zero" violates */ + /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero + ... */ + if (PseudoZero <= Zero) + { + BadCond (Failure, "Positive expressions can underflow to an\n"); + printf ("allegedly negative value\n"); + printf ("PseudoZero that prints out as: %s .\n", PseudoZero.str()); + X = -PseudoZero; + if (X <= Zero) + { + printf ("But -PseudoZero, which should be\n"); + printf ("positive, isn't; it prints out as %s .\n", X.str()); + } + } + else + { + BadCond (Flaw, "Underflow can stick at an allegedly positive\n"); + printf ("value PseudoZero that prints out as %s .\n", + PseudoZero.str()); + } + TstPtUf (); + } + /*=============================================*/ + Milestone = 120; + /*=============================================*/ + if (CInvrse * Y > CInvrse * Y1) + { + S = H * S; + E0 = Underflow; + } + if (!((E1 == Zero) || (E1 == E0))) + { + BadCond (Defect, ""); + if (E1 < E0) + { + printf ("Products underflow at a higher"); + printf (" threshold than differences.\n"); + if (PseudoZero == Zero) + E0 = E1; + } + else + { + printf ("Difference underflows at a higher"); + printf (" threshold than products.\n"); + } + } + printf ("Smallest strictly positive number found is E0 = %s .\n", E0.str()); + Z = E0; + TstPtUf (); + Underflow = E0; + if (N == 1) + Underflow = Y; + I = 4; + if (E1 == Zero) + I = 3; + if (UfThold == Zero) + I = I - 2; + UfNGrad = true; + switch (I) + { + case 1: + UfThold = Underflow; + if ((CInvrse * Q) != ((CInvrse * Y) * S)) + { + UfThold = Y; + BadCond (Failure, "Either accuracy deteriorates as numbers\n"); + printf ("approach a threshold = %s\n", UfThold.str()); + printf (" coming down from %s\n", C.str()); + printf + (" or else multiplication gets too many last digits wrong.\n"); + } + Pause (); + break; + + case 2: + BadCond (Failure, + "Underflow confuses Comparison, which alleges that\n"); + printf ("Q == Y while denying that |Q - Y| == 0; these values\n"); + printf ("print out as Q = %s, Y = %s .\n", Q.str(), Y2.str()); + printf ("|Q - Y| = %s .\n", FABS (Q - Y2).str()); + UfThold = Q; + break; + + case 3: + X = X; + break; + + case 4: + if ((Q == UfThold) && (E1 == E0) && (FABS (UfThold - E1 / E9) <= E1)) + { + UfNGrad = false; + printf ("Underflow is gradual; it incurs Absolute Error =\n"); + printf ("(roundoff in UfThold) < E0.\n"); + Y = E0 * CInvrse; + Y = Y * (OneAndHalf + U2); + X = CInvrse * (One + U2); + Y = Y / X; + IEEE = (Y == E0); + } + } + if (UfNGrad) + { + printf ("\n"); + if (setjmp (ovfl_buf)) + { + printf ("Underflow / UfThold failed!\n"); + R = H + H; + } + else + R = SQRT (Underflow / UfThold); + if (R <= H) + { + Z = R * UfThold; + X = Z * (One + R * H * (One + H)); + } + else + { + Z = UfThold; + X = Z * (One + H * H * (One + H)); + } + if (!((X == Z) || (X - Z != Zero))) + { + BadCond (Flaw, ""); + printf ("X = %s\n\tis not equal to Z = %s .\n", X.str(), Z.str()); + Z9 = X - Z; + printf ("yet X - Z yields %s .\n", Z9.str()); + printf (" Should this NOT signal Underflow, "); + printf ("this is a SERIOUS DEFECT\nthat causes "); + printf ("confusion when innocent statements like\n");; + printf (" if (X == Z) ... else"); + printf (" ... (f(X) - f(Z)) / (X - Z) ...\n"); + printf ("encounter Division by Zero although actually\n"); + if (setjmp (ovfl_buf)) + printf ("X / Z fails!\n"); + else + printf ("X / Z = 1 + %s .\n", ((X / Z - Half) - Half).str()); + } + } + printf ("The Underflow threshold is %s, below which\n", UfThold.str()); + printf ("calculation may suffer larger Relative error than "); + printf ("merely roundoff.\n"); + Y2 = U1 * U1; + Y = Y2 * Y2; + Y2 = Y * U1; + if (Y2 <= UfThold) + { + if (Y > E0) + { + BadCond (Defect, ""); + I = 5; + } + else + { + BadCond (Serious, ""); + I = 4; + } + printf ("Range is too narrow; U1^%d Underflows.\n", I); + } + /*=============================================*/ + Milestone = 130; + /*=============================================*/ + Y = -FLOOR (Half - TwoForty * LOG (UfThold) / LOG (HInvrse)) / TwoForty; + Y2 = Y + Y; + printf ("Since underflow occurs below the threshold\n"); + printf ("UfThold = (%s) ^ (%s)\nonly underflow ", HInvrse.str(), Y.str()); + printf ("should afflict the expression\n\t(%s) ^ (%s);\n", + HInvrse.str(), Y2.str()); + printf ("actually calculating yields:"); + if (setjmp (ovfl_buf)) + { + BadCond (Serious, "trap on underflow.\n"); + } + else + { + V9 = POW (HInvrse, Y2); + printf (" %s .\n", V9.str()); + if (!((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) + { + BadCond (Serious, "this is not between 0 and underflow\n"); + printf (" threshold = %s .\n", UfThold.str()); + } + else if (!(V9 > UfThold * (One + E9))) + printf ("This computed value is O.K.\n"); + else + { + BadCond (Defect, "this is not between 0 and underflow\n"); + printf (" threshold = %s .\n", UfThold.str()); + } + } + /*=============================================*/ + Milestone = 160; + /*=============================================*/ + Pause (); + printf ("Searching for Overflow threshold:\n"); + printf ("This may generate an error.\n"); + Y = -CInvrse; + V9 = HInvrse * Y; + if (setjmp (ovfl_buf)) + { + I = 0; + V9 = Y; + goto overflow; + } + do + { + V = Y; + Y = V9; + V9 = HInvrse * Y; + } + while (V9 < Y); + I = 1; +overflow: + Z = V9; + printf ("Can `Z = -Y' overflow?\n"); + printf ("Trying it on Y = %s .\n", Y.str()); + V9 = -Y; + V0 = V9; + if (V - Y == V + V0) + printf ("Seems O.K.\n"); + else + { + printf ("finds a "); + BadCond (Flaw, "-(-Y) differs from Y.\n"); + } + if (Z != Y) + { + BadCond (Serious, ""); + printf ("overflow past %s\n\tshrinks to %s .\n", Y.str(), Z.str()); + } + if (I) + { + Y = V * (HInvrse * U2 - HInvrse); + Z = Y + ((One - HInvrse) * U2) * V; + if (Z < V0) + Y = Z; + if (Y < V0) + V = Y; + if (V0 - V < V0) + V = V0; + } + else + { + V = Y * (HInvrse * U2 - HInvrse); + V = V + ((One - HInvrse) * U2) * Y; + } + printf ("Overflow threshold is V = %s .\n", V.str()); + if (I) + printf ("Overflow saturates at V0 = %s .\n", V0.str()); + else + printf ("There is no saturation value because " + "the system traps on overflow.\n"); + V9 = V * One; + printf ("No Overflow should be signaled for V * 1 = %s\n", V9.str()); + V9 = V / One; + printf (" nor for V / 1 = %s.\n", V9.str()); + printf ("Any overflow signal separating this * from the one\n"); + printf ("above is a DEFECT.\n"); + /*=============================================*/ + Milestone = 170; + /*=============================================*/ + if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) + { + BadCond (Failure, "Comparisons involving "); + printf ("+-%s, +-%s\nand +-%s are confused by Overflow.", + V.str(), V0.str(), UfThold.str()); + } + /*=============================================*/ + Milestone = 175; + /*=============================================*/ + printf ("\n"); + for (Indx = 1; Indx <= 3; ++Indx) + { + switch (Indx) + { + case 1: + Z = UfThold; + break; + case 2: + Z = E0; + break; + case 3: + Z = PseudoZero; + break; + } + if (Z != Zero) + { + V9 = SQRT (Z); + Y = V9 * V9; + if (Y / (One - Radix * E9) < Z || Y > (One + Radix * E9) * Z) + { /* dgh: + E9 --> * E9 */ + if (V9 > U1) + BadCond (Serious, ""); + else + BadCond (Defect, ""); + printf ("Comparison alleges that what prints as Z = %s\n", + Z.str()); + printf (" is too far from sqrt(Z) ^ 2 = %s .\n", Y.str()); + } + } + } + /*=============================================*/ + Milestone = 180; + /*=============================================*/ + for (Indx = 1; Indx <= 2; ++Indx) + { + if (Indx == 1) + Z = V; + else + Z = V0; + V9 = SQRT (Z); + X = (One - Radix * E9) * V9; + V9 = V9 * X; + if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) + { + Y = V9; + if (X < W) + BadCond (Serious, ""); + else + BadCond (Defect, ""); + printf ("Comparison alleges that Z = %s\n", Z.str()); + printf (" is too far from sqrt(Z) ^ 2 (%s) .\n", Y.str()); + } + } + /*=============================================*/ + Milestone = 190; + /*=============================================*/ + Pause (); + X = UfThold * V; + Y = Radix * Radix; + if (X * Y < One || X > Y) + { + if (X * Y < U1 || X > Y / U1) + BadCond (Defect, "Badly"); + else + BadCond (Flaw, ""); + + printf (" unbalanced range; UfThold * V = %s\n\t%s\n", + X.str(), "is too far from 1.\n"); + } + /*=============================================*/ + Milestone = 200; + /*=============================================*/ + for (Indx = 1; Indx <= 5; ++Indx) + { + X = F9; + switch (Indx) + { + case 2: + X = One + U2; + break; + case 3: + X = V; + break; + case 4: + X = UfThold; + break; + case 5: + X = Radix; + } + Y = X; + if (setjmp (ovfl_buf)) + printf (" X / X traps when X = %s\n", X.str()); + else + { + V9 = (Y / X - Half) - Half; + if (V9 == Zero) + continue; + if (V9 == -U1 && Indx < 5) + BadCond (Flaw, ""); + else + BadCond (Serious, ""); + printf (" X / X differs from 1 when X = %s\n", X.str()); + printf (" instead, X / X - 1/2 - 1/2 = %s .\n", V9.str()); + } + } + /*=============================================*/ + Milestone = 210; + /*=============================================*/ + MyZero = Zero; + printf ("\n"); + printf ("What message and/or values does Division by Zero produce?\n"); + printf (" Trying to compute 1 / 0 produces ..."); + if (!setjmp (ovfl_buf)) + printf (" %s .\n", (One / MyZero).str()); + printf ("\n Trying to compute 0 / 0 produces ..."); + if (!setjmp (ovfl_buf)) + printf (" %s .\n", (Zero / MyZero).str()); + /*=============================================*/ + Milestone = 220; + /*=============================================*/ + Pause (); + printf ("\n"); + { + static const char *msg[] = { + "FAILUREs encountered =", + "SERIOUS DEFECTs discovered =", + "DEFECTs discovered =", + "FLAWs discovered =" + }; + int i; + for (i = 0; i < 4; i++) + if (ErrCnt[i]) + printf ("The number of %-29s %d.\n", msg[i], ErrCnt[i]); + } + printf ("\n"); + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] + ErrCnt[Flaw]) > 0) + { + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] == 0) + && (ErrCnt[Flaw] > 0)) + { + printf ("The arithmetic diagnosed seems "); + printf ("Satisfactory though flawed.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) && (ErrCnt[Defect] > 0)) + { + printf ("The arithmetic diagnosed may be Acceptable\n"); + printf ("despite inconvenient Defects.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) + { + printf ("The arithmetic diagnosed has "); + printf ("unacceptable Serious Defects.\n"); + } + if (ErrCnt[Failure] > 0) + { + printf ("Potentially fatal FAILURE may have spoiled this"); + printf (" program's subsequent diagnoses.\n"); + } + } + else + { + printf ("No failures, defects nor flaws have been discovered.\n"); + if (!((RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (RSqrt == Rounded))) + printf ("The arithmetic diagnosed seems Satisfactory.\n"); + else + { + if (StickyBit >= One && + (Radix - Two) * (Radix - Nine - One) == Zero) + { + printf ("Rounding appears to conform to "); + printf ("the proposed IEEE standard P"); + if ((Radix == Two) && + ((Precision - Four * Three * Two) * + (Precision - TwentySeven - TwentySeven + One) == Zero)) + printf ("754"); + else + printf ("854"); + if (IEEE) + printf (".\n"); + else + { + printf (",\nexcept for possibly Double Rounding"); + printf (" during Gradual Underflow.\n"); + } + } + printf ("The arithmetic diagnosed appears to be Excellent!\n"); + } + } + printf ("END OF TEST.\n"); + return 0; +} + +template<typename FLOAT> +FLOAT +Paranoia<FLOAT>::Sign (FLOAT X) +{ + return X >= FLOAT (long (0)) ? 1 : -1; +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::Pause () +{ + if (do_pause) + { + fputs ("Press return...", stdout); + fflush (stdout); + getchar(); + } + printf ("\nDiagnosis resumes after milestone Number %d", Milestone); + printf (" Page: %d\n\n", PageNo); + ++Milestone; + ++PageNo; +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::TstCond (int K, int Valid, const char *T) +{ + if (!Valid) + { + BadCond (K, T); + printf (".\n"); + } +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::BadCond (int K, const char *T) +{ + static const char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" }; + + ErrCnt[K] = ErrCnt[K] + 1; + printf ("%s: %s", msg[K], T); +} + +/* Random computes + X = (Random1 + Random9)^5 + Random1 = X - FLOOR(X) + 0.000005 * X; + and returns the new value of Random1. */ + +template<typename FLOAT> +FLOAT +Paranoia<FLOAT>::Random () +{ + FLOAT X, Y; + + X = Random1 + Random9; + Y = X * X; + Y = Y * Y; + X = X * Y; + Y = X - FLOOR (X); + Random1 = Y + X * FLOAT ("0.000005"); + return (Random1); +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::SqXMinX (int ErrKind) +{ + FLOAT XA, XB; + + XB = X * BInvrse; + XA = X - XB; + SqEr = ((SQRT (X * X) - XB) - XA) / OneUlp; + if (SqEr != Zero) + { + if (SqEr < MinSqEr) + MinSqEr = SqEr; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + J = J + 1; + BadCond (ErrKind, "\n"); + printf ("sqrt(%s) - %s = %s\n", (X * X).str(), X.str(), + (OneUlp * SqEr).str()); + printf ("\tinstead of correct value 0 .\n"); + } +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::NewD () +{ + X = Z1 * Q; + X = FLOOR (Half - X / Radix) * Radix + X; + Q = (Q - X * Z) / Radix + X * X * (D / Radix); + Z = Z - Two * X * D; + if (Z <= Zero) + { + Z = -Z; + Z1 = -Z1; + } + D = Radix * D; +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::SR3750 () +{ + if (!((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) + { + I = I + 1; + X2 = SQRT (X * D); + Y2 = (X2 - Z2) - (Y - Z2); + X2 = X8 / (Y - Half); + X2 = X2 - Half * X2 * X2; + SqEr = (Y2 + Half) + (Half - X2); + if (SqEr < MinSqEr) + MinSqEr = SqEr; + SqEr = Y2 - X2; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + } +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::IsYeqX () +{ + if (Y != X) + { + if (N <= 0) + { + if (Z == Zero && Q <= Zero) + printf ("WARNING: computing\n"); + else + BadCond (Defect, "computing\n"); + printf ("\t(%s) ^ (%s)\n", Z.str(), Q.str()); + printf ("\tyielded %s;\n", Y.str()); + printf ("\twhich compared unequal to correct %s ;\n", X.str()); + printf ("\t\tthey differ by %s .\n", (Y - X).str()); + } + N = N + 1; /* ... count discrepancies. */ + } +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::PrintIfNPositive () +{ + if (N > 0) + printf ("Similar discrepancies have occurred %d times.\n", N); +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::TstPtUf () +{ + N = 0; + if (Z != Zero) + { + printf ("Since comparison denies Z = 0, evaluating "); + printf ("(Z + Z) / Z should be safe.\n"); + if (setjmp (ovfl_buf)) + goto very_serious; + Q9 = (Z + Z) / Z; + printf ("What the machine gets for (Z + Z) / Z is %s .\n", Q9.str()); + if (FABS (Q9 - Two) < Radix * U2) + { + printf ("This is O.K., provided Over/Underflow"); + printf (" has NOT just been signaled.\n"); + } + else + { + if ((Q9 < One) || (Q9 > Two)) + { + very_serious: + N = 1; + ErrCnt[Serious] = ErrCnt[Serious] + 1; + printf ("This is a VERY SERIOUS DEFECT!\n"); + } + else + { + N = 1; + ErrCnt[Defect] = ErrCnt[Defect] + 1; + printf ("This is a DEFECT!\n"); + } + } + V9 = Z * One; + Random1 = V9; + V9 = One * Z; + Random2 = V9; + V9 = Z / One; + if ((Z == Random1) && (Z == Random2) && (Z == V9)) + { + if (N > 0) + Pause (); + } + else + { + N = 1; + BadCond (Defect, "What prints as Z = "); + printf ("%s\n\tcompares different from ", Z.str()); + if (Z != Random1) + printf ("Z * 1 = %s ", Random1.str()); + if (!((Z == Random2) || (Random2 == Random1))) + printf ("1 * Z == %s\n", Random2.str()); + if (!(Z == V9)) + printf ("Z / 1 = %s\n", V9.str()); + if (Random2 != Random1) + { + ErrCnt[Defect] = ErrCnt[Defect] + 1; + BadCond (Defect, "Multiplication does not commute!\n"); + printf ("\tComparison alleges that 1 * Z = %s\n", Random2.str()); + printf ("\tdiffers from Z * 1 = %s\n", Random1.str()); + } + Pause (); + } + } +} + +template<typename FLOAT> +void +Paranoia<FLOAT>::notify (const char *s) +{ + printf ("%s test appears to be inconsistent...\n", s); + printf (" PLEASE NOTIFY KARPINKSI!\n"); +} + +/* ====================================================================== */ + +int main(int ac, char **av) +{ + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + while (1) + switch (getopt (ac, av, "pvg:fdl")) + { + case -1: + return 0; + case 'p': + do_pause = true; + break; + case 'v': + verbose = true; + break; + case 'g': + { + static const struct { + const char *name; + const struct real_format *fmt; + } fmts[] = { +#define F(x) { #x, &x##_format } + F(ieee_single), + F(ieee_double), + F(ieee_extended_motorola), + F(ieee_extended_intel_96), + F(ieee_extended_intel_128), + F(ibm_extended), + F(ieee_quad), + F(vax_f), + F(vax_d), + F(vax_g), + F(i370_single), + F(i370_double), + F(c4x_single), + F(c4x_extended), + F(real_internal), +#undef F + }; + + int i, n = sizeof (fmts)/sizeof(*fmts); + + for (i = 0; i < n; ++i) + if (strcmp (fmts[i].name, optarg) == 0) + break; + + if (i == n) + { + printf ("Unknown implementation \"%s\"; " + "available implementations:\n", optarg); + for (i = 0; i < n; ++i) + printf ("\t%s\n", fmts[i].name); + return 1; + } + + // We cheat and use the same mode all the time, but vary + // the format used for that mode. + real_format_for_mode[int(real_c_float::MODE) - int(QFmode)] + = fmts[i].fmt; + + Paranoia<real_c_float>().main(); + break; + } + + case 'f': + Paranoia < native_float<float> >().main(); + break; + case 'd': + Paranoia < native_float<double> >().main(); + break; + case 'l': +#ifndef NO_LONG_DOUBLE + Paranoia < native_float<long double> >().main(); +#endif + break; + + case '?': + puts ("-p\tpause between pages"); + puts ("-g<FMT>\treal.c implementation FMT"); + puts ("-f\tnative float"); + puts ("-d\tnative double"); + puts ("-l\tnative long double"); + return 0; + } +} + +/* GCC stuff referenced by real.o. */ + +extern "C" void +fancy_abort () +{ + abort (); +} + +int target_flags = 0; + +extern "C" int +floor_log2_wide (unsigned HOST_WIDE_INT x) +{ + int log = -1; + while (x != 0) + log++, + x >>= 1; + return log; +} diff --git a/gnu/usr.bin/gcc/contrib/regression/ChangeLog b/gnu/usr.bin/gcc/contrib/regression/ChangeLog new file mode 100644 index 00000000000..f4ac779df84 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/regression/ChangeLog @@ -0,0 +1,59 @@ +2003-10-16 Release Manager + + * GCC 3.3.2 Released. + +2003-08-04 Release Manager + + * GCC 3.3.1 Released. + +2003-08-04 Release Manager + + * GCC 3.3.1 Released. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2003-05-13 Release Manager + + * GCC 3.3 Released. + +2002-10-22 Geoffrey Keating <geoffk@apple.com> + + * btest-gcc.sh: Add gdb.sum to TESTLOGS only when GDB testsuite is run. + +2002-10-11 Geoffrey Keating <geoffk@apple.com> + + * objs-gcc.sh: Don't install GDB testsuite if GDB was not built. + * btest-gcc.sh: Don't run GDB testsuite if it doesn't exist. + +2002-10-09 Phil Edwards <pme@gcc.gnu.org> + + * btest-gcc.sh, objs-gcc.sh: Update TARGET comments. + +2002-10-09 Geoffrey Keating <geoffk@apple.com> + + * objs-gcc.sh: On (non-linux) native hosts, use 'make bootstrap'. + +2002-03-09 Geoffrey Keating <geoffk@redhat.com> + + * btest-gcc.sh: For crosses, assume newlib and GNU binutils. + * site.exp: Correct mips-elf triplet. + +2002-01-31 Geoffrey Keating <geoffk@redhat.com> + + * btest-gcc.sh: New file. + * objs-gcc.sh: New file. + * site.exp: New file. + * ChangeLog: New file. + * README: New file. + + diff --git a/gnu/usr.bin/gcc/contrib/regression/README b/gnu/usr.bin/gcc/contrib/regression/README new file mode 100644 index 00000000000..7e0e657932e --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/regression/README @@ -0,0 +1,18 @@ +This directory contains scripts that are used by the regression +tester, <http://people.redhat.com/geoffk/gcc-regression/>. + +The primary script is 'btest-gcc.sh'. This is the script that is run +to actually test the compiler. + +'objs-gcc.sh' takes a combined tree and builds (but does not test) the +tools required for 'btest-gcc.sh'. It is run periodically to update +the tools. This script is followed by running 'btest-gcc.sh' using +the newly-build tools to check that they will not cause regressions. + +'site.exp' is what $DEJAGNU points to when the regression tester runs +these scripts. + +Note that any changes made here need to be approved by the regression +tester's maintainer (see MAINTAINERS). The changes will be used on +the tester's next run, so `experimental' changes are very strongly +discouraged :-). diff --git a/gnu/usr.bin/gcc/contrib/regression/btest-gcc.sh b/gnu/usr.bin/gcc/contrib/regression/btest-gcc.sh new file mode 100755 index 00000000000..524dfd9cffd --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/regression/btest-gcc.sh @@ -0,0 +1,177 @@ +#!/bin/sh + +# Test GCC. +# Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# INPUT: +# btest <target> <source> <prefix> <state> <build> +# TARGET is the target triplet. It should be the same one as used in +# constructing PREFIX. Or it can be the keyword 'native', indicating +# a target of whatever platform the script is running on. +TARGET=$1 +# SOURCE is the directory containing the toplevel configure. +SOURCE=$2 + +# PREFIX is the directory for the --prefix option to configure. +# For cross compilers, it needs to contain header files, +# libraries, and binutils. PATH should probably include +# $PREFIX/bin. +PREFIX=$3 +# This script also needs to include the GDB testsuite in +# $PREFIX/share/gdb-testsuite. +GDB_TESTSUITE=$PREFIX/share/gdb-testsuite + +# STATE is where the tester maintains its internal state, +# described below. +STATE=$4 + +# BUILD is a temporary directory that this script will +# delete and recreate, containing the build tree. +BUILD=$5 + +# you also probably need to set these variables: +# PATH: should contain a native gcc, and a cross gdb. +# DEJAGNU: should point to a site.exp suitable for testing +# the compiler and debugger. + + +# OUTPUT: in $RESULT, one of the following keywords: +# error the script failed due to +# a misconfiguration or resource limitation +# build the build failed +# regress-<n> the build succeeded, but there were <n> +# testsuite regressions, listed in $REGRESS +# pass build succeeded and there were no regressions +RESULT=$STATE/RESULT +# in BUILD_LOG, the output of the build +BUILD_LOG=$STATE/build_log +# in FAILED, a list of failing testcases +FAILED=$STATE/failed +# in PASSES, the list of testcases we expect to pass +PASSES=$STATE/passes +# in REGRESS, a list of testcases we expected to pass but that failed +REGRESS=$STATE/regress + +# Make sure various files exist. +[ -d $STATE ] || mkdir $STATE +[ -f $PASSES ] || touch $PASSES + +# These lines should stay in this order, because +# that way if something is badly wrong and $RESULT can't +# be modified then cron will mail the error message. +# The reverse order could lead to the testsuite claiming that +# everything always passes, without running any tests. +echo error > $RESULT || exit 1 +exec > $BUILD_LOG 2>&1 || exit 1 + +set -x + +# Nuke $BUILD and recreate it. +rm -rf $BUILD $REGRESS $FAILED +mkdir $BUILD || exit 1 +cd $BUILD || exit 1 + +H_BUILD=`$SOURCE/config.guess || exit 1` +H_HOST=$H_BUILD +if [ $TARGET = native ] ; then + H_TARGET=$H_HOST +else + H_TARGET=$TARGET +fi +H_REAL_TARGET=`$SOURCE/config.sub $H_TARGET || exit 1` + +# TESTLOGS is the list of dejagnu .sum files that the tester should +# look at. +TESTLOGS="gcc/testsuite/gcc.sum +gcc/testsuite/g++.sum +gcc/testsuite/g77.sum +gcc/testsuite/objc.sum" +# $H_TARGET/libstdc++-v3/testsuite/libstdc++-v3.sum + +# Build. +echo build > $RESULT +if [ $H_HOST = $H_TARGET ] ; then + $SOURCE/configure --prefix=$PREFIX --target=$H_TARGET || exit 1 + if ! make bootstrap ; then + [ -s gcc/.bad_compare ] || exit 1 + cat gcc/.bad_compare >> $REGRESS || exit 1 + make all || exit 1 + fi +else + $SOURCE/configure --prefix=$PREFIX --target=$H_TARGET \ + --with-gnu-ld --with-gnu-as --with-newlib || exit 1 + make || exit 1 +fi +echo error > $RESULT || exit 1 + +# Test GCC against its internal testsuite. +make -k check-gcc + +# Test libstd++-v3 +make check-target-libstdc++-v3 + +# Test the just-built GCC with the GDB testsuite. +if [ -d $GDB_TESTSUITE ] ; then + mkdir test-gdb || exit 1 + cd $GDB_TESTSUITE || exit 1 + for i in gdb.* ; do + if [ -d $i ] ; then + mkdir $BUILD/test-gdb/$i + fi + done + cd $BUILD/test-gdb || exit 1 + echo "set host_alias $H_HOST" > site.exp + echo "set host_triplet $H_HOST" >> site.exp + echo "set target_alias $H_TARGET" >> site.exp + echo "set target_triplet $H_REAL_TARGET" >> site.exp + echo "set build_alias $H_BUILD" >> site.exp + echo "set build_triplet $H_BUILD" >> site.exp + echo "set srcdir $GDB_TESTSUITE" >> site.exp + runtest --tool gdb + TESTLOGS="$TESTLOGS test-gdb/gdb.sum" +fi + +# Sanity-check the testlogs. They should contain at least one PASS. +cd $BUILD || exit 1 +for LOG in $TESTLOGS ; do + if ! grep ^PASS: $LOG > /dev/null ; then + echo build > $RESULT + exit 1 + fi +done + +# Work out what failed +for LOG in $TESTLOGS ; do + L=`basename $LOG` + awk '/^FAIL: / { print "'$L'",$2; }' $LOG || exit 1 +done | sort | uniq > $FAILED || exit 1 +comm -12 $FAILED $PASSES >> $REGRESS || exit 1 +NUMREGRESS=`wc -l < $REGRESS | tr -d ' '` +if [ $NUMREGRESS -ne 0 ] ; then + echo regress-$NUMREGRESS > $RESULT + exit 1 +fi + +# It passed. Update the state. +for LOG in $TESTLOGS ; do + L=`basename $LOG` + awk '/^PASS: / { print "'$L'",$2; }' $LOG || exit 1 +done | sort | uniq | comm -23 - $FAILED > ${PASSES}~ || exit 1 +[ -s ${PASSES}~ ] || exit 1 +mv ${PASSES}~ ${PASSES} || exit 1 +echo pass > $RESULT +exit 0 diff --git a/gnu/usr.bin/gcc/contrib/regression/objs-gcc.sh b/gnu/usr.bin/gcc/contrib/regression/objs-gcc.sh new file mode 100755 index 00000000000..cc152d1f80c --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/regression/objs-gcc.sh @@ -0,0 +1,127 @@ +#!/bin/sh + +# Build tools for testing GCC. +# Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# INPUT: +# btest <target> <source> <prefix> <state> <build> +# TARGET is the target triplet. It should be the same one as used in +# constructing PREFIX. Or it can be the keyword 'native', indicating +# a target of whatever platform the script is running on. +TARGET=$1 +# SOURCE is the directory containing the toplevel configure. +SOURCE=$2 + +# PREFIX is the directory for the --prefix option to configure. +PREFIX=$3 + +# STATE is where the tester maintains its internal state, +# described below. +STATE=$4 + +# BUILD is a temporary directory that this script will +# delete and recreate, containing the build tree. +BUILD=$5 + +# you also probably need to set these variables: +# DEJAGNU: should point to a site.exp suitable for testing +# the compiler and debugger. + +# OUTPUT: in $RESULT, one of the following keywords: +# error the script failed due to +# a misconfiguration or resource limitation +# build the build failed +# regress-<n> the build succeeded, but there were <n> +# testsuite regressions, listed in $REGRESS +# pass build succeeded and there were no regressions +RESULT=$STATE/RESULT +# in BUILD_LOG, the output of the build +BUILD_LOG=$STATE/build_log +# in FAILED, a list of failing testcases +FAILED=$STATE/failed +# in PASSES, the list of testcases we expect to pass +PASSES=$STATE/passes +# in REGRESS, a list of testcases we expected to pass but that failed +REGRESS=$STATE/regress + +# Make sure various files exist. +[ -d $STATE ] || mkdir $STATE +[ -f $PASSES ] || touch $PASSES + +# These lines should stay in this order, because +# that way if something is badly wrong and $RESULT can't +# be modified then cron will mail the error message. +# The reverse order could lead to the testsuite claiming that +# everything always passes, without running any tests. +echo error > $RESULT || exit 1 +exec > $BUILD_LOG 2>&1 || exit 1 + +set -x + +# TESTLOGS is the list of dejagnu .sum files that the tester should +# look at. +TESTLOGS="test/gcc/gcc.sum +test/g++/g++.sum" + +# Nuke $BUILD and recreate it. +rm -rf $BUILD $REGRESS $FAILED +mkdir $BUILD $BUILD/build $BUILD/objs || exit 1 +cd $BUILD || exit 1 + +# This script used to use config.guess, but that is not how releng +# determines hostnames. +H_BUILD=`$SOURCE/config.guess || exit 1` +H_HOST=$H_BUILD +if [ $TARGET = native ] ; then + H_TARGET=$H_HOST +else + H_TARGET=$TARGET +fi +H_REAL_TARGET=`$SOURCE/config.sub $H_TARGET || exit 1` +H_REAL_BUILD=`$SOURCE/config.sub $H_BUILD || exit 1` +H_REAL_HOST=`$SOURCE/config.sub $H_HOST || exit 1` + +# Build. +echo build > $RESULT + +cd $BUILD/build || exit 1 +TMP_PREFIX=$BUILD/install +$SOURCE/configure --prefix=$PREFIX --target=$H_TARGET || exit 1 +if [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-gnu ] + then + make all-gdb all-dejagnu all-ld || exit 1 + make install-gdb install-dejagnu install-ld || exit 1 +elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then + make bootstrap || exit 1 + make install || exit 1 +else + make || exit 1 + make install || exit 1 +fi + +if [ -x $PREFIX/bin/$TARGET-gdb ] ; then + mkdir -p $PREFIX/share/gdb-testsuite || exit 1 + cd $SOURCE/gdb/testsuite || exit 1 + find . -print | cpio -pdmu $PREFIX/share/gdb-testsuite || exit 1 + # selftest.exp requires keeping old sources around, which is impractical + rm $PREFIX/share/gdb-testsuite/gdb.base/selftest.exp + # these tests seem to be broken and randomly failing + rm -r $PREFIX/share/gdb-testsuite/gdb.mi +fi + +echo pass > $RESULT +exit 0 diff --git a/gnu/usr.bin/gcc/contrib/regression/site.exp b/gnu/usr.bin/gcc/contrib/regression/site.exp new file mode 100644 index 00000000000..0892afa3a52 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/regression/site.exp @@ -0,0 +1,18 @@ +global target_list + +case "$target_triplet" in { + { "powerpc*-*eabi*" } { +# if { [info exists tool] && $tool == "gcc" } { +# set target_list { "powerpc-sim{,-fpic}" } +# } else { + set target_list { "powerpc-sim" } +# } + } + { "mips*-*-elf" } { + set target_list { "mips-sim" } + } + + default { + set target_list { "unix" } + } +} diff --git a/gnu/usr.bin/gcc/contrib/test_installed b/gnu/usr.bin/gcc/contrib/test_installed new file mode 100755 index 00000000000..54afa245e31 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/test_installed @@ -0,0 +1,121 @@ +#! /bin/sh + +# (C) 1998, 2000, 2002, 2003 Free Software Foundation +# Originally by Alexandre Oliva <oliva@dcc.unicamp.br> + +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html + +# This scripts assumes it lives in the contrib directory of the GCC +# source tree, so it will find the testsuite tree from its location. +# If you move it elsewhere, or want to use another testsuite tree, you +# can override the defaults with --srcdir=/some/dir/GCC or +# --testsuite=/some/dir/GCC/gcc/testsuite. If you specify +# --testsuite, --srcdir will be ignored; otherwise, `/gcc/testsuite' +# will be appended to the srcdir. + +# You may specify where the binaries to be tested should be picked up +# from. If you specify --prefix=/some/dir, gcc, g++ and g77 will be +# looked for at /some/dir/bin. Each one may be overridden by +# specifying --with-gcc=/pathname/to/gcc, --with-g++=/pathname/to/g++ +# and --with-g77=/pathname/to/g77. If you specify --without-gcc, +# --without-g++ or --without-g77, the test for the specified program +# will be skipped. By default, gcc, g++ and g77 will be searched in +# the PATH. + +# An additional argument may specify --tmpdir=/some/dir; by default, +# temporaries will be stored in the current directory, where the log +# files will be stored. + +# The script will interpret arguments until it finds one it does not +# understand. The remaining ones will be passed to `runtest'. A +# double-dash can be used to explicitly separate the arguments to +# `test_installed' from the ones to `runtest'. + +# This script should be run in an empty directory; it will refuse to +# run if it finds a file named site.exp in the current directory. + + +if test -f site.exp; then + echo site.exp already exists >&2 + exit 1 +fi + +while true; do + case "$1" in + --with-testsuite=*) testsuite=`echo "$1" | sed 's/[^=]*=//'`; shift;; + --srcdir=*) srcdir=`echo "$1" | sed 's/[^=]*=//'`; shift;; + + --prefix=*) prefix=`echo "$1" | sed 's/[^=]*=//'`; shift;; + --with-gcc=*) GCC_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; + --with-g++=*) GXX_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; + --with-g77=*) G77_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; + --without-gcc) GCC_UNDER_TEST=no; shift;; + --without-g++) GXX_UNDER_TEST=no; shift;; + --without-g77) G77_UNDER_TEST=no; shift;; + --without-objc) OBJC_UNDER_TEST=no; shift;; + + --tmpdir=*) tmpdir=`echo "$1" | sed 's/[^=]*=//'`; shift;; + + --help) cat <<\EOF +Runs the testsuite for an installed version of gcc/g++/g77/objc +Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation +by Alexandre Oliva <oliva@dcc.unicamp.br> + +Supported arguments: + +--help prints this page + +--with-testsuite=/some/dir/gcc/testsuite specify the testsuite directory +--srcdir=/some/dir same as --with-testsuite=/some/dir/gcc/testsuite + [deduced from shell-script pathname] + +--prefix=/some/dir use gcc, g++ and g77 from /some/dir/bin [PATH] +--with-gcc=/some/dir/bin/gcc use specified gcc program [gcc] +--with-g++=/some/dir/bin/g++ use specified g++ program [g++] +--with-g77=/some/dir/bin/g77 use specified g77 program [g77] +--without-gcc do not run gcc testsuite +--without-g++ do not run g++ testsuite +--without-g77 do not run g77 testsuite +--without-objc do not run objc testsuite + +--tmpdir=/some/dir create temporaries and leave failed programs + at specified directory [.] + +-- end of argument list; following arguments are passed to runtest +EOF + exit + ;; + + --) shift; break;; + *) break;; + esac +done + +if test x"${testsuite+set}" != x"set" && test x"${srcdir+set}" != x"set"; then + file=$0 + while [ -h $file ]; do + file=`ls -l $file | sed s/'.* -> '//` + done + srcdir=`CDPATH=. && cd \`echo "$file" | sed 's,/*[^/]*$,,;s,^$,.,'\`/.. >/dev/null && ${PWDCMD-pwd}` +fi + +cat >site.exp <<EOF +set rootme "." +set tmpdir "${tmpdir-`${PWDCMD-pwd}`}" +set srcdir "${testsuite-${srcdir}/gcc/testsuite}" +set CFLAGS "" +set CXXFLAGS "" +set GCC_UNDER_TEST "${GCC_UNDER_TEST-${prefix}${prefix+/bin/}gcc}" +set GXX_UNDER_TEST "${GXX_UNDER_TEST-${prefix}${prefix+/bin/}g++}" +set G77_UNDER_TEST "${G77_UNDER_TEST-${prefix}${prefix+/bin/}g77}" +set OBJC_UNDER_TEST "${OBJC_UNDER_TEST-${prefix}${prefix+/bin/}gcc}" +EOF + +test x"${GCC_UNDER_TEST}" = x"no" || runtest --tool gcc ${1+"$@"} +test x"${GXX_UNDER_TEST}" = x"no" || runtest --tool g++ ${1+"$@"} +test x"${G77_UNDER_TEST}" = x"no" || runtest --tool g77 ${1+"$@"} +test x"${OBJC_UNDER_TEST}" = x"no" || runtest --tool objc ${1+"$@"} + +exit 0 diff --git a/gnu/usr.bin/gcc/contrib/test_summary b/gnu/usr.bin/gcc/contrib/test_summary new file mode 100755 index 00000000000..5b9cdc8f39e --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/test_summary @@ -0,0 +1,142 @@ +#! /bin/sh + +# (C) 1998, 1999, 2000, 2002 Free Software Foundation +# Originally by Alexandre Oliva <oliva@dcc.unicamp.br> + +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html + +# This script processes *.{sum,log} files, producing a shell-script +# that sends e-mail to the appropriate lists and renames files to +# *.sent. It currently handles only gcc, but it should be quite easy +# to modify it to handle other packages and its mailing lists. + +# The scripts assumes it is run in the root directory of the build +# tree, and it will include all .sum files it finds in the mail +# report. + +# configure flags are extracted from ./config.status + +# if the BOOT_CFLAGS environment variable is set, it will be included +# in the mail report too. + +# The usage pattern of this script is as follows: + +# test_summary | more # so as to observe what should be done + +# test_summary | sh # so as to actually send e-mail and move log files + +# It accepts a few command line arguments. For example: +# -o: re-reads logs that have been mailed already (.sum.sent) +# -t: prevents logs from being renamed +# -p: prepend specified file (or list of files: -p "a b") to the report +# -i: append specified file (or list of files: -i "a b") to the report +# -m: specify the e-mail address to send notes to. An appropriate default +# should be selected from the log files. +# -f: force reports to be mailed; if omitted, only reports that differ +# from the sent.* version are sent. + +# Find a good awk. +if test -z "$AWK" ; then + for AWK in gawk nawk awk ; do + if type $AWK 2>&1 | grep 'not found' > /dev/null 2>&1 ; then + : + else + break + fi + done +fi + +: ${filesuffix=}; export filesuffix +: ${move=true}; export move +: ${forcemail=false}; export forcemail +while true; do + case "$1" in + -o) filesuffix=.sent; move=false; : ${mailto=nobody}; shift;; + -t) move=false; shift;; + -p) prepend_logs=${prepend_logs+"$prepend_logs "}"$2"; shift 2;; + -i) append_logs=${append_logs+"$append_logs "}"$2"; shift 2;; + -m) mailto=$2; forcemail=true; shift 2;; + -f) unset mailto; forcemail=true; shift;; + *) break;; + esac +done +: ${mailto="\" address \""}; export mailto +files=`find . -name \*.sum$filesuffix -print | sort` +anyfile=false anychange=$forcemail && +for file in $files; do + [ -f $file ] && + anyfile=true && + { $anychange || + anychange=`diff -u $file.sent $file 2>/dev/null | + if test ! -f $file.sent || + egrep '^[-+](XPASS|FAIL)' >/dev/null; then + echo true + else + echo false + fi + ` + } + true +done && +$anyfile && +if $forcemail || $anychange; then :; else mailto=nobody; fi && +# We use cat instead of listing the files as arguments to AWK because +# GNU awk 3.0.0 would break if any of the filenames contained `=' and +# was preceded by an invalid ``variable'' name. +cat ./config.status $files | +$AWK ' +BEGIN { + lang=""; + address="gcc-testresults@gcc.gnu.org"; + version="gcc"; + print "cat <<'"'"'EOF'"'"' |"; +'${prepend_logs+" system(\"cat $prepend_logs\"); "}' +} +$1 ~ /\/configure$/ { + srcdir = $1; + gsub(/\/configure$/, "", srcdir); + printf "LAST_UPDATED: "; + system("tail -1 " srcdir "/LAST_UPDATED"); + print ""; + + $1 = "configure flags:"; configflags = $0; + gsub(/--with-gcc-version-trigger=[^ ]* /, "", configflags); + gsub(/ --norecursion/, "", configflags) +} +/^Running target / { print ""; print; } +/^Target / { if (host != "") next; else host = $3; } +/^Host / && host ~ /^unix\{.*\}$/ { host = $3 " " substr(host, 5); } +/^Native / { if (host != "") next; else host = $4; } +/^[ ]*=== [^ ]+ tests ===/ { + if (lang == "") lang = " "$2" "; else lang = " "; +} +$2 == "version" { save = $0; $1 = ""; $2 = ""; version = $0; gsub(/^ */, "", version); gsub(/\r$/, "", version); $0 = save; } +/\===.*Summary/ { print ""; print; blanks=1; } +/tests ===/ || /^(Target|Host|Native)/ || $2 == "version" { print; blanks=1; } +/^(XPASS|FAIL|UNRESOLVED|WARNING|ERROR|# of )/ { print; } +# dumpall != 0 && /^X?(PASS|FAIL|UNTESTED)|^testcase/ { dumpall=0; } +# dumpall != 0 { print; } +# /^FAIL/ { dumpall=1; } +/^$/ && blanks>0 { print; --blanks; } +END { if (lang != "") { + print ""; + print "Compiler version: " prefix version lang; + print "Platform: " host; + print configflags; + '${BOOT_CFLAGS+'print "BOOT_CFLAGS='"${BOOT_CFLAGS}"'";'}' + if (boot_cflags != 0) print boot_cflags; +'${append_logs+" system(\"cat $append_logs\"); "}' + print "EOF"; + print "Mail -s \"Results for " prefix version lang "testsuite on " host "\" '"${mailto}"' &&"; +}} +{ next; } +' | sed "s/\([\`\$\\\\]\)/\\\\\\1/g" && +if $move; then + for file in $files `ls -1 $files | sed s/sum$/log/`; do + [ -f $file ] && echo "mv `${PWDCMD-pwd}`/$file `${PWDCMD-pwd}`/$file.sent &&" + done +fi && +echo true +exit 0 diff --git a/gnu/usr.bin/gcc/contrib/texi2pod.pl b/gnu/usr.bin/gcc/contrib/texi2pod.pl new file mode 100755 index 00000000000..d3839458896 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/texi2pod.pl @@ -0,0 +1,431 @@ +#! /usr/bin/perl -w + +# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + +# This file is part of GNU CC. + +# GNU CC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# GNU CC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with GNU CC; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston MA 02111-1307, USA. + +# This does trivial (and I mean _trivial_) conversion of Texinfo +# markup to Perl POD format. It's intended to be used to extract +# something suitable for a manpage from a Texinfo document. + +$output = 0; +$skipping = 0; +%sects = (); +$section = ""; +@icstack = (); +@endwstack = (); +@skstack = (); +@instack = (); +$shift = ""; +%defs = (); +$fnno = 1; +$inf = ""; +$ibase = ""; + +while ($_ = shift) { + if (/^-D(.*)$/) { + if ($1 ne "") { + $flag = $1; + } else { + $flag = shift; + } + $value = ""; + ($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/); + die "no flag specified for -D\n" + unless $flag ne ""; + die "flags may only contain letters, digits, hyphens, dashes and underscores\n" + unless $flag =~ /^[a-zA-Z0-9_-]+$/; + $defs{$flag} = $value; + } elsif (/^-/) { + usage(); + } else { + $in = $_, next unless defined $in; + $out = $_, next unless defined $out; + usage(); + } +} + +if (defined $in) { + $inf = gensym(); + open($inf, "<$in") or die "opening \"$in\": $!\n"; + $ibase = $1 if $in =~ m|^(.+)/[^/]+$|; +} else { + $inf = \*STDIN; +} + +if (defined $out) { + open(STDOUT, ">$out") or die "opening \"$out\": $!\n"; +} + +while(defined $inf) { +while(<$inf>) { + # Certain commands are discarded without further processing. + /^\@(?: + [a-z]+index # @*index: useful only in complete manual + |need # @need: useful only in printed manual + |(?:end\s+)?group # @group .. @end group: ditto + |page # @page: ditto + |node # @node: useful only in .info file + |(?:end\s+)?ifnottex # @ifnottex .. @end ifnottex: use contents + )\b/x and next; + + chomp; + + # Look for filename and title markers. + /^\@setfilename\s+([^.]+)/ and $fn = $1, next; + /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next; + + # Identify a man title but keep only the one we are interested in. + /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do { + if (exists $defs{$1}) { + $fn = $1; + $tl = postprocess($2); + } + next; + }; + + # Look for blocks surrounded by @c man begin SECTION ... @c man end. + # This really oughta be @ifman ... @end ifman and the like, but such + # would require rev'ing all other Texinfo translators. + /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do { + $output = 1 if exists $defs{$2}; + $sect = $1; + next; + }; + /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next; + /^\@c\s+man\s+end/ and do { + $sects{$sect} = "" unless exists $sects{$sect}; + $sects{$sect} .= postprocess($section); + $section = ""; + $output = 0; + next; + }; + + # handle variables + /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do { + $defs{$1} = $2; + next; + }; + /^\@clear\s+([a-zA-Z0-9_-]+)/ and do { + delete $defs{$1}; + next; + }; + + next unless $output; + + # Discard comments. (Can't do it above, because then we'd never see + # @c man lines.) + /^\@c\b/ and next; + + # End-block handler goes up here because it needs to operate even + # if we are skipping. + /^\@end\s+([a-z]+)/ and do { + # Ignore @end foo, where foo is not an operation which may + # cause us to skip, if we are presently skipping. + my $ended = $1; + next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex|copying)$/; + + die "\@end $ended without \@$ended at line $.\n" unless defined $endw; + die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw; + + $endw = pop @endwstack; + + if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) { + $skipping = pop @skstack; + next; + } elsif ($ended =~ /^(?:example|smallexample|display)$/) { + $shift = ""; + $_ = ""; # need a paragraph break + } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) { + $_ = "\n=back\n"; + $ic = pop @icstack; + } else { + die "unknown command \@end $ended at line $.\n"; + } + }; + + # We must handle commands which can cause skipping even while we + # are skipping, otherwise we will not process nested conditionals + # correctly. + /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do { + push @endwstack, $endw; + push @skstack, $skipping; + $endw = "ifset"; + $skipping = 1 unless exists $defs{$1}; + next; + }; + + /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do { + push @endwstack, $endw; + push @skstack, $skipping; + $endw = "ifclear"; + $skipping = 1 if exists $defs{$1}; + next; + }; + + /^\@(ignore|menu|iftex|copying)\b/ and do { + push @endwstack, $endw; + push @skstack, $skipping; + $endw = $1; + $skipping = 1; + next; + }; + + next if $skipping; + + # Character entities. First the ones that can be replaced by raw text + # or discarded outright: + s/\@copyright\{\}/(c)/g; + s/\@dots\{\}/.../g; + s/\@enddots\{\}/..../g; + s/\@([.!? ])/$1/g; + s/\@[:-]//g; + s/\@bullet(?:\{\})?/*/g; + s/\@TeX\{\}/TeX/g; + s/\@pounds\{\}/\#/g; + s/\@minus(?:\{\})?/-/g; + s/\\,/,/g; + + # Now the ones that have to be replaced by special escapes + # (which will be turned back into text by unmunge()) + s/&/&/g; + s/\@\{/{/g; + s/\@\}/}/g; + s/\@\@/&at;/g; + + # Inside a verbatim block, handle @var specially. + if ($shift ne "") { + s/\@var\{([^\}]*)\}/<$1>/g; + } + + # POD doesn't interpret E<> inside a verbatim block. + if ($shift eq "") { + s/</</g; + s/>/>/g; + } else { + s/</</g; + s/>/>/g; + } + + # Single line command handlers. + + /^\@include\s+(.+)$/ and do { + push @instack, $inf; + $inf = gensym(); + + # Try cwd and $ibase. + open($inf, "<" . $1) + or open($inf, "<" . $ibase . "/" . $1) + or die "cannot open $1 or $ibase/$1: $!\n"; + next; + }; + + /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/ + and $_ = "\n=head2 $1\n"; + /^\@subsection\s+(.+)$/ + and $_ = "\n=head3 $1\n"; + + # Block command handlers: + /^\@itemize\s+(\@[a-z]+|\*|-)/ and do { + push @endwstack, $endw; + push @icstack, $ic; + $ic = $1; + $_ = "\n=over 4\n"; + $endw = "itemize"; + }; + + /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do { + push @endwstack, $endw; + push @icstack, $ic; + if (defined $1) { + $ic = $1 . "."; + } else { + $ic = "1."; + } + $_ = "\n=over 4\n"; + $endw = "enumerate"; + }; + + /^\@([fv]?table)\s+(\@[a-z]+)/ and do { + push @endwstack, $endw; + push @icstack, $ic; + $endw = $1; + $ic = $2; + $ic =~ s/\@(?:samp|strong|key|gcctabopt|env)/B/; + $ic =~ s/\@(?:code|kbd)/C/; + $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/; + $ic =~ s/\@(?:file)/F/; + $_ = "\n=over 4\n"; + }; + + /^\@((?:small)?example|display)/ and do { + push @endwstack, $endw; + $endw = $1; + $shift = "\t"; + $_ = ""; # need a paragraph break + }; + + /^\@itemx?\s*(.+)?$/ and do { + if (defined $1) { + # Entity escapes prevent munging by the <> processing below. + $_ = "\n=item $ic\<$1\>\n"; + } else { + $_ = "\n=item $ic\n"; + $ic =~ y/A-Ya-y/B-Zb-z/; + $ic =~ s/(\d+)/$1 + 1/eg; + } + }; + + $section .= $shift.$_."\n"; +} +# End of current file. +close($inf); +$inf = pop @instack; +} + +die "No filename or title\n" unless defined $fn && defined $tl; + +$sects{NAME} = "$fn \- $tl\n"; +$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES}; + +for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES + BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) { + if(exists $sects{$sect}) { + $head = $sect; + $head =~ s/SEEALSO/SEE ALSO/; + print "=head1 $head\n\n"; + print scalar unmunge ($sects{$sect}); + print "\n"; + } +} + +sub usage +{ + die "usage: $0 [-D toggle...] [infile [outfile]]\n"; +} + +sub postprocess +{ + local $_ = $_[0]; + + # @value{foo} is replaced by whatever 'foo' is defined as. + while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) { + if (! exists $defs{$2}) { + print STDERR "Option $2 not defined\n"; + s/\Q$1\E//; + } else { + $value = $defs{$2}; + s/\Q$1\E/$value/; + } + } + + # Formatting commands. + # Temporary escape for @r. + s/\@r\{([^\}]*)\}/R<$1>/g; + s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g; + s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g; + s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g; + s/\@sc\{([^\}]*)\}/\U$1/g; + s/\@file\{([^\}]*)\}/F<$1>/g; + s/\@w\{([^\}]*)\}/S<$1>/g; + s/\@(?:dmn|math)\{([^\}]*)\}/$1/g; + + # Cross references are thrown away, as are @noindent and @refill. + # (@noindent is impossible in .pod, and @refill is unnecessary.) + # @* is also impossible in .pod; we discard it and any newline that + # follows it. Similarly, our macro @gol must be discarded. + + s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g; + s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g; + s/;\s+\@pxref\{(?:[^\}]*)\}//g; + s/\@noindent\s*//g; + s/\@refill//g; + s/\@gol//g; + s/\@\*\s*\n?//g; + + # @uref can take one, two, or three arguments, with different + # semantics each time. @url and @email are just like @uref with + # one argument, for our purposes. + s/\@(?:uref|url|email)\{([^\},]*)\}/<B<$1>>/g; + s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g; + s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g; + + # Un-escape <> at this point. + s/</</g; + s/>/>/g; + + # Now un-nest all B<>, I<>, R<>. Theoretically we could have + # indefinitely deep nesting; in practice, one level suffices. + 1 while s/([BIR])<([^<>]*)([BIR])<([^<>]*)>/$1<$2>$3<$4>$1</g; + + # Replace R<...> with bare ...; eliminate empty markup, B<>; + # shift white space at the ends of [BI]<...> expressions outside + # the expression. + s/R<([^<>]*)>/$1/g; + s/[BI]<>//g; + s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g; + s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g; + + # Extract footnotes. This has to be done after all other + # processing because otherwise the regexp will choke on formatting + # inside @footnote. + while (/\@footnote/g) { + s/\@footnote\{([^\}]+)\}/[$fnno]/; + add_footnote($1, $fnno); + $fnno++; + } + + return $_; +} + +sub unmunge +{ + # Replace escaped symbols with their equivalents. + local $_ = $_[0]; + + s/</E<lt>/g; + s/>/E<gt>/g; + s/{/\{/g; + s/}/\}/g; + s/&at;/\@/g; + s/&/&/g; + return $_; +} + +sub add_footnote +{ + unless (exists $sects{FOOTNOTES}) { + $sects{FOOTNOTES} = "\n=over 4\n\n"; + } + + $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++; + $sects{FOOTNOTES} .= $_[0]; + $sects{FOOTNOTES} .= "\n\n"; +} + +# stolen from Symbol.pm +{ + my $genseq = 0; + sub gensym + { + my $name = "GEN" . $genseq++; + my $ref = \*{$name}; + delete $::{$name}; + return $ref; + } +} diff --git a/gnu/usr.bin/gcc/contrib/warn_summary b/gnu/usr.bin/gcc/contrib/warn_summary new file mode 100755 index 00000000000..10b4c0d7831 --- /dev/null +++ b/gnu/usr.bin/gcc/contrib/warn_summary @@ -0,0 +1,210 @@ +#!/bin/sh +# +# This script parses the output of a gcc bootstrap when using warning +# flags and determines various statistics. +# +# usage: warn_summary [-llf] [-s stage] [-nosub|-ch|-cp|-f|-java|-ada|-intl|-fixinc] +# [-pass|-wpass] [file(s)] +# +# -llf +# Filter out long lines from the bootstrap output before any other +# action. This is useful for systems with broken awks/greps which choke +# on long lines. It is not done by default as it sometimes slows things +# down. +# +# -s number +# Take warnings from stage "Number". Stage 0 means show warnings from +# before and after the gcc bootstrap directory. E.g. libraries, etc. +# This presupposes using "gcc -W*" for the stage1 compiler. +# +# -nosub +# Only show warnings from the gcc top level directory. +# -ch|-cp|-f|-java|-ada|-intl|-fixinc +# Only show warnings from the specified language subdirectory. +# These override each other so only the last one passed takes effect. +# +# -pass +# Pass through the bootstrap output after filtering stage and subdir +# (useful for manual inspection.) This is all lines, not just warnings. +# -wpass +# Pass through only warnings from the bootstrap output after filtering +# stage and subdir. +# +# By Kaveh Ghazi (ghazi@caip.rutgers.edu) 12/13/97. + + +# Some awks choke on long lines, sed seems to do a better job. +# Truncate lines > 255 characters. RE '.\{255,\}' doesn't seem to work. :-( +# Only do this if -llf was specified, because it can really slow things down. +longLineFilter() +{ + if test -z "$llf" ; then + cat + else + sed 's/^\(...............................................................................................................................................................................................................................................................\).*/\1/' + fi +} + +# This function does one of three things. It either passes through +# all warning data, or passes through gcc toplevel warnings, or passes +# through a particular subdirectory set of warnings. +subdirectoryFilter() +{ + longLineFilter | ( + if test -z "$filter" ; then + # Pass through all lines. + cat + else + if test "$filter" = nosub ; then + # Omit all subdirectories. + egrep -v '/gcc/(ch|cp|f|java|intl|fixinc)/' + else + # Pass through only subdir $filter. + grep "/gcc/$filter/" + fi + fi ) +} + +# This function displays all lines from stageN of the bootstrap. If +# stage==0, then show lines prior to stage1 and lines from after the last +# stage. I.e. utilities, libraries, etc. +stageNfilter() +{ + if test "$stageN" -lt 1 ; then + # stage "0" means check everything *but* gcc. + $AWK "BEGIN{t=1} ; /^Bootstrapping the compiler/{t=0} ; /^Building runtime libraries/{t=1} ; {if(t==1)print}" + else + if test "$stageN" -eq 1 ; then + $AWK "/^Bootstrapping the compiler|^Building the C and C\+\+ compiler/{t=1} ; /stage$stageN/{t=0} ; {if(t==1)print}" + else + stageNminus1=`expr $stageN - 1` + $AWK "/stage${stageNminus1}\//{t=1} ; /stage$stageN/{t=0} ; {if(t==1)print}" + fi + fi +} + +# This function displays lines containing warnings. +warningFilter() +{ + grep ' warning: ' +} + +# This function replaces `xxx' with `???', where xxx is usually some +# variable or function name. This allows similar warnings to be +# counted together when summarizing. However it avoids replacing +# certain C keywords which are known appear in various messages. + +keywordFilter() { + sed 's/.*warning: //; + s/`\(int\)'"'"'/"\1"/g; + s/`\(long\)'"'"'/"\1"/g; + s/`\(char\)'"'"'/"\1"/g; + s/`\(inline\)'"'"'/"\1"/g; + s/`\(else\)'"'"'/"\1"/g; + s/`\(return\)'"'"'/"\1"/g; + s/`\(static\)'"'"'/"\1"/g; + s/`\(extern\)'"'"'/"\1"/g; + s/`\(const\)'"'"'/"\1"/g; + s/`\(noreturn\)'"'"'/"\1"/g; + s/`\(longjmp\)'"'"' or `\(vfork\)'"'"'/"\1" or "\2"/g; + s/`'"[^']*'/"'`???'"'/g;"' + s/.*format, .* arg (arg [0-9][0-9]*)/??? format, ??? arg (arg ???)/; + s/\([( ]\)arg [0-9][0-9]*\([) ]\)/\1arg ???\2/; + s/"\([^"]*\)"/`\1'"'"'/g' +} + +# This function strips out relative pathnames for source files printed +# by the warningFilter function. This is done so that as the snapshot +# directory name changes every week, the output of this program can be +# compared to previous runs without spurious diffs caused by source +# directory name changes. + +srcdirFilter() +{ + sed ' +s%^[^ ]*/\(gcc/\)%\1%; +s%^[^ ]*/\(include/\)%\1%; +s%^[^ ]*/\(texinfo/\)%\1%; +s%^[^ ]*/\(fastjar/\)%\1%; +s%^[^ ]*/\(zlib/\)%\1%; +s%^[^ ]*/\(lib[a-z23+-]*/\)%\1%;' +} + +# Start the main section. + +usage="usage: `basename $0` [-llf] [-s stage] [-nosub|-ch|-cp|-f|-java|-ada|-intl|-fixinc] [-pass|-wpass] [file(s)]" +stageN=3 +tmpfile=/tmp/tmp-warn.$$ + +# Remove $tmpfile on exit and various signals. +trap "rm -f $tmpfile" 0 +trap "rm -f $tmpfile ; exit 1" 1 2 3 5 9 13 15 + +# Find a good awk. +if test -z "$AWK" ; then + for AWK in gawk nawk awk ; do + if type $AWK 2>&1 | grep 'not found' > /dev/null 2>&1 ; then + : + else + break + fi + done +fi + +# Parse command line arguments. +while test -n "$1" ; do + case "$1" in + -llf) llf=1 ; shift ;; + -s) if test -z "$2"; then echo $usage 1>&2; exit 1; fi + stageN="$2"; shift 2 ;; + -s*) stageN="`expr $1 : '-s\(.*\)'`" ; shift ;; + -nosub|-ch|-cp|-f|-java|-ada|-intl|-fixinc) filter="`expr $1 : '-\(.*\)'`" ; shift ;; + -pass) pass=1 ; shift ;; + -wpass) pass=w ; shift ;; + -*) echo $usage 1>&2 ; exit 1 ;; + *) break ;; + esac +done + +# Check for a valid value of $stageN. +case "$stageN" in + [0-9]) ;; + *) echo "Stage <$stageN> must be in the range [0..9]." 1>&2 ; exit 1 ;; +esac + +for file in "$@" ; do + + stageNfilter < $file | subdirectoryFilter > $tmpfile + + # (Just) show me the warnings. + if test "$pass" != '' ; then + if test "$pass" = w ; then + warningFilter < $tmpfile + else + cat $tmpfile + fi + continue + fi + + if test -z "$filter" ; then + echo "Counting all warnings," + else + if test "$filter" = nosub ; then + echo "Counting non-subdirectory warnings," + else + echo "Counting warnings in the gcc/$filter subdirectory," + fi + fi + count=`warningFilter < $tmpfile | wc -l` + echo there are $count warnings in stage$stageN of this bootstrap. + + echo + echo Number of warnings per file: + warningFilter < $tmpfile | srcdirFilter | $AWK -F: '{print$1}' | sort | \ + uniq -c | sort -nr + + echo + echo Number of warning types: + warningFilter < $tmpfile | keywordFilter | sort | uniq -c | sort -nr + +done |