aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2002-05-12 21:50:48 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2002-05-12 21:50:48 +0000
commitf4603a02f970cde1167a7b0208e9500f7ee2f1c7 (patch)
treefb9e5c8f6a275c09cb3f77d4c3fda42fef054ef6
parent641c89aab9592a1b042122c5abafcb081cfce429 (diff)
downloadsrc-f4603a02f970cde1167a7b0208e9500f7ee2f1c7.tar.gz
src-f4603a02f970cde1167a7b0208e9500f7ee2f1c7.zip
Remove files not part of GCC 3.1.
Notes
Notes: svn path=/vendor/gcc/dist/; revision=96480
-rw-r--r--contrib/gcc/BUGS27
-rw-r--r--contrib/gcc/NEWS1539
-rw-r--r--contrib/gcc/PROBLEMS117
-rw-r--r--contrib/gcc/PROJECTS449
-rw-r--r--contrib/gcc/README26
-rw-r--r--contrib/gcc/README-bugs144
-rw-r--r--contrib/gcc/README.DWARF574
-rw-r--r--contrib/gcc/README.TRAD55
-rw-r--r--contrib/gcc/TESTS.FLUNK39
-rw-r--r--contrib/gcc/assert.h54
-rw-r--r--contrib/gcc/build-make35
-rw-r--r--contrib/gcc/c-iterate.c604
-rw-r--r--contrib/gcc/c-parse.gperf88
-rw-r--r--contrib/gcc/cccp.c11136
-rw-r--r--contrib/gcc/cexp.y1222
-rw-r--r--contrib/gcc/config/alpha/netbsd-elf.h32
-rw-r--r--contrib/gcc/config/alpha/t-crtbe9
-rw-r--r--contrib/gcc/config/alpha/vms-tramp.asm22
-rw-r--r--contrib/gcc/config/alpha/x-alpha2
-rw-r--r--contrib/gcc/config/alpha/xm-alpha.h76
-rw-r--r--contrib/gcc/config/alpha/xm-openbsd.h23
-rw-r--r--contrib/gcc/config/i386/config-nt.sed38
-rw-r--r--contrib/gcc/config/i386/dgux.c192
-rw-r--r--contrib/gcc/config/i386/os2.h76
-rw-r--r--contrib/gcc/config/i386/perform.h98
-rw-r--r--contrib/gcc/config/i386/sco.h117
-rw-r--r--contrib/gcc/config/i386/sco4.h86
-rw-r--r--contrib/gcc/config/i386/sco4dbx.h81
-rw-r--r--contrib/gcc/config/i386/sco5gas.h24
-rw-r--r--contrib/gcc/config/i386/scodbx.h84
-rw-r--r--contrib/gcc/config/i386/t-i386bare3
-rw-r--r--contrib/gcc/config/i386/t-vsta2
-rw-r--r--contrib/gcc/config/i386/t-winnt6
-rw-r--r--contrib/gcc/config/i386/win-nt.h150
-rw-r--r--contrib/gcc/config/i386/x-aix12
-rw-r--r--contrib/gcc/config/i386/x-cygwin4
-rw-r--r--contrib/gcc/config/i386/x-dgux11
-rw-r--r--contrib/gcc/config/i386/x-djgpp24
-rw-r--r--contrib/gcc/config/i386/x-isc3
-rw-r--r--contrib/gcc/config/i386/x-isc34
-rw-r--r--contrib/gcc/config/i386/x-ncr300034
-rw-r--r--contrib/gcc/config/i386/x-next3
-rw-r--r--contrib/gcc/config/i386/x-osf1elf8
-rw-r--r--contrib/gcc/config/i386/x-osfrose27
-rw-r--r--contrib/gcc/config/i386/x-sco7
-rw-r--r--contrib/gcc/config/i386/x-sco410
-rw-r--r--contrib/gcc/config/i386/x-sco510
-rw-r--r--contrib/gcc/config/i386/x-sysv31
-rw-r--r--contrib/gcc/config/i386/x-vsta1
-rw-r--r--contrib/gcc/config/i386/xm-aix.h2
-rw-r--r--contrib/gcc/config/i386/xm-bsd386.h3
-rw-r--r--contrib/gcc/config/i386/xm-dgux.h4
-rw-r--r--contrib/gcc/config/i386/xm-dos.h38
-rw-r--r--contrib/gcc/config/i386/xm-freebsd.h4
-rw-r--r--contrib/gcc/config/i386/xm-gnu.h5
-rw-r--r--contrib/gcc/config/i386/xm-i386.h43
-rw-r--r--contrib/gcc/config/i386/xm-isc.h4
-rw-r--r--contrib/gcc/config/i386/xm-linux.h24
-rw-r--r--contrib/gcc/config/i386/xm-lynx.h33
-rw-r--r--contrib/gcc/config/i386/xm-next.h5
-rw-r--r--contrib/gcc/config/i386/xm-openbsd.h23
-rw-r--r--contrib/gcc/config/i386/xm-os2.h75
-rw-r--r--contrib/gcc/config/i386/xm-osf.h2
-rw-r--r--contrib/gcc/config/i386/xm-osf1elf.h6
-rw-r--r--contrib/gcc/config/i386/xm-sco.h13
-rw-r--r--contrib/gcc/config/i386/xm-sco5.h7
-rw-r--r--contrib/gcc/config/i386/xm-sun.h21
-rw-r--r--contrib/gcc/config/i386/xm-sysv3.h3
-rw-r--r--contrib/gcc/config/i386/xm-sysv4.h5
-rw-r--r--contrib/gcc/config/i386/xm-uwin.h39
-rw-r--r--contrib/gcc/config/i386/xm-winnt.h24
-rw-r--r--contrib/gcc/config/sparc/sol2-sld-64.h335
-rw-r--r--contrib/gcc/config/sparc/sol2-sld.h9
-rw-r--r--contrib/gcc/config/sparc/t-sp642
-rw-r--r--contrib/gcc/config/sparc/t-sunos407
-rw-r--r--contrib/gcc/config/sparc/x-sysv42
-rw-r--r--contrib/gcc/config/sparc/xm-linux.h26
-rw-r--r--contrib/gcc/config/sparc/xm-lynx.h39
-rw-r--r--contrib/gcc/config/sparc/xm-openbsd.h23
-rw-r--r--contrib/gcc/config/sparc/xm-pbd.h10
-rw-r--r--contrib/gcc/config/sparc/xm-sol2.h4
-rw-r--r--contrib/gcc/config/sparc/xm-sp64.h27
-rw-r--r--contrib/gcc/config/sparc/xm-sparc.h49
-rw-r--r--contrib/gcc/config/sparc/xm-sysv4-64.h27
-rw-r--r--contrib/gcc/config/sparc/xm-sysv4.h48
-rw-r--r--contrib/gcc/config/x-linux5
-rw-r--r--contrib/gcc/config/x-linux-aout14
-rw-r--r--contrib/gcc/config/x-lynx6
-rw-r--r--contrib/gcc/config/x-svr49
-rw-r--r--contrib/gcc/config/xm-alloca.h4
-rw-r--r--contrib/gcc/config/xm-freebsd.h24
-rw-r--r--contrib/gcc/config/xm-gnu.h32
-rw-r--r--contrib/gcc/config/xm-interix.h77
-rw-r--r--contrib/gcc/config/xm-linux.h33
-rw-r--r--contrib/gcc/config/xm-lynx.h51
-rw-r--r--contrib/gcc/config/xm-openbsd.h35
-rw-r--r--contrib/gcc/config/xm-siglist.h6
-rw-r--r--contrib/gcc/config/xm-std32.h34
-rw-r--r--contrib/gcc/config/xm-svr3.h25
-rw-r--r--contrib/gcc/config/xm-svr4.h29
-rw-r--r--contrib/gcc/configure.lang233
-rw-r--r--contrib/gcc/cp/Makefile.in324
-rw-r--r--contrib/gcc/cp/errfn.c352
-rw-r--r--contrib/gcc/cp/exception.cc343
-rw-r--r--contrib/gcc/cp/gxx.gperf111
-rw-r--r--contrib/gcc/cp/gxxint.texi2075
-rw-r--r--contrib/gcc/cp/inc/exception39
-rw-r--r--contrib/gcc/cp/inc/new42
-rw-r--r--contrib/gcc/cp/inc/new.h11
-rw-r--r--contrib/gcc/cp/inc/typeinfo58
-rw-r--r--contrib/gcc/cp/input.c207
-rw-r--r--contrib/gcc/cp/new.cc42
-rw-r--r--contrib/gcc/cp/new1.cc89
-rw-r--r--contrib/gcc/cp/new2.cc80
-rw-r--r--contrib/gcc/cp/sig.c1067
-rw-r--r--contrib/gcc/cp/tinfo.cc134
-rw-r--r--contrib/gcc/cp/tinfo.h55
-rw-r--r--contrib/gcc/cp/tinfo2.cc300
-rw-r--r--contrib/gcc/cp/xref.c829
-rw-r--r--contrib/gcc/cpp.texi2967
-rw-r--r--contrib/gcc/cppalloc.c81
-rw-r--r--contrib/gcc/cppulp.c26
-rw-r--r--contrib/gcc/cross-make14
-rw-r--r--contrib/gcc/doprint.c295
-rwxr-xr-xcontrib/gcc/dostage22
-rwxr-xr-xcontrib/gcc/dostage33
-rw-r--r--contrib/gcc/dwarfout.h42
-rw-r--r--contrib/gcc/eh-common.h142
-rwxr-xr-xcontrib/gcc/exgettext118
-rw-r--r--contrib/gcc/extend.texi3782
-rw-r--r--contrib/gcc/f/BUGS159
-rw-r--r--contrib/gcc/f/INSTALL352
-rw-r--r--contrib/gcc/f/Makefile.in529
-rw-r--r--contrib/gcc/f/NEWS412
-rw-r--r--contrib/gcc/f/assert.j27
-rw-r--r--contrib/gcc/f/config.j27
-rw-r--r--contrib/gcc/f/convert.j28
-rw-r--r--contrib/gcc/f/flags.j27
-rw-r--r--contrib/gcc/f/g77install.texi2251
-rw-r--r--contrib/gcc/f/glimits.j28
-rw-r--r--contrib/gcc/f/hconfig.j27
-rw-r--r--contrib/gcc/f/input.j27
-rw-r--r--contrib/gcc/f/output.j27
-rw-r--r--contrib/gcc/f/proj.c68
-rw-r--r--contrib/gcc/f/rtl.j28
-rw-r--r--contrib/gcc/f/system.j27
-rw-r--r--contrib/gcc/f/tconfig.j27
-rw-r--r--contrib/gcc/f/tm.j27
-rw-r--r--contrib/gcc/f/toplev.j27
-rw-r--r--contrib/gcc/f/tree.j28
-rwxr-xr-xcontrib/gcc/fixcpp109
-rw-r--r--contrib/gcc/fixinc-nt.sed5
-rwxr-xr-xcontrib/gcc/fixincludes3265
-rw-r--r--contrib/gcc/frame.c872
-rw-r--r--contrib/gcc/frame.h85
-rw-r--r--contrib/gcc/gansidecl.h85
-rw-r--r--contrib/gcc/gcc.texi4776
-rw-r--r--contrib/gcc/gcov.texi344
-rw-r--r--contrib/gcc/ginclude/math-3300.h461
-rw-r--r--contrib/gcc/ginclude/math-68881.h529
-rw-r--r--contrib/gcc/ginclude/ppc-asm.h170
-rw-r--r--contrib/gcc/ginclude/proto.h4
-rw-r--r--contrib/gcc/ginclude/va-alpha.h128
-rw-r--r--contrib/gcc/ginclude/va-arc.h111
-rw-r--r--contrib/gcc/ginclude/va-c4x.h34
-rw-r--r--contrib/gcc/ginclude/va-clipper.h60
-rw-r--r--contrib/gcc/ginclude/va-h8300.h56
-rw-r--r--contrib/gcc/ginclude/va-i860.h214
-rw-r--r--contrib/gcc/ginclude/va-i960.h79
-rw-r--r--contrib/gcc/ginclude/va-m32r.h86
-rw-r--r--contrib/gcc/ginclude/va-m88k.h87
-rw-r--r--contrib/gcc/ginclude/va-mips.h277
-rw-r--r--contrib/gcc/ginclude/va-mn10200.h37
-rw-r--r--contrib/gcc/ginclude/va-mn10300.h35
-rw-r--r--contrib/gcc/ginclude/va-pa.h52
-rw-r--r--contrib/gcc/ginclude/va-ppc.h255
-rw-r--r--contrib/gcc/ginclude/va-pyr.h130
-rw-r--r--contrib/gcc/ginclude/va-sh.h229
-rw-r--r--contrib/gcc/ginclude/va-sparc.h165
-rw-r--r--contrib/gcc/ginclude/va-spur.h64
-rw-r--r--contrib/gcc/ginclude/va-v850.h34
-rw-r--r--contrib/gcc/install.texi2381
-rw-r--r--contrib/gcc/invoke.texi6785
-rwxr-xr-xcontrib/gcc/just-fixinc39
-rw-r--r--contrib/gcc/libgcc1-test.c106
-rw-r--r--contrib/gcc/libgcc1.c596
-rwxr-xr-xcontrib/gcc/listing227
-rw-r--r--contrib/gcc/makefile.vms413
-rw-r--r--contrib/gcc/md.texi4258
-rw-r--r--contrib/gcc/objc/Makefile.in73
-rw-r--r--contrib/gcc/objc/objc.gperf64
-rwxr-xr-xcontrib/gcc/patch-apollo-includes69
-rw-r--r--contrib/gcc/pcp.h101
-rw-r--r--contrib/gcc/pself.c1
-rw-r--r--contrib/gcc/pself1.c1
-rw-r--r--contrib/gcc/pself2.c1
-rw-r--r--contrib/gcc/pself3.c1
-rw-r--r--contrib/gcc/pself4.c2
-rw-r--r--contrib/gcc/pself5.c5
-rw-r--r--contrib/gcc/rtl.texi2998
-rw-r--r--contrib/gcc/sched.c4470
-rw-r--r--contrib/gcc/stupid.c770
-rw-r--r--contrib/gcc/tm.texi7691
-rw-r--r--contrib/gcc/unprotoize.c2
204 files changed, 0 insertions, 80672 deletions
diff --git a/contrib/gcc/BUGS b/contrib/gcc/BUGS
deleted file mode 100644
index 2d875a092efb..000000000000
--- a/contrib/gcc/BUGS
+++ /dev/null
@@ -1,27 +0,0 @@
-If you think you may have found a bug in GCC, please
-read the Bugs section of the GCC manual for advice on
-
-(1) how to tell when to report a bug,
-(2) where to send your bug report, and
-(3) how to write a useful bug report and what information
-it needs to have.
-
-There are three ways to read the Bugs section.
-
-(1) In a printed copy of the GCC manual. You can order one from the
-Free Software Foundation; see the file ORDERS. But if you don't have
-a copy on hand and you think you have found a bug, you shouldn't wait
-to get a printed manual; you should read the section right away as
-described below.
-
-(2) With Info. Start Emacs, do C-h i to enter Info,
-then m gcc RET to get to the GCC manual, then m Bugs RET
-to get to the section on bugs. Or use standalone Info in
-a like manner. (Standalone Info is part of the Texinfo distribution.)
-
-(3) By hand. Search for the chapter "Reporting Bugs" in gcc.texi, or
- cat /usr/local/info/gcc* | more "+/^File: gcc.info, Node: Bugs,"
-
-You may also want to take a look at the GCC FAQ, in which there are
-additional instructions for submitting bug reports:
- http://www.gnu.org/software/gcc/faq.html#bugreport
diff --git a/contrib/gcc/NEWS b/contrib/gcc/NEWS
deleted file mode 100644
index 5023a93b5214..000000000000
--- a/contrib/gcc/NEWS
+++ /dev/null
@@ -1,1539 +0,0 @@
-This file contains information about GCC releases which has been
-generated automatically from the online release notes. This file
-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.
-
-======================================================================
-http://gcc.gnu.org/gcc-2.95/gcc-2.95.3.html
-
- GCC 2.95.3
-
- March 16, 2001
-
- The GNU project and the GCC developers are pleased to announce the
- release of GCC version 2.95.3. GCC used to stand for the GNU C
- Compiler, but since the compiler supports several other languages
- aside from C, it now stands for the GNU Compiler Collection.
-
- This is a minor release to address several bugs in the [1]GCC version
- 2.95.2 release.
-
- * Generic bugfixes and improvements
- + Fix numerous problems that caused incorrect optimization in
- the register reloading code.
- + Fix numerous problems that caused incorrect optimization in
- the loop optimizer.
- + Fix aborts in the functions build_insn_chain and scan_loops
- under some circumstances.
- + Fix an alias analysis bug.
- + Fix an infinite compilation bug in the combiner.
- + A few problems with complex number support have been fixed.
- + It is no longer possible for gcc to act as a fork bomb when
- installed incorrectly.
- + The -fpack-struct option should be recognized now.
- + Fixed a bug that caused incorrect code to be generated due to
- a lost stack adjustment.
- * Platform specific bugfixes and improvements
- + Support building ARM toolchains hosted on Windows.
- + Fix attribute calculations in ARM toolchains.
- + arm-linux support has been improved.
- + Fix a PIC failure on sparc targets.
- + On ix86 targets, the regparm attribute should now work
- reliably.
- + Several updates for the h8300 port.
-
- The whole suite has been extensively [2]regression tested and
- [3]package tested. It should be reliable and suitable for widespread
- use.
-
- The GCC 2.95 release has several new optimizations, new targets, new
- languages and other new features as compared to EGCS 1.1 or GCC 2.8.
- See the [4]new features page for a more complete list of new features
- found in the GCC 2.95 releases.
-
- The sources include installation instructions in both HTML and
- plaintext forms in the install directory in the distribution. However,
- the most up to date [5]installation instructions and [6]build/test
- status are on the web pages. We will update those pages as new
- information becomes available.
-
- The GCC developers would like to thank the numerous people that have
- contributed new features, test results, bugfixes, etc to GCC. This
- [7]amazing group of volunteers is what makes GCC successful.
-
- And finally, we can't in good conscience fail to mention some
- [8]caveats to using GCC 2.95.3.
-
- Download GCC 2.95.3 from the [9]GNU FTP server (ftp://ftp.gnu.org)
- Download GCC 2.95.3 from the [10]GCC FTP server (ftp://gcc.gnu.org)
- [11]Find a GNU mirror site
- [12]Find a GCC mirror site
-
- For additional information about GCC please see the [13]GCC project
- web server or contact the [14]GCC development mailing list.
- _________________________________________________________________
-
-
- [15]The GCC team
- Last modified 2001-03-16
-
-References
-
- 1. http://gcc.gnu.org/gcc-2.95/gcc-2.95.2.html
- 2. http://gcc.gnu.org/gcc-2.95/regress.html
- 3. http://gcc.gnu.org/gcc-2.95/othertest.html
- 4. http://gcc.gnu.org/gcc-2.95/features.html
- 5. http://gcc.gnu.org/install/index.html
- 6. http://gcc.gnu.org/gcc-2.95/buildstat.html
- 7. http://gcc.gnu.org/thanks.html
- 8. http://gcc.gnu.org/gcc-2.95/caveats.html
- 9. ftp://ftp.gnu.org/pub/gnu/gcc/
- 10. ftp://gcc.gnu.org/pub/gcc/releases/index.html
- 11. http://www.gnu.org/order/ftp.html
- 12. http://gcc.gnu.org/mirrors.html
- 13. http://gcc.gnu.org/index.html
- 14. mailto:gcc@gcc.gnu.org
- 15. http://gcc.gnu.org/about.html
-======================================================================
-http://gcc.gnu.org/gcc-2.95/gcc-2.95.2.html
-
- GCC 2.95.2
-
- October 27, 1999
-
- The GNU project and the GCC developers are pleased to announce the
- release of GCC version 2.95.2. GCC used to stand for the GNU C
- Compiler, but since the compiler supports several other languages
- aside from C, it now stands for the GNU Compiler Collection.
-
- This is a minor release to address several bugs in the GCC version
- 2.95.1 release.
-
- The -fstrict-aliasing is not enabled by default for GCC 2.95.2. While
- the optimizations performed by -fstrict-aliasing are valid according
- to the C and C++ standards, the optimization have caused some
- problems, particularly with old non-conforming code.
-
- The GCC developers are experimenting with ways to warn users about
- code which violates the C/C++ standards, but those warnings are not
- ready for widespread use at this time. Rather than wait for those
- warnings the GCC developers have chosen to disable -fstrict-aliasing
- by default for the GCC 2.95.2 release.
-
- We strongly encourage developers to find and fix code which violates
- the C/C++ standards as -fstrict-aliasing may be enabled by default in
- future releases. Use the option -fstrict-aliasing to re-enable these
- optimizations.
-
- * Generic bugfixes and improvements
- + Fix incorrectly optimized memory reference in global common
- subexpression elimination (GCSE) optimization pass.
- + Fix code generation bug in regmove.c in which it could
- incorrectly change a "const" value.
- + Fix bug in optimization of conditionals involving volatile
- memory references.
- + Avoid over-allocation of stack space for some procedures.
- + Fixed bug in the compiler which caused incorrect optimization
- of an obscure series of bit manipulations, shifts and
- arithmetic.
- + Fixed register allocator bug which caused teTeX to be
- mis-compiled on Sparc targets.
- + Avoid incorrect optimization of degenerate case statements
- for certain targets such as the ARM.
- + Fix out of range memory reference in the jump optimizer.
- + Avoid dereferencing null pointer in fix-header.
- + Fix test for GCC specific features so that it is possible to
- bootstrap with gcc-2.6.2 and older versions of GCC.
- + Fix typo in scheduler which could potentially cause out of
- range memory accesses.
- + Avoid incorrect loop reversal which caused incorrect code for
- certain loops on PowerPC targets.
- + Avoid incorrect optimization of switch statements on certain
- targets (for example the ARM).
- * Platform specific bugfixes and improvements
- + Work around bug in Sun V5.0 compilers which caused bootstrap
- comparison failures on Sparc targets.
- + Fix Sparc backend bug which caused aborts in final.c.
- + Fix sparc-hal-solaris2* configuration fragments.
- + Fix bug in sparc block profiling.
- + Fix obscure code generation bug for the PARISC targets.
- + Define __STDC_EXT__ for HPUX configurations.
- + Various POWERPC64 code generation bugfixes.
- + Fix abort for PPC targets using ELF (ex GNU/Linux).
- + Fix collect2 problems for AIX targets.
- + Correct handling of .file directive for PPC targets.
- + Fix bug in fix_trunc x86 patterns.
- + Fix x86 port to correctly pop the FP stack for functions that
- return structures in memory.
- + Fix minor bug in strlen x86 pattern.
- + Use stabs debugging instead of dwarf1 for x86-solaris
- targets.
- + Fix template repository code to handle leading underscore in
- mangled names.
- + Fix weak/weak alias support for OpenBSD.
- + GNU/Linux for the ARM has C++ compatible include files.
- * Language & Runtime specific fixes.
- + Fix handling of constructor attribute in the C front-end
- which caused problems building the Chill runtime library on
- some targets.
- + Fix minor problem merging type qualifiers in the C front-end.
- + Fix aliasing bug for pointers and references (C/C++).
- + Fix incorrect "non-constant initializer bug" when
- -traditional or -fwritable-strings is enabled.
- + Fix build error for Chill front-end on SunOS.
- + Do not complain about duplicate instantiations when using
- -frepo (C++)
- + Fix array bounds handling in C++ front-end which caused
- problems with dwarf debugging information in some
- circumstances.
- + Fix minor namespace problem.
- + Fix problem linking java programs.
-
- The whole suite has been extensively [1]regression tested and
- [2]package tested. It should be reliable and suitable for widespread
- use.
-
- The GCC 2.95 release has several new optimizations, new targets, new
- languages and other new features as compared to EGCS 1.1 or GCC 2.8.
- See the [3]new features page for a more complete list of new features
- found in the GCC 2.95 releases.
-
- The sources include installation instructions in both HTML and
- plaintext forms in the install directory in the distribution. However,
- the most up to date [4]installation instructions and [5]build/test
- status are on the web pages. We will update those pages as new
- information becomes available.
-
- The GCC developers would like to thank the numerous people that have
- contributed new features, test results, bugfixes, etc to GCC. This
- [6]amazing group of volunteers is what makes GCC successful.
-
- And finally, we can't in good conscience fail to mention some
- [7]caveats to using GCC 2.95.2.
-
- Download GCC 2.95.2 from the [8]GNU FTP server (ftp://ftp.gnu.org)
- Download GCC 2.95.2 from the [9]GCC/EGCS FTP server
- (ftp://gcc.gnu.org)
- [10]Find a GNU mirror site
- [11]Find a GCC/EGCS mirror site
-
- For additional information about GCC please see the [12]GCC project
- web server or contact the [13]GCC development mailing list.
- _________________________________________________________________
-
-
- [14]The GCC team
- Last modified 2001-02-12
-
-References
-
- 1. http://gcc.gnu.org/gcc-2.95/regress.html
- 2. http://gcc.gnu.org/gcc-2.95/othertest.html
- 3. http://gcc.gnu.org/gcc-2.95/features.html
- 4. http://gcc.gnu.org/install/index.html
- 5. http://gcc.gnu.org/gcc-2.95/buildstat.html
- 6. http://gcc.gnu.org/thanks.html
- 7. http://gcc.gnu.org/gcc-2.95/caveats.html
- 8. ftp://ftp.gnu.org/pub/gnu/gcc/
- 9. ftp://gcc.gnu.org/pub/gcc/releases/index.html
- 10. http://www.gnu.org/order/ftp.html
- 11. http://gcc.gnu.org/mirrors.html
- 12. http://gcc.gnu.org/index.html
- 13. mailto:gcc@gcc.gnu.org
- 14. http://gcc.gnu.org/about.html
-======================================================================
-http://gcc.gnu.org/gcc-2.95/gcc-2.95.1.html
-
- GCC 2.95.1
-
- August 19, 1999
-
- The GNU project and the GCC/EGCS developers are pleased to announce
- the release of GCC version 2.95.1. GCC used to stand for the GNU C
- Compiler, but since the compiler supports several other languages
- aside from C, it now stands for the GNU Compiler Collection.
-
- This is a minor release to address several bugs in the GCC version
- 2.95 release.
-
- * Generic bugfixes and improvements
- + Various documentation fixes related to the GCC/EGCS merger.
- + Fix memory management bug which could lead to spurious
- aborts, core dumps or random parsing errors in the compiler.
- + Fix a couple bugs in the dwarf1 and dwarf2 debug record
- support.
- + Fix infinite loop in the CSE optimizer.
- + Avoid undefined behavior in compiler FP emulation code
- + Fix install problem when prefix is overridden on the make
- install command.
- + Fix problem with unwanted installation of assert.h on some
- systems.
- + Fix problem with finding the wrong assembler in a single tree
- build.
- + Avoid increasing the known alignment of a register that is
- already known to be a pointer.
- * Platform specific bugfixes and improvements
- + Codegen bugfix for prologue/epilogue for cpu32 target.
- + Fix long long code generation bug for the Coldfire target.
- + Fix various aborts in the SH compiler.
- + Fix bugs in libgcc support library for the SH.
- + Fix alpha ev6 code generation bug.
- + Fix problems with EXIT_SUCCESS/EXIT_FAILURE redefinitions on
- AIX platforms.
- + Fix -fpic code generation bug for rs6000/ppc svr4 targets.
- + Fix varargs/stdarg code generation bug for rs6000/ppc svr4
- targets.
- + Fix weak symbol handling for rs6000/ppc svr4 targets.
- + Fix various problems with 64bit code generation for the
- rs6000/ppc port.
- + Fix codegen bug which caused tetex to be mis-compiled on the
- x86
- + Fix compiler abort in new cfg code exposed by x86 port.
- + Fix out of range array reference in code convert flat
- registers to the x87 stacked FP register file.
- + Fix minor vxworks configuration bug
- + Fix return type of bsearch for SunOS 4.x.
- * Language & Runtime specific fixes.
- + The G++ signature extension has been deprecated. It will be
- removed in the next major release of G++. Use of signatures
- will result in a warning from the compiler.
- + Several bugs relating to templates and namespaces were fixed.
- + A bug that caused crashes when combining templates with -g on
- DWARF1 platforms was fixed.
- + Pointers-to-members, virtual functions, and multiple
- inheritance should now work together correctly.
- + Some code-generation bugs relating to function try blocks
- were fixed.
- + G++ is a little bit more lenient with certain archaic
- constructs than in GCC 2.95.
- + Fix to prevent shared library version #s from bring truncated
- to 1 digit
- + Fix missing std:: in the libstdc++ library.
- + Fix stream locking problems in libio.
- + Fix problem in java compiler driver.
-
- The whole suite has been extensively [1]regression tested and
- [2]package tested. It should be reliable and suitable for widespread
- use.
-
- The compiler has several new optimizations, new targets, new languages
- and other new features. See the [3]new features page for a more
- complete list of new features found in the GCC 2.95 releases.
-
- The sources include installation instructions in both HTML and
- plaintext forms in the install directory in the distribution. However,
- the most up to date [4]installation instructions and [5]build/test
- status are on the web pages. We will update those pages as new
- information becomes available.
-
- The GCC developers would like to thank the numerous people that have
- contributed new features, test results, bugfixes, etc to GCC. This
- [6]amazing group of volunteers is what makes GCC successful.
-
- And finally, we can't in good conscience fail to mention some
- [7]caveats to using GCC 2.95.1.
-
- Download GCC 2.95.1 from the [8]GNU FTP server (ftp://ftp.gnu.org)
- Download GCC 2.95.1 from the [9]GCC/EGCS FTP server
- (ftp://go.cygnus.com)
- [10]Find a GNU mirror site
- [11]Find a GCC/EGCS mirror site
-
- For additional information about GCC please see the [12]GCC project
- web server or contact the [13]GCC development mailing list.
- _________________________________________________________________
-
-
- [14]The GCC team
- Last modified 2001-02-12
-
-References
-
- 1. http://gcc.gnu.org/gcc-2.95/regress.html
- 2. http://gcc.gnu.org/gcc-2.95/othertest.html
- 3. http://gcc.gnu.org/gcc-2.95/features.html
- 4. http://gcc.gnu.org/install/index.html
- 5. http://gcc.gnu.org/gcc-2.95/buildstat.html
- 6. http://gcc.gnu.org/thanks.html
- 7. http://gcc.gnu.org/gcc-2.95/caveats.html
- 8. ftp://ftp.gnu.org/pub/gnu/gcc/
- 9. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 10. http://www.gnu.org/order/ftp.html
- 11. http://gcc.gnu.org/mirrors.html
- 12. http://gcc.gnu.org/index.html
- 13. mailto:gcc@gcc.gnu.org
- 14. http://gcc.gnu.org/about.html
-======================================================================
-http://gcc.gnu.org/gcc-2.95/gcc-2.95.html
-
- GCC 2.95
-
- July 31, 1999
-
- The GNU project and the GCC/EGCS developers are pleased to announce
- the release of GCC version 2.95. GCC used to stand for the GNU C
- Compiler, but since the compiler supports several other languages
- aside from C, it now stands for the GNU Compiler Collection.
-
- This is the first release of GCC since the April 1999 GCC/EGCS
- reunification and includes nearly a year's worth of new development
- and bugfixes.
-
- The whole suite has been extensively [1]regression tested and
- [2]package tested. It should be reliable and suitable for widespread
- use.
-
- The compiler has several new optimizations, new targets, new languages
- and other new features. See the [3]new features page for a more
- complete list of new features found in the GCC 2.95 releases.
-
- The sources include installation instructions in both HTML and
- plaintext forms in the install directory in the distribution. However,
- the most up to date [4]installation instructions and [5]build/test
- status are on the web pages. We will update those pages as new
- information becomes available.
-
- The GCC developers would like to thank the numerous people that have
- contributed new features, test results, bugfixes, etc to GCC. This
- [6]amazing group of volunteers is what makes GCC successful.
-
- And finally, we can't in good conscience fail to mention some
- [7]caveats to using GCC 2.95.
-
- Download GCC 2.95 from the [8]GNU FTP server (ftp://ftp.gnu.org)
- Download GCC 2.95 from the [9]GCC/EGCS FTP server
- (ftp://go.cygnus.com)
- [10]Find a GNU mirror site
- [11]Find a GCC/EGCS mirror site
-
- For additional information about GCC please see the [12]GCC project
- web server or contact the [13]GCC development mailing list.
- _________________________________________________________________
-
-
- [14]The GCC team
- Last modified 2001-02-12
-
-References
-
- 1. http://gcc.gnu.org/gcc-2.95/regress.html
- 2. http://gcc.gnu.org/gcc-2.95/othertest.html
- 3. http://gcc.gnu.org/gcc-2.95/features.html
- 4. http://gcc.gnu.org/install/index.html
- 5. http://gcc.gnu.org/gcc-2.95/buildstat.html
- 6. http://gcc.gnu.org/thanks.html
- 7. http://gcc.gnu.org/gcc-2.95/caveats.html
- 8. ftp://ftp.gnu.org/pub/gnu/gcc/
- 9. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 10. http://www.gnu.org/order/ftp.html
- 11. http://gcc.gnu.org/mirrors.html
- 12. http://gcc.gnu.org/index.html
- 13. mailto:gcc@gcc.gnu.org
- 14. http://gcc.gnu.org/about.html
-======================================================================
-http://gcc.gnu.org/gcc-2.95/features.html
-
- GCC 2.95 New Features
-
- * General Optimizer Improvements:
- + [1]Localized register spilling to improve speed and code
- density especially on small register class machines.
- + [2]Global CSE using lazy code motion algorithms.
- + [3]Improved global constant/copy propagation.
- + [4]Improved control flow graph analysis and manipulation.
- + [5]Local dead store elimination.
- + [6]Memory Load hoisting/store sinking in loops.
- + [7]Type based alias analysis is enabled by default. Note this
- feature will expose bugs in the Linux kernel. Please refer to
- the [8]FAQ for additional information on this issue.
- + Major revamp of GIV detection, combination and simplification
- to improve loop performance.
- + Major improvements to register allocation and reloading.
- * New Languages and Language specific improvements
- + [9]Many C++ improvements.
- + [10]Many Fortran improvements.
- + [11]Java front-end has been integrated. A [12]runtime library
- is available separately.
- + [13]ISO C99 support
- + [14]Chill front-end and runtime has been integrated.
- + Boehm garbage collector support in libobjc.
- + More support for various pragmas which appear in vendor
- include files
- * New Targets and Target Specific Improvements
- + [15]Sparc backend rewrite.
- + -mschedule=8000 will optimize code for PA8000 class
- processors; -mpa-risc-2-0 will generate code for PA2.0
- processors
- + Various micro-optimizations for the ia32 port. K6
- optimizations
- + Compiler will attempt to align doubles in the stack on the
- ia32 port
- + Alpha EV6 support
- + PowerPC 750
- + RS6000/PowerPC: -mcpu=401 was added as an alias for
- -mcpu=403. -mcpu=e603e was added to do -mcpu=603e and
- -msoft-float.
- + c3x, c4x
- + HyperSparc
- + SparcLite86x
- + sh4
- + Support for new systems (OpenBSD, FreeBSD, UWIN, Interix,
- arm-linux)
- + vxWorks targets include support for vxWorks threads
- + StrongARM 110 and ARM9 support added. ARM Scheduling
- parameters rewritten.
- + Various changes to the MIPS port to avoid assembler macros,
- which
- + Various performance improvements to the i960 port.
- + Major rewrite of ns32k port in turn improves performance
- * Other significant improvements
- + [16]Ability to dump cfg information and display it using vcg.
- + The new faster scheme for fixing vendor header files is
- enabled by default.
- + Experimental internationalization support.
- + multibyte character support
- + Some compile-time speedups for pathological problems
- + Better support for complex types
- * Plus the usual mountain of bugfixes
- * Core compiler is based on the gcc2 development tree from Sept 30,
- 1998, so we have all of the [17]features found in GCC 2.8.
- _________________________________________________________________
-
-
- [18]The GCC team
- Last modified 2001-02-12
-
-References
-
- 1. http://gcc.gnu.org/news/spill.html
- 2. http://gcc.gnu.org/news/lcm.html
- 3. http://gcc.gnu.org/news/cprop.html
- 4. http://gcc.gnu.org/news/cfg.html
- 5. http://gcc.gnu.org/news/dse.html
- 6. http://gcc.gnu.org/news/hoist.html
- 7. http://gcc.gnu.org/news/alias.html
- 8. http://gcc.gnu.org/fom_serv/cache/24.html
- 9. http://gcc.gnu.org/gcc-2.95/c++features.html
- 10. http://gcc.gnu.org/onlinedocs/g77_news.html
- 11. http://sources.redhat.com/java/gcj-announce.txt
- 12. http://gcc.gnu.org/javaannounce.html
- 13. http://gcc.gnu.org/c99status.html
- 14. http://gcc.gnu.org/news/chill.html
- 15. http://gcc.gnu.org/news/sparc.html
- 16. http://gcc.gnu.org/news/egcs-vcg.html
- 17. http://gcc.gnu.org/egcs-1.0/features-2.8.html
- 18. http://gcc.gnu.org/about.html
-======================================================================
-http://gcc.gnu.org/gcc-2.95/caveats.html
-
- GCC 2.95 Caveats
-
- * GCC 2.95 will issue an error for invalid asm statements that had
- been silently accepted by earlier versions of the compiler. This
- is particularly noticeable when compiling older versions of the
- Linux kernel (2.0.xx). Please refer to the [1]FAQ for more
- information on this issue.
- * GCC 2.95 implements type based alias analysis to disambiguate
- memory references. Some programs, particularly the Linux kernel
- violate ANSI/ISO aliasing rules and therefore may not operate
- correctly when compiled with GCC 2.95. Please refer to the [2]FAQ
- for more information on this issue.
- * GCC 2.95 has a known bug in its handling of complex variables for
- 64bit targets. Instead of silently generating incorrect code, GCC
- 2.95 will issue a fatal error for situations it can not handle.
- This primarily affects the Fortran community as Fortran makes more
- use of complex variables than C or C++.
- * GCC 2.95 has an integrated libstdc++, but does not have an
- integrated libg++. Furthermore old libg++ releases will not work
- with GCC 2.95. You can retrieve a recent copy of libg++ from the
- [3]GCC ftp server.
- Note most C++ programs only need libstdc++.
- * Exception handling may not work with shared libraries,
- particularly on alphas, hppas, rs6000/powerpc and mips based
- platforms. Exception handling is known to work on x86 GNU/Linux
- platforms with shared libraries.
- * In general, GCC 2.95 is more rigorous about rejecting invalid C++
- code or deprecated C++ constructs than G++ 2.7, G++ 2.8, EGCS 1.0,
- or EGCS 1.1. As a result it may be necessary to fix C++ code
- before it will compile with GCC 2.95.
- * G++ is also converting toward the ISO C++ standard; as a result
- code which was previously valid (and thus accepted by other
- compilers and older versions of g++) may no longer be accepted.
- The flag -fpermissive may allow some non-conforming code to
- compile with GCC 2.95.
- * GCC 2.95 compiled C++ code is not binary compatible with EGCS
- 1.1.x, EGCS 1.0.x or GCC 2.8.x.
- * GCC 2.95 does not have changes from the GCC 2.8 tree that were
- made between Sept 30, 1998 and April 30, 1999 (the official end of
- the GCC 2.8 project). Future GCC releases will include all the
- changes from the defunct GCC 2.8 sources.
- _________________________________________________________________
-
-
- [4]The GCC team
- Last modified 2001-02-12
-
-References
-
- 1. http://gcc.gnu.org/faq.html#asmclobber
- 2. http://gcc.gnu.org/fom_serv/cache/24.html
- 3. ftp://gcc.gnu.org/pub/gcc/infrastructure/libg++-2.8.1.3.tar.gz
- 4. http://gcc.gnu.org/about.html
-======================================================================
-http://gcc.gnu.org/egcs-1.1/egcs-1.1.2.html
-
- EGCS 1.1.2
-
- March 15, 1999
-
- We are pleased to announce the release of EGCS 1.1.2.
-
- EGCS is a collaborative effort involving several groups of hackers
- using an open development model to accelerate development and testing
- of GNU compilers and runtime libraries.
-
- EGCS 1.1.2 is a minor update to the EGCS 1.1.1 compiler to fix several
- serious problems in EGCS 1.1.1.
- * General improvements and fixes
- + Fix bug in loop optimizer which caused the SPARC (and
- potentially other) ports to segfault.
- + Fix infinite recursion in alias analysis and combiner code.
- + Fix bug in regclass preferencing.
- + Fix incorrect loop reversal which caused incorrect code to be
- generated for several targets.
- + Fix return value for builtin memcpy.
- + Reduce compile time for certain loops which exposed quadratic
- behavior in the loop optimizer.
- + Fix bug which caused volatile memory to be written multiple
- times when only one write was needed/desired.
- + Fix compiler abort in caller-save.c
- + Fix combiner bug which caused incorrect code generation for
- certain division by constant operations.
- + Fix incorrect code generation due to a bug in range check
- optimizations.
- + Fix incorrect code generation due to mis-handling of
- clobbered values in CSE.
- + Fix compiler abort/segfault due to incorrect register
- splitting when unrolling loops.
- + Fix code generation involving autoincremented addresses with
- ternary operators.
- + Work around bug in the scheduler which caused qt to be
- mis-compiled on some platforms.
- + Fix code generation problems with -fshort-enums.
- + Tighten security for temporary files.
- + Improve compile time for codes which make heavy use of
- overloaded functions.
- + Fix multiply defined constructor/destructor symbol problems.
- + Avoid setting bogus RPATH environemnt variable during
- bootstrap.
- + Avoid GNU-make dependencies in the texinfo subdir.
- + Install CPP wrapper script in $(prefix)/bin if --enable-cpp.
- --enable-cpp= can be used to specify an additional install
- directory for the cpp wrapper script.
- + Fix CSE bug which caused incorrect label-label refs to appear
- on some platforms.
- + Avoid linking in EH routines from libgcc if they are not
- needed.
- + Avoid obscure bug in aliasing code.
- + Fix bug in weak symbol handling.
- * Platform-specific improvements and fixes
- + Fix detection of PPro/PII on Unixware 7.
- + Fix compiler segfault when building spec99 and other programs
- for SPARC targets.
- + Fix code-generation bugs for integer and floating point
- conditional move instructions on the PPro/PII.
- + Use fixincludes to fix byteorder problems on i?86-*-sysv.
- + Fix build failure for the arc port.
- + Fix floating point format configuration for i?86-gnu port
- + Fix problems with hppa1.0-hp-hpux10.20 configuration when
- threads are enabled
- + Fix coldfire code generation bugs.
- + Fix "unrecognized insn" problems for Alpha and PPC ports.
- + Fix h8/300 code generation problem with floating point values
- in memory.
- + Fix unrecognized insn problems for the m68k port.
- + Fix namespace-pollution problem for the x86 port.
- + Fix problems with old assembler on x86 NeXT systems.
- + Fix PIC code-generation problems for the SPARC port.
- + Fix minor bug with LONG_CALLS in PowerPC SVR4 support.
- + Fix minor ISO namespace violation in Alpha varargs/stdarg
- support.
- + Fix incorrect "braf" instruction usage for the SH port.
- + Fix minor bug in va-sh which prevented its use with -ansi.
- + Fix problems recognizing and supporting FreeBSD.
- + Handle OpenBSD systems correctly.
- + Minor fixincludes fix for Digital UNIX 4.0B.
- + Fix problems with ctors/dtors in SCO shared libraries.
- + Abort instead of generating incorrect code for PPro/PII
- floating point conditional moves.
- + Avoid multiply defined symbols on Linux/GNU systems using
- libc-5.4.xx.
- + Fix abort in alpha compiler.
-
- Fortran-specific fixes
- * Fix the IDate intrinsic (VXT) (in libg2c) so the returned year is
- in the documented, non-Y2K-compliant range of 0-99, instead of
- being returned as 100 in the year 2000.
- * Fix the `Date_and_Time' intrinsic (in libg2c) to return the
- milliseconds value properly in Values(8).
- * Fix the `LStat' intrinsic (in libg2c) to return device-ID
- information properly in SArray(7).
-
- An important goal of EGCS is to allow wide scale testing of new
- features and optimizations which are still under development. However,
- EGCS has been carefully tested and should be comparable in quality to
- most gcc releases.
-
- EGCS 1.1.2 is based on the June 6, 1998 snapshot of the GCC 2.8
- development sources; it contains all of the new features found in GCC
- 2.8.1 as well as all new development from gcc2 up to June 6, 1998.
-
- See the [1]new features page for a more complete list of new features
- found in EGCS 1.1 releases.
-
- The EGCS 1.1.2 release includes installation instructions in both HTML
- and plaintext forms (see the INSTALL directory in the toplevel
- directory of the EGCS 1.1.2 distribution). However, we also keep the
- most up to date [2]installation instructions and [3]build/test status
- on our web page. We will update those pages as new information becomes
- available.
-
- The EGCS project would like to thank the numerous people that have
- contributed new features, test results, bugfixes, etc. This [4]amazing
- group of volunteers is what makes EGCS successful.
-
- And finally, we can't in good conscience fail to mention some
- [5]caveats to using EGCS 1.1.2. [6]Download EGCS 1.1.2 from
- egcs.cygnus.com (USA California) -->
-
- [7]Download EGCS 1.1.2 from go.cygnus.com (USA California - High speed
- link provided by Stanford)
-
- The EGCS 1.1.2 release is also available on many [8]mirror sites.
- _________________________________________________________________
-
- Last modified on July 28, 1999.
-
-References
-
- 1. http://gcc.gnu.org/egcs-1.1/features.html
- 2. http://gcc.gnu.org/install/index.html
- 3. http://gcc.gnu.org/egcs-1.1/buildstat.html
- 4. http://gcc.gnu.org/thanks.html
- 5. http://gcc.gnu.org/egcs-1.1/caveats.html
- 6. ftp://egcs.cygnus.com/pub/egcs/releases/index.html
- 7. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 8. http://gcc.gnu.org/mirrors.html
-======================================================================
-http://gcc.gnu.org/egcs-1.1/egcs-1.1.1.html
-
- EGCS 1.1.1
-
- December 1, 1998
-
- We are pleased to announce the release of EGCS 1.1.1.
-
- EGCS is a collaborative effort involving several groups of hackers
- using an open development model to accelerate development and testing
- of GNU compilers and runtime libraries.
-
- EGCS 1.1.1 is a minor update to the EGCS 1.1 compiler to fix several
- serious problems in EGCS 1.1.
- * General improvements and fixes
- + Avoid some stack overflows when compiling large functions.
- + Avoid incorrect loop invariant code motions.
- + Fix some core dumps on Linux kernel code.
- + Bring back the imake -Di386 and friends fix from EGCS 1.0.2.
- + Fix code generation problem in gcse.
- + Various documentation related fixes.
- * g++/libstdc++ improvements and fixes
- + MT safe EH fix for setjmp/longjmp based exception handling.
- + Fix a few bad interactions between optimization and exception
- handling.
- + Fixes for demangling of template names starting with "__".
- + Fix a bug that would fail to run destructors in some cases
- with -O2.
- + Fix 'new' of classes with virtual bases.
- + Fix crash building Qt on the Alpha.
- + Fix failure compiling WIFEXITED macro on GNU/Linux.
- + Fix some -frepo failures.
- * g77 and libf2c improvements and fixes
- + Various documentation fixes.
- + Avoid compiler crash on RAND intrinsic.
- + Fix minor bugs in makefiles exposed by BSD make programs.
- + Define _XOPEN_SOURCE for libI77 build to avoid potential
- problems on some 64-bit systems.
- + Fix problem with implicit endfile on rewind.
- + Fix spurious recursive I/O errors.
- * platform specific improvements and fixes
- + Match all versions of UnixWare7.
- + Do not assume x86 SVR4 or UnixWare targets can handle stabs
- + Fix PPC/RS6000 LEGITIMIZE_ADDRESS macro and bug in conversion
- from unsigned ints to double precision floats.
- + Fix ARM ABI issue with NetBSD.
- + Fix a few arm code generation bugs.
- + Fixincludes will fix additional broken SCO OpenServer header
- files.
- + Fix a m68k backend bug which caused invalid offsets in reg+d
- addresses.
- + Fix problems with 64bit AIX 4.3 support.
- + Fix handling of long longs for varargs/stdarg functions on
- the ppc.
- + Minor fixes to CPP predefines for Windows.
- + Fix code generation problems with gpr<->fpr copies for 64bit
- ppc
- + Fix a few coldfire code generation bugs.
- + Fix some more header file problems on SunOS 4.x
- + Fix assert.h handling for RTEMS.
- + Fix Windows handling of TREE_SYMBOL_REFERENCED.
- + Fix x86 compiler abort in reg-stack pass.
- + Fix cygwin/windows problem with section attributes.
- + Fix Alpha code generation problem exposed by SMP Linux
- kernels.
- + Fix typo in m68k 32->64bit integer conversion.
- + Make sure target libraries build with -fPIC for PPC & Alpha
- targets.
-
- An important goal of EGCS is to allow wide scale testing of new
- features and optimizations which are still under development. However,
- EGCS has been carefully tested and should be comparable in quality to
- most gcc releases.
-
- EGCS 1.1.1 is based on the June 6, 1998 snapshot of the GCC 2.8
- development sources; it contains all of the new features found in GCC
- 2.8.1 as well as all new development from gcc2 up to June 6, 1998.
-
- See the [1]new features page for a more complete list of new features
- found in EGCS 1.1 releases.
-
- The EGCS 1.1.1 release includes installation instructions in both HTML
- and plaintext forms (see the INSTALL directory in the toplevel
- directory of the EGCS 1.1.1 distribution). However, we also keep the
- most up to date [2]installation instructions and [3]build/test status
- on our web page. We will update those pages as new information becomes
- available.
-
- The EGCS project would like to thank the numerous people that have
- contributed new features, test results, bugfixes, etc. This [4]amazing
- group of volunteers is what makes EGCS successful.
-
- And finally, we can't in good conscience fail to mention some
- [5]caveats to using EGCS 1.1.1.
-
- [6]Download EGCS 1.1.1 from egcs.cygnus.com (USA California)
-
- The EGCS 1.1.1 release is also available on many mirror sites.
- [7]Goto mirror list to find a closer site
- _________________________________________________________________
-
- Last modified on July 28, 1999.
-
-References
-
- 1. http://gcc.gnu.org/egcs-1.1/features.html
- 2. http://gcc.gnu.org/install/index.html
- 3. http://gcc.gnu.org/egcs-1.1/buildstat.html
- 4. http://gcc.gnu.org/thanks.html
- 5. http://gcc.gnu.org/egcs-1.1/caveats.html
- 6. ftp://egcs.cygnus.com/pub/egcs/releases/index.html
- 7. http://gcc.gnu.org/mirrors.html
-======================================================================
-http://gcc.gnu.org/egcs-1.1/egcs-1.1.html
-
- EGCS 1.1
-
- September 3, 1998
-
- We are pleased to announce the release of EGCS 1.1.
-
- EGCS is a free software project to further the development of the GNU
- compilers using an open development environment.
-
- EGCS 1.1 is a major new release of the EGCS compiler system. It has
- been [1]extensively tested and is believed to be stable and suitable
- for widespread use.
-
- EGCS 1.1 is based on an June 6, 1998 snapshot of the GCC 2.8
- development sources; it contains all of the new features found in GCC
- 2.8.1 as well as all new development from GCC up to June 6, 1998.
-
- EGCS also contains many improvements and features not found in GCC or
- in older versions of EGCS.
- * Global common subexpression elimination and global constant/copy
- propagation (aka [2]gcse)
- * Ongoing improvements to the [3]alias analysis support to allow for
- better optimizations throughout the compiler.
- * Vastly improved [4]C++ compiler and integrated C++ runtime
- libraries.
- * Fixes for the /tmp symlink race security problems.
- * New targets including mips16, arm-thumb and 64 bit PowerPC.
- * Improvements to GNU Fortran (g77) compiler and runtime library
- made since [5]g77 version 0.5.23.
-
- See the [6]new features page for a more complete list of new features
- found in EGCS 1.1 releases.
-
- The EGCS 1.1 release includes installation instructions in both HTML
- and plaintext forms (see the INSTALL directory in the toplevel
- directory of the EGCS 1.1 distribution). However, we also keep the
- most up to date [7]installation instructions and [8]build/test status
- on our web page. We will update those pages as new information becomes
- available.
-
- The EGCS project would like to thank the numerous people that have
- contributed new features, test results, bugfixes, etc. This [9]amazing
- group of volunteers is what makes EGCS successful.
-
- And finally, we can't in good conscience fail to mention some
- [10]caveats to using EGCS 1.1.
-
- [11]Download EGCS 1.1 from egcs.cygnus.com (USA California)
-
- [12]Download EGCS 1.1 from go.cygnus.com (USA California -- High speed
- link provided by Stanford)
-
- The EGCS 1.1 release is also available on many mirror sites.
- [13]Goto mirror list to find a closer site
- _________________________________________________________________
-
- Last modified on September 4, 1999.
-
-References
-
- 1. http://gcc.gnu.org/egcs-1.1/egcs-1.1-test.html
- 2. http://gcc.gnu.org/news/gcse.html
- 3. http://gcc.gnu.org/news/alias.html
- 4. http://gcc.gnu.org/egcs-1.1/c++features.html
- 5. http://gcc.gnu.org/onlinedocs/g77_news.html
- 6. http://gcc.gnu.org/egcs-1.1/features.html
- 7. http://gcc.gnu.org/install/index.html
- 8. http://gcc.gnu.org/egcs-1.1/buildstat.html
- 9. http://gcc.gnu.org/thanks.html
- 10. http://gcc.gnu.org/egcs-1.1/caveats.html
- 11. ftp://egcs.cygnus.com/pub/egcs/releases/index.html
- 12. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 13. http://gcc.gnu.org/mirrors.html
-======================================================================
-http://gcc.gnu.org/egcs-1.1/features.html
-
- EGCS 1.1 new features
-
- * Integrated GNU Fortran (g77) compiler and runtime library with
- improvements, based on [1]g77 version 0.5.23.
- * Vast improvements in the C++ compiler; so many they have [2]page
- of their own!
- * Compiler implements [3]global common subexpression elimination and
- global copy/constant propagation.
- * More major improvements in the [4]alias analysis code.
- * More major improvements in the exception handling code to improve
- performance, lower static overhead and provide the infrastructure
- for future improvements.
- * The infamous /tmp symlink race security problems have been fixed.
- * The regmove optimization pass has been nearly completely rewritten
- to improve performance of generated code.
- * The compiler now recomputes register usage information before
- local register allocation. By providing more accurate information
- to the priority based allocator, we get better register
- allocation.
- * The register reloading phase of the compiler optimizes spill code
- much better than in previous releases.
- * Some bad interactions between the register allocator and
- instruction scheduler have been fixed, resulting in much better
- code for certain programs. Additionally, we have tuned the
- scheduler in various ways to improve performance of generated code
- for some architectures.
- * The compiler's branch shortening algorithms have been
- significantly improved to work better on targets which align jump
- targets.
- * The compiler now supports -Os to prefer optimizing for code space
- over optimizing for code speed.
- * The compiler will now totally eliminate library calls which
- compute constant values. This primarily helps targets with no
- integer div/mul support and targets without floating point
- support.
- * The compiler now supports an extensive "--help" option.
- * cpplib has been greatly improved and may be suitable for limited
- use.
- * Memory footprint for the compiler has been significantly reduced
- for some pathological cases.
- * The time to build EGCS has been improved for certain targets
- (particularly the alpha and mips platforms).
- * Many infrastructure improvements throughout the compiler, plus the
- usual mountain of bugfixes and minor improvements.
- * Target dependent improvements:
- + SPARC port now includes V8 plus and V9 support as well as
- performance tuning for Ultra class machines. The SPARC port
- now uses the Haifa scheduler.
- + Alpha port has been tuned for the EV6 processor and has an
- optimized expansion of memcpy/bzero. The Alpha port now uses
- the Haifa scheduler.
- + RS6000/PowerPC: EGCS 1.1 includes support for the Power64
- architecture and aix4.3 support. The RS6000/PowerPC port now
- uses the Haifa scheduler.
- + x86: Alignment of static store data and jump targets is per
- Intel recommendations now. Various improvements throughout
- the x86 port to improve performance on Pentium processors.
- Conditional move support has been fixed and enabled for PPro
- processors. The x86 port also better supports 64bit
- operations now.
- + MIPS has improved multiply/multiply-add support and now
- includes mips16 ISA support.
- + M68k has many micro-optimizations and Coldfire fixes.
- * Core compiler is based on the GCC development tree from June 9,
- 1998, so we have all of the [5]features found in GCC 2.8.
-
- [6]Return to the EGCS home page
-
- Last modified: September 4, 1999
-
-References
-
- 1. http://gcc.gnu.org/onlinedocs/g77_news.html
- 2. http://gcc.gnu.org/egcs-1.1/c++features.html
- 3. http://gcc.gnu.org/news/gcse.html
- 4. http://gcc.gnu.org/news/alias.html
- 5. http://gcc.gnu.org/egcs-1.0/features-2.8.html
- 6. http://gcc.gnu.org/index.html
-======================================================================
-http://gcc.gnu.org/egcs-1.1/caveats.html
-
- EGCS 1.1 Caveats
-
- * EGCS has an integrated libstdc++, but does not have an integrated
- libg++. Furthermore old libg++ releases will not work with EGCS;
- HJ Lu has made a [1]libg++ snapshot available which may work with
- EGCS.
- Note most C++ programs only need libstdc++.
- * Exception handling may not work with shared libraries,
- particularly on alphas, hppas, rs6000/powerpc and mips based
- platforms. Exception handling is known to work on x86-linux
- platforms with shared libraries.
- * Some versions of the Linux kernel have bugs which prevent them
- from being compiled or from running when compiled by EGCS. See
- [2]the FAQ for additional information.
- * In general, EGCS is more rigorous about rejecting invalid C++ code
- or deprecated C++ constructs than g++-2.7, g++-2.8 or EGCS 1.0. As
- a result it may be necessary to fix C++ code before it will
- compile with EGCS.
- * G++ is also converting toward the ISO C++ standard; as a result
- code which was previously valid (and thus accepted by other
- compilers and older versions of g++) may no longer be accepted.
- * EGCS 1.1 compiled C++ code is not binary compatible with EGCS
- 1.0.x or GCC 2.8.x due to changes necessary to support thread safe
- exception handling.
-
- [3]Return to the GCC home page
-
- Last modified: July 28, 1999
-
-References
-
- 1. ftp://ftp.yggdrasil.com/private/hjl/libg++-2.8.1.2.tar.gz
- 2. http://gcc.gnu.org/fom_serv/cache/24.html
- 3. http://gcc.gnu.org/index.html
-======================================================================
-http://gcc.gnu.org/egcs-1.0/egcs-1.0.3.html
-
- EGCS 1.0.3
-
- May 15, 1998
-
- We are pleased to announce the release of EGCS 1.0.3.
-
- EGCS is a collaborative effort involving several groups of hackers
- using an open development model to accelerate development and testing
- of GNU compilers and runtime libraries.
-
- EGCS 1.0.3 is a minor update to the EGCS 1.0.2 compiler to fix a few
- problems reported by Red Hat for builds of Red Hat 5.1.
- * Generic bugfixes:
- + Fix a typo in the libio library which resulted in incorrect
- behavior of istream::get.
- + Fix the Fortran negative array index problem.
- + Fix a major problem with the ObjC runtime thread support
- exposed by glibc2.
- + Reduce memory consumption of the Haifa scheduler.
- * Target specific bugfixes:
- + Fix one x86 floating point code generation bug exposed by
- glibc2 builds.
- + Fix one x86 internal compiler error exposed by glibc2 builds.
- + Fix profiling bugs on the Alpha.
- + Fix ImageMagick & emacs 20.2 build problems on the Alpha.
- + Fix rs6000/ppc bug when converting values from integer types
- to floating point types.
-
- An important goal of EGCS is to allow wide scale testing of new
- features and optimizations which are still under development. However,
- EGCS has been carefully tested and should be comparable in quality to
- most GCC releases.
-
- EGCS 1.0.3 is based on an August 2, 1997 snapshot of the GCC 2.8
- development sources; it contains nearly all of the new features found
- in GCC 2.8.
-
- EGCS also contains many improvements and features not found in GCC 2.7
- or GCC 2.8.
- * Integrated C++ runtime libraries, including support for most major
- GNU/Linux systems!
- * The integrated libstdc++ library includes a verbatim copy of
- [1]SGI's STL release instead of a modified copy.
- * Integrated GNU Fortran compiler
- * New instruction scheduler
- * New alias analysis code
-
- See the [2]new features page for a more complete list of new features
- found in EGCS 1.0.x releases.
-
- The EGCS 1.0.3 release includes installation instructions in both HTML
- and plaintext forms (see the INSTALL directory in the toplevel
- directory of the EGCS 1.0.3 distribution). However, we also keep the
- most up to date [3]installation instructions and [4]build/test status
- on our web page. We will update those pages as new information becomes
- available.
-
- And, we can't in good conscience fail to mention some [5]caveats to
- using EGCS.
-
- Update: Big thanks to Stanford for providing a high speed link for
- downloading EGCS (go.cygnus.com)!
-
- [6]Download EGCS 1.0.3 from ftp.cygnus.com (USA California)
-
- [7]Download EGCS 1.0.3 from go.cygnus.com (USA California -- High
- speed link provided by Stanford)
-
- The EGCS 1.0.3 release is also available on many mirror sites.
- [8]Goto mirror list to find a closer site
-
- We'd like to thank the numerous people that have contributed new
- features, test results, bugfixes, etc. Unfortunately, they're far too
- numerous to mention by name.
- _________________________________________________________________
-
- Last modified on February 22, 1999.
-
-References
-
- 1. http://www.sgi.com/Technology/STL
- 2. http://gcc.gnu.org/egcs-1.0/features.html
- 3. http://gcc.gnu.org/install/index.html
- 4. http://gcc.gnu.org/egcs-1.0/buildstat.html
- 5. http://gcc.gnu.org/egcs-1.0/caveats.html
- 6. ftp://egcs.cygnus.com/pub/egcs/releases/index.html
- 7. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 8. http://gcc.gnu.org/mirrors.html
-======================================================================
-http://gcc.gnu.org/egcs-1.0/egcs-1.0.2.html
-
- EGCS 1.0.2
-
- March 16, 1998
-
- We are pleased to announce the release of EGCS 1.0.2.
-
- EGCS is a collaborative effort involving several groups of hackers
- using an open development model to accelerate development and testing
- of GNU compilers and runtime libraries.
-
- EGCS 1.0.2 is a minor update to the EGCS 1.0.1 compiler to fix several
- serious problems in EGCS 1.0.1.
- * General improvements and fixes
- + Memory consumption significantly reduced, especially for
- templates and inline functions.
- + Fix various problems with glibc2.1.
- + Fix loop optimization bug exposed by rs6000/ppc port.
- + Fix to avoid potential code generation problems in jump.c.
- + Fix some undefined symbol problems in dwarf1 debug support.
- * g++/libstdc++ improvements and fixes
- + libstdc++ in the EGCS release has been updated and should be
- link compatible with libstdc++-2.8.
- + Various fixes in libio/libstdc++ to work better on Linux
- systems.
- + Fix problems with duplicate symbols on systems that do not
- support weak symbols.
- + Memory corruption bug and undefined symbols in bastring have
- been fixed.
- + Various exception handling fixes.
- + Fix compiler abort for very long thunk names.
- * g77 improvements and fixes
- + Fix compiler crash for omitted bound in Fortran CASE
- statement.
- + Add missing entries to g77 lang-options.
- + Fix problem with -fpedantic in the g77 compiler.
- + Fix "backspace" problem with g77 on alphas.
- + Fix x86 backend problem with Fortran literals and -fpic.
- + Fix some of the problems with negative subscripts for g77 on
- alphas.
- + Fixes for Fortran builds on cygwin32/mingw32.
- * platform specific improvements and fixes
- + Fix long double problems on x86 (exposed by glibc)
- + x86 ports define i386 again to keep imake happy.
- + Fix exception handling support on NetBSD ports.
- + Several changes to collect2 to fix many problems with AIX.
- + Define __ELF__ for rs6000/linux.
- + Fix -mcall-linux problem on rs6000/linux.
- + Fix stdarg/vararg problem for rs6000/linux.
- + Allow autoconf to select a proper install problem on AIX 3.1.
- + m68k port support includes -mcpu32 option as well as cpu32
- multilibs.
- + Fix stdarg bug for irix6.
- + Allow EGCS to build on irix5 without the gnu assembler.
- + Fix problem with static linking on sco5.
- + Fix bootstrap on sco5 with native compiler.
- + Fix for abort building newlib on H8 target.
- + Fix fixincludes handling of math.h on SunOS.
- + Minor fix for motorola 3300 m68k systems.
-
- An important goal of EGCS is to allow wide scale testing of new
- features and optimizations which are still under development. However,
- EGCS has been carefully tested and should be comparable in quality to
- most GCC releases.
-
- EGCS 1.0.2 is based on an August 2, 1997 snapshot of the GCC 2.8
- development sources; it contains nearly all of the new features found
- in GCC 2.8.
-
- EGCS also contains many improvements and features not found in GCC 2.7
- or GCC 2.8.
- * Integrated C++ runtime libraries, including support for most major
- linux systems!
- * The integrated libstdc++ library includes a verbatim copy of
- [1]SGI's STL release.
- * Integrated GNU Fortran compiler
- * New instruction scheduler
- * New alias analysis code
-
- See the [2]new features page for a more complete list of new features
- found in EGCS 1.0.x releases.
-
- The EGCS 1.0.2 release includes installation instructions in both HTML
- and plaintext forms (see the INSTALL directory in the toplevel
- directory of the EGCS 1.0.2 distribution). However, we also keep the
- most up to date [3]installation instructions and [4]build/test status
- on our web page. We will update those pages as new information becomes
- available.
-
- And, we can't in good conscience fail to mention some [5]caveats to
- using EGCS.
-
- Update: Big thanks to Stanford for providing a high speed link for
- downloading EGCS (go.cygnus.com)!
-
- [6]Download EGCS 1.0.2 from ftp.cygnus.com (USA California)
-
- [7]Download EGCS 1.0.2 from go.cygnus.com (USA California -- High
- speed link provided by Stanford)
-
- The EGCS 1.0.2 release is also available on many mirror sites.
- [8]Goto mirror list to find a closer site
-
- We'd like to thank the numerous people that have contributed new
- features, test results, bugfixes, etc. Unfortunately, they're far too
- numerous to mention by name.
- _________________________________________________________________
-
- Last modified on July 28, 1999.
-
-References
-
- 1. http://www.sgi.com/Technology/STL/
- 2. http://gcc.gnu.org/egcs-1.0/features.html
- 3. http://gcc.gnu.org/install/index.html
- 4. http://gcc.gnu.org/egcs-1.0/buildstat.html
- 5. http://gcc.gnu.org/egcs-1.0/caveats.html
- 6. ftp://egcs.cygnus.com/pub/egcs/releases/index.html
- 7. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 8. http://gcc.gnu.org/mirrors.html
-======================================================================
-http://gcc.gnu.org/egcs-1.0/egcs-1.0.1.html
-
- EGCS 1.0.1
-
- January 6, 1998
-
- We are pleased to announce the release of EGCS 1.0.1.
-
- EGCS is a collaborative effort involving several groups of hackers
- using an open development model to accelerate development and testing
- of GNU compilers and runtime libraries.
-
- EGCS 1.0.1 is a minor update to the EGCS 1.0 compiler to fix a few
- critical bugs and add support for Red Hat 5.0 Linux. Changes since the
- EGCS 1.0 release:
- * Add support for Red Hat 5.0 Linux and better support for Linux
- systems using glibc2.
- Many programs failed to link when compiled with EGCS 1.0 on Red
- Hat 5.0 or on systems with newer versions of glibc2. EGCS 1.0.1
- should fix these problems.
- * Compatability with both EGCS 1.0 and GCC 2.8 libgcc exception
- handling interfaces.
- To avoid future compatibility problems, we strongly urge anyone
- who is planning on distributing shared libraries that contain C++
- code to upgrade to EGCS 1.0.1 first.
- Soon after EGCS 1.0 was released, the GCC developers made some
- incompatible changes in libgcc's exception handling interfaces.
- These changes were needed to solve problems on some platforms.
- This means that GCC 2.8.0, when released, will not be seamlessly
- compatible with shared libraries built by EGCS 1.0. The reason is
- that the libgcc.a in GCC 2.8.0 will not contain a function needed
- by the old interface.
- The result of this is that there may be compatibility problems
- with shared libraries built by EGCS 1.0 when used with GCC 2.8.0.
- With EGCS 1.0.1, generated code uses the new (GCC 2.8.0)
- interface, and libgcc.a has the support routines for both the old
- and the new interfaces (so EGCS 1.0.1 and EGCS 1.0 code can be
- freely mixed, and EGCS 1.0.1 and GCC 2.8.0 code can be freely
- mixed).
- The maintainers of GCC 2.x have decided against including seamless
- support for the old interface in 2.8.0, since it was never
- "official", so to avoid future compatibility problems we recommend
- against distributing any shared libraries built by EGCS 1.0 that
- contain C++ code (upgrade to 1.0.1 and use that).
- * Various bugfixes in the x86, hppa, mips, and rs6000/ppc backends.
- The x86 changes fix code generation errors exposed when building
- glibc2 and the Linux dynamic linker (ld.so).
- The hppa change fixes a compiler abort when configured for use
- with RTEMS.
- The MIPS changes fix problems with the definition of LONG_MAX on
- newer systems, allow for command line selection of the target ABI,
- and fix one code generation problem.
- The rs6000/ppc change fixes some problems with passing structures
- to varargs/stdarg functions.
- * A few machine independent bugfixes, mostly to fix code generation
- errors when building Linux kernels or glibc.
- * Fix a few critical exception handling and template bugs in the C++
- compiler.
- * Fix Fortran namelist bug on alphas.
- * Fix build problems on x86-solaris systems.
-
- An important goal of EGCS is to allow wide scale testing of new
- features and optimizations which are still under development. However,
- EGCS has been carefully tested and should be comparable in quality to
- most GCC releases.
-
- EGCS 1.0.1 is based on an August 2, 1997 snapshot of the GCC 2.8
- development sources; it contains nearly all of the new features found
- in GCC 2.8.
-
- EGCS also contains many improvements and features not found in GCC 2.7
- and even the soon to be released GCC 2.8 compilers.
- * Integrated C++ runtime libraries, including support for most major
- linux systems!
- * The integrated libstdc++ library includes a verbatim copy of
- [1]SGI's STL release.
- * Integrated GNU Fortran compiler
- * New instruction scheduler
- * New alias analysis code
-
- See the [2]new features page for a more complete list of new features
- found in EGCS 1.0.x releases.
-
- The EGCS 1.0.1 release includes installation instructions in both HTML
- and plaintext forms (see the INSTALL directory in the toplevel
- directory of the EGCS 1.0.1 distribution). However, we also keep the
- most up to date [3]installation instructions and [4]build/test status
- on our web page. We will update those pages as new information becomes
- available.
-
- And, we can't in good conscience fail to mention some [5]caveats to
- using EGCS.
-
- Update: Big thanks to Stanford for providing a high speed link for
- downloading EGCS (go.cygnus.com)!
-
- [6]Download EGCS 1.0.1 from ftp.cygnus.com (USA California)
-
- [7]Download EGCS 1.0.1 from go.cygnus.com (USA California -- High
- speed link provided by Stanford)
-
- The EGCS 1.0.1 release is also available on many mirror sites.
- [8]Goto mirror list to find a closer site
-
- We'd like to thank the numerous people that have contributed new
- features, test results, bugfixes, etc. Unfortunately, they're far too
- numerous to mention by name.
- _________________________________________________________________
-
- Last modified on July 28, 1999.
-
-References
-
- 1. http://www.sgi.com/Technology/STL/
- 2. http://gcc.gnu.org/egcs-1.0/features.html
- 3. http://gcc.gnu.org/install/index.html
- 4. http://gcc.gnu.org/egcs-1.0/buildstat.html
- 5. http://gcc.gnu.org/egcs-1.0/caveats.html
- 6. ftp://egcs.cygnus.com/pub/egcs/releases/index.html
- 7. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 8. http://gcc.gnu.org/mirrors.html
-======================================================================
-http://gcc.gnu.org/egcs-1.0/egcs-1.0.html
-
- EGCS 1.0
-
- December 3, 1997
-
- We are pleased to announce the release of EGCS 1.0.
-
- EGCS is a collaborative effort involving several groups of hackers
- using an open development model to accelerate development and testing
- of GNU compilers and runtime libraries.
-
- An important goal of EGCS is to allow wide scale testing of
- experimental features and optimizations; therefore, EGCS contains some
- features and optimizations which are still under development. However,
- EGCS has been carefully tested and should be comparable in quality to
- most GCC releases.
-
- EGCS 1.0 is based on an August 2, 1997 snapshot of the GCC 2.8
- development sources; it contains nearly all of the new features found
- in GCC 2.8.
-
- EGCS 1.0 also contains many improvements and features not found in GCC
- 2.7 and even the soon to be released GCC 2.8 compilers.
- * Integrated C++ runtime libraries, including support for most major
- linux systems!
- * The integrated libstdc++ library includes a verbatim copy of
- [1]SGI's STL release.
- * Integrated GNU Fortran compiler
- * New instruction scheduler
- * New alias analysis code
-
- See the [2]new features page for a more complete list of new features.
-
- The EGCS 1.0 release includes installation instructions in both HTML
- and plaintext forms (see the INSTALL directory in the toplevel
- directory of the EGCS 1.0 distribution). However, we also keep the
- most up to date [3]installation instructions and [4]build/test status
- on our web page. We will update those pages as new information becomes
- available.
-
- And, we can't in good conscience fail to mention some [5]caveats to
- using EGCS.
-
- Update: The T1 into our main California offices has been 100%
- saturated since shortly after the release. We've added an EGCS 1.0
- mirror at our Massachusetts office to help share the load. We also
- encourage folks to use the many mirrors available throughout the
- world.
-
- Update: Big thanks to Stanford for providing a high speed link for
- downloading EGCS! (go.cygnus.com)
-
- [6]Download EGCS 1.0 from ftp.cygnus.com (USA California)
-
- [7]Download EGCS 1.0 from go.cygnus.com (USA California -- High speed
- link provided by Stanford)
-
- The EGCS 1.0 release should be available on most mirror sites by now.
- [8]Goto mirror list to find a closer site
-
- We'd like to thank the numerous people that have contributed new
- features, test results, bugfixes, etc. Unfortunately, they're far too
- numerous to mention by name.
- _________________________________________________________________
-
- Last modified on July 28, 1999.
-
-References
-
- 1. http://www.sgi.com/Technology/STL
- 2. http://gcc.gnu.org/egcs-1.0/features.html
- 3. http://gcc.gnu.org/install/index.html
- 4. http://gcc.gnu.org/egcs-1.0/buildstat.html
- 5. http://gcc.gnu.org/egcs-1.0/caveats.html
- 6. ftp://egcs.cygnus.com/pub/egcs/releases/index.html
- 7. ftp://go.cygnus.com/pub/sourceware.cygnus.com/pub/egcs/releases/index.html
- 8. http://gcc.gnu.org/mirrors.html
-======================================================================
-http://gcc.gnu.org/egcs-1.0/features.html
-
- EGCS 1.0 features
-
- * Core compiler is based on the gcc2 development tree from Aug 2,
- 1997, so we have most of the [1]features found in GCC 2.8.
- * Integrated GNU Fortran compiler based on g77-0.5.22-19970929.
- * Vast improvements in the C++ compiler; so many they have [2]page
- of their own!
- * Integrated C++ runtime libraries, including support for most major
- linux systems!
- * New instruction scheduler from IBM Haifa which includes support
- for function wide instruction scheduling as well as superscalar
- scheduling.
- * Significantly improved alias analysis code.
- * Improved register allocation for two address machines.
- * Significant code generation improvements for Fortran code on
- Alphas
- * Various optimizations from the g77 project as well as improved
- loop optimizations.
- * Dwarf2 debug format support for some targets.
- * egcs libstdc++ includes the SGI STL implementation without
- changes.
- * As a result of these and other changes, egcs libstc++ is not
- binary compatible with previous releases of libstdc++.
- * Various new ports -- UltraSPARC, Irix6.2 & Irix6.3 support, The
- SCO Openserver 5 family (5.0.{0,2,4} and Internet FastStart 1.0
- and 1.1), Support for RTEMS on several embedded targets, Support
- for arm-linux, Mitsubishi M32R, Hitachi H8/S, Matsushita MN102 and
- MN103, NEC V850, Sparclet, Solaris & Linux on PowerPCs, etc.
- * Integrated testsuites for gcc, g++, g77, libstdc++ and libio.
- * RS6000/PowerPC ports generate code which can run on all
- RS6000/PowerPC variants by default.
- * -mcpu= and -march= switches for the x86 port to allow better
- control over how the x86 port generates code.
- * Includes the template repository patch (aka repo patch); note the
- new template code makes repo obsolete for ELF systems using gnu-ld
- such as Linux.
- * Plus the usual assortment of bugfixes and improvements.
-
- [3]Return to the egcs home page
-
- Last modified: July 28, 1999
-
-References
-
- 1. http://gcc.gnu.org/egcs-1.0/features-2.8.html
- 2. http://gcc.gnu.org/egcs-1.0/c++features.html
- 3. http://gcc.gnu.org/index.html
-======================================================================
-http://gcc.gnu.org/egcs-1.0/caveats.html
-
- EGCS 1.0 Caveats
-
- * EGCS has an integrated libstdc++, but does not have an integrated
- libg++. Furthermore old libg++ releases will not work with egc; HJ
- Lu has made a [1]libg++ snapshot available which may work with
- EGCS.
- Note most C++ programs only need libstdc++.
- * Note that using -pedantic or -Wreturn-type can cause an explosion
- in the amount of memory needed for template-heavy C++ code, such
- as code that uses STL. Also note that -Wall includes
- -Wreturn-type, so if you use -Wall you will need to specify
- -Wno-return-type to turn it off.
- * Exception handling may not work with shared libraries,
- particularly on alphas, hppas, and mips based platforms. Exception
- handling is known to work on x86-linux platforms with shared
- libraries.
- * Some versions of the Linux kernel have bugs which prevent them
- from being compiled or from running when compiled by EGCS. See
- [2]the FAQ for additional information.
- * In general, EGCS is more rigorous about rejecting invalid C++ code
- or deprecated C++ constructs than G++ 2.7. As a result it may be
- necessary to fix C++ code before it will compile with EGCS.
- * G++ is also aggressively tracking the C++ standard; as a result
- code which was previously valid (and thus accepted by other
- compilers and older versions of G++) may no longer be accepted.
- * EGCS 1.0 may not work with Red Hat Linux 5.0 on all targets. EGCS
- 1.0.x and later releases should work with Red Hat Linux 5.0.
-
- [3]Return to the GCC home page
-
- Last modified: August 27, 1998
-
-References
-
- 1. ftp://ftp.yggdrasil.com/private/hjl/libg++-2.8.1.2.tar.gz
- 2. http://gcc.gnu.org/fom_serv/cache/24.html
- 3. http://gcc.gnu.org/index.html
-======================================================================
diff --git a/contrib/gcc/PROBLEMS b/contrib/gcc/PROBLEMS
deleted file mode 100644
index bc532e641a8d..000000000000
--- a/contrib/gcc/PROBLEMS
+++ /dev/null
@@ -1,117 +0,0 @@
-3. When find_reloads is used to count number of spills needed
-it does not take into account the fact that a reload may
-turn out to be a dummy.
-
-I'm not sure this really happens any more. Doesn't it find
-all the dummies on both passes?
-
-10. movl a3@,a0
- movl a3@(16),a1
- clrb a0@(a1:l)
-is generated and may be worse than
- movl a3@,a0
- addl a3@(16),a0
- clrb a0@
-If ordering of operands is improved, many more
-such cases will be generated from typical array accesses.
-
-38. Hack expand_mult so that if there is no same-modes multiply
-it will use a widening multiply and then truncate rather than
-calling the library.
-
-39. Hack expanding of division to notice cases for
-long -> short division.
-
-40. Represent divide insns as (DIV:SI ...) followed by
-a separate lowpart extract. Represent remainder insns as DIV:SI
-followed by a separate highpart extract. Then cse can work on
-the DIV:SI part. Problem is, this may not be desirable on machines
-where computing the quotient alone does not necessarily give
-a remainder--such as the 68020 for long operands.
-
-52. Reloading can look at how reload_contents got set up.
-If it was copied from a register, just reload from that register.
-Otherwise, perhaps can change the previous insn to move the
-data via the reload reg, thus avoiding one memory ref.
-
-63. Potential problem in cc_status.value2, if it ever activates itself
-after a two-address subtraction (which currently cannot happen).
-It is supposed to compare the current value of the destination
-but eliminating it would use the results of the subtraction, equivalent
-to comparing the previous value of the destination.
-
-65. Should loops that neither start nor end with a break
-be rearranged to end with the last break?
-
-69. Define the floating point converting arithmetic instructions
-for the 68881.
-
-74. Combine loop opt with cse opt in one pass. Do cse on each loop,
-then loop opt on that loop, and go from innermost loops outward.
-Make loop invariants available for cse at end of loop.
-
-85. pea can force a value to be reloaded into an areg
-which can make it worse than separate adding and pushing.
-This can only happen for adding something within addql range
-and it only loses if the qty becomes dead at that point
-so it can be added to with no copying.
-
-93. If a pseudo doesn't get a hard reg everywhere,
-can it get one during a loop?
-
-96. Can do SImode bitfield insns without reloading, but must
-alter the operands in special ways.
-
-99. final could check loop-entry branches to see if they
-screw up deletion of a test instruction. If they do,
-can put another test instruction before the branch and
-make it conditional and redirect it.
-
-106. Aliasing may be impossible if data types of refs differ
-and data type of containing objects also differ.
-(But check this wrt unions.)
-
-108. Can speed up flow analysis by making a table saying which
-register is set and which registers are used by each instruction that
-only sets one register and only uses two. This way avoid the tree
-walk for such instructions (most instructions).
-
-109. It is desirable to avoid converting INDEX to SImode if a
-narrower mode suffices, as HImode does on the 68000.
-How can this be done?
-
-110. Possible special combination pattern:
-If the two operands to a comparison die there and both come from insns
-that are identical except for replacing one operand with the other,
-throw away those insns. Ok if insns being discarded are known 1 to 1.
-An andl #1 after a seq is 1 to 1, but how should compiler know that?
-
-112. Can convert float to unsigned int by subtracting a constant,
-converting to signed int, and changing the sign bit.
-
-117. Any number of slow zero-extensions in one loop, that have
-their clr insns moved out of the loop, can share one register
-if their original life spans are disjoint.
-But it may be hard to be sure of this since
-the life span data that regscan produces may be hard to interpret
-validly or may be incorrect after cse.
-
-118. In cse, when a bfext insn refers to a register, if the field
-corresponds to a halfword or a byte and the register is equivalent
-to a memory location, it would be possible to detect this and
-replace it with a simple memory reference.
-
-121. Insns that store two values cannot be moved out of loops.
-The code in scan_loop doesn't even try to deal with them.
-
-122. When insn-output.c turns a bit-test into a sign-test,
-it should see whether the cc is already set up with that sign.
-
-123. When a conditional expression is used as a function arg, it would
-be faster (and in some cases shorter) to push each alternative rather
-than compute in a register and push that. This would require
-being able to specify "push this" as a target for expand_expr.
-
-124. On the 386, bad code results from foo (bar ()) when bar
-returns a double, because the pseudo used fails to get preferenced
-into an fp reg because of the distinction between regs 8 and 9.
diff --git a/contrib/gcc/PROJECTS b/contrib/gcc/PROJECTS
deleted file mode 100644
index 2c2111a2a6e3..000000000000
--- a/contrib/gcc/PROJECTS
+++ /dev/null
@@ -1,449 +0,0 @@
-C++ template friend functions (mmitchell@usa.net)
-
-Haifa scheduler (haifa-sched.c, loop.[ch], unroll.[ch], genattrtab.c):
-(contact law@cygnus.com before starting any serious haifa work)
-
- * Fix all the formatting problems. Simple, mindless work.
-
- * Fix/add comments throughout the code. Many of the comments are from
- the old scheduler and are out of date and misleading. Many new hunks
- of code don't have sufficient comments and documentation. Those which
- do have comments need to be rewritten to use complete sentences and
- proper formatting.
-
- * Someone needs make one (or more) passes over the scheduler as a whole to
- just clean it up. Try to move the machine dependent bits into the target
- files where they belong, avoid re-creating functions where or near
- equivalents already exist (ie is_conditional_branch and friends), etc., etc.
-
- * Document the new scheduling options. Remove those options which are
- not really useful (like reverse scheduling for example). In general
- the haifa scheduler adds _way_ too many options. I'm definitely of the
- opinion that gcc already has too many -foptions, and haifa doesn't help
- that situation.
-
- * Testing and benchmarking. We've converted a few ports to using the
- Haifa scheduler (hppa, sparc, ppc, alpha). We need to continue testing
- and benchmarking the new scheduler on additional targets.
-
- We need to have some kind of docs for how to best describe a machine to
- the haifa scheduler to get good performance. Some existing ports have
- been tuned to deal with the old scheduler -- they may need to be tuned
- to generate good schedules with haifa.
-
-
-
-Improvements to global cse and partial redundancy elimination:
-
-The current implementation of global cse uses partial redundancy elimination
-as described in Chow's thesis.
-
-Long term we want to use lazy code motion as the basis for partial redundancy
-elimination. lcm will find as many (or more) redunancies *and* it will
-place the remaining computations at computationally optimal placement points
-within the function. This reduces the number of redundant operations performed
-as well as reducing register lifetimes. My experiments have shown that the
-cases were the current PRE code hurts performance are greatly helped by using
-lazy code motion.
-
-lcm also provides the underlying framework for several additional optimizations
-such as shrink wrapping, spill code motion, dead store elimination, and generic
-load/store motion (all the other examples are subcases of load/store motion).
-
-It can probably also be used to improve the reg-stack pass of the compiler.
-
-Contact law@cygnus.com if you're interested in working on lazy code motion.
-
--------------
-
-The old PROJECTS file. Stuff I know has been done has been deleted.
-Stuff in progress has a contact name associated with it.
-has been
-
-1. Better optimization.
-
-* Constants in unused inline functions
-
-It would be nice to delay output of string constants so that string
-constants mentioned in unused inline functions are never generated.
-Perhaps this would also take care of string constants in dead code.
-
-The difficulty is in finding a clean way for the RTL which refers
-to the constant (currently, only by an assembler symbol name)
-to point to the constant and cause it to be output.
-
-* Optimize a sequence of if statements whose conditions are exclusive.
-
-It is possible to optimize
-
- if (x == 1) ...;
- if (x == 2) ...;
- if (x == 3) ...;
-
-into
-
- if (x == 1) ...;
- else if (x == 2) ...;
- else if (x == 3) ...;
-
-provided that x is not altered by the contents of the if statements.
-
-It's not certain whether this is worth doing. Perhaps programmers
-nearly always write the else's themselves, leaving few opportunities
-to improve anything.
-
-* Un-cse.
-
-Perhaps we should have an un-cse step right after cse, which tries to
-replace a reg with its value if the value can be substituted for the
-reg everywhere, if that looks like an improvement. Which is if the
-reg is used only a few times. Use rtx_cost to determine if the
-change is really an improvement.
-
-* Clean up how cse works.
-
-The scheme is that each value has just one hash entry. The
-first_same_value and next_same_value chains are no longer needed.
-
-For arithmetic, each hash table elt has the following slots:
-
-* Operation. This is an rtx code.
-* Mode.
-* Operands 0, 1 and 2. These point to other hash table elements.
-
-So, if we want to enter (PLUS:SI (REG:SI 30) (CONST_INT 104)), we
-first enter (CONST_INT 104) and find the entry that (REG:SI 30) now
-points to. Then we put these elts into operands 0 and 1 of a new elt.
-We put PLUS and SI into the new elt.
-
-Registers and mem refs would never be entered into the table as such.
-However, the values they contain would be entered. There would be a
-table indexed by regno which points at the hash entry for the value in
-that reg.
-
-The hash entry index now plays the role of a qty number.
-We still need qty_first_reg, reg_next_eqv, etc. to record which regs
-share a particular qty.
-
-When a reg is used whose contents are unknown, we need to create a
-hash table entry whose contents say "unknown", as a place holder for
-whatever the reg contains. If that reg is added to something, then
-the hash entry for the sum will refer to the "unknown" entry. Use
-UNKNOWN for the rtx code in this entry. This replaces make_new_qty.
-
-For a constant, a unique hash entry would be made based on the
-value of the constant.
-
-What about MEM? Each time a memory address is referenced, we need a
-qty (a hash table elt) to represent what is in it. (Just as for a
-register.) If this isn't known, create one, just as for a reg whose
-contents are unknown.
-
-We need a way to find all mem refs that still contain a certain value.
-Do this with a chain of hash elts (for memory addresses) that point to
-locations that hold the value. The hash elt for the value itself should
-point to the start of the chain. It would be good for the hash elt
-for an address to point to the hash elt for the contents of that address
-(but this ptr can be null if the contents have never been entered).
-
-With this data structure, nothing need ever be invalidated except
-the lists of which regs or mems hold a particular value. It is easy
-to see if there is a reg or mem that is equiv to a particular value.
-If the value is constant, it is always explicitly constant.
-
-* Support more general tail-recursion among different functions.
-
-This might be possible under certain circumstances, such as when
-the argument lists of the functions have the same lengths.
-Perhaps it could be done with a special declaration.
-
-You would need to verify in the calling function that it does not
-use the addresses of any local variables and does not use setjmp.
-
-* Put short statics vars at low addresses and use short addressing mode?
-
-Useful on the 68000/68020 and perhaps on the 32000 series,
-provided one has a linker that works with the feature.
-This is said to make a 15% speedup on the 68000.
-
-* Keep global variables in registers.
-
-Here is a scheme for doing this. A global variable, or a local variable
-whose address is taken, can be kept in a register for an entire function
-if it does not use non-constant memory addresses and (for globals only)
-does not call other functions. If the entire function does not meet
-this criterion, a loop may.
-
-The VAR_DECL for such a variable would have to have two RTL expressions:
-the true home in memory, and the pseudo-register used temporarily.
-It is necessary to emit insns to copy the memory location into the
-pseudo-register at the beginning of the function or loop, and perhaps
-back out at the end. These insns should have REG_EQUIV notes so that,
-if the pseudo-register does not get a hard register, it is spilled into
-the memory location which exists in any case.
-
-The easiest way to set up these insns is to modify the routine
-put_var_into_stack so that it does not apply to the entire function
-(sparing any loops which contain nothing dangerous) and to call it at
-the end of the function regardless of where in the function the
-address of a local variable is taken. It would be called
-unconditionally at the end of the function for all relevant global
-variables.
-
-For debugger output, the thing to do is to invent a new binding level
-around the appropriate loop and define the variable name as a register
-variable with that scope.
-
-* Live-range splitting.
-
-Currently a variable is allocated a hard register either for the full
-extent of its use or not at all. Sometimes it would be good to
-allocate a variable a hard register for just part of a function; for
-example, through a particular loop where the variable is mostly used,
-or outside of a particular loop where the variable is not used. (The
-latter is nice because it might let the variable be in a register most
-of the time even though the loop needs all the registers.)
-
-Contact meissner@cygnus.com before starting any work on live range
-splitting.
-
-* Detect dead stores into memory?
-
-A store into memory is dead if it is followed by another store into
-the same location; and, in between, there is no reference to anything
-that might be that location (including no reference to a variable
-address).
-
-This can be modeled as a partial redundancy elimination/lazy code motion
-problem. Contact law@cygnus.com before working on dead store elimination
-optimizations.
-
-* Loop optimization.
-
-Strength reduction and iteration variable elimination could be
-smarter. They should know how to decide which iteration variables are
-not worth making explicit because they can be computed as part of an
-address calculation. Based on this information, they should decide
-when it is desirable to eliminate one iteration variable and create
-another in its place.
-
-It should be possible to compute what the value of an iteration
-variable will be at the end of the loop, and eliminate the variable
-within the loop by computing that value at the loop end.
-
-When a loop has a simple increment that adds 1,
-instead of jumping in after the increment,
-decrement the loop count and jump to the increment.
-This allows aob insns to be used.
-
-* Using constraints on values.
-
-Many operations could be simplified based on knowledge of the
-minimum and maximum possible values of a register at any particular time.
-These limits could come from the data types in the tree, via rtl generation,
-or they can be deduced from operations that are performed. For example,
-the result of an `and' operation one of whose operands is 7 must be in
-the range 0 to 7. Compare instructions also tell something about the
-possible values of the operand, in the code beyond the test.
-
-Value constraints can be used to determine the results of a further
-comparison. They can also indicate that certain `and' operations are
-redundant. Constraints might permit a decrement and branch
-instruction that checks zeroness to be used when the user has
-specified to exit if negative.
-
-* Smarter reload pass.
-
-The reload pass as currently written can reload values only into registers
-that are reserved for reloading. This means that in order to use a
-register for reloading it must spill everything out of that register.
-
-It would be straightforward, though complicated, for reload1.c to keep
-track, during its scan, of which hard registers were available at each
-point in the function, and use for reloading even registers that were
-free only at the point they were needed. This would avoid much spilling
-and make better code.
-
-* Change the type of a variable.
-
-Sometimes a variable is declared as `int', it is assigned only once
-from a value of type `char', and then it is used only by comparison
-against constants. On many machines, better code would result if
-the variable had type `char'. If the compiler could detect this
-case, it could change the declaration of the variable and change
-all the places that use it.
-
-* Better handling for very sparse switches.
-
-There may be cases where it would be better to compile a switch
-statement to use a fixed hash table rather than the current
-combination of jump tables and binary search.
-
-* Order of subexpressions.
-
-It might be possible to make better code by paying attention
-to the order in which to generate code for subexpressions of an expression.
-
-* More code motion.
-
-Consider hoisting common code up past conditional branches or tablejumps.
-
-Contact law@cygnus.com before working on code hoisting.
-
-* Trace scheduling.
-
-This technique is said to be able to figure out which way a jump
-will usually go, and rearrange the code to make that path the
-faster one.
-
-* Distributive law.
-
-The C expression *(X + 4 * (Y + C)) compiles better on certain
-machines if rewritten as *(X + 4*C + 4*Y) because of known addressing
-modes. It may be tricky to determine when, and for which machines, to
-use each alternative.
-
-Some work has been done on this, in combine.c.
-
-* Can optimize by changing if (x) y; else z; into z; if (x) y;
-if z and x do not interfere and z has no effects not undone by y.
-This is desirable if z is faster than jumping.
-
-* For a two-insn loop on the 68020, such as
- foo: movb a2@+,a3@+
- jne foo
-it is better to insert dbeq d0,foo before the jne.
-d0 can be a junk register. The challenge is to fit this into
-a portable framework: when can you detect this situation and
-still be able to allocate a junk register?
-
-2. Simpler porting.
-
-Right now, describing the target machine's instructions is done
-cleanly, but describing its addressing mode is done with several
-ad-hoc macro definitions. Porting would be much easier if there were
-an RTL description for addressing modes like that for instructions.
-Tools analogous to genflags and genrecog would generate macros from
-this description.
-
-There would be one pattern in the address-description file for each
-kind of addressing, and this pattern would have:
-
- * the RTL expression for the address
- * C code to verify its validity (since that may depend on
- the exact data).
- * C code to print the address in assembler language.
- * C code to convert the address into a valid one, if it is not valid.
- (This would replace LEGITIMIZE_ADDRESS).
- * Register constraints for all indeterminates that appear
- in the RTL expression.
-
-3. Other languages.
-
-Front ends for Pascal, Fortran, Algol, Cobol, Modula-2 and Ada are
-desirable.
-
-Pascal, Modula-2 and Ada require the implementation of functions
-within functions. Some of the mechanisms for this already exist.
-
-4. More extensions.
-
-* Generated unique labels. Have some way of generating distinct labels
-for use in extended asm statements. I don't know what a good syntax would
-be.
-
-* A way of defining a structure containing a union, in which the choice of
-union alternative is controlled by a previous structure component.
-
-Here is a possible syntax for this.
-
-struct foo {
- enum { INT, DOUBLE } code;
- auto union { case INT: int i; case DOUBLE: double d;} value : code;
-};
-
-* Allow constructor expressions as lvalues, like this:
-
- (struct foo) {a, b, c} = foo();
-
-This would call foo, which returns a structure, and then store the
-several components of the structure into the variables a, b, and c.
-
-5. Generalize the machine model.
-
-* Some new compiler features may be needed to do a good job on machines
-where static data needs to be addressed using base registers.
-
-* Some machines have two stacks in different areas of memory, one used
-for scalars and another for large objects. The compiler does not
-now have a way to understand this.
-
-6. Useful warnings.
-
-* Warn about statements that are undefined because the order of
-evaluation of increment operators makes a big difference. Here is an
-example:
-
- *foo++ = hack (*foo);
-
-7. Better documentation of how GCC works and how to port it.
-
-Here is an outline proposed by Allan Adler.
-
-I. Overview of this document
-II. The machines on which GCC is implemented
- A. Prose description of those characteristics of target machines and
- their operating systems which are pertinent to the implementation
- of GCC.
- i. target machine characteristics
- ii. comparison of this system of machine characteristics with
- other systems of machine specification currently in use
- B. Tables of the characteristics of the target machines on which
- GCC is implemented.
- C. A priori restrictions on the values of characteristics of target
- machines, with special reference to those parts of the source code
- which entail those restrictions
- i. restrictions on individual characteristics
- ii. restrictions involving relations between various characteristics
- D. The use of GCC as a cross-compiler
- i. cross-compilation to existing machines
- ii. cross-compilation to non-existent machines
- E. Assumptions which are made regarding the target machine
- i. assumptions regarding the architecture of the target machine
- ii. assumptions regarding the operating system of the target machine
- iii. assumptions regarding software resident on the target machine
- iv. where in the source code these assumptions are in effect made
-III. A systematic approach to writing the files tm.h and xm.h
- A. Macros which require special care or skill
- B. Examples, with special reference to the underlying reasoning
-IV. A systematic approach to writing the machine description file md
- A. Minimal viable sets of insn descriptions
- B. Examples, with special reference to the underlying reasoning
-V. Uses of the file aux-output.c
-VI. Specification of what constitutes correct performance of an
- implementation of GCC
- A. The components of GCC
- B. The itinerary of a C program through GCC
- C. A system of benchmark programs
- D. What your RTL and assembler should look like with these benchmarks
- E. Fine tuning for speed and size of compiled code
-VII. A systematic procedure for debugging an implementation of GCC
- A. Use of GDB
- i. the macros in the file .gdbinit for GCC
- ii. obstacles to the use of GDB
- a. functions implemented as macros can't be called in GDB
- B. Debugging without GDB
- i. How to turn off the normal operation of GCC and access specific
- parts of GCC
- C. Debugging tools
- D. Debugging the parser
- i. how machine macros and insn definitions affect the parser
- E. Debugging the recognizer
- i. how machine macros and insn definitions affect the recognizer
-
-ditto for other components
-
-VIII. Data types used by GCC, with special reference to restrictions not
- specified in the formal definition of the data type
-IX. References to the literature for the algorithms used in GCC
-
diff --git a/contrib/gcc/README b/contrib/gcc/README
deleted file mode 100644
index a12bf7594630..000000000000
--- a/contrib/gcc/README
+++ /dev/null
@@ -1,26 +0,0 @@
-This directory contains the GNU Compiler Collection (GCC) version 2.95.
-It includes all of the support for compiling C, C++, Objective C, Fortran,
-Java, and Chill.
-
-The GNU Compiler Collection is free software. See the file COPYING for copying
-permission.
-
-See the file gcc.texi (together with other files that it includes) for
-installation and porting information. The file INSTALL contains a
-copy of the installation information, as plain ASCII.
-
-Installing this package will create various files in subdirectories of
-/usr/local/lib, which are passes used by the compiler and a library
-named libgcc.a. It will also create /usr/local/bin/gcc, which is
-the user-level command to do a compilation.
-
-See the Bugs chapter of the GCC Manual for how to report bugs
-usefully. An online readable version of the manual is in the files
-gcc.info*.
-
-The files pself.c and pself1.c are not part of GCC.
-They are programs that print themselves on standard output.
-They were written by Dario Dariol and Giovanni Cozzi, and are
-included for your hacking pleasure. Likewise pself2.c
-(Who is the author of that?) and pself3.c (by Vlad Taeerov and Rashit
-Fakhreyev).
diff --git a/contrib/gcc/README-bugs b/contrib/gcc/README-bugs
deleted file mode 100644
index 06e15bb8af70..000000000000
--- a/contrib/gcc/README-bugs
+++ /dev/null
@@ -1,144 +0,0 @@
-The purpose of GCC pretesting is to verify that the new GCC
-distribution, about to be released, works properly on your system *with
-no change whatever*, when installed following the precise
-recommendations that come with the distribution.
-
-Here are some guidelines on how to do pretesting so as to make it
-helpful. All of them follow from common sense together with the
-nature of the purpose and the situation.
-
-* It is absolutely vital that you mention even the smallest change or
-departure from the standard sources and installation procedure.
-
-Otherwise, you are not testing the same program that I wrote. Testing
-a different program is usually of no use whatever. It can even cause
-trouble if you fail to tell me that you tested some other program
-instead of what I know as GCC. I might think that GCC works, when in
-fact it has not been properly tried, and might have a glaring fault.
-
-* Even changing the compilation options counts as a change in the
-program. The GCC sources specify which compilation options to use.
-Some of them are specified in makefiles, and some in machine-specific
-configuration files.
-
-You have ways to override this--but if you do, then you are not
-testing what ordinary users will do. Therefore, when pretesting, it
-is vital to test with the default compilation options.
-
-(It is okay to test with nonstandard options as well as testing with
-the standard ones.)
-
-* The machine and system configuration files of GCC are parts of
-GCC. So when you test GCC, you need to do it with the
-configuration files that come with GCC.
-
-If GCC does not come with configuration files for a certain machine,
-and you test it with configuration files that don't come with GCC,
-this is effectively changing GCC. Because the crucial fact about
-the planned release is that, without changes, it doesn't work on that
-machine.
-
-To make GCC work on that machine, I would need to install new
-configuration files. That is not out of the question, since it is
-safe--it certainly won't break any other machines that already work.
-But you will have to rush me the legal papers to give the FSF
-permission to use a large piece of text.
-
-* Look for recommendations for your system.
-
-You can find these recommendations in the Installation node of the
-manual, and in the file INSTALL. (These two files have the same text.)
-
-These files say which configuration name to use for your machine, so
-use the ones that are recommended. If you guess, you might guess
-wrong and encounter spurious difficulties. What's more, if you don't
-follow the recommendations then you aren't helping to test that its
-recommendations are valid.
-
-These files may describe other things that you need to do to make GCC
-work on your machine. If so, you should follow these recommendations
-also, for the same reason.
-
-Also look at the Trouble chapter of the manual for items that
-pertain to your machine.
-
-* Don't delay sending information.
-
-When you find a problem, please double check it if you can do so
-quickly. But don't spend a long time double-checking. A good rule is
-always to tell me about every problem on the same day you encounter
-it, even if that means you can't find a solution before you report the
-problem.
-
-I'd much rather hear about a problem today and a solution tomorrow
-than get both of them tomorrow at the same time.
-
-* Make each bug report self-contained.
-
-If you refer back to another message, whether from you or from someone
-else, then it will be necessary for anyone who wants to investigate
-the bug to find the other message. This may be difficult, it is
-probably time-consuming.
-
-To help me save time, simply copy the relevant parts of any previous
-messages into your own bug report.
-
-In particular, if I ask you for more information because a bug report
-was incomplete, it is best to send me the *entire* collection of
-relevant information, all together. If you send just the additional
-information, that makes me do extra work. There is even a risk that
-I won't remember what question you are sending me the answer to.
-
-* Always be precise when talking about changes you have made. Show
-things rather than describing them. Use exact filenames (relative to
-the main directory of the distribution), not partial ones. For
-example, say "I changed Makefile" rather than "I changed the
-makefile". Instead of saying "I defined the MUMBLE macro", send a
-diff that shows your change.
-
-* Always use `diff -c' to make diffs. If you don't include context,
-it may be hard for me to figure out where you propose to make the
-changes. I might have to ignore your patch because I can't tell what
-it means.
-
-* When you write a fix, keep in mind that I can't install a change
-that would break other systems.
-
-People often suggest fixing a problem by changing machine-independent
-files such as toplev.c to do something special that a particular
-system needs. Sometimes it is totally obvious that such changes would
-break GCC for almost all users. I can't possibly make a change like
-that. All I can do is send it back to you and ask you to find a fix
-that is safe to install.
-
-Sometimes people send fixes that *might* be an improvement in
-general--but it is hard to be sure of this. I can install such
-changes some of the time, but not during pretest, when I am trying to
-get a new version to work reliably as quickly as possible.
-
-The safest changes for me to install are changes to the configuration
-files for a particular machine. At least I know those can't create
-bugs on other machines.
-
-* Don't try changing GCC unless it fails to work if you don't change it.
-
-* Don't even suggest changes that would only make GCC cleaner.
-Every change I install could introduce a bug, so I won't install
-a change unless I see it is necessary.
-
-* If you would like to suggest changes for purposes other than fixing
-serious bugs, don't wait till pretest time. Instead, send them just
-after I make a release. That's the best time for me to install them.
-
-* In some cases, if you don't follow these guidelines, your
-information might still be useful, but I might have to do more work to
-make use of it. Unfortunately, I am so far behind in my work that I
-just can't get the job done unless you help me to do it efficiently.
-
-
- Thank you
- rms
-
-Local Variables:
-mode: text
-End:
diff --git a/contrib/gcc/README.DWARF b/contrib/gcc/README.DWARF
deleted file mode 100644
index 97459508b3c4..000000000000
--- a/contrib/gcc/README.DWARF
+++ /dev/null
@@ -1,574 +0,0 @@
-Notes on the GNU Implementation of DWARF Debugging Information
---------------------------------------------------------------
-Last Updated: Sun Jul 17 08:17:42 PDT 1994 by rfg@segfault.us.com
-------------------------------------------------------------
-
-This file describes special and unique aspects of the GNU implementation
-of the DWARF debugging information language, as provided in the GNU version
-2.x compiler(s).
-
-For general information about the DWARF debugging information language,
-you should obtain the DWARF version 1 specification document (and perhaps
-also the DWARF version 2 draft specification document) developed by the
-UNIX International Programming Languages Special Interest Group. A copy
-of the DWARF version 1 specification (in PostScript form) may be
-obtained either from me <rfg@netcom.com> or from the main Data General
-FTP server. (See below.) The file you are looking at now only describes
-known deviations from the DWARF version 1 specification, together with
-those things which are allowed by the DWARF version 1 specification but
-which are known to cause interoperability problems (e.g. with SVR4 SDB).
-
-To obtain a copy of the DWARF Version 1 and/or DWARF Version 2 specification
-from Data General's FTP server, use the following procedure:
-
----------------------------------------------------------------------------
- ftp to machine: "dg-rtp.dg.com" (128.222.1.2).
-
- Log in as "ftp".
- cd to "plsig"
- get any of the following file you are interested in:
-
- dwarf.1.0.3.ps
- dwarf.2.0.0.index.ps
- dwarf.2.0.0.ps
----------------------------------------------------------------------------
-
-The generation of DWARF debugging information by the GNU version 2.x C
-compiler has now been tested rather extensively for m88k, i386, i860, and
-Sparc targets. The DWARF output of the GNU C compiler appears to inter-
-operate well with the standard SVR4 SDB debugger on these kinds of target
-systems (but of course, there are no guarantees).
-
-DWARF generation for the GNU g++ compiler is still not operable. This is
-due primarily to the many remaining cases where the g++ front end does not
-conform to the conventions used in the GNU C front end for representing
-various kinds of declarations in the TREE data structure. It is not clear
-at this time how these problems will be addressed.
-
-Future plans for the dwarfout.c module of the GNU compiler(s) includes the
-addition of full support for GNU FORTRAN. (This should, in theory, be a
-lot simpler to add than adding support for g++... but we'll see.)
-
-Many features of the DWARF version 2 specification have been adapted to
-(and used in) the GNU implementation of DWARF (version 1). In most of
-these cases, a DWARF version 2 approach is used in place of (or in addition
-to) DWARF version 1 stuff simply because it is apparent that DWARF version
-1 is not sufficiently expressive to provide the kinds of information which
-may be necessary to support really robust debugging. In all of these cases
-however, the use of DWARF version 2 features should not interfere in any
-way with the interoperability (of GNU compilers) with generally available
-"classic" (pre version 1) DWARF consumer tools (e.g. SVR4 SDB).
-
-The DWARF generation enhancement for the GNU compiler(s) was initially
-donated to the Free Software Foundation by Network Computing Devices.
-(Thanks NCD!) Additional development and maintenance of dwarfout.c has
-been largely supported (i.e. funded) by Intel Corporation. (Thanks Intel!)
-
-If you have questions or comments about the DWARF generation feature, please
-send mail to me <rfg@netcom.com>. I will be happy to investigate any bugs
-reported and I may even provide fixes (but of course, I can make no promises).
-
-The DWARF debugging information produced by GCC may deviate in a few minor
-(but perhaps significant) respects from the DWARF debugging information
-currently produced by other C compilers. A serious attempt has been made
-however to conform to the published specifications, to existing practice,
-and to generally accepted norms in the GNU implementation of DWARF.
-
- ** IMPORTANT NOTE ** ** IMPORTANT NOTE ** ** IMPORTANT NOTE **
-
-Under normal circumstances, the DWARF information generated by the GNU
-compilers (in an assembly language file) is essentially impossible for
-a human being to read. This fact can make it very difficult to debug
-certain DWARF-related problems. In order to overcome this difficulty,
-a feature has been added to dwarfout.c (enabled by the -fverbose-asm
-option) which causes additional comments to be placed into the assembly
-language output file, out to the right-hand side of most bits of DWARF
-material. The comments indicate (far more clearly that the obscure
-DWARF hex codes do) what is actually being encoded in DWARF. Thus, the
--fverbose-asm option can be highly useful for those who must study the
-DWARF output from the GNU compilers in detail.
-
----------
-
-(Footnote: Within this file, the term `Debugging Information Entry' will
-be abbreviated as `DIE'.)
-
-
-Release Notes (aka known bugs)
--------------------------------
-
-In one very obscure case involving dynamically sized arrays, the DWARF
-"location information" for such an array may make it appear that the
-array has been totally optimized out of existence, when in fact it
-*must* actually exist. (This only happens when you are using *both* -g
-*and* -O.) This is due to aggressive dead store elimination in the
-compiler, and to the fact that the DECL_RTL expressions associated with
-variables are not always updated to correctly reflect the effects of
-GCC's aggressive dead store elimination.
-
--------------------------------
-
-When attempting to set a breakpoint at the "start" of a function compiled
-with -g1, the debugger currently has no way of knowing exactly where the
-end of the prologue code for the function is. Thus, for most targets,
-all the debugger can do is to set the breakpoint at the AT_low_pc address
-for the function. But if you stop there and then try to look at one or
-more of the formal parameter values, they may not have been "homed" yet,
-so you may get inaccurate answers (or perhaps even addressing errors).
-
-Some people may consider this simply a non-feature, but I consider it a
-bug, and I hope to provide some GNU-specific attributes (on function
-DIEs) which will specify the address of the end of the prologue and the
-address of the beginning of the epilogue in a future release.
-
--------------------------------
-
-It is believed at this time that old bugs relating to the AT_bit_offset
-values for bit-fields have been fixed.
-
-There may still be some very obscure bugs relating to the DWARF description
-of type `long long' bit-fields for target machines (e.g. 80x86 machines)
-where the alignment of type `long long' data objects is different from
-(and less than) the size of a type `long long' data object.
-
-Please report any problems with the DWARF description of bit-fields as you
-would any other GCC bug. (Procedures for bug reporting are given in the
-GNU C compiler manual.)
-
---------------------------------
-
-At this time, GCC does not know how to handle the GNU C "nested functions"
-extension. (See the GCC manual for more info on this extension to ANSI C.)
-
---------------------------------
-
-The GNU compilers now represent inline functions (and inlined instances
-thereof) in exactly the manner described by the current DWARF version 2
-(draft) specification. The version 1 specification for handling inline
-functions (and inlined instances) was known to be brain-damaged (by the
-PLSIG) when the version 1 spec was finalized, but it was simply too late
-in the cycle to get it removed before the version 1 spec was formally
-released to the public (by UI).
-
---------------------------------
-
-At this time, GCC does not generate the kind of really precise information
-about the exact declared types of entities with signed integral types which
-is required by the current DWARF draft specification.
-
-Specifically, the current DWARF draft specification seems to require that
-the type of an non-unsigned integral bit-field member of a struct or union
-type be represented as either a "signed" type or as a "plain" type,
-depending upon the exact set of keywords that were used in the
-type specification for the given bit-field member. It was felt (by the
-UI/PLSIG) that this distinction between "plain" and "signed" integral types
-could have some significance (in the case of bit-fields) because ANSI C
-does not constrain the signedness of a plain bit-field, whereas it does
-constrain the signedness of an explicitly "signed" bit-field. For this
-reason, the current DWARF specification calls for compilers to produce
-type information (for *all* integral typed entities... not just bit-fields)
-which explicitly indicates the signedness of the relevant type to be
-"signed" or "plain" or "unsigned".
-
-Unfortunately, the GNU DWARF implementation is currently incapable of making
-such distinctions.
-
---------------------------------
-
-
-Known Interoperability Problems
--------------------------------
-
-Although the GNU implementation of DWARF conforms (for the most part) with
-the current UI/PLSIG DWARF version 1 specification (with many compatible
-version 2 features added in as "vendor specific extensions" just for good
-measure) there are a few known cases where GCC's DWARF output can cause
-some confusion for "classic" (pre version 1) DWARF consumers such as the
-System V Release 4 SDB debugger. These cases are described in this section.
-
---------------------------------
-
-The DWARF version 1 specification includes the fundamental type codes
-FT_ext_prec_float, FT_complex, FT_dbl_prec_complex, and FT_ext_prec_complex.
-Since GNU C is only a C compiler (and since C doesn't provide any "complex"
-data types) the only one of these fundamental type codes which GCC ever
-generates is FT_ext_prec_float. This fundamental type code is generated
-by GCC for the `long double' data type. Unfortunately, due to an apparent
-bug in the SVR4 SDB debugger, SDB can become very confused wherever any
-attempt is made to print a variable, parameter, or field whose type was
-given in terms of FT_ext_prec_float.
-
-(Actually, SVR4 SDB fails to understand *any* of the four fundamental type
-codes mentioned here. This will fact will cause additional problems when
-there is a GNU FORTRAN front-end.)
-
---------------------------------
-
-In general, it appears that SVR4 SDB is not able to effectively ignore
-fundamental type codes in the "implementation defined" range. This can
-cause problems when a program being debugged uses the `long long' data
-type (or the signed or unsigned varieties thereof) because these types
-are not defined by ANSI C, and thus, GCC must use its own private fundamental
-type codes (from the implementation-defined range) to represent these types.
-
---------------------------------
-
-
-General GNU DWARF extensions
-----------------------------
-
-In the current DWARF version 1 specification, no mechanism is specified by
-which accurate information about executable code from include files can be
-properly (and fully) described. (The DWARF version 2 specification *does*
-specify such a mechanism, but it is about 10 times more complicated than
-it needs to be so I'm not terribly anxious to try to implement it right
-away.)
-
-In the GNU implementation of DWARF version 1, a fully downward-compatible
-extension has been implemented which permits the GNU compilers to specify
-which executable lines come from which files. This extension places
-additional information (about source file names) in GNU-specific sections
-(which should be totally ignored by all non-GNU DWARF consumers) so that
-this extended information can be provided (to GNU DWARF consumers) in a way
-which is totally transparent (and invisible) to non-GNU DWARF consumers
-(e.g. the SVR4 SDB debugger). The additional information is placed *only*
-in specialized GNU-specific sections, where it should never even be seen
-by non-GNU DWARF consumers.
-
-To understand this GNU DWARF extension, imagine that the sequence of entries
-in the .lines section is broken up into several subsections. Each contiguous
-sequence of .line entries which relates to a sequence of lines (or statements)
-from one particular file (either a `base' file or an `include' file) could
-be called a `line entries chunk' (LEC).
-
-For each LEC there is one entry in the .debug_srcinfo section.
-
-Each normal entry in the .debug_srcinfo section consists of two 4-byte
-words of data as follows:
-
- (1) The starting address (relative to the entire .line section)
- of the first .line entry in the relevant LEC.
-
- (2) The starting address (relative to the entire .debug_sfnames
- section) of a NUL terminated string representing the
- relevant filename. (This filename name be either a
- relative or an absolute filename, depending upon how the
- given source file was located during compilation.)
-
-Obviously, each .debug_srcinfo entry allows you to find the relevant filename,
-and it also points you to the first .line entry that was generated as a result
-of having compiled a given source line from the given source file.
-
-Each subsequent .line entry should also be assumed to have been produced
-as a result of compiling yet more lines from the same file. The end of
-any given LEC is easily found by looking at the first 4-byte pointer in
-the *next* .debug_srcinfo entry. That next .debug_srcinfo entry points
-to a new and different LEC, so the preceding LEC (implicitly) must have
-ended with the last .line section entry which occurs at the 2 1/2 words
-just before the address given in the first pointer of the new .debug_srcinfo
-entry.
-
-The following picture may help to clarify this feature. Let's assume that
-`LE' stands for `.line entry'. Also, assume that `* 'stands for a pointer.
-
-
- .line section .debug_srcinfo section .debug_sfnames section
- ----------------------------------------------------------------
-
- LE <---------------------- *
- LE * -----------------> "foobar.c" <---
- LE |
- LE |
- LE <---------------------- * |
- LE * -----------------> "foobar.h" <| |
- LE | |
- LE | |
- LE <---------------------- * | |
- LE * -----------------> "inner.h" | |
- LE | |
- LE <---------------------- * | |
- LE * ------------------------------- |
- LE |
- LE |
- LE |
- LE |
- LE <---------------------- * |
- LE * -----------------------------------
- LE
- LE
- LE
-
-In effect, each entry in the .debug_srcinfo section points to *both* a
-filename (in the .debug_sfnames section) and to the start of a block of
-consecutive LEs (in the .line section).
-
-Note that just like in the .line section, there are specialized first and
-last entries in the .debug_srcinfo section for each object file. These
-special first and last entries for the .debug_srcinfo section are very
-different from the normal .debug_srcinfo section entries. They provide
-additional information which may be helpful to a debugger when it is
-interpreting the data in the .debug_srcinfo, .debug_sfnames, and .line
-sections.
-
-The first entry in the .debug_srcinfo section for each compilation unit
-consists of five 4-byte words of data. The contents of these five words
-should be interpreted (by debuggers) as follows:
-
- (1) The starting address (relative to the entire .line section)
- of the .line section for this compilation unit.
-
- (2) The starting address (relative to the entire .debug_sfnames
- section) of the .debug_sfnames section for this compilation
- unit.
-
- (3) The starting address (in the execution virtual address space)
- of the .text section for this compilation unit.
-
- (4) The ending address plus one (in the execution virtual address
- space) of the .text section for this compilation unit.
-
- (5) The date/time (in seconds since midnight 1/1/70) at which the
- compilation of this compilation unit occurred. This value
- should be interpreted as an unsigned quantity because gcc
- might be configured to generate a default value of 0xffffffff
- in this field (in cases where it is desired to have object
- files created at different times from identical source files
- be byte-for-byte identical). By default, these timestamps
- are *not* generated by dwarfout.c (so that object files
- compiled at different times will be byte-for-byte identical).
- If you wish to enable this "timestamp" feature however, you
- can simply place a #define for the symbol `DWARF_TIMESTAMPS'
- in your target configuration file and then rebuild the GNU
- compiler(s).
-
-Note that the first string placed into the .debug_sfnames section for each
-compilation unit is the name of the directory in which compilation occurred.
-This string ends with a `/' (to help indicate that it is the pathname of a
-directory). Thus, the second word of each specialized initial .debug_srcinfo
-entry for each compilation unit may be used as a pointer to the (string)
-name of the compilation directory, and that string may in turn be used to
-"absolutize" any relative pathnames which may appear later on in the
-.debug_sfnames section entries for the same compilation unit.
-
-The fifth and last word of each specialized starting entry for a compilation
-unit in the .debug_srcinfo section may (depending upon your configuration)
-indicate the date/time of compilation, and this may be used (by a debugger)
-to determine if any of the source files which contributed code to this
-compilation unit are newer than the object code for the compilation unit
-itself. If so, the debugger may wish to print an "out-of-date" warning
-about the compilation unit.
-
-The .debug_srcinfo section associated with each compilation will also have
-a specialized terminating entry. This terminating .debug_srcinfo section
-entry will consist of the following two 4-byte words of data:
-
- (1) The offset, measured from the start of the .line section to
- the beginning of the terminating entry for the .line section.
-
- (2) A word containing the value 0xffffffff.
-
---------------------------------
-
-In the current DWARF version 1 specification, no mechanism is specified by
-which information about macro definitions and un-definitions may be provided
-to the DWARF consumer.
-
-The DWARF version 2 (draft) specification does specify such a mechanism.
-That specification was based on the GNU ("vendor specific extension")
-which provided some support for macro definitions and un-definitions,
-but the "official" DWARF version 2 (draft) specification mechanism for
-handling macros and the GNU implementation have diverged somewhat. I
-plan to update the GNU implementation to conform to the "official"
-DWARF version 2 (draft) specification as soon as I get time to do that.
-
-Note that in the GNU implementation, additional information about macro
-definitions and un-definitions is *only* provided when the -g3 level of
-debug-info production is selected. (The default level is -g2 and the
-plain old -g option is considered to be identical to -g2.)
-
-GCC records information about macro definitions and undefinitions primarily
-in a section called the .debug_macinfo section. Normal entries in the
-.debug_macinfo section consist of the following three parts:
-
- (1) A special "type" byte.
-
- (2) A 3-byte line-number/filename-offset field.
-
- (3) A NUL terminated string.
-
-The interpretation of the second and third parts is dependent upon the
-value of the leading (type) byte.
-
-The type byte may have one of four values depending upon the type of the
-.debug_macinfo entry which follows. The 1-byte MACINFO type codes presently
-used, and their meanings are as follows:
-
- MACINFO_start A base file or an include file starts here.
- MACINFO_resume The current base or include file ends here.
- MACINFO_define A #define directive occurs here.
- MACINFO_undef A #undef directive occur here.
-
-(Note that the MACINFO_... codes mentioned here are simply symbolic names
-for constants which are defined in the GNU dwarf.h file.)
-
-For MACINFO_define and MACINFO_undef entries, the second (3-byte) field
-contains the number of the source line (relative to the start of the current
-base source file or the current include files) when the #define or #undef
-directive appears. For a MACINFO_define entry, the following string field
-contains the name of the macro which is defined, followed by its definition.
-Note that the definition is always separated from the name of the macro
-by at least one whitespace character. For a MACINFO_undef entry, the
-string which follows the 3-byte line number field contains just the name
-of the macro which is being undef'ed.
-
-For a MACINFO_start entry, the 3-byte field following the type byte contains
-the offset, relative to the start of the .debug_sfnames section for the
-current compilation unit, of a string which names the new source file which
-is beginning its inclusion at this point. Following that 3-byte field,
-each MACINFO_start entry always contains a zero length NUL terminated
-string.
-
-For a MACINFO_resume entry, the 3-byte field following the type byte contains
-the line number WITHIN THE INCLUDING FILE at which the inclusion of the
-current file (whose inclusion ends here) was initiated. Following that
-3-byte field, each MACINFO_resume entry always contains a zero length NUL
-terminated string.
-
-Each set of .debug_macinfo entries for each compilation unit is terminated
-by a special .debug_macinfo entry consisting of a 4-byte zero value followed
-by a single NUL byte.
-
---------------------------------
-
-In the current DWARF draft specification, no provision is made for providing
-a separate level of (limited) debugging information necessary to support
-tracebacks (only) through fully-debugged code (e.g. code in system libraries).
-
-A proposal to define such a level was submitted (by me) to the UI/PLSIG.
-This proposal was rejected by the UI/PLSIG for inclusion into the DWARF
-version 1 specification for two reasons. First, it was felt (by the PLSIG)
-that the issues involved in supporting a "traceback only" subset of DWARF
-were not well understood. Second, and perhaps more importantly, the PLSIG
-is already having enough trouble agreeing on what it means to be "conforming"
-to the DWARF specification, and it was felt that trying to specify multiple
-different *levels* of conformance would only complicate our discussions of
-this already divisive issue. Nonetheless, the GNU implementation of DWARF
-provides an abbreviated "traceback only" level of debug-info production for
-use with fully-debugged "system library" code. This level should only be
-used for fully debugged system library code, and even then, it should only
-be used where there is a very strong need to conserve disk space. This
-abbreviated level of debug-info production can be used by specifying the
--g1 option on the compilation command line.
-
---------------------------------
-
-As mentioned above, the GNU implementation of DWARF currently uses the DWARF
-version 2 (draft) approach for inline functions (and inlined instances
-thereof). This is used in preference to the version 1 approach because
-(quite simply) the version 1 approach is highly brain-damaged and probably
-unworkable.
-
---------------------------------
-
-
-GNU DWARF Representation of GNU C Extensions to ANSI C
-------------------------------------------------------
-
-The file dwarfout.c has been designed and implemented so as to provide
-some reasonable DWARF representation for each and every declarative
-construct which is accepted by the GNU C compiler. Since the GNU C
-compiler accepts a superset of ANSI C, this means that there are some
-cases in which the DWARF information produced by GCC must take some
-liberties in improvising DWARF representations for declarations which
-are only valid in (extended) GNU C.
-
-In particular, GNU C provides at least three significant extensions to
-ANSI C when it comes to declarations. These are (1) inline functions,
-and (2) dynamic arrays, and (3) incomplete enum types. (See the GCC
-manual for more information on these GNU extensions to ANSI C.) When
-used, these GNU C extensions are represented (in the generated DWARF
-output of GCC) in the most natural and intuitively obvious ways.
-
-In the case of inline functions, the DWARF representation is exactly as
-called for in the DWARF version 2 (draft) specification for an identical
-function written in C++; i.e. we "reuse" the representation of inline
-functions which has been defined for C++ to support this GNU C extension.
-
-In the case of dynamic arrays, we use the most obvious representational
-mechanism available; i.e. an array type in which the upper bound of
-some dimension (usually the first and only dimension) is a variable
-rather than a constant. (See the DWARF version 1 specification for more
-details.)
-
-In the case of incomplete enum types, such types are represented simply
-as TAG_enumeration_type DIEs which DO NOT contain either AT_byte_size
-attributes or AT_element_list attributes.
-
---------------------------------
-
-
-Future Directions
------------------
-
-The codes, formats, and other paraphernalia necessary to provide proper
-support for symbolic debugging for the C++ language are still being worked
-on by the UI/PLSIG. The vast majority of the additions to DWARF which will
-be needed to completely support C++ have already been hashed out and agreed
-upon, but a few small issues (e.g. anonymous unions, access declarations)
-are still being discussed. Also, we in the PLSIG are still discussing
-whether or not we need to do anything special for C++ templates. (At this
-time it is not yet clear whether we even need to do anything special for
-these.)
-
-Unfortunately, as mentioned above, there are quite a few problems in the
-g++ front end itself, and these are currently responsible for severely
-restricting the progress which can be made on adding DWARF support
-specifically for the g++ front-end. Furthermore, Richard Stallman has
-expressed the view that C++ friendships might not be important enough to
-describe (in DWARF). This view directly conflicts with both the DWARF
-version 1 and version 2 (draft) specifications, so until this small
-misunderstanding is cleared up, DWARF support for g++ is unlikely.
-
-With regard to FORTRAN, the UI/PLSIG has defined what is believed to be a
-complete and sufficient set of codes and rules for adequately representing
-all of FORTRAN 77, and most of Fortran 90 in DWARF. While some support for
-this has been implemented in dwarfout.c, further implementation and testing
-will have to await the arrival of the GNU Fortran front-end (which is
-currently in early alpha test as of this writing).
-
-GNU DWARF support for other languages (i.e. Pascal and Modula) is a moot
-issue until there are GNU front-ends for these other languages.
-
-GNU DWARF support for DWARF version 2 will probably not be attempted until
-such time as the version 2 specification is finalized. (More work needs
-to be done on the version 2 specification to make the new "abbreviations"
-feature of version 2 more easily implementable. Until then, it will be
-a royal pain the ass to implement version 2 "abbreviations".) For the
-time being, version 2 features will be added (in a version 1 compatible
-manner) when and where these features seem necessary or extremely desirable.
-
-As currently defined, DWARF only describes a (binary) language which can
-be used to communicate symbolic debugging information from a compiler
-through an assembler and a linker, to a debugger. There is no clear
-specification of what processing should be (or must be) done by the
-assembler and/or the linker. Fortunately, the role of the assembler
-is easily inferred (by anyone knowledgeable about assemblers) just by
-looking at examples of assembly-level DWARF code. Sadly though, the
-allowable (or required) processing steps performed by a linker are
-harder to infer and (perhaps) even harder to agree upon. There are
-several forms of very useful `post-processing' steps which intelligent
-linkers *could* (in theory) perform on object files containing DWARF,
-but any and all such link-time transformations are currently both disallowed
-and unspecified.
-
-In particular, possible link-time transformations of DWARF code which could
-provide significant benefits include (but are not limited to):
-
- Commonization of duplicate DIEs obtained from multiple input
- (object) files.
-
- Cross-compilation type checking based upon DWARF type information
- for objects and functions.
-
- Other possible `compacting' transformations designed to save disk
- space and to reduce linker & debugger I/O activity.
diff --git a/contrib/gcc/README.TRAD b/contrib/gcc/README.TRAD
deleted file mode 100644
index 07ccd16437b1..000000000000
--- a/contrib/gcc/README.TRAD
+++ /dev/null
@@ -1,55 +0,0 @@
-This is a partial list of how `gcc -traditional' disagrees with
-traditional C compilers (perhaps only some of them). Most of these
-differences are not bugs.
-
----------------------------------------------------------------------------
-K&R-1 (2.4.3) says:
-
- "If the character following a backslash is not one of those
- specified {in the table above}, the backslash is ignored."
-
-Up until recently, `gcc -traditional' complained about \x \a and \v
-appearing in a character or string literal. I believe however that
-this non-feature has been eliminated (recently).
-
----------------------------------------------------------------------------
-When in -traditional mode, gcc allows the following erroneous pair of
-declarations to appear together in a given scope:
-
- typedef int foo;
- typedef foo foo;
-
----------------------------------------------------------------------------
-K&R-1 (8.5) says:
-
- "No field may be wider than a word."
-
-Gcc however allows:
-
- struct S { int i:33; };
-
----------------------------------------------------------------------------
-In K&R-1 there is no restriction against comments crossing include file
-boundaries. Gcc however doesn't allow this, even when in -traditional mode.
-
----------------------------------------------------------------------------
-Regarding the length of identifiers, K&R-1 (2.2) says:
-
- "No more than the first eight characters are significant,
- although more may be used."
-
-Gcc treats all characters of identifiers as significant, even when in
--traditional mode.
-
----------------------------------------------------------------------------
-K&R-1 (2.2) says:
-
- "An identifier is a sequence of letters and digits; the first
- character must be a letter. The underscore _ counts as a letter."
-
-Gcc also allows dollar signs in identifiers. (This may also be an issue
-for the -pedantic option.)
-
----------------------------------------------------------------------------
-
-
diff --git a/contrib/gcc/TESTS.FLUNK b/contrib/gcc/TESTS.FLUNK
deleted file mode 100644
index 04641e3c8fb8..000000000000
--- a/contrib/gcc/TESTS.FLUNK
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a collection of things that test suites have
-said were "wrong" with GCC--but that I don't agree with.
-
-First, test suites sometimes test for compatibility with
-traditional C. GCC with -traditional is not completely
-compatible with traditional C, and in some ways I think it
-should not be.
-
-* K&R C allowed \x to appear in a string literal (or character
-literal?) even in cases where it is *not* followed by a sequence of
-hex digits. I'm not convinced this is desirable.
-
-* K&R compilers allow comments to cross over an inclusion boundary (i.e.
-started in an include file and ended in the including file).
-I think this would be quite ugly and can't imagine it could
-be needed.
-
-Sometimes tests disagree with GCC's interpretation of the ANSI standard.
-
-* One test claims that this function should return 1.
-
- enum {A, B} foo;
-
- func (enum {B, A} arg)
- {
- return B;
- }
-
-I think it should return 0, because the definition of B that
-applies is the one in func.
-
-* Some tests report failure when the compiler does not produce
-an error message for a certain program.
-
-ANSI C requires a "diagnostic" message for certain kinds of invalid
-programs, but a warning counts as a diagnostic. If GCC produces
-a warning but not an error, that is correct ANSI support.
-When test suites call this "failure", the tests are broken.
-
diff --git a/contrib/gcc/assert.h b/contrib/gcc/assert.h
deleted file mode 100644
index ecc02ee99912..000000000000
--- a/contrib/gcc/assert.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Allow this file to be included multiple times
- with different settings of NDEBUG. */
-#undef assert
-#undef __assert
-
-#ifdef NDEBUG
-#define assert(ignore) ((void) 0)
-#else
-
-#ifndef __GNUC__
-
-#define assert(expression) \
- ((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
-
-#define __assert(expression, file, lineno) \
- (printf ("%s:%u: failed assertion\n", file, lineno), \
- abort (), 0)
-
-#else
-
-#if defined(__STDC__) || defined (__cplusplus)
-
-/* Defined in libgcc.a */
-#ifdef __cplusplus
-extern "C" {
-extern void __eprintf (const char *, const char *, unsigned, const char *)
- __attribute__ ((noreturn));
-}
-#else
-extern void __eprintf (const char *, const char *, unsigned, const char *)
- __attribute__ ((noreturn));
-#endif
-
-#define assert(expression) \
- ((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
-
-#define __assert(expression, file, line) \
- (__eprintf ("%s:%u: failed assertion `%s'\n", \
- file, line, expression), 0)
-
-#else /* no __STDC__ and not C++; i.e. -traditional. */
-
-extern void __eprintf () __attribute__ ((noreturn)); /* Defined in libgcc.a */
-
-#define assert(expression) \
- ((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
-
-#define __assert(expression, file, lineno) \
- (__eprintf ("%s:%u: failed assertion `%s'\n", \
- file, lineno, "expression"), 0)
-
-#endif /* no __STDC__ and not C++; i.e. -traditional. */
-#endif /* no __GNU__; i.e., /bin/cc. */
-#endif
diff --git a/contrib/gcc/build-make b/contrib/gcc/build-make
deleted file mode 100644
index f9049ae0db96..000000000000
--- a/contrib/gcc/build-make
+++ /dev/null
@@ -1,35 +0,0 @@
-# We have to use the cross-compiler we just built to compile it.
-CC = gcc -b $(host)
-
-# Need those to compile binaries running on host machine.
-# It is configured by
-#
-# configure --host=target_cpu-target_os \
-# --target=host=target_cpu-target_os --build=host_cpu-host_os
-#
-# That HOST stuff has to be taken care of very carefully.
-HOST_PREFIX=l-
-HOST_PREFIX_1=$(HOST_PREFIX)
-HOST_CC=$(CC) -b $(build)
-HOST_CFLAGS=$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS)
-HOST_CLIB=
-HOST_LDFLAGS=$(LDFLAGS)
-HOST_CPPFLAGS=$(ALL_CPPFLAGS)
-HOST_ALLOCA=$(ALLOCA)
-HOST_MALLOC=$(MALLOC)
-HOST_OBSTACK=$(OBSTACK)
-
-# To build the native compiler with the cross compiler, the headers
-# for the target are already fixed. And /usr/include is for host, not
-# target.
-FIXINCLUDES=Makefile.in
-
-# Don't run fixproto either
-STMP_FIXPROTO =
-
-# Cause installation using install-build. We do nothing here.
-#INSTALL_TARGET = install-build
-
-# Don't try to compile the things we can't compile or we have made
-# while making gcc with the cross-compiler.
-#ALL = all.build
diff --git a/contrib/gcc/c-iterate.c b/contrib/gcc/c-iterate.c
deleted file mode 100644
index dc0cc8a84af4..000000000000
--- a/contrib/gcc/c-iterate.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/* Build expressions with type checking for C compiler.
- Copyright (C) 1987, 88, 89, 92, 93, 96, 1997, 1998 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 file is part of the C front end.
- It is responsible for implementing iterators,
- both their declarations and the expansion of statements using them. */
-
-#include "config.h"
-#include "system.h"
-#include "tree.h"
-#include "c-tree.h"
-#include "flags.h"
-#include "obstack.h"
-#include "rtl.h"
-#include "toplev.h"
-#include "expr.h"
-
-/*
- KEEPING TRACK OF EXPANSIONS
-
- In order to clean out expansions corresponding to statements inside
- "{(...)}" constructs we have to keep track of all expansions. The
- cleanup is needed when an automatic, or implicit, expansion on
- iterator, say X, happens to a statement which contains a {(...)}
- form with a statement already expanded on X. In this case we have
- to go back and cleanup the inner expansion. This can be further
- complicated by the fact that {(...)} can be nested.
-
- To make this cleanup possible, we keep lists of all expansions, and
- to make it work for nested constructs, we keep a stack. The list at
- the top of the stack (ITER_STACK.CURRENT_LEVEL) corresponds to the
- currently parsed level. All expansions of the levels below the
- current one are kept in one list whose head is pointed to by
- ITER_STACK.SUBLEVEL_FIRST (SUBLEVEL_LAST is there for making merges
- easy). The process works as follows:
-
- -- On "({" a new node is added to the stack by PUSH_ITERATOR_STACK.
- The sublevel list is not changed at this point.
-
- -- On "})" the list for the current level is appended to the sublevel
- list.
-
- -- On ";" sublevel lists are appended to the current level lists.
- The reason is this: if they have not been superseded by the
- expansion at the current level, they still might be
- superseded later by the expansion on the higher level.
- The levels do not have to distinguish levels below, so we
- can merge the lists together. */
-
-struct ixpansion
-{
- tree ixdecl; /* Iterator decl */
- rtx ixprologue_start; /* First insn of epilogue. NULL means */
- /* explicit (FOR) expansion*/
- rtx ixprologue_end;
- rtx ixepilogue_start;
- rtx ixepilogue_end;
- struct ixpansion *next; /* Next in the list */
-};
-
-struct iter_stack_node
-{
- struct ixpansion *first; /* Head of list of ixpansions */
- struct ixpansion *last; /* Last node in list of ixpansions */
- struct iter_stack_node *next; /* Next level iterator stack node */
-};
-
-struct iter_stack_node *iter_stack;
-struct iter_stack_node sublevel_ixpansions;
-
-/* A special obstack, and a pointer to the start of
- all the data in it (so we can free everything easily). */
-static struct obstack ixp_obstack;
-static char *ixp_firstobj;
-
-/* During collect_iterators, a list of SAVE_EXPRs already scanned. */
-static tree save_exprs;
-
-static void expand_stmt_with_iterators_1 PROTO((tree, tree));
-static tree collect_iterators PROTO((tree, tree));
-static void iterator_loop_prologue PROTO((tree, rtx *, rtx *));
-static void iterator_loop_epilogue PROTO((tree, rtx *, rtx *));
-static int top_level_ixpansion_p PROTO((void));
-static void isn_append PROTO((struct iter_stack_node *,
- struct iter_stack_node *));
-static void istack_sublevel_to_current PROTO((void));
-static void add_ixpansion PROTO((tree, rtx, rtx, rtx, rtx));
-static void delete_ixpansion PROTO((tree));
-
-/* Initialize our obstack once per compilation. */
-
-void
-init_iterators ()
-{
- gcc_obstack_init (&ixp_obstack);
- ixp_firstobj = (char *) obstack_alloc (&ixp_obstack, 0);
-}
-
-/* Handle the start of an explicit `for' loop for iterator IDECL. */
-
-void
-iterator_for_loop_start (idecl)
- tree idecl;
-{
- ITERATOR_BOUND_P (idecl) = 1;
- add_ixpansion (idecl, 0, 0, 0, 0);
- iterator_loop_prologue (idecl, 0, 0);
-}
-
-/* Handle the end of an explicit `for' loop for iterator IDECL. */
-
-void
-iterator_for_loop_end (idecl)
- tree idecl;
-{
- iterator_loop_epilogue (idecl, 0, 0);
- ITERATOR_BOUND_P (idecl) = 0;
-}
-
-/*
- ITERATOR RTL EXPANSIONS
-
- Expanding simple statements with iterators is straightforward:
- collect the list of all free iterators in the statement, and
- generate a loop for each of them.
-
- An iterator is "free" if it has not been "bound" by a FOR
- operator. The DECL_RTL of the iterator is the loop counter. */
-
-/* Expand a statement STMT, possibly containing iterator usage, into RTL. */
-
-void
-iterator_expand (stmt)
- tree stmt;
-{
- tree iter_list;
- save_exprs = NULL_TREE;
- iter_list = collect_iterators (stmt, NULL_TREE);
- expand_stmt_with_iterators_1 (stmt, iter_list);
- istack_sublevel_to_current ();
-}
-
-
-static void
-expand_stmt_with_iterators_1 (stmt, iter_list)
- tree stmt, iter_list;
-{
- if (iter_list == 0)
- expand_expr_stmt (stmt);
- else
- {
- tree current_iterator = TREE_VALUE (iter_list);
- tree iter_list_tail = TREE_CHAIN (iter_list);
- rtx p_start, p_end, e_start, e_end;
-
- iterator_loop_prologue (current_iterator, &p_start, &p_end);
- expand_stmt_with_iterators_1 (stmt, iter_list_tail);
- iterator_loop_epilogue (current_iterator, &e_start, &e_end);
-
- /** Delete all inner expansions based on current_iterator **/
- /** before adding the outer one. **/
-
- delete_ixpansion (current_iterator);
- add_ixpansion (current_iterator, p_start, p_end, e_start, e_end);
- }
-}
-
-
-/* Return a list containing all the free (i.e. not bound by a
- containing `for' statement) iterators mentioned in EXP, plus those
- in LIST. Do not add duplicate entries to the list. */
-
-static tree
-collect_iterators (exp, list)
- tree exp, list;
-{
- if (exp == 0) return list;
-
- switch (TREE_CODE (exp))
- {
- case VAR_DECL:
- if (! ITERATOR_P (exp) || ITERATOR_BOUND_P (exp))
- return list;
- if (value_member (exp, list))
- return list;
- return tree_cons (NULL_TREE, exp, list);
-
- case TREE_LIST:
- {
- tree tail;
- for (tail = exp; tail; tail = TREE_CHAIN (tail))
- list = collect_iterators (TREE_VALUE (tail), list);
- return list;
- }
-
- case SAVE_EXPR:
- /* In each scan, scan a given save_expr only once. */
- if (value_member (exp, save_exprs))
- return list;
-
- save_exprs = tree_cons (NULL_TREE, exp, save_exprs);
- return collect_iterators (TREE_OPERAND (exp, 0), list);
-
- /* we do not automatically iterate blocks -- one must */
- /* use the FOR construct to do that */
-
- case BLOCK:
- return list;
-
- default:
- switch (TREE_CODE_CLASS (TREE_CODE (exp)))
- {
- case '1':
- return collect_iterators (TREE_OPERAND (exp, 0), list);
-
- case '2':
- case '<':
- return collect_iterators (TREE_OPERAND (exp, 0),
- collect_iterators (TREE_OPERAND (exp, 1),
- list));
-
- case 'e':
- case 'r':
- {
- int num_args = tree_code_length[(int) TREE_CODE (exp)];
- int i;
-
- /* Some tree codes have RTL, not trees, as operands. */
- switch (TREE_CODE (exp))
- {
- case CALL_EXPR:
- num_args = 2;
- break;
- case METHOD_CALL_EXPR:
- num_args = 3;
- break;
- case WITH_CLEANUP_EXPR:
- num_args = 1;
- break;
- case RTL_EXPR:
- return list;
- default:
- break;
- }
-
- for (i = 0; i < num_args; i++)
- list = collect_iterators (TREE_OPERAND (exp, i), list);
- return list;
- }
- default:
- return list;
- }
- }
-}
-
-/* Emit rtl for the start of a loop for iterator IDECL.
-
- If necessary, create loop counter rtx and store it as DECL_RTL of IDECL.
-
- The prologue normally starts and ends with notes, which are returned
- by this function in *START_NOTE and *END_NODE.
- If START_NOTE and END_NODE are 0, we don't make those notes. */
-
-static void
-iterator_loop_prologue (idecl, start_note, end_note)
- tree idecl;
- rtx *start_note, *end_note;
-{
- tree expr;
-
- /* Force the save_expr in DECL_INITIAL to be calculated
- if it hasn't been calculated yet. */
- expand_expr (DECL_INITIAL (idecl), const0_rtx, VOIDmode,
- EXPAND_NORMAL);
-
- if (DECL_RTL (idecl) == 0)
- expand_decl (idecl);
-
- if (start_note)
- *start_note = emit_note (0, NOTE_INSN_DELETED);
-
- /* Initialize counter. */
- expr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, integer_zero_node);
- TREE_SIDE_EFFECTS (expr) = 1;
- expand_expr (expr, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
- expand_start_loop_continue_elsewhere (1);
-
- ITERATOR_BOUND_P (idecl) = 1;
-
- if (end_note)
- *end_note = emit_note (0, NOTE_INSN_DELETED);
-}
-
-/* Similar to the previous function, but for the end of the loop.
-
- DECL_RTL is zeroed unless we are inside "({...})". The reason for that is
- described below.
-
- When we create two (or more) loops based on the same IDECL, and
- both inside the same "({...})" construct, we must be prepared to
- delete both of the loops and create a single one on the level
- above, i.e. enclosing the "({...})". The new loop has to use the
- same counter rtl because the references to the iterator decl
- (IDECL) have already been expanded as references to the counter
- rtl.
-
- It is incorrect to use the same counter reg in different functions,
- and it is desirable to use different counters in disjoint loops
- when we know there's no need to combine them (because then they can
- get allocated separately). */
-
-static void
-iterator_loop_epilogue (idecl, start_note, end_note)
- tree idecl;
- rtx *start_note, *end_note;
-{
- tree test, incr;
-
- if (start_note)
- *start_note = emit_note (0, NOTE_INSN_DELETED);
- expand_loop_continue_here ();
- incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0);
- incr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr);
- TREE_SIDE_EFFECTS (incr) = 1;
- expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
- test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0);
- expand_exit_loop_if_false (0, test);
- expand_end_loop ();
-
- ITERATOR_BOUND_P (idecl) = 0;
- /* we can reset rtl since there is not chance that this expansion */
- /* would be superseded by a higher level one */
- /* but don't do this if the decl is static, since we need to share */
- /* the same decl in that case. */
- if (top_level_ixpansion_p () && ! TREE_STATIC (idecl))
- DECL_RTL (idecl) = 0;
- if (end_note)
- *end_note = emit_note (0, NOTE_INSN_DELETED);
-}
-
-/* Return true if we are not currently inside a "({...})" construct. */
-
-static int
-top_level_ixpansion_p ()
-{
- return iter_stack == 0;
-}
-
-/* Given two chains of iter_stack_nodes,
- append the nodes in X into Y. */
-
-static void
-isn_append (x, y)
- struct iter_stack_node *x, *y;
-{
- if (x->first == 0)
- return;
-
- if (y->first == 0)
- {
- y->first = x->first;
- y->last = x->last;
- }
- else
- {
- y->last->next = x->first;
- y->last = x->last;
- }
-}
-
-/** Make X empty **/
-
-#define ISN_ZERO(X) (X).first=(X).last=0
-
-/* Move the ixpansions in sublevel_ixpansions into the current
- node on the iter_stack, or discard them if the iter_stack is empty.
- We do this at the end of a statement. */
-
-static void
-istack_sublevel_to_current ()
-{
- /* At the top level we can throw away sublevel's expansions **/
- /* because there is nobody above us to ask for a cleanup **/
- if (iter_stack != 0)
- /** Merging with empty sublevel list is a no-op **/
- if (sublevel_ixpansions.last)
- isn_append (&sublevel_ixpansions, iter_stack);
-
- if (iter_stack == 0)
- obstack_free (&ixp_obstack, ixp_firstobj);
-
- ISN_ZERO (sublevel_ixpansions);
-}
-
-/* Push a new node on the iter_stack, when we enter a ({...}). */
-
-void
-push_iterator_stack ()
-{
- struct iter_stack_node *new_top
- = (struct iter_stack_node *)
- obstack_alloc (&ixp_obstack, sizeof (struct iter_stack_node));
-
- new_top->first = 0;
- new_top->last = 0;
- new_top->next = iter_stack;
- iter_stack = new_top;
-}
-
-/* Pop iter_stack, moving the ixpansions in the node being popped
- into sublevel_ixpansions. */
-
-void
-pop_iterator_stack ()
-{
- if (iter_stack == 0)
- abort ();
-
- isn_append (iter_stack, &sublevel_ixpansions);
- /** Pop current level node: */
- iter_stack = iter_stack->next;
-}
-
-
-/* Record an iterator expansion ("ixpansion") for IDECL.
- The remaining parameters are the notes in the loop entry
- and exit rtl. */
-
-static void
-add_ixpansion (idecl, pro_start, pro_end, epi_start, epi_end)
- tree idecl;
- rtx pro_start, pro_end, epi_start, epi_end;
-{
- struct ixpansion *newix;
-
- /* Do nothing if we are not inside "({...})",
- as in that case this expansion can't need subsequent RTL modification. */
- if (iter_stack == 0)
- return;
-
- newix = (struct ixpansion *) obstack_alloc (&ixp_obstack,
- sizeof (struct ixpansion));
- newix->ixdecl = idecl;
- newix->ixprologue_start = pro_start;
- newix->ixprologue_end = pro_end;
- newix->ixepilogue_start = epi_start;
- newix->ixepilogue_end = epi_end;
-
- newix->next = iter_stack->first;
- iter_stack->first = newix;
- if (iter_stack->last == 0)
- iter_stack->last = newix;
-}
-
-/* Delete the RTL for all ixpansions for iterator IDECL
- in our sublevels. We do this when we make a larger
- containing expansion for IDECL. */
-
-static void
-delete_ixpansion (idecl)
- tree idecl;
-{
- struct ixpansion *previx = 0, *ix;
-
- for (ix = sublevel_ixpansions.first; ix; ix = ix->next)
- if (ix->ixdecl == idecl)
- {
- /** zero means that this is a mark for FOR -- **/
- /** we do not delete anything, just issue an error. **/
-
- if (ix->ixprologue_start == 0)
- error_with_decl (idecl,
- "`for (%s)' appears within implicit iteration");
- else
- {
- rtx insn;
- /* We delete all insns, including notes because leaving loop */
- /* notes and barriers produced by iterator expansion would */
- /* be misleading to other phases */
-
- for (insn = NEXT_INSN (ix->ixprologue_start);
- insn != ix->ixprologue_end;
- insn = NEXT_INSN (insn))
- delete_insn (insn);
- for (insn = NEXT_INSN (ix->ixepilogue_start);
- insn != ix->ixepilogue_end;
- insn = NEXT_INSN (insn))
- delete_insn (insn);
- }
-
- /* Delete this ixpansion from sublevel_ixpansions. */
- if (previx)
- previx->next = ix->next;
- else
- sublevel_ixpansions.first = ix->next;
- if (sublevel_ixpansions.last == ix)
- sublevel_ixpansions.last = previx;
- }
- else
- previx = ix;
-}
-
-#ifdef DEBUG_ITERATORS
-
-/* The functions below are for use from source level debugger.
- They print short forms of iterator lists and the iterator stack. */
-
-/* Print the name of the iterator D. */
-
-void
-prdecl (d)
- tree d;
-{
- if (d)
- {
- if (TREE_CODE (d) == VAR_DECL)
- {
- tree tname = DECL_NAME (d);
- char *dname = IDENTIFIER_POINTER (tname);
- fprintf (stderr, dname);
- }
- else
- fprintf (stderr, "<<?>>");
- }
- else
- fprintf (stderr, "<<0>>");
-}
-
-/* Print Iterator List -- names only */
-
-tree
-pil (head)
- tree head;
-{
- tree current, next;
- for (current = head; current; current = next)
- {
- tree node = TREE_VALUE (current);
- prdecl (node);
- next = TREE_CHAIN (current);
- if (next) fprintf (stderr, ",");
- }
- fprintf (stderr, "\n");
-}
-
-/* Print IXpansion List */
-
-struct ixpansion *
-pixl (head)
- struct ixpansion *head;
-{
- struct ixpansion *current, *next;
- fprintf (stderr, "> ");
- if (head == 0)
- fprintf (stderr, "(empty)");
-
- for (current=head; current; current = next)
- {
- tree node = current->ixdecl;
- prdecl (node);
- next = current->next;
- if (next)
- fprintf (stderr, ",");
- }
- fprintf (stderr, "\n");
- return head;
-}
-
-/* Print Iterator Stack. */
-
-void
-pis ()
-{
- struct iter_stack_node *stack_node;
-
- fprintf (stderr, "--SubLevel: ");
- pixl (sublevel_ixpansions.first);
- fprintf (stderr, "--Stack:--\n");
- for (stack_node = iter_stack;
- stack_node;
- stack_node = stack_node->next)
- pixl (stack_node->first);
-}
-
-#endif /* DEBUG_ITERATORS */
diff --git a/contrib/gcc/c-parse.gperf b/contrib/gcc/c-parse.gperf
deleted file mode 100644
index 888eee9ebe1f..000000000000
--- a/contrib/gcc/c-parse.gperf
+++ /dev/null
@@ -1,88 +0,0 @@
-%{
-/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
-%}
-struct resword { const char *name; short token; enum rid rid; };
-%%
-@class, CLASS, NORID
-@compatibility_alias, ALIAS, NORID
-@defs, DEFS, NORID
-@encode, ENCODE, NORID
-@end, END, NORID
-@implementation, IMPLEMENTATION, NORID
-@interface, INTERFACE, NORID
-@private, PRIVATE, NORID
-@protected, PROTECTED, NORID
-@protocol, PROTOCOL, NORID
-@public, PUBLIC, NORID
-@selector, SELECTOR, NORID
-__alignof, ALIGNOF, NORID
-__alignof__, ALIGNOF, NORID
-__asm, ASM_KEYWORD, NORID
-__asm__, ASM_KEYWORD, NORID
-__attribute, ATTRIBUTE, NORID
-__attribute__, ATTRIBUTE, NORID
-__complex, TYPESPEC, RID_COMPLEX
-__complex__, TYPESPEC, RID_COMPLEX
-__const, TYPE_QUAL, RID_CONST
-__const__, TYPE_QUAL, RID_CONST
-__extension__, EXTENSION, NORID
-__imag, IMAGPART, NORID
-__imag__, IMAGPART, NORID
-__inline, SCSPEC, RID_INLINE
-__inline__, SCSPEC, RID_INLINE
-__iterator, SCSPEC, RID_ITERATOR
-__iterator__, SCSPEC, RID_ITERATOR
-__label__, LABEL, NORID
-__real, REALPART, NORID
-__real__, REALPART, NORID
-__restrict, TYPE_QUAL, RID_RESTRICT
-__restrict__, TYPE_QUAL, RID_RESTRICT
-__signed, TYPESPEC, RID_SIGNED
-__signed__, TYPESPEC, RID_SIGNED
-__typeof, TYPEOF, NORID
-__typeof__, TYPEOF, NORID
-__volatile, TYPE_QUAL, RID_VOLATILE
-__volatile__, TYPE_QUAL, RID_VOLATILE
-asm, ASM_KEYWORD, NORID
-auto, SCSPEC, RID_AUTO
-break, BREAK, NORID
-bycopy, TYPE_QUAL, RID_BYCOPY
-byref, TYPE_QUAL, RID_BYREF
-case, CASE, NORID
-char, TYPESPEC, RID_CHAR
-const, TYPE_QUAL, RID_CONST
-continue, CONTINUE, NORID
-default, DEFAULT, NORID
-do, DO, NORID
-double, TYPESPEC, RID_DOUBLE
-else, ELSE, NORID
-enum, ENUM, NORID
-extern, SCSPEC, RID_EXTERN
-float, TYPESPEC, RID_FLOAT
-for, FOR, NORID
-goto, GOTO, NORID
-id, OBJECTNAME, RID_ID
-if, IF, NORID
-in, TYPE_QUAL, RID_IN
-inout, TYPE_QUAL, RID_INOUT
-inline, SCSPEC, RID_INLINE
-int, TYPESPEC, RID_INT
-long, TYPESPEC, RID_LONG
-oneway, TYPE_QUAL, RID_ONEWAY
-out, TYPE_QUAL, RID_OUT
-register, SCSPEC, RID_REGISTER
-restrict, TYPE_QUAL, RID_RESTRICT
-return, RETURN, NORID
-short, TYPESPEC, RID_SHORT
-signed, TYPESPEC, RID_SIGNED
-sizeof, SIZEOF, NORID
-static, SCSPEC, RID_STATIC
-struct, STRUCT, NORID
-switch, SWITCH, NORID
-typedef, SCSPEC, RID_TYPEDEF
-typeof, TYPEOF, NORID
-union, UNION, NORID
-unsigned, TYPESPEC, RID_UNSIGNED
-void, TYPESPEC, RID_VOID
-volatile, TYPE_QUAL, RID_VOLATILE
-while, WHILE, NORID
diff --git a/contrib/gcc/cccp.c b/contrib/gcc/cccp.c
deleted file mode 100644
index 023502fbde41..000000000000
--- a/contrib/gcc/cccp.c
+++ /dev/null
@@ -1,11136 +0,0 @@
-/* C Compatible Compiler Preprocessor (CCCP)
- Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
- Written by Paul Rubin, June 1986
- Adapted to ANSI C, Richard Stallman, Jan 1987
-
-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, 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#include "config.h"
-
-#include "system.h"
-#include <signal.h>
-
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-
-typedef unsigned char U_CHAR;
-
-#include "pcp.h"
-#include "intl.h"
-#include "prefix.h"
-
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif /* MULTIBYTE_CHARS */
-
-#ifndef GET_ENV_PATH_LIST
-#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
-#endif
-
-#ifndef STANDARD_INCLUDE_DIR
-# define STANDARD_INCLUDE_DIR "/usr/include"
-#endif
-
-/* By default, colon separates directories in a path. */
-#ifndef PATH_SEPARATOR
-# define PATH_SEPARATOR ':'
-#endif
-
-/* By default, a slash separates directory names. */
-#ifndef DIR_SEPARATOR
-# define DIR_SEPARATOR '/'
-#endif
-
-/* By default, the suffix for object files is ".o". */
-#ifdef OBJECT_SUFFIX
-# define HAVE_OBJECT_SUFFIX
-#else
-# define OBJECT_SUFFIX ".o"
-#endif
-
-/* VMS-specific definitions */
-#ifdef VMS
-#include <descrip.h>
-#include <ssdef.h>
-#include <syidef.h>
-#define open(fname,mode,prot) VMS_open (fname,mode,prot)
-#define fopen(fname,mode) VMS_fopen (fname,mode)
-#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
-#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
-static int VMS_fstat (), VMS_stat ();
-static int VMS_open ();
-static FILE *VMS_fopen ();
-static FILE *VMS_freopen ();
-static int hack_vms_include_specification ();
-#define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
-#define INO_T_HASH(a) 0
-#define INCLUDE_LEN_FUDGE 12 /* leave room for VMS syntax conversion */
-#endif /* VMS */
-
-/* Windows does not natively support inodes, and neither does MSDOS. */
-#if (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN)) \
- || defined (__MSDOS__)
-#define INO_T_EQ(a, b) 0
-#endif
-
-#ifndef INO_T_EQ
-#define INO_T_EQ(a, b) ((a) == (b))
-#endif
-
-#ifndef INO_T_HASH
-#define INO_T_HASH(a) (a)
-#endif
-
-#ifndef INCLUDE_LEN_FUDGE
-#define INCLUDE_LEN_FUDGE 0
-#endif
-
-/* External declarations. */
-
-extern char *version_string;
-HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
-HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
-
-/* Name under which this program was invoked. */
-
-static char *progname;
-
-/* Nonzero means use extra default include directories for C++. */
-
-static int cplusplus;
-
-/* Nonzero means handle cplusplus style comments */
-
-static int cplusplus_comments;
-
-/* Nonzero means handle #import, for objective C. */
-
-static int objc;
-
-/* Nonzero means this is an assembly file, and allow
- unknown directives, which could be comments. */
-
-static int lang_asm;
-
-/* Current maximum length of directory names in the search path
- for include files. (Altered as we get more of them.) */
-
-static int max_include_len;
-
-/* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */
-
-static int for_lint = 0;
-
-/* Nonzero means copy comments into the output file. */
-
-static int put_out_comments = 0;
-
-/* Nonzero means don't process the ANSI trigraph sequences. */
-
-static int no_trigraphs = 0;
-
-/* Nonzero means print the names of included files rather than
- the preprocessed output. 1 means just the #include "...",
- 2 means #include <...> as well. */
-
-static int print_deps = 0;
-
-/* Nonzero if missing .h files in -M output are assumed to be generated
- files and not errors. */
-
-static int print_deps_missing_files = 0;
-
-/* Nonzero means print names of header files (-H). */
-
-static int print_include_names = 0;
-
-/* Nonzero means don't output line number information. */
-
-static int no_line_directives;
-
-/* Nonzero means output the text in failing conditionals,
- inside #failed ... #endfailed. */
-
-static int output_conditionals;
-
-/* dump_only means inhibit output of the preprocessed text
- and instead output the definitions of all user-defined
- macros in a form suitable for use as input to cccp.
- dump_names means pass #define and the macro name through to output.
- dump_definitions means pass the whole definition (plus #define) through
-*/
-
-static enum {dump_none, dump_only, dump_names, dump_definitions}
- dump_macros = dump_none;
-
-/* Nonzero means pass all #define and #undef directives which we actually
- process through to the output stream. This feature is used primarily
- to allow cc1 to record the #defines and #undefs for the sake of
- debuggers which understand about preprocessor macros, but it may
- also be useful with -E to figure out how symbols are defined, and
- where they are defined. */
-static int debug_output = 0;
-
-/* Nonzero means pass #include lines through to the output,
- even if they are ifdefed out. */
-static int dump_includes;
-
-/* Nonzero indicates special processing used by the pcp program. The
- special effects of this mode are:
-
- Inhibit all macro expansion, except those inside #if directives.
-
- Process #define directives normally, and output their contents
- to the output file.
-
- Output preconditions to pcp_outfile indicating all the relevant
- preconditions for use of this file in a later cpp run.
-*/
-static FILE *pcp_outfile;
-
-/* Nonzero means we are inside an IF during a -pcp run. In this mode
- macro expansion is done, and preconditions are output for all macro
- uses requiring them. */
-static int pcp_inside_if;
-
-/* Nonzero means never to include precompiled files.
- This is 1 since there's no way now to make precompiled files,
- so it's not worth testing for them. */
-static int no_precomp = 1;
-
-/* Nonzero means give all the error messages the ANSI standard requires. */
-
-int pedantic;
-
-/* Nonzero means try to make failure to fit ANSI C an error. */
-
-static int pedantic_errors;
-
-/* Nonzero means don't print warning messages. -w. */
-
-static int inhibit_warnings = 0;
-
-/* Nonzero means warn if slash-star appears in a slash-star comment,
- or if newline-backslash appears in a slash-slash comment. */
-
-static int warn_comments;
-
-/* Nonzero means warn if a macro argument is (or would be)
- stringified with -traditional. */
-
-static int warn_stringify;
-
-/* Nonzero means warn if there are any trigraphs. */
-
-static int warn_trigraphs;
-
-/* Nonzero means warn if undefined identifiers are evaluated in an #if. */
-
-static int warn_undef;
-
-/* Nonzero means warn if #import is used. */
-
-static int warn_import = 1;
-
-/* Nonzero means turn warnings into errors. */
-
-static int warnings_are_errors;
-
-/* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */
-
-int traditional;
-
-/* Nonzero for the 1989 C Standard, including corrigenda and amendments. */
-
-int c89;
-
-/* Nonzero for the 199x C Standard. */
-
-int c9x;
-
-/* Nonzero causes output not to be done,
- but directives such as #define that have side effects
- are still obeyed. */
-
-static int no_output;
-
-/* Nonzero means we should look for header.gcc files that remap file names. */
-static int remap;
-
-/* Nonzero means this file was included with a -imacros or -include
- command line and should not be recorded as an include file. */
-
-static int no_record_file;
-
-/* Nonzero means that we have finished processing the command line options.
- This flag is used to decide whether or not to issue certain errors
- and/or warnings. */
-
-static int done_initializing = 0;
-
-/* Line where a newline was first seen in a string constant. */
-
-static int multiline_string_line = 0;
-
-/* I/O buffer structure.
- The `fname' field is nonzero for source files and #include files
- and for the dummy text used for -D and -U.
- It is zero for rescanning results of macro expansion
- and for expanding macro arguments. */
-#define INPUT_STACK_MAX 400
-static struct file_buf {
- char *fname;
- /* Filename specified with #line directive. */
- char *nominal_fname;
- /* The length of nominal_fname, which may contain embedded NULs. */
- size_t nominal_fname_len;
- /* Include file description. */
- struct include_file *inc;
- /* Record where in the search path this file was found.
- For #include_next. */
- struct file_name_list *dir;
- int lineno;
- int length;
- U_CHAR *buf;
- U_CHAR *bufp;
- /* Macro that this level is the expansion of.
- Included so that we can reenable the macro
- at the end of this level. */
- struct hashnode *macro;
- /* Value of if_stack at start of this file.
- Used to prohibit unmatched #endif (etc) in an include file. */
- struct if_stack *if_stack;
- /* Object to be freed at end of input at this level. */
- U_CHAR *free_ptr;
- /* True if this is a system header file; see is_system_include. */
- char system_header_p;
-} instack[INPUT_STACK_MAX];
-
-static int last_error_tick; /* Incremented each time we print it. */
-static int input_file_stack_tick; /* Incremented when the status changes. */
-
-/* Current nesting level of input sources.
- `instack[indepth]' is the level currently being read. */
-static int indepth = -1;
-#define CHECK_DEPTH(code) \
- if (indepth >= (INPUT_STACK_MAX - 1)) \
- { \
- error_with_line (line_for_error (instack[indepth].lineno), \
- "macro or `#include' recursion too deep"); \
- code; \
- }
-
-/* Current depth in #include directives that use <...>. */
-static int system_include_depth = 0;
-
-typedef struct file_buf FILE_BUF;
-
-/* The output buffer. Its LENGTH field is the amount of room allocated
- for the buffer, not the number of chars actually present. To get
- that, subtract outbuf.buf from outbuf.bufp. */
-
-#define OUTBUF_SIZE 10 /* initial size of output buffer */
-static FILE_BUF outbuf;
-
-/* Grow output buffer OBUF points at
- so it can hold at least NEEDED more chars. */
-
-#define check_expand(OBUF, NEEDED) \
- (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED)) \
- ? grow_outbuf ((OBUF), (NEEDED)) : 0)
-
-struct file_name_list
- {
- struct file_name_list *next;
- /* If the following is 1, it is a C-language system include
- directory. */
- int c_system_include_path;
- /* Mapping of file names for this directory. */
- struct file_name_map *name_map;
- /* Non-zero if name_map is valid. */
- int got_name_map;
- /* The include directory status. */
- struct stat st;
- /* The include prefix: "" denotes the working directory,
- otherwise fname must end in '/'.
- The actual size is dynamically allocated. */
- char fname[1];
- };
-
-/* #include "file" looks in source file dir, then stack. */
-/* #include <file> just looks in the stack. */
-/* -I directories are added to the end, then the defaults are added. */
-/* The */
-static struct default_include {
- char *fname; /* The name of the directory. */
- char *component; /* The component containing the directory */
- int cplusplus; /* Only look here if we're compiling C++. */
- int cxx_aware; /* Includes in this directory don't need to
- be wrapped in extern "C" when compiling
- C++. */
- int included; /* Set if the directory is acceptable. */
-} include_defaults_array[]
-#ifdef INCLUDE_DEFAULTS
- = INCLUDE_DEFAULTS;
-#else
- = {
- /* Pick up GNU C++ specific include files. */
- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 },
-#ifdef CROSS_COMPILE
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
- /* For cross-compilation, this dir name is generated
- automatically in Makefile.in. */
- { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 },
-#ifdef TOOL_INCLUDE_DIR
- /* This is another place that the target system's headers might be. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
-#endif
-#else /* not CROSS_COMPILE */
-#ifdef LOCAL_INCLUDE_DIR
- /* This should be /usr/local/include and should come before
- the fixincludes-fixed header files. */
- { LOCAL_INCLUDE_DIR, 0, 0, 1, 0 },
-#endif
-#ifdef TOOL_INCLUDE_DIR
- /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
- Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
-#endif
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
- /* Some systems have an extra dir of include files. */
-#ifdef SYSTEM_INCLUDE_DIR
- { SYSTEM_INCLUDE_DIR, 0, 0, 0, 0 },
-#endif
-#ifndef STANDARD_INCLUDE_COMPONENT
-#define STANDARD_INCLUDE_COMPONENT 0
-#endif
- { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 0 },
-#endif /* not CROSS_COMPILE */
- { 0, 0, 0, 0, 0 }
- };
-#endif /* no INCLUDE_DEFAULTS */
-
-/* The code looks at the defaults through this pointer, rather than through
- the constant structure above. This pointer gets changed if an environment
- variable specifies other defaults. */
-static struct default_include *include_defaults = include_defaults_array;
-
-static struct file_name_list *include = 0; /* First dir to search */
- /* First dir to search for <file> */
-/* This is the first element to use for #include <...>.
- If it is 0, use the entire chain for such includes. */
-static struct file_name_list *first_bracket_include = 0;
-/* This is the first element in the chain that corresponds to
- a directory of system header files. */
-static struct file_name_list *first_system_include = 0;
-static struct file_name_list *last_include = 0; /* Last in chain */
-
-/* Chain of include directories to put at the end of the other chain. */
-static struct file_name_list *after_include = 0;
-static struct file_name_list *last_after_include = 0; /* Last in chain */
-
-/* Chain to put at the start of the system include files. */
-static struct file_name_list *before_system = 0;
-static struct file_name_list *last_before_system = 0; /* Last in chain */
-
-/* Directory prefix that should replace `/usr' in the standard
- include file directories. */
-static char *include_prefix;
-
-/* Maintain and search list of included files. */
-
-struct include_file {
- struct include_file *next; /* for include_hashtab */
- struct include_file *next_ino; /* for include_ino_hashtab */
- char *fname;
- /* If the following is the empty string, it means #pragma once
- was seen in this include file, or #import was applied to the file.
- Otherwise, if it is nonzero, it is a macro name.
- Don't include the file again if that macro is defined. */
- U_CHAR *control_macro;
- /* Nonzero if the dependency on this include file has been output. */
- int deps_output;
- struct stat st;
-};
-
-/* Hash tables of files already included with #include or #import.
- include_hashtab is by full name; include_ino_hashtab is by inode number. */
-
-#define INCLUDE_HASHSIZE 61
-static struct include_file *include_hashtab[INCLUDE_HASHSIZE];
-static struct include_file *include_ino_hashtab[INCLUDE_HASHSIZE];
-
-/* Global list of strings read in from precompiled files. This list
- is kept in the order the strings are read in, with new strings being
- added at the end through stringlist_tailp. We use this list to output
- the strings at the end of the run.
-*/
-static STRINGDEF *stringlist;
-static STRINGDEF **stringlist_tailp = &stringlist;
-
-
-/* Structure returned by create_definition */
-typedef struct macrodef MACRODEF;
-struct macrodef
-{
- struct definition *defn;
- U_CHAR *symnam;
- int symlen;
-};
-
-enum sharp_token_type {
- NO_SHARP_TOKEN = 0, /* token not present */
-
- SHARP_TOKEN = '#', /* token spelled with # only */
- WHITE_SHARP_TOKEN, /* token spelled with # and white space */
-
- PERCENT_COLON_TOKEN = '%', /* token spelled with %: only */
- WHITE_PERCENT_COLON_TOKEN /* token spelled with %: and white space */
-};
-
-/* Structure allocated for every #define. For a simple replacement
- such as
- #define foo bar ,
- nargs = -1, the `pattern' list is null, and the expansion is just
- the replacement text. Nargs = 0 means a functionlike macro with no args,
- e.g.,
- #define getchar() getc (stdin) .
- When there are args, the expansion is the replacement text with the
- args squashed out, and the reflist is a list describing how to
- build the output from the input: e.g., "3 chars, then the 1st arg,
- then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
- The chars here come from the expansion. Whatever is left of the
- expansion after the last arg-occurrence is copied after that arg.
- Note that the reflist can be arbitrarily long---
- its length depends on the number of times the arguments appear in
- the replacement text, not how many args there are. Example:
- #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
- pattern list
- { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
- where (x, y) means (nchars, argno). */
-
-typedef struct definition DEFINITION;
-struct definition {
- int nargs;
- int length; /* length of expansion string */
- int predefined; /* True if the macro was builtin or */
- /* came from the command line */
- U_CHAR *expansion;
- int line; /* Line number of definition */
- char *file; /* File of definition */
- size_t file_len; /* Length of file (which can contain NULs) */
- char rest_args; /* Nonzero if last arg. absorbs the rest */
- struct reflist {
- struct reflist *next;
-
- enum sharp_token_type stringify; /* set if a # operator before arg */
- enum sharp_token_type raw_before; /* set if a ## operator before arg */
- enum sharp_token_type raw_after; /* set if a ## operator after arg */
-
- char rest_args; /* Nonzero if this arg. absorbs the rest */
- int nchars; /* Number of literal chars to copy before
- this arg occurrence. */
- int argno; /* Number of arg to substitute (origin-0) */
- } *pattern;
- union {
- /* Names of macro args, concatenated in reverse order
- with comma-space between them.
- The only use of this is that we warn on redefinition
- if this differs between the old and new definitions. */
- U_CHAR *argnames;
- } args;
-};
-
-/* different kinds of things that can appear in the value field
- of a hash node. Actually, this may be useless now. */
-union hashval {
- char *cpval;
- DEFINITION *defn;
- KEYDEF *keydef;
-};
-
-/*
- * special extension string that can be added to the last macro argument to
- * allow it to absorb the "rest" of the arguments when expanded. Ex:
- * #define wow(a, b...) process (b, a, b)
- * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); }
- * { wow (one, two); } -> { process (two, one, two); }
- * if this "rest_arg" is used with the concat token '##' and if it is not
- * supplied then the token attached to with ## will not be outputted. Ex:
- * #define wow (a, b...) process (b ## , a, ## b)
- * { wow (1, 2); } -> { process (2, 1, 2); }
- * { wow (one); } -> { process (one); {
- */
-static char rest_extension[] = "...";
-#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
-
-/* This is the implicit parameter name when using variable number of
- parameters for macros using the ISO C 9x extension. */
-static char va_args_name[] = "__VA_ARGS__";
-#define VA_ARGS_NAME_LENGTH (sizeof (va_args_name) - 1)
-
-/* The structure of a node in the hash table. The hash table
- has entries for all tokens defined by #define directives (type T_MACRO),
- plus some special tokens like __LINE__ (these each have their own
- type, and the appropriate code is run when that type of node is seen.
- It does not contain control words like "#define", which are recognized
- by a separate piece of code. */
-
-/* different flavors of hash nodes --- also used in keyword table */
-enum node_type {
- T_DEFINE = 1, /* the `#define' keyword */
- T_INCLUDE, /* the `#include' keyword */
- T_INCLUDE_NEXT, /* the `#include_next' keyword */
- T_IMPORT, /* the `#import' keyword */
- T_IFDEF, /* the `#ifdef' keyword */
- T_IFNDEF, /* the `#ifndef' keyword */
- T_IF, /* the `#if' keyword */
- T_ELSE, /* `#else' */
- T_PRAGMA, /* `#pragma' */
- T_ELIF, /* `#elif' */
- T_UNDEF, /* `#undef' */
- T_LINE, /* `#line' */
- T_ERROR, /* `#error' */
- T_WARNING, /* `#warning' */
- T_ENDIF, /* `#endif' */
- T_SCCS, /* `#sccs', used on system V. */
- T_IDENT, /* `#ident', used on system V. */
- T_ASSERT, /* `#assert', taken from system V. */
- T_UNASSERT, /* `#unassert', taken from system V. */
- T_SPECLINE, /* special symbol `__LINE__' */
- T_DATE, /* `__DATE__' */
- T_FILE, /* `__FILE__' */
- T_BASE_FILE, /* `__BASE_FILE__' */
- T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
- T_VERSION, /* `__VERSION__' */
- T_SIZE_TYPE, /* `__SIZE_TYPE__' */
- T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */
- T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */
- T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */
- T_REGISTER_PREFIX_TYPE, /* `__REGISTER_PREFIX__' */
- T_IMMEDIATE_PREFIX_TYPE, /* `__IMMEDIATE_PREFIX__' */
- T_TIME, /* `__TIME__' */
- T_CONST, /* Constant value, used by `__STDC__' */
- T_MACRO, /* macro defined by `#define' */
- T_DISABLED, /* macro temporarily turned off for rescan */
- T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
- T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
- T_UNUSED /* Used for something not defined. */
- };
-
-struct hashnode {
- struct hashnode *next; /* double links for easy deletion */
- struct hashnode *prev;
- struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash
- chain is kept, in case the node is the head
- of the chain and gets deleted. */
- enum node_type type; /* type of special token */
- int length; /* length of token, for quick comparison */
- U_CHAR *name; /* the actual name */
- union hashval value; /* pointer to expansion, or whatever */
-};
-
-typedef struct hashnode HASHNODE;
-
-/* Some definitions for the hash table. The hash function MUST be
- computed as shown in hashf () below. That is because the rescan
- loop computes the hash value `on the fly' for most tokens,
- in order to avoid the overhead of a lot of procedure calls to
- the hashf () function. Hashf () only exists for the sake of
- politeness, for use when speed isn't so important. */
-
-#define HASHSIZE 1403
-static HASHNODE *hashtab[HASHSIZE];
-#define HASHSTEP(old, c) ((old << 2) + c)
-#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
-
-
-/* We let tm.h override the types used here, to handle trivial differences
- such as the choice of unsigned int or long unsigned int for size_t.
- When machines start needing nontrivial differences in the size type,
- it would be best to do something here to figure out automatically
- from other information what type to use. */
-
-/* The string value for __SIZE_TYPE__. */
-
-#ifndef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
-#endif
-
-/* The string value for __PTRDIFF_TYPE__. */
-
-#ifndef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-#endif
-
-/* The string value for __WCHAR_TYPE__. */
-
-#ifndef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-#endif
-char * wchar_type = WCHAR_TYPE;
-#undef WCHAR_TYPE
-
-/* The string value for __USER_LABEL_PREFIX__ */
-
-#ifndef USER_LABEL_PREFIX
-#define USER_LABEL_PREFIX ""
-#endif
-char * user_label_prefix = USER_LABEL_PREFIX;
-#undef USER_LABEL_PREFIX
-
-/* The string value for __REGISTER_PREFIX__ */
-
-#ifndef REGISTER_PREFIX
-#define REGISTER_PREFIX ""
-#endif
-
-/* The string value for __IMMEDIATE_PREFIX__ */
-
-#ifndef IMMEDIATE_PREFIX
-#define IMMEDIATE_PREFIX ""
-#endif
-
-/* In the definition of a #assert name, this structure forms
- a list of the individual values asserted.
- Each value is itself a list of "tokens".
- These are strings that are compared by name. */
-
-struct tokenlist_list {
- struct tokenlist_list *next;
- struct arglist *tokens;
-};
-
-struct assertion_hashnode {
- struct assertion_hashnode *next; /* double links for easy deletion */
- struct assertion_hashnode *prev;
- /* also, a back pointer to this node's hash
- chain is kept, in case the node is the head
- of the chain and gets deleted. */
- struct assertion_hashnode **bucket_hdr;
- int length; /* length of token, for quick comparison */
- U_CHAR *name; /* the actual name */
- /* List of token-sequences. */
- struct tokenlist_list *value;
-};
-
-typedef struct assertion_hashnode ASSERTION_HASHNODE;
-
-/* Some definitions for the hash table. The hash function MUST be
- computed as shown in hashf below. That is because the rescan
- loop computes the hash value `on the fly' for most tokens,
- in order to avoid the overhead of a lot of procedure calls to
- the hashf function. hashf only exists for the sake of
- politeness, for use when speed isn't so important. */
-
-#define ASSERTION_HASHSIZE 37
-static ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE];
-
-/* Nonzero means inhibit macroexpansion of what seem to be
- assertion tests, in rescan. For #if. */
-static int assertions_flag;
-
-/* `struct directive' defines one #-directive, including how to handle it. */
-
-#define DO_PROTO PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *))
-
-struct directive {
- int length; /* Length of name */
- int (*func) DO_PROTO; /* Function to handle directive */
- char *name; /* Name of directive */
- enum node_type type; /* Code which describes which directive. */
-};
-
-#define IS_INCLUDE_DIRECTIVE_TYPE(t) \
-((int) T_INCLUDE <= (int) (t) && (int) (t) <= (int) T_IMPORT)
-
-/* These functions are declared to return int instead of void since they
- are going to be placed in the table and some old compilers have trouble with
- pointers to functions returning void. */
-
-static int do_assert DO_PROTO;
-static int do_define DO_PROTO;
-static int do_elif DO_PROTO;
-static int do_else DO_PROTO;
-static int do_endif DO_PROTO;
-static int do_error DO_PROTO;
-static int do_ident DO_PROTO;
-static int do_if DO_PROTO;
-static int do_include DO_PROTO;
-static int do_line DO_PROTO;
-static int do_pragma DO_PROTO;
-#ifdef SCCS_DIRECTIVE
-static int do_sccs DO_PROTO;
-#endif
-static int do_unassert DO_PROTO;
-static int do_undef DO_PROTO;
-static int do_warning DO_PROTO;
-static int do_xifdef DO_PROTO;
-
-/* Here is the actual list of #-directives, most-often-used first. */
-
-static struct directive directive_table[] = {
- { 6, do_define, "define", T_DEFINE},
- { 2, do_if, "if", T_IF},
- { 5, do_xifdef, "ifdef", T_IFDEF},
- { 6, do_xifdef, "ifndef", T_IFNDEF},
- { 5, do_endif, "endif", T_ENDIF},
- { 4, do_else, "else", T_ELSE},
- { 4, do_elif, "elif", T_ELIF},
- { 4, do_line, "line", T_LINE},
- { 7, do_include, "include", T_INCLUDE},
- { 12, do_include, "include_next", T_INCLUDE_NEXT},
- { 6, do_include, "import", T_IMPORT},
- { 5, do_undef, "undef", T_UNDEF},
- { 5, do_error, "error", T_ERROR},
- { 7, do_warning, "warning", T_WARNING},
-#ifdef SCCS_DIRECTIVE
- { 4, do_sccs, "sccs", T_SCCS},
-#endif
- { 6, do_pragma, "pragma", T_PRAGMA},
- { 5, do_ident, "ident", T_IDENT},
- { 6, do_assert, "assert", T_ASSERT},
- { 8, do_unassert, "unassert", T_UNASSERT},
- { -1, 0, "", T_UNUSED},
-};
-
-/* When a directive handler is called,
- this points to the # (or the : of the %:) that started the directive. */
-U_CHAR *directive_start;
-
-/* table to tell if char can be part of a C identifier. */
-U_CHAR is_idchar[256];
-/* table to tell if char can be first char of a c identifier. */
-U_CHAR is_idstart[256];
-/* table to tell if c is horizontal space. */
-static U_CHAR is_hor_space[256];
-/* table to tell if c is horizontal or vertical space. */
-U_CHAR is_space[256];
-
-#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
-#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
-
-static int errors = 0; /* Error counter for exit code */
-
-/* Name of output file, for error messages. */
-static char *out_fname;
-
-/* Nonzero to ignore \ in string constants. Use to treat #line 1 "A:\file.h
- as a non-form feed. If you want it to be a form feed, you must use
- # 1 "\f". */
-static int ignore_escape_flag = 1;
-
-/* Stack of conditionals currently in progress
- (including both successful and failing conditionals). */
-
-struct if_stack {
- struct if_stack *next; /* for chaining to the next stack frame */
- char *fname; /* copied from input when frame is made */
- size_t fname_len; /* similarly */
- int lineno; /* similarly */
- int if_succeeded; /* true if a leg of this if-group
- has been passed through rescan */
- U_CHAR *control_macro; /* For #ifndef at start of file,
- this is the macro name tested. */
- enum node_type type; /* type of last directive seen in this group */
-};
-typedef struct if_stack IF_STACK_FRAME;
-static IF_STACK_FRAME *if_stack = NULL;
-
-/* Buffer of -M output. */
-static char *deps_buffer;
-
-/* Number of bytes allocated in above. */
-static int deps_allocated_size;
-
-/* Number of bytes used. */
-static int deps_size;
-
-/* Number of bytes since the last newline. */
-static int deps_column;
-
-/* Nonzero means -I- has been seen,
- so don't look for #include "foo" the source-file directory. */
-static int ignore_srcdir;
-
-static int safe_read PROTO((int, char *, int));
-static void safe_write PROTO((int, char *, int));
-static void eprint_string PROTO((const char *, size_t));
-
-int main PROTO((int, char **));
-
-static void path_include PROTO((char *));
-
-static U_CHAR *index0 PROTO((U_CHAR *, int, size_t));
-
-static void trigraph_pcp PROTO((FILE_BUF *));
-
-static void newline_fix PROTO((U_CHAR *));
-static void name_newline_fix PROTO((U_CHAR *));
-
-static char *get_lintcmd PROTO((U_CHAR *, U_CHAR *, U_CHAR **, int *, int *));
-
-static void rescan PROTO((FILE_BUF *, int));
-
-static FILE_BUF expand_to_temp_buffer PROTO((U_CHAR *, U_CHAR *, int, int));
-
-static int handle_directive PROTO((FILE_BUF *, FILE_BUF *));
-
-static struct tm *timestamp PROTO((void));
-static void special_symbol PROTO((HASHNODE *, FILE_BUF *));
-
-static int is_system_include PROTO((char *));
-static char *base_name PROTO((char *));
-static int absolute_filename PROTO((char *));
-static size_t simplify_filename PROTO((char *));
-
-static char *read_filename_string PROTO((int, FILE *));
-static struct file_name_map *read_name_map PROTO((char *));
-static int open_include_file PROTO((char *, struct file_name_list *, U_CHAR *, struct include_file **));
-static char *remap_include_file PROTO((char *, struct file_name_list *));
-static int lookup_ino_include PROTO((struct include_file *));
-
-static void finclude PROTO((int, struct include_file *, FILE_BUF *, int, struct file_name_list *));
-static void record_control_macro PROTO((struct include_file *, U_CHAR *));
-
-static char *check_precompiled PROTO((int, struct stat *, char *, char **));
-static int check_preconditions PROTO((char *));
-static void pcfinclude PROTO((U_CHAR *, U_CHAR *, FILE_BUF *));
-static void pcstring_used PROTO((HASHNODE *));
-static void write_output PROTO((void));
-static void pass_thru_directive PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *));
-
-static MACRODEF create_definition PROTO((U_CHAR *, U_CHAR *, FILE_BUF *));
-
-static int check_macro_name PROTO((U_CHAR *, int));
-static int compare_defs PROTO((DEFINITION *, DEFINITION *));
-static int comp_def_part PROTO((int, U_CHAR *, int, U_CHAR *, int, int));
-
-static DEFINITION *collect_expansion PROTO((U_CHAR *, U_CHAR *, int, struct arglist *));
-
-int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
-static int compare_token_lists PROTO((struct arglist *, struct arglist *));
-
-static struct arglist *read_token_list PROTO((U_CHAR **, U_CHAR *, int *));
-static void free_token_list PROTO((struct arglist *));
-
-static ASSERTION_HASHNODE *assertion_install PROTO((U_CHAR *, int, int));
-static ASSERTION_HASHNODE *assertion_lookup PROTO((U_CHAR *, int, int));
-static void delete_assertion PROTO((ASSERTION_HASHNODE *));
-
-static void do_once PROTO((void));
-
-static HOST_WIDEST_INT eval_if_expression PROTO((U_CHAR *, int));
-static void conditional_skip PROTO((FILE_BUF *, int, enum node_type, U_CHAR *, FILE_BUF *));
-static void skip_if_group PROTO((FILE_BUF *, int, FILE_BUF *));
-static void validate_else PROTO((U_CHAR *, U_CHAR *));
-
-static U_CHAR *skip_to_end_of_comment PROTO((FILE_BUF *, int *, int));
-static U_CHAR *skip_quoted_string PROTO((U_CHAR *, U_CHAR *, int, int *, int *, int *));
-static char *quote_string PROTO((char *, char *, size_t));
-static U_CHAR *skip_paren_group PROTO((FILE_BUF *));
-
-/* Last arg to output_line_directive. */
-enum file_change_code {same_file, enter_file, leave_file};
-static void output_line_directive PROTO((FILE_BUF *, FILE_BUF *, int, enum file_change_code));
-
-static void macroexpand PROTO((HASHNODE *, FILE_BUF *));
-
-struct argdata;
-static int macarg PROTO((struct argdata *, int));
-
-static U_CHAR *macarg1 PROTO((U_CHAR *, U_CHAR *, struct hashnode *, int *, int *, int *, int));
-
-static int discard_comments PROTO((U_CHAR *, int, int));
-
-static int change_newlines PROTO((U_CHAR *, int));
-
-static char *my_strerror PROTO((int));
-static void notice PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
-static void vnotice PROTO((const char *, va_list));
-void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void verror PROTO((const char *, va_list));
-static void error_from_errno PROTO((char *));
-void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
-static void vwarning PROTO((const char *, va_list));
-static void error_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
-static void verror_with_line PROTO((int, const char *, va_list));
-static void vwarning_with_line PROTO((int, const char *, va_list));
-static void warning_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
-void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void pedwarn_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
-static void pedwarn_with_file_and_line PVPROTO((const char *, size_t, int, const char *, ...)) ATTRIBUTE_PRINTF_4;
-static void pedwarn_strange_white_space PROTO((int));
-
-static void print_containing_files PROTO((void));
-
-static int line_for_error PROTO((int));
-static int grow_outbuf PROTO((FILE_BUF *, int));
-
-static HASHNODE *install PROTO((U_CHAR *, int, enum node_type, char *, int));
-HASHNODE *lookup PROTO((U_CHAR *, int, int));
-static void delete_macro PROTO((HASHNODE *));
-static int hashf PROTO((U_CHAR *, int, int));
-
-static void dump_single_macro PROTO((HASHNODE *, FILE *));
-static void dump_all_macros PROTO((void));
-static void dump_defn_1 PROTO((U_CHAR *, int, int, FILE *));
-static void dump_arg_n PROTO((DEFINITION *, int, FILE *));
-
-static void initialize_char_syntax PROTO((void));
-static void initialize_builtins PROTO((FILE_BUF *, FILE_BUF *));
-
-static void make_definition PROTO((char *));
-static void make_undef PROTO((char *, FILE_BUF *));
-
-static void make_assertion PROTO((const char *, const char *));
-
-static struct file_name_list *new_include_prefix PROTO((struct file_name_list *, const char *, const char *, const char *));
-static void append_include_chain PROTO((struct file_name_list *, struct file_name_list *));
-
-static int quote_string_for_make PROTO((char *, const char *));
-static void deps_output PROTO((const char *, int));
-
-void fatal PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
-static void perror_with_name PROTO((char *));
-static void pfatal_with_name PROTO((char *)) ATTRIBUTE_NORETURN;
-static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
-
-static void memory_full PROTO((void)) ATTRIBUTE_NORETURN;
-static void print_help PROTO((void));
-
-/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
- retrying if necessary. If MAX_READ_LEN is defined, read at most
- that bytes at a time. Return a negative value if an error occurs,
- otherwise return the actual number of bytes read,
- which must be LEN unless end-of-file was reached. */
-
-static int
-safe_read (desc, ptr, len)
- int desc;
- char *ptr;
- int len;
-{
- int left, rcount, nchars;
-
- left = len;
- while (left > 0) {
- rcount = left;
-#ifdef MAX_READ_LEN
- if (rcount > MAX_READ_LEN)
- rcount = MAX_READ_LEN;
-#endif
- nchars = read (desc, ptr, rcount);
- if (nchars < 0)
- {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif
- return nchars;
- }
- if (nchars == 0)
- break;
- ptr += nchars;
- left -= nchars;
- }
- return len - left;
-}
-
-/* Write LEN bytes at PTR to descriptor DESC,
- retrying if necessary, and treating any real error as fatal.
- If MAX_WRITE_LEN is defined, write at most that many bytes at a time. */
-
-static void
-safe_write (desc, ptr, len)
- int desc;
- char *ptr;
- int len;
-{
- int wcount, written;
-
- while (len > 0) {
- wcount = len;
-#ifdef MAX_WRITE_LEN
- if (wcount > MAX_WRITE_LEN)
- wcount = MAX_WRITE_LEN;
-#endif
- written = write (desc, ptr, wcount);
- if (written < 0)
- {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif
- pfatal_with_name (out_fname);
- }
- ptr += written;
- len -= written;
- }
-}
-
-/* Print a string to stderr, with extra handling in case it contains
- embedded NUL characters. Any present are written as is.
-
- Using fwrite for this purpose produces undesireable results on VMS
- when stderr happens to be a record oriented file, such as a batch log
- file, rather than a stream oriented one. */
-
-static void
-eprint_string (string, length)
- const char *string;
- size_t length;
-{
- size_t segment_length;
-
- do {
- fprintf(stderr, "%s", string);
- length -= (segment_length = strlen(string));
- if (length > 0)
- {
- fputc('\0', stderr);
- length -= 1;
- /* Advance past the portion which has already been printed. */
- string += segment_length + 1;
- }
- } while (length > 0);
-}
-
-
-static void
-print_help ()
-{
- printf ("Usage: %s [switches] input output\n", progname);
- printf ("Switches:\n");
- printf (" -include <file> Include the contents of <file> before other files\n");
- printf (" -imacros <file> Accept definition of marcos in <file>\n");
- printf (" -iprefix <path> Specify <path> as a prefix for next two options\n");
- printf (" -iwithprefix <dir> Add <dir> to the end of the system include paths\n");
- printf (" -iwithprefixbefore <dir> Add <dir> to the end of the main include paths\n");
- printf (" -isystem <dir> Add <dir> to the start of the system include paths\n");
- printf (" -idirafter <dir> Add <dir> to the end of the system include paths\n");
- printf (" -I <dir> Add <dir> to the end of the main include paths\n");
- printf (" -nostdinc Do not search the system include directories\n");
- printf (" -nostdinc++ Do not search the system include directories for C++\n");
- printf (" -o <file> Put output into <file>\n");
- printf (" -pedantic Issue all warnings demanded by strict ANSI C\n");
- printf (" -traditional Follow K&R pre-processor behaviour\n");
- printf (" -trigraphs Support ANSI C trigraphs\n");
- printf (" -lang-c Assume that the input sources are in C\n");
- printf (" -lang-c89 Assume that the input is C89; depricated\n");
- printf (" -lang-c++ Assume that the input sources are in C++\n");
- printf (" -lang-objc Assume that the input sources are in ObjectiveC\n");
- printf (" -lang-objc++ Assume that the input sources are in ObjectiveC++\n");
- printf (" -lang-asm Assume that the input sources are in assembler\n");
- printf (" -lang-chill Assume that the input sources are in Chill\n");
- printf (" -std=<std name> Specify the conformance standard; one of:\n");
- printf (" gnu89, gnu9x, c89, c9x, iso9899:1990,\n");
- printf (" iso9899:199409, iso9899:199x\n");
- printf (" -+ Allow parsing of C++ style features\n");
- printf (" -w Inhibit warning messages\n");
- printf (" -Wtrigraphs Warn if trigraphs are encountered\n");
- printf (" -Wno-trigraphs Do not warn about trigraphs\n");
- printf (" -Wcomment{s} Warn if one comment starts inside another\n");
- printf (" -Wno-comment{s} Do not warn about comments\n");
- printf (" -Wtraditional Warn if a macro argument is/would be turned into\n");
- printf (" a string if -traditional is specified\n");
- printf (" -Wno-traditional Do not warn about stringification\n");
- printf (" -Wundef Warn if an undefined macro is used by #if\n");
- printf (" -Wno-undef Do not warn about testing undefined macros\n");
- printf (" -Wimport Warn about the use of the #import directive\n");
- printf (" -Wno-import Do not warn about the use of #import\n");
- printf (" -Werror Treat all warnings as errors\n");
- printf (" -Wno-error Do not treat warnings as errors\n");
- printf (" -Wall Enable all preprocessor warnings\n");
- printf (" -M Generate make dependencies\n");
- printf (" -MM As -M, but ignore system header files\n");
- printf (" -MD As -M, but put output in a .d file\n");
- printf (" -MMD As -MD, but ignore system header files\n");
- printf (" -MG Treat missing header file as generated files\n");
- printf (" -g Include #define and #undef directives in the output\n");
- printf (" -D<macro> Define a <macro> with string '1' as its value\n");
- printf (" -D<macro>=<val> Define a <macro> with <val> as its value\n");
- printf (" -A<question> (<answer>) Assert the <answer> to <question>\n");
- printf (" -U<macro> Undefine <macro> \n");
- printf (" -u or -undef Do not predefine any macros\n");
- printf (" -v Display the version number\n");
- printf (" -H Print the name of header files as they are used\n");
- printf (" -C Do not discard comments\n");
- printf (" -dM Display a list of macro definitions active at end\n");
- printf (" -dD Preserve macro definitions in output\n");
- printf (" -dN As -dD except that only the names are preserved\n");
- printf (" -dI Include #include directives in the output\n");
- printf (" -ifoutput Describe skipped code blocks in output \n");
- printf (" -P Do not generate #line directives\n");
- printf (" -$ Do not include '$' in identifiers\n");
- printf (" -remap Remap file names when including files.\n");
- printf (" -h or --help Display this information\n");
-}
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- struct stat st;
- char *in_fname;
- char *cp;
- int f, i;
- FILE_BUF *fp;
-
- char **pend_files;
- char **pend_defs;
- char **pend_undefs;
- char **pend_assertions;
- char **pend_includes;
-
- /* Record the option used with each element of pend_assertions.
- This is preparation for supporting more than one option for making
- an assertion. */
- char **pend_assertion_options;
- int no_standard_includes = 0;
- int no_standard_cplusplus_includes = 0;
- int missing_newline = 0;
-
- /* Non-0 means don't output the preprocessed program. */
- int inhibit_output = 0;
- /* Non-0 means -v, so print the full set of include dirs. */
- int verbose = 0;
-
- /* File name which deps are being written to.
- This is 0 if deps are being written to stdout. */
- char *deps_file = 0;
- /* Fopen file mode to open deps_file with. */
- char *deps_mode = "a";
- /* Stream on which to print the dependency information. */
- FILE *deps_stream = 0;
- /* Target-name to write with the dependency information. */
- char *deps_target = 0;
-
-#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
- /* Get rid of any avoidable limit on stack size. */
- {
- struct rlimit rlim;
-
- /* Set the stack limit huge so that alloca (particularly stringtab
- in dbxread.c) does not fail. */
- getrlimit (RLIMIT_STACK, &rlim);
- rlim.rlim_cur = rlim.rlim_max;
- setrlimit (RLIMIT_STACK, &rlim);
- }
-#endif
-
-#ifdef SIGPIPE
- signal (SIGPIPE, pipe_closed);
-#endif
-
-#ifdef HAVE_LC_MESSAGES
- setlocale (LC_MESSAGES, "");
-#endif
- (void) bindtextdomain (PACKAGE, localedir);
- (void) textdomain (PACKAGE);
-
- progname = base_name (argv[0]);
-
-#ifdef VMS
- {
- /* Remove extension from PROGNAME. */
- char *p;
- char *s = progname = xstrdup (progname);
-
- if ((p = rindex (s, ';')) != 0) *p = '\0'; /* strip version number */
- if ((p = rindex (s, '.')) != 0 /* strip type iff ".exe" */
- && (p[1] == 'e' || p[1] == 'E')
- && (p[2] == 'x' || p[2] == 'X')
- && (p[3] == 'e' || p[3] == 'E')
- && !p[4])
- *p = '\0';
- }
-#endif
-
- /* Do not invoke xmalloc before this point, since locale and
- progname need to be set first, in case a diagnostic is issued. */
-
- pend_files = (char **) xmalloc (argc * sizeof (char *));
- pend_defs = (char **) xmalloc (argc * sizeof (char *));
- pend_undefs = (char **) xmalloc (argc * sizeof (char *));
- pend_assertions = (char **) xmalloc (argc * sizeof (char *));
- pend_includes = (char **) xmalloc (argc * sizeof (char *));
- pend_assertion_options = (char **) xmalloc (argc * sizeof (char *));
-
- in_fname = NULL;
- out_fname = NULL;
-
- /* Initialize is_idchar. */
- initialize_char_syntax ();
-
- no_line_directives = 0;
- no_trigraphs = 1;
- dump_macros = dump_none;
- no_output = 0;
- cplusplus = 0;
- cplusplus_comments = 1;
-
- bzero ((char *) pend_files, argc * sizeof (char *));
- bzero ((char *) pend_defs, argc * sizeof (char *));
- bzero ((char *) pend_undefs, argc * sizeof (char *));
- bzero ((char *) pend_assertions, argc * sizeof (char *));
- bzero ((char *) pend_includes, argc * sizeof (char *));
-
-#ifdef MULTIBYTE_CHARS
- /* Change to the native locale for multibyte conversions. */
- setlocale (LC_CTYPE, "");
- literal_codeset = getenv ("LANG");
-#endif
-
- /* Process switches and find input file name. */
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] != '-') {
- if (out_fname != NULL)
- {
- print_help ();
- fatal ("Too many arguments");
- }
- else if (in_fname != NULL)
- out_fname = argv[i];
- else
- in_fname = argv[i];
- } else {
- switch (argv[i][1]) {
-
- case 'i':
- if (!strcmp (argv[i], "-include")) {
- int temp = i;
-
- if (i + 1 == argc)
- fatal ("Filename missing after `-include' option");
- else
- simplify_filename (pend_includes[temp] = argv[++i]);
- }
- if (!strcmp (argv[i], "-imacros")) {
- int temp = i;
-
- if (i + 1 == argc)
- fatal ("Filename missing after `-imacros' option");
- else
- simplify_filename (pend_files[temp] = argv[++i]);
- }
- if (!strcmp (argv[i], "-iprefix")) {
- if (i + 1 == argc)
- fatal ("Filename missing after `-iprefix' option");
- else
- include_prefix = argv[++i];
- }
- if (!strcmp (argv[i], "-ifoutput")) {
- output_conditionals = 1;
- }
- if (!strcmp (argv[i], "-isystem")) {
- struct file_name_list *dirtmp;
-
- if (! (dirtmp = new_include_prefix (NULL_PTR, NULL_PTR,
- "", argv[++i])))
- break;
- dirtmp->c_system_include_path = 1;
-
- if (before_system == 0)
- before_system = dirtmp;
- else
- last_before_system->next = dirtmp;
- last_before_system = dirtmp; /* Tail follows the last one */
- }
- /* Add directory to end of path for includes,
- with the default prefix at the front of its name. */
- if (!strcmp (argv[i], "-iwithprefix")) {
- struct file_name_list *dirtmp;
- char *prefix;
-
- if (include_prefix != 0)
- prefix = include_prefix;
- else {
- prefix = xstrdup (GCC_INCLUDE_DIR);
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
- prefix[strlen (prefix) - 7] = 0;
- }
-
- if (! (dirtmp = new_include_prefix (NULL_PTR, NULL_PTR,
- prefix, argv[++i])))
- break;
-
- if (after_include == 0)
- after_include = dirtmp;
- else
- last_after_include->next = dirtmp;
- last_after_include = dirtmp; /* Tail follows the last one */
- }
- /* Add directory to main path for includes,
- with the default prefix at the front of its name. */
- if (!strcmp (argv[i], "-iwithprefixbefore")) {
- struct file_name_list *dirtmp;
- char *prefix;
-
- if (include_prefix != 0)
- prefix = include_prefix;
- else {
- prefix = xstrdup (GCC_INCLUDE_DIR);
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
- prefix[strlen (prefix) - 7] = 0;
- }
-
- dirtmp = new_include_prefix (NULL_PTR, NULL_PTR, prefix, argv[++i]);
- append_include_chain (dirtmp, dirtmp);
- }
- /* Add directory to end of path for includes. */
- if (!strcmp (argv[i], "-idirafter")) {
- struct file_name_list *dirtmp;
-
- if (! (dirtmp = new_include_prefix (NULL_PTR, NULL_PTR,
- "", argv[++i])))
- break;
-
- if (after_include == 0)
- after_include = dirtmp;
- else
- last_after_include->next = dirtmp;
- last_after_include = dirtmp; /* Tail follows the last one */
- }
- break;
-
- case 'o':
- if (out_fname != NULL)
- fatal ("Output filename specified twice");
- if (i + 1 == argc)
- fatal ("Filename missing after -o option");
- out_fname = argv[++i];
- if (!strcmp (out_fname, "-"))
- out_fname = "";
- break;
-
- case 'p':
- if (!strcmp (argv[i], "-pedantic"))
- pedantic = 1;
- else if (!strcmp (argv[i], "-pedantic-errors")) {
- pedantic = 1;
- pedantic_errors = 1;
- } else if (!strcmp (argv[i], "-pcp")) {
- char *pcp_fname;
- if (i + 1 == argc)
- fatal ("Filename missing after -pcp option");
- pcp_fname = argv[++i];
- pcp_outfile
- = ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
- ? fopen (pcp_fname, "w")
- : stdout);
- if (pcp_outfile == 0)
- pfatal_with_name (pcp_fname);
- no_precomp = 1;
- }
- break;
-
- case 't':
- if (!strcmp (argv[i], "-traditional")) {
- traditional = 1;
- cplusplus_comments = 0;
- } else if (!strcmp (argv[i], "-trigraphs")) {
- no_trigraphs = 0;
- }
- break;
-
- case 'l':
- if (! strcmp (argv[i], "-lang-c"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 1, objc = 0;
- else if (! strcmp (argv[i], "-lang-c89"))
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, c9x = 0, objc = 0;
- else if (! strcmp (argv[i], "-lang-c++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 0;
- else if (! strcmp (argv[i], "-lang-objc"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 1;
- else if (! strcmp (argv[i], "-lang-objc++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 1;
- else if (! strcmp (argv[i], "-lang-asm"))
- lang_asm = 1;
- else if (! strcmp (argv[i], "-lint"))
- for_lint = 1;
- break;
-
- case '+':
- cplusplus = 1, cplusplus_comments = 1;
- break;
-
- case 's':
- if (!strcmp (argv[i], "-std=iso9899:1990")
- || !strcmp (argv[i], "-std=iso9899:199409")
- || !strcmp (argv[i], "-std=c89")
- || !strcmp (argv[i], "-std=gnu89"))
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, c9x = 0, objc = 0;
- else if (!strcmp (argv[i], "-std=iso9899:199x")
- || !strcmp (argv[i], "-std=c9x")
- || !strcmp (argv[i], "-std=gnu9x"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 1, objc = 0;
- break;
-
- case 'w':
- inhibit_warnings = 1;
- break;
-
- case 'W':
- if (!strcmp (argv[i], "-Wtrigraphs"))
- warn_trigraphs = 1;
- else if (!strcmp (argv[i], "-Wno-trigraphs"))
- warn_trigraphs = 0;
- else if (!strcmp (argv[i], "-Wcomment"))
- warn_comments = 1;
- else if (!strcmp (argv[i], "-Wno-comment"))
- warn_comments = 0;
- else if (!strcmp (argv[i], "-Wcomments"))
- warn_comments = 1;
- else if (!strcmp (argv[i], "-Wno-comments"))
- warn_comments = 0;
- else if (!strcmp (argv[i], "-Wtraditional"))
- warn_stringify = 1;
- else if (!strcmp (argv[i], "-Wno-traditional"))
- warn_stringify = 0;
- else if (!strcmp (argv[i], "-Wundef"))
- warn_undef = 1;
- else if (!strcmp (argv[i], "-Wno-undef"))
- warn_undef = 0;
- else if (!strcmp (argv[i], "-Wimport"))
- warn_import = 1;
- else if (!strcmp (argv[i], "-Wno-import"))
- warn_import = 0;
- else if (!strcmp (argv[i], "-Werror"))
- warnings_are_errors = 1;
- else if (!strcmp (argv[i], "-Wno-error"))
- warnings_are_errors = 0;
- else if (!strcmp (argv[i], "-Wall"))
- {
- warn_trigraphs = 1;
- warn_comments = 1;
- }
- break;
-
- case 'f':
- if (!strcmp (argv[i], "-fleading-underscore"))
- user_label_prefix = "_";
- else if (!strcmp (argv[i], "-fno-leading-underscore"))
- user_label_prefix = "";
- break;
-
- case 'M':
- /* The style of the choices here is a bit mixed.
- The chosen scheme is a hybrid of keeping all options in one string
- and specifying each option in a separate argument:
- -M|-MM|-MD file|-MMD file [-MG]. An alternative is:
- -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely:
- -M[M][G][D file]. This is awkward to handle in specs, and is not
- as extensible. */
- /* ??? -MG must be specified in addition to one of -M or -MM.
- This can be relaxed in the future without breaking anything.
- The converse isn't true. */
-
- /* -MG isn't valid with -MD or -MMD. This is checked for later. */
- if (!strcmp (argv[i], "-MG"))
- {
- print_deps_missing_files = 1;
- break;
- }
- if (!strcmp (argv[i], "-M"))
- print_deps = 2;
- else if (!strcmp (argv[i], "-MM"))
- print_deps = 1;
- else if (!strcmp (argv[i], "-MD"))
- print_deps = 2;
- else if (!strcmp (argv[i], "-MMD"))
- print_deps = 1;
- /* For -MD and -MMD options, write deps on file named by next arg. */
- if (!strcmp (argv[i], "-MD")
- || !strcmp (argv[i], "-MMD")) {
- if (i + 1 == argc)
- fatal ("Filename missing after %s option", argv[i]);
- i++;
- deps_file = argv[i];
- deps_mode = "w";
- } else {
- /* For -M and -MM, write deps on standard output
- and suppress the usual output. */
- deps_stream = stdout;
- inhibit_output = 1;
- }
- break;
-
- case 'd':
- {
- char *p = argv[i] + 2;
- char c;
- while ((c = *p++)) {
- /* Arg to -d specifies what parts of macros to dump */
- switch (c) {
- case 'M':
- dump_macros = dump_only;
- no_output = 1;
- break;
- case 'N':
- dump_macros = dump_names;
- break;
- case 'D':
- dump_macros = dump_definitions;
- break;
- case 'I':
- dump_includes = 1;
- break;
- }
- }
- }
- break;
-
- case 'g':
- if (argv[i][2] == '3')
- debug_output = 1;
- break;
-
- case '-':
- if (strcmp (argv[i], "--help") != 0)
- return i;
- print_help ();
- exit (0);
- break;
-
- case 'v':
- notice ("GNU CPP version %s", version_string);
-#ifdef TARGET_VERSION
- TARGET_VERSION;
-#endif
- fprintf (stderr, "\n");
- verbose = 1;
- break;
-
- case 'H':
- print_include_names = 1;
- break;
-
- case 'D':
- if (argv[i][2] != 0)
- pend_defs[i] = argv[i] + 2;
- else if (i + 1 == argc)
- fatal ("Macro name missing after -D option");
- else
- i++, pend_defs[i] = argv[i];
- break;
-
- case 'A':
- {
- char *p;
-
- if (argv[i][2] != 0)
- p = argv[i] + 2;
- else if (i + 1 == argc)
- fatal ("Assertion missing after -A option");
- else
- p = argv[++i];
-
- if (!strcmp (p, "-")) {
- /* -A- eliminates all predefined macros and assertions.
- Let's include also any that were specified earlier
- on the command line. That way we can get rid of any
- that were passed automatically in from GCC. */
- int j;
- for (j = 0; j < i; j++)
- pend_defs[j] = pend_assertions[j] = 0;
- } else {
- pend_assertions[i] = p;
- pend_assertion_options[i] = "-A";
- }
- }
- break;
-
- case 'U': /* JF #undef something */
- if (argv[i][2] != 0)
- pend_undefs[i] = argv[i] + 2;
- else if (i + 1 == argc)
- fatal ("Macro name missing after -U option");
- else
- pend_undefs[i] = argv[i+1], i++;
- break;
-
- case 'C':
- put_out_comments = 1;
- break;
-
- case 'E': /* -E comes from cc -E; ignore it. */
- break;
-
- case 'P':
- no_line_directives = 1;
- break;
-
- case '$': /* Don't include $ in identifiers. */
- is_idchar['$'] = is_idstart['$'] = 0;
- break;
-
- case 'I': /* Add directory to path for includes. */
- {
- struct file_name_list *dirtmp;
-
- if (! ignore_srcdir && !strcmp (argv[i] + 2, "-")) {
- ignore_srcdir = 1;
- /* Don't use any preceding -I directories for #include <...>. */
- first_bracket_include = 0;
- }
- else {
- dirtmp = new_include_prefix (last_include, NULL_PTR, "",
- argv[i][2] ? argv[i] + 2 : argv[++i]);
- append_include_chain (dirtmp, dirtmp);
- }
- }
- break;
-
- case 'n':
- if (!strcmp (argv[i], "-nostdinc"))
- /* -nostdinc causes no default include directories.
- You must specify all include-file directories with -I. */
- no_standard_includes = 1;
- else if (!strcmp (argv[i], "-nostdinc++"))
- /* -nostdinc++ causes no default C++-specific include directories. */
- no_standard_cplusplus_includes = 1;
- else if (!strcmp (argv[i], "-noprecomp"))
- no_precomp = 1;
- break;
-
- case 'r':
- if (!strcmp (argv[i], "-remap"))
- remap = 1;
- break;
-
- case '\0': /* JF handle '-' as file name meaning stdin or stdout */
- if (in_fname == NULL) {
- in_fname = "";
- break;
- } else if (out_fname == NULL) {
- out_fname = "";
- break;
- } /* else fall through into error */
-
- default:
- fatal ("Invalid option `%s'", argv[i]);
- }
- }
- }
-
- /* Add dirs from CPATH after dirs from -I. */
- /* There seems to be confusion about what CPATH should do,
- so for the moment it is not documented. */
- /* Some people say that CPATH should replace the standard include dirs,
- but that seems pointless: it comes before them, so it overrides them
- anyway. */
- GET_ENV_PATH_LIST (cp, "CPATH");
- if (cp && ! no_standard_includes)
- path_include (cp);
-
- /* Initialize output buffer */
-
- outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);
- outbuf.bufp = outbuf.buf;
- outbuf.length = OUTBUF_SIZE;
-
- /* Do partial setup of input buffer for the sake of generating
- early #line directives (when -g is in effect). */
-
- fp = &instack[++indepth];
- if (in_fname == NULL)
- in_fname = "";
- fp->nominal_fname = fp->fname = in_fname;
- fp->nominal_fname_len = strlen (in_fname);
- fp->lineno = 0;
-
- /* In C++, wchar_t is a distinct basic type, and we can expect
- __wchar_t to be defined by cc1plus. */
- if (cplusplus)
- wchar_type = "__wchar_t";
-
- /* Install __LINE__, etc. Must follow initialize_char_syntax
- and option processing. */
- initialize_builtins (fp, &outbuf);
-
- /* Now handle the command line options. */
-
- /* Do -U's, -D's and -A's in the order they were seen. */
- for (i = 1; i < argc; i++) {
- if (pend_undefs[i]) {
- if (debug_output)
- output_line_directive (fp, &outbuf, 0, same_file);
- make_undef (pend_undefs[i], &outbuf);
- }
- if (pend_defs[i]) {
- if (debug_output)
- output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (pend_defs[i]);
- }
- if (pend_assertions[i])
- make_assertion (pend_assertion_options[i], pend_assertions[i]);
- }
-
- done_initializing = 1;
-
- { /* Read the appropriate environment variable and if it exists
- replace include_defaults with the listed path. */
- char *epath = 0;
- switch ((objc << 1) + cplusplus)
- {
- case 0:
- GET_ENV_PATH_LIST (epath, "C_INCLUDE_PATH");
- break;
- case 1:
- GET_ENV_PATH_LIST (epath, "CPLUS_INCLUDE_PATH");
- break;
- case 2:
- GET_ENV_PATH_LIST (epath, "OBJC_INCLUDE_PATH");
- break;
- case 3:
- GET_ENV_PATH_LIST (epath, "OBJCPLUS_INCLUDE_PATH");
- break;
- }
- /* If the environment var for this language is set,
- add to the default list of include directories. */
- if (epath) {
- int num_dirs;
- char *startp, *endp;
-
- for (num_dirs = 1, startp = epath; *startp; startp++)
- if (*startp == PATH_SEPARATOR)
- num_dirs++;
- include_defaults
- = (struct default_include *) xmalloc ((num_dirs
- * sizeof (struct default_include))
- + sizeof (include_defaults_array));
- startp = endp = epath;
- num_dirs = 0;
- while (1) {
- char c = *endp++;
- if (c == PATH_SEPARATOR || !c) {
- endp[-1] = 0;
- include_defaults[num_dirs].fname
- = startp == endp ? "." : xstrdup (startp);
- endp[-1] = c;
- include_defaults[num_dirs].component = 0;
- include_defaults[num_dirs].cplusplus = cplusplus;
- include_defaults[num_dirs].cxx_aware = 1;
- num_dirs++;
- if (!c)
- break;
- startp = endp;
- }
- }
- /* Put the usual defaults back in at the end. */
- bcopy ((char *) include_defaults_array,
- (char *) &include_defaults[num_dirs],
- sizeof (include_defaults_array));
- }
- }
-
- append_include_chain (before_system, last_before_system);
- first_system_include = before_system;
-
- /* Unless -fnostdinc,
- tack on the standard include file dirs to the specified list */
- if (!no_standard_includes) {
- struct default_include *p = include_defaults;
- char *specd_prefix = include_prefix;
- char *default_prefix = xstrdup (GCC_INCLUDE_DIR);
- int default_len = 0;
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
- default_len = strlen (default_prefix) - 7;
- default_prefix[default_len] = 0;
- }
- /* Search "translated" versions of GNU directories.
- These have /usr/local/lib/gcc... replaced by specd_prefix. */
- if (specd_prefix != 0 && default_len != 0)
- for (p = include_defaults; p->fname; p++) {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
- /* Does this dir start with the prefix? */
- if (!strncmp (p->fname, default_prefix, default_len)) {
- /* Yes; change prefix and add to search list. */
- struct file_name_list *new
- = new_include_prefix (NULL_PTR, NULL_PTR, specd_prefix,
- p->fname + default_len);
- if (new) {
- new->c_system_include_path = !p->cxx_aware;
- append_include_chain (new, new);
- if (first_system_include == 0)
- first_system_include = new;
- p->included = 1;
- }
- }
- }
- }
- /* Search ordinary names for GNU include directories. */
- for (p = include_defaults; p->fname; p++) {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
- struct file_name_list *new
- = new_include_prefix (NULL_PTR, p->component, "", p->fname);
- if (new) {
- new->c_system_include_path = !p->cxx_aware;
- append_include_chain (new, new);
- if (first_system_include == 0)
- first_system_include = new;
- p->included = 1;
- }
- }
- }
- }
-
- /* Tack the after_include chain at the end of the include chain. */
- append_include_chain (after_include, last_after_include);
- if (first_system_include == 0)
- first_system_include = after_include;
-
- /* With -v, print the list of dirs to search. */
- if (verbose) {
- struct file_name_list *p;
- notice ("#include \"...\" search starts here:\n");
- for (p = include; p; p = p->next) {
- if (p == first_bracket_include)
- notice ("#include <...> search starts here:\n");
- if (!p->fname[0])
- fprintf (stderr, " .\n");
- else if (!strcmp (p->fname, "/") || !strcmp (p->fname, "//"))
- fprintf (stderr, " %s\n", p->fname);
- else
- /* Omit trailing '/'. */
- fprintf (stderr, " %.*s\n", (int) strlen (p->fname) - 1, p->fname);
- }
- notice ("End of search list.\n");
- {
- struct default_include * d;
- notice ("The following default directories have been omitted from the search path:\n");
- for (d = include_defaults; d->fname; d++)
- if (! d->included)
- fprintf (stderr, " %s\n", d->fname);
- notice ("End of omitted list.\n");
- }
- }
-
- /* -MG doesn't select the form of output and must be specified with one of
- -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't
- inhibit compilation. */
- if (print_deps_missing_files && (print_deps == 0 || !inhibit_output))
- fatal ("-MG must be specified with one of -M or -MM");
-
- /* Either of two environment variables can specify output of deps.
- Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
- where OUTPUT_FILE is the file to write deps info to
- and DEPS_TARGET is the target to mention in the deps. */
-
- if (print_deps == 0
- && (getenv ("SUNPRO_DEPENDENCIES") != 0
- || getenv ("DEPENDENCIES_OUTPUT") != 0)) {
- char *spec = getenv ("DEPENDENCIES_OUTPUT");
- char *s;
- char *output_file;
-
- if (spec == 0) {
- spec = getenv ("SUNPRO_DEPENDENCIES");
- print_deps = 2;
- }
- else
- print_deps = 1;
-
- s = spec;
- /* Find the space before the DEPS_TARGET, if there is one. */
- /* This should use index. (mrs) */
- while (*s != 0 && *s != ' ') s++;
- if (*s != 0) {
- deps_target = s + 1;
- output_file = xmalloc (s - spec + 1);
- bcopy (spec, output_file, s - spec);
- output_file[s - spec] = 0;
- }
- else {
- deps_target = 0;
- output_file = spec;
- }
-
- deps_file = output_file;
- deps_mode = "a";
- }
-
- /* For -M, print the expected object file name
- as the target of this Make-rule. */
- if (print_deps) {
- deps_allocated_size = 200;
- deps_buffer = xmalloc (deps_allocated_size);
- deps_buffer[0] = 0;
- deps_size = 0;
- deps_column = 0;
-
- if (deps_target) {
- deps_output (deps_target, ':');
- } else if (*in_fname == 0) {
- deps_output ("-", ':');
- } else {
- char *p, *q;
- int len;
-
- q = base_name (in_fname);
-
- /* Copy remainder to mungable area. */
- p = (char *) alloca (strlen(q) + 8);
- strcpy (p, q);
-
- /* Output P, but remove known suffixes. */
- len = strlen (p);
- q = p + len;
- if (len >= 2
- && p[len - 2] == '.'
- && index("cCsSm", p[len - 1]))
- q = p + (len - 2);
- else if (len >= 3
- && p[len - 3] == '.'
- && p[len - 2] == 'c'
- && p[len - 1] == 'c')
- q = p + (len - 3);
- else if (len >= 4
- && p[len - 4] == '.'
- && p[len - 3] == 'c'
- && p[len - 2] == 'x'
- && p[len - 1] == 'x')
- q = p + (len - 4);
- else if (len >= 4
- && p[len - 4] == '.'
- && p[len - 3] == 'c'
- && p[len - 2] == 'p'
- && p[len - 1] == 'p')
- q = p + (len - 4);
-
- /* Supply our own suffix. */
- strcpy (q, OBJECT_SUFFIX);
-
- deps_output (p, ':');
- deps_output (in_fname, ' ');
- }
- }
-
- /* Scan the -imacros files before the main input.
- Much like #including them, but with no_output set
- so that only their macro definitions matter. */
-
- no_output++; no_record_file++;
- for (i = 1; i < argc; i++)
- if (pend_files[i]) {
- struct include_file *inc;
- int fd = open_include_file (pend_files[i], NULL_PTR, NULL_PTR, &inc);
- if (fd < 0) {
- perror_with_name (pend_files[i]);
- return FATAL_EXIT_CODE;
- }
- finclude (fd, inc, &outbuf, 0, NULL_PTR);
- }
- no_output--; no_record_file--;
-
- /* Copy the entire contents of the main input file into
- the stacked input buffer previously allocated for it. */
-
- /* JF check for stdin */
- if (in_fname == NULL || *in_fname == 0) {
- in_fname = "";
- f = 0;
- } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0)
- goto perror;
-
- if (fstat (f, &st) != 0)
- pfatal_with_name (in_fname);
- fp->nominal_fname = fp->fname = in_fname;
- fp->nominal_fname_len = strlen (in_fname);
- fp->lineno = 1;
- fp->system_header_p = 0;
- /* JF all this is mine about reading pipes and ttys */
- if (! S_ISREG (st.st_mode)) {
- /* Read input from a file that is not a normal disk file.
- We cannot preallocate a buffer with the correct size,
- so we must read in the file a piece at the time and make it bigger. */
- int size;
- int bsize;
- int cnt;
-
- if (S_ISDIR (st.st_mode))
- fatal ("Input file `%s' is a directory", in_fname);
-
- bsize = 2000;
- size = 0;
- fp->buf = (U_CHAR *) xmalloc (bsize + 2);
- for (;;) {
- cnt = safe_read (f, (char *) fp->buf + size, bsize - size);
- if (cnt < 0) goto perror; /* error! */
- size += cnt;
- if (size != bsize) break; /* End of file */
- bsize *= 2;
- fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
- }
- fp->length = size;
- } else {
- /* Read a file whose size we can determine in advance.
- For the sake of VMS, st.st_size is just an upper bound. */
- size_t s = (size_t) st.st_size;
- if (s != st.st_size || s + 2 < s)
- memory_full ();
- fp->buf = (U_CHAR *) xmalloc (s + 2);
- fp->length = safe_read (f, (char *) fp->buf, s);
- if (fp->length < 0) goto perror;
- }
- fp->bufp = fp->buf;
- fp->if_stack = if_stack;
-
- /* Make sure data ends with a newline. And put a null after it. */
-
- if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
- /* Backslash-newline at end is not good enough. */
- || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
- fp->buf[fp->length++] = '\n';
- missing_newline = 1;
- }
- fp->buf[fp->length] = '\0';
-
- /* Unless inhibited, convert trigraphs in the input. */
-
- if (!no_trigraphs)
- trigraph_pcp (fp);
-
- /* Now that we know the input file is valid, open the output. */
-
- if (!out_fname || !strcmp (out_fname, ""))
- out_fname = "stdout";
- else if (! freopen (out_fname, "w", stdout))
- pfatal_with_name (out_fname);
-
- output_line_directive (fp, &outbuf, 0, same_file);
-
- /* Scan the -include files before the main input. */
-
- no_record_file++;
- for (i = 1; i < argc; i++)
- if (pend_includes[i]) {
- struct include_file *inc;
- int fd = open_include_file (pend_includes[i], NULL_PTR, NULL_PTR, &inc);
- if (fd < 0) {
- perror_with_name (pend_includes[i]);
- return FATAL_EXIT_CODE;
- }
- finclude (fd, inc, &outbuf, 0, NULL_PTR);
- }
- no_record_file--;
-
- /* Scan the input, processing macros and directives. */
-
- rescan (&outbuf, 0);
-
- if (missing_newline)
- fp->lineno--;
-
- if (pedantic && missing_newline)
- pedwarn ("file does not end in newline");
-
- /* Now we have processed the entire input
- Write whichever kind of output has been requested. */
-
- if (dump_macros == dump_only)
- dump_all_macros ();
- else if (! inhibit_output) {
- write_output ();
- }
-
- if (print_deps) {
- /* Don't actually write the deps file if compilation has failed. */
- if (errors == 0) {
- if (deps_file && ! (deps_stream = fopen (deps_file, deps_mode)))
- pfatal_with_name (deps_file);
- fputs (deps_buffer, deps_stream);
- putc ('\n', deps_stream);
- if (deps_file) {
- if (ferror (deps_stream) || fclose (deps_stream) != 0)
- fatal ("I/O error on output");
- }
- }
- }
-
- if (pcp_outfile && pcp_outfile != stdout
- && (ferror (pcp_outfile) || fclose (pcp_outfile) != 0))
- fatal ("I/O error on `-pcp' output");
-
- if (ferror (stdout) || fclose (stdout) != 0)
- fatal ("I/O error on output");
-
- if (errors)
- exit (FATAL_EXIT_CODE);
- exit (SUCCESS_EXIT_CODE);
-
- perror:
- pfatal_with_name (in_fname);
- return 0;
-}
-
-/* Given a colon-separated list of file names PATH,
- add all the names to the search path for include files. */
-
-static void
-path_include (path)
- char *path;
-{
- char *p;
-
- p = path;
-
- if (*p)
- while (1) {
- char *q = p;
- char c;
- struct file_name_list *dirtmp;
-
- /* Find the end of this name. */
- while ((c = *q++) != PATH_SEPARATOR && c)
- continue;
-
- q[-1] = 0;
- dirtmp = new_include_prefix (last_include, NULL_PTR,
- "", p == q ? "." : p);
- q[-1] = c;
- append_include_chain (dirtmp, dirtmp);
-
- /* Advance past this name. */
- p = q;
- if (! c)
- break;
- }
-}
-
-/* Return the address of the first character in S that equals C.
- S is an array of length N, possibly containing '\0's, and followed by '\0'.
- Return 0 if there is no such character. Assume that C itself is not '\0'.
- If we knew we could use memchr, we could just invoke memchr (S, C, N),
- but unfortunately memchr isn't autoconfigured yet. */
-
-static U_CHAR *
-index0 (s, c, n)
- U_CHAR *s;
- int c;
- size_t n;
-{
- char *p = (char *) s;
- for (;;) {
- char *q = index (p, c);
- if (q)
- return (U_CHAR *) q;
- else {
- size_t l = strlen (p);
- if (l == n)
- return 0;
- l++;
- p += l;
- n -= l;
- }
- }
-}
-
-/* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF
- before main CCCP processing. Name `pcp' is also in honor of the
- drugs the trigraph designers must have been on.
-
- Using an extra pass through the buffer takes a little extra time,
- but is infinitely less hairy than trying to handle trigraphs inside
- strings, etc. everywhere, and also makes sure that trigraphs are
- only translated in the top level of processing. */
-
-static void
-trigraph_pcp (buf)
- FILE_BUF *buf;
-{
- register U_CHAR c, *fptr, *bptr, *sptr, *lptr;
- int len;
-
- fptr = bptr = sptr = buf->buf;
- lptr = fptr + buf->length;
- while ((sptr = index0 (sptr, '?', (size_t) (lptr - sptr))) != NULL) {
- if (*++sptr != '?')
- continue;
- switch (*++sptr) {
- case '=':
- c = '#';
- break;
- case '(':
- c = '[';
- break;
- case '/':
- c = '\\';
- break;
- case ')':
- c = ']';
- break;
- case '\'':
- c = '^';
- break;
- case '<':
- c = '{';
- break;
- case '!':
- c = '|';
- break;
- case '>':
- c = '}';
- break;
- case '-':
- c = '~';
- break;
- case '?':
- sptr--;
- continue;
- default:
- continue;
- }
- len = sptr - fptr - 2;
-
- /* BSD doc says bcopy () works right for overlapping strings. In ANSI
- C, this will be memmove (). */
- if (bptr != fptr && len > 0)
- bcopy ((char *) fptr, (char *) bptr, len);
-
- bptr += len;
- *bptr++ = c;
- fptr = ++sptr;
- }
- len = buf->length - (fptr - buf->buf);
- if (bptr != fptr && len > 0)
- bcopy ((char *) fptr, (char *) bptr, len);
- buf->length -= fptr - bptr;
- buf->buf[buf->length] = '\0';
- if (warn_trigraphs && fptr != bptr)
- warning_with_line (0, "%lu trigraph(s) encountered",
- (unsigned long) (fptr - bptr) / 2);
-}
-
-/* Move all backslash-newline pairs out of embarrassing places.
- Exchange all such pairs following BP
- with any potentially-embarrassing characters that follow them.
- Potentially-embarrassing characters are / and *
- (because a backslash-newline inside a comment delimiter
- would cause it not to be recognized). */
-
-static void
-newline_fix (bp)
- U_CHAR *bp;
-{
- register U_CHAR *p = bp;
-
- /* First count the backslash-newline pairs here. */
-
- while (p[0] == '\\' && p[1] == '\n')
- p += 2;
-
- /* What follows the backslash-newlines is not embarrassing. */
-
- if (*p != '/' && *p != '*')
- return;
-
- /* Copy all potentially embarrassing characters
- that follow the backslash-newline pairs
- down to where the pairs originally started. */
-
- while (*p == '*' || *p == '/')
- *bp++ = *p++;
-
- /* Now write the same number of pairs after the embarrassing chars. */
- while (bp < p) {
- *bp++ = '\\';
- *bp++ = '\n';
- }
-}
-
-/* Like newline_fix but for use within a directive-name.
- Move any backslash-newlines up past any following symbol constituents. */
-
-static void
-name_newline_fix (bp)
- U_CHAR *bp;
-{
- register U_CHAR *p = bp;
-
- /* First count the backslash-newline pairs here. */
- while (p[0] == '\\' && p[1] == '\n')
- p += 2;
-
- /* What follows the backslash-newlines is not embarrassing. */
-
- if (!is_idchar[*p])
- return;
-
- /* Copy all potentially embarrassing characters
- that follow the backslash-newline pairs
- down to where the pairs originally started. */
-
- while (is_idchar[*p])
- *bp++ = *p++;
-
- /* Now write the same number of pairs after the embarrassing chars. */
- while (bp < p) {
- *bp++ = '\\';
- *bp++ = '\n';
- }
-}
-
-/* Look for lint commands in comments.
-
- When we come in here, ibp points into a comment. Limit is as one expects.
- scan within the comment -- it should start, after lwsp, with a lint command.
- If so that command is returned as a (constant) string.
-
- Upon return, any arg will be pointed to with argstart and will be
- arglen long. Note that we don't parse that arg since it will just
- be printed out again. */
-
-static char *
-get_lintcmd (ibp, limit, argstart, arglen, cmdlen)
- register U_CHAR *ibp;
- register U_CHAR *limit;
- U_CHAR **argstart; /* point to command arg */
- int *arglen, *cmdlen; /* how long they are */
-{
- HOST_WIDEST_INT linsize;
- register U_CHAR *numptr; /* temp for arg parsing */
-
- *arglen = 0;
-
- SKIP_WHITE_SPACE (ibp);
-
- if (ibp >= limit) return NULL;
-
- linsize = limit - ibp;
-
- /* Oh, I wish C had lexical functions... hell, I'll just open-code the set */
- if ((linsize >= 10) && !bcmp (ibp, "NOTREACHED", 10)) {
- *cmdlen = 10;
- return "NOTREACHED";
- }
- if ((linsize >= 8) && !bcmp (ibp, "ARGSUSED", 8)) {
- *cmdlen = 8;
- return "ARGSUSED";
- }
- if ((linsize >= 11) && !bcmp (ibp, "LINTLIBRARY", 11)) {
- *cmdlen = 11;
- return "LINTLIBRARY";
- }
- if ((linsize >= 7) && !bcmp (ibp, "VARARGS", 7)) {
- *cmdlen = 7;
- ibp += 7; linsize -= 7;
- if ((linsize == 0) || ! ISDIGIT (*ibp)) return "VARARGS";
-
- /* OK, read a number */
- for (numptr = *argstart = ibp; (numptr < limit) && ISDIGIT (*numptr);
- numptr++);
- *arglen = numptr - *argstart;
- return "VARARGS";
- }
- return NULL;
-}
-
-/*
- * The main loop of the program.
- *
- * Read characters from the input stack, transferring them to the
- * output buffer OP.
- *
- * Macros are expanded and push levels on the input stack.
- * At the end of such a level it is popped off and we keep reading.
- * At the end of any other kind of level, we return.
- * #-directives are handled, except within macros.
- *
- * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input
- * and insert them when appropriate. This is set while scanning macro
- * arguments before substitution. It is zero when scanning for final output.
- * There are three types of Newline markers:
- * * Newline - follows a macro name that was not expanded
- * because it appeared inside an expansion of the same macro.
- * This marker prevents future expansion of that identifier.
- * When the input is rescanned into the final output, these are deleted.
- * These are also deleted by ## concatenation.
- * * Newline Space (or Newline and any other whitespace character)
- * stands for a place that tokens must be separated or whitespace
- * is otherwise desirable, but where the ANSI standard specifies there
- * is no whitespace. This marker turns into a Space (or whichever other
- * whitespace char appears in the marker) in the final output,
- * but it turns into nothing in an argument that is stringified with #.
- * Such stringified arguments are the only place where the ANSI standard
- * specifies with precision that whitespace may not appear.
- *
- * During this function, IP->bufp is kept cached in IBP for speed of access.
- * Likewise, OP->bufp is kept in OBP. Before calling a subroutine
- * IBP, IP and OBP must be copied back to memory. IP and IBP are
- * copied back with the RECACHE macro. OBP must be copied back from OP->bufp
- * explicitly, and before RECACHE, since RECACHE uses OBP.
- */
-
-static void
-rescan (op, output_marks)
- FILE_BUF *op;
- int output_marks;
-{
- /* Character being scanned in main loop. */
- register U_CHAR c;
-
- /* Length of pending accumulated identifier. */
- register int ident_length = 0;
-
- /* Hash code of pending accumulated identifier. */
- register int hash = 0;
-
- /* Current input level (&instack[indepth]). */
- FILE_BUF *ip;
-
- /* Pointer for scanning input. */
- register U_CHAR *ibp;
-
- /* Pointer to end of input. End of scan is controlled by LIMIT. */
- register U_CHAR *limit;
-
- /* Pointer for storing output. */
- register U_CHAR *obp;
-
- /* REDO_CHAR is nonzero if we are processing an identifier
- after backing up over the terminating character.
- Sometimes we process an identifier without backing up over
- the terminating character, if the terminating character
- is not special. Backing up is done so that the terminating character
- will be dispatched on again once the identifier is dealt with. */
- int redo_char = 0;
-
- /* 1 if within an identifier inside of which a concatenation
- marker (Newline -) has been seen. */
- int concatenated = 0;
-
- /* While scanning a comment or a string constant,
- this records the line it started on, for error messages. */
- int start_line;
-
- /* Record position of last `real' newline. */
- U_CHAR *beg_of_line;
-
-/* Pop the innermost input stack level, assuming it is a macro expansion. */
-
-#define POPMACRO \
-do { ip->macro->type = T_MACRO; \
- if (ip->free_ptr) free (ip->free_ptr); \
- --indepth; } while (0)
-
-/* Reload `rescan's local variables that describe the current
- level of the input stack. */
-
-#define RECACHE \
-do { ip = &instack[indepth]; \
- ibp = ip->bufp; \
- limit = ip->buf + ip->length; \
- op->bufp = obp; \
- check_expand (op, limit - ibp); \
- beg_of_line = 0; \
- obp = op->bufp; } while (0)
-
- if (no_output && instack[indepth].fname != 0)
- skip_if_group (&instack[indepth], 1, NULL);
-
- obp = op->bufp;
- RECACHE;
-
- beg_of_line = ibp;
-
- /* Our caller must always put a null after the end of
- the input at each input stack level. */
- if (*limit != 0)
- abort ();
-
- while (1) {
- c = *ibp++;
- *obp++ = c;
-
- switch (c) {
- case '\\':
- if (*ibp == '\n' && !ip->macro) {
- /* At the top level, always merge lines ending with backslash-newline,
- even in middle of identifier. But do not merge lines in a macro,
- since backslash might be followed by a newline-space marker. */
- ++ibp;
- ++ip->lineno;
- --obp; /* remove backslash from obuf */
- break;
- }
- /* If ANSI, backslash is just another character outside a string. */
- if (!traditional)
- goto randomchar;
- /* Otherwise, backslash suppresses specialness of following char,
- so copy it here to prevent the switch from seeing it.
- But first get any pending identifier processed. */
- if (ident_length > 0)
- goto specialchar;
- if (ibp < limit)
- *obp++ = *ibp++;
- break;
-
- case '%':
- if (ident_length || ip->macro || traditional)
- goto randomchar;
- while (*ibp == '\\' && ibp[1] == '\n') {
- ibp += 2;
- ++ip->lineno;
- }
- if (*ibp != ':')
- break;
- /* Treat this %: digraph as if it were #. */
- /* Fall through. */
-
- case '#':
- if (assertions_flag) {
- if (ident_length)
- goto specialchar;
- /* Copy #foo (bar lose) without macro expansion. */
- obp[-1] = '#'; /* In case it was '%'. */
- SKIP_WHITE_SPACE (ibp);
- while (is_idchar[*ibp])
- *obp++ = *ibp++;
- SKIP_WHITE_SPACE (ibp);
- if (*ibp == '(') {
- ip->bufp = ibp;
- skip_paren_group (ip);
- bcopy ((char *) ibp, (char *) obp, ip->bufp - ibp);
- obp += ip->bufp - ibp;
- ibp = ip->bufp;
- }
- break;
- }
-
- /* If this is expanding a macro definition, don't recognize
- preprocessing directives. */
- if (ip->macro != 0)
- goto randomchar;
- /* If this is expand_into_temp_buffer,
- don't recognize them either. Warn about them
- only after an actual newline at this level,
- not at the beginning of the input level. */
- if (! ip->fname) {
- if (ip->buf != beg_of_line)
- warning ("preprocessing directive not recognized within macro arg");
- goto randomchar;
- }
- if (ident_length)
- goto specialchar;
-
-
- /* # keyword: a # must be first nonblank char on the line */
- if (beg_of_line == 0)
- goto randomchar;
- {
- U_CHAR *bp;
-
- /* Scan from start of line, skipping whitespace, comments
- and backslash-newlines, and see if we reach this #.
- If not, this # is not special. */
- bp = beg_of_line;
- /* If -traditional, require # to be at beginning of line. */
- if (!traditional) {
- while (1) {
- if (is_hor_space[*bp])
- bp++;
- else if (*bp == '\\' && bp[1] == '\n')
- bp += 2;
- else if (*bp == '/' && bp[1] == '*') {
- bp += 2;
- while (1)
- {
- if (*bp == '*')
- {
- if (bp[1] == '/')
- {
- bp += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- bp++;
- }
- }
- /* There is no point in trying to deal with C++ // comments here,
- because if there is one, then this # must be part of the
- comment and we would never reach here. */
- else break;
- }
- if (c == '%') {
- if (bp[0] != '%')
- break;
- while (bp[1] == '\\' && bp[2] == '\n')
- bp += 2;
- if (bp + 1 != ibp)
- break;
- /* %: appears at start of line; skip past the ':' too. */
- bp++;
- ibp++;
- }
- }
- if (bp + 1 != ibp)
- goto randomchar;
- }
-
- /* This # can start a directive. */
-
- --obp; /* Don't copy the '#' */
-
- ip->bufp = ibp;
- op->bufp = obp;
- if (! handle_directive (ip, op)) {
-#ifdef USE_C_ALLOCA
- alloca (0);
-#endif
- /* Not a known directive: treat it as ordinary text.
- IP, OP, IBP, etc. have not been changed. */
- if (no_output && instack[indepth].fname) {
- /* If not generating expanded output,
- what we do with ordinary text is skip it.
- Discard everything until next # directive. */
- skip_if_group (&instack[indepth], 1, 0);
- RECACHE;
- beg_of_line = ibp;
- break;
- }
- *obp++ = '#'; /* Copy # (even if it was originally %:). */
- /* Don't expand an identifier that could be a macro directive.
- (Section 3.8.3 of the ANSI C standard) */
- SKIP_WHITE_SPACE (ibp);
- if (is_idstart[*ibp])
- {
- *obp++ = *ibp++;
- while (is_idchar[*ibp])
- *obp++ = *ibp++;
- }
- goto randomchar;
- }
-#ifdef USE_C_ALLOCA
- alloca (0);
-#endif
- /* A # directive has been successfully processed. */
- /* If not generating expanded output, ignore everything until
- next # directive. */
- if (no_output && instack[indepth].fname)
- skip_if_group (&instack[indepth], 1, 0);
- obp = op->bufp;
- RECACHE;
- beg_of_line = ibp;
- break;
-
- case '\"': /* skip quoted string */
- case '\'':
- /* A single quoted string is treated like a double -- some
- programs (e.g., troff) are perverse this way */
-
- /* Handle any pending identifier;
- but the L in L'...' or L"..." is not an identifier. */
- if (ident_length) {
- if (! (ident_length == 1 && hash == HASHSTEP (0, 'L')))
- goto specialchar;
- ident_length = hash = 0;
- }
-
- start_line = ip->lineno;
-
- /* Skip ahead to a matching quote. */
-
- while (1) {
- if (ibp >= limit) {
- if (ip->macro != 0) {
- /* try harder: this string crosses a macro expansion boundary.
- This can happen naturally if -traditional.
- Otherwise, only -D can make a macro with an unmatched quote. */
- POPMACRO;
- RECACHE;
- continue;
- }
- if (!traditional) {
- error_with_line (line_for_error (start_line),
- "unterminated string or character constant");
- if (multiline_string_line) {
- error_with_line (multiline_string_line,
- "possible real start of unterminated constant");
- multiline_string_line = 0;
- }
- }
- break;
- }
- *obp++ = *ibp;
- switch (*ibp++) {
- case '\n':
- ++ip->lineno;
- ++op->lineno;
- /* Traditionally, end of line ends a string constant with no error.
- So exit the loop and record the new line. */
- if (traditional) {
- beg_of_line = ibp;
- goto while2end;
- }
- if (c == '\'') {
- error_with_line (line_for_error (start_line),
- "unterminated character constant");
- goto while2end;
- }
- if (multiline_string_line == 0) {
- if (pedantic)
- pedwarn_with_line (line_for_error (start_line),
- "string constant runs past end of line");
- multiline_string_line = ip->lineno - 1;
- }
- break;
-
- case '\\':
- if (*ibp == '\n') {
- /* Backslash newline is replaced by nothing at all, but
- keep the line counts correct. But if we are reading
- from a macro, keep the backslash newline, since backslash
- newlines have already been processed. */
- if (ip->macro)
- *obp++ = '\n';
- else
- --obp;
- ++ibp;
- ++ip->lineno;
- } else {
- /* ANSI stupidly requires that in \\ the second \
- is *not* prevented from combining with a newline. */
- if (!ip->macro) {
- while (*ibp == '\\' && ibp[1] == '\n') {
- ibp += 2;
- ++ip->lineno;
- }
- }
- *obp++ = *ibp++;
- }
- break;
-
- case '\"':
- case '\'':
- if (ibp[-1] == c)
- goto while2end;
- break;
-#ifdef MULTIBYTE_CHARS
- default:
- {
- int length;
- --ibp;
- length = local_mblen (ibp, limit - ibp);
- if (length > 0)
- {
- --obp;
- bcopy (ibp, obp, length);
- obp += length;
- ibp += length;
- }
- else
- ++ibp;
- }
- break;
-#endif
- }
- }
- while2end:
- break;
-
- case '/':
- if (ip->macro != 0)
- goto randomchar;
- if (*ibp == '\\' && ibp[1] == '\n')
- newline_fix (ibp);
- if (*ibp != '*'
- && !(cplusplus_comments && *ibp == '/'))
- goto randomchar;
- if (ident_length)
- goto specialchar;
-
- if (*ibp == '/') {
- /* C++ style comment... */
- start_line = ip->lineno;
-
- /* Comments are equivalent to spaces. */
- if (! put_out_comments)
- obp[-1] = ' ';
-
- {
- U_CHAR *before_bp = ibp;
-
- while (++ibp < limit) {
- if (*ibp == '\n')
- {
- if (put_out_comments) {
- bcopy ((char *) before_bp, (char *) obp, ibp - before_bp);
- obp += ibp - before_bp;
- }
- break;
- }
- if (*ibp == '\\')
- {
- if (ibp + 1 < limit && ibp[1] == '\n')
- {
- if (warn_comments)
- warning ("multiline `//' comment");
- ++ip->lineno;
- /* Copy the newline into the output buffer, in order to
- avoid the pain of a #line every time a multiline comment
- is seen. */
- if (!put_out_comments)
- *obp++ = '\n';
- ++op->lineno;
- ++ibp;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
-#endif
- }
- }
- break;
- }
- }
-
- /* Ordinary C comment. Skip it, optionally copying it to output. */
-
- start_line = ip->lineno;
-
- ++ibp; /* Skip the star. */
-
- /* If this cpp is for lint, we peek inside the comments: */
- if (for_lint) {
- U_CHAR *argbp;
- int cmdlen, arglen;
- char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
-
- if (lintcmd != NULL) {
- op->bufp = obp;
- check_expand (op, cmdlen + arglen + 14);
- obp = op->bufp;
- /* I believe it is always safe to emit this newline: */
- obp[-1] = '\n';
- bcopy ("#pragma lint ", (char *) obp, 13);
- obp += 13;
- bcopy (lintcmd, (char *) obp, cmdlen);
- obp += cmdlen;
-
- if (arglen != 0) {
- *(obp++) = ' ';
- bcopy (argbp, (char *) obp, arglen);
- obp += arglen;
- }
-
- /* OK, now bring us back to the state we were in before we entered
- this branch. We need #line because the #pragma's newline always
- messes up the line count. */
- op->bufp = obp;
- output_line_directive (ip, op, 0, same_file);
- check_expand (op, limit - ibp + 2);
- obp = op->bufp;
- *(obp++) = '/';
- }
- }
-
- /* Comments are equivalent to spaces.
- Note that we already output the slash; we might not want it.
- For -traditional, a comment is equivalent to nothing. */
- if (! put_out_comments) {
- if (traditional)
- obp--;
- else
- obp[-1] = ' ';
- }
- else
- *obp++ = '*';
-
- {
- U_CHAR *before_bp = ibp;
-
- for (;;) {
- switch (*ibp++) {
- case '*':
- if (ibp[-2] == '/' && warn_comments)
- warning ("`/*' within comment");
- if (*ibp == '\\' && ibp[1] == '\n')
- newline_fix (ibp);
- if (*ibp == '/')
- goto comment_end;
- break;
-
- case '\n':
- ++ip->lineno;
- /* Copy the newline into the output buffer, in order to
- avoid the pain of a #line every time a multiline comment
- is seen. */
- if (!put_out_comments)
- *obp++ = '\n';
- ++op->lineno;
- break;
-
- case 0:
- if (limit < ibp) {
- error_with_line (line_for_error (start_line),
- "unterminated comment");
- goto limit_reached;
- }
- break;
-#ifdef MULTIBYTE_CHARS
- default:
- {
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
- }
- break;
-#endif
- }
- }
- comment_end:
-
- ibp++;
- if (put_out_comments) {
- bcopy ((char *) before_bp, (char *) obp, ibp - before_bp);
- obp += ibp - before_bp;
- }
- }
- break;
-
- case '$':
- if (! is_idchar['$'])
- goto randomchar;
- if (pedantic)
- pedwarn ("`$' in identifier");
- goto letter;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* If digit is not part of identifier, it starts a number,
- which means that following letters are not an identifier.
- "0x5" does not refer to an identifier "x5".
- So copy all alphanumerics that follow without accumulating
- as an identifier. Periods also, for sake of "3.e7". */
-
- if (ident_length == 0) {
- for (;;) {
- if (!ip->macro) {
- while (ibp[0] == '\\' && ibp[1] == '\n') {
- ++ip->lineno;
- ibp += 2;
- }
- }
- c = *ibp++;
- if (!is_idchar[c] && c != '.') {
- --ibp;
- break;
- }
- *obp++ = c;
- /* A sign can be part of a preprocessing number
- if it follows an `e' or `p'. */
- if (c == 'e' || c == 'E' || c == 'p' || c == 'P') {
- if (!ip->macro) {
- while (ibp[0] == '\\' && ibp[1] == '\n') {
- ++ip->lineno;
- ibp += 2;
- }
- }
- if (*ibp == '+' || *ibp == '-') {
- *obp++ = *ibp++;
- /* But traditional C does not let the token go past the sign,
- and C89 does not allow `p'. */
- if (traditional || (c89 && (c == 'p' || c == 'P')))
- break;
- }
- }
- }
- break;
- }
- /* fall through */
-
- case '_':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- letter:
- ident_length++;
- /* Compute step of hash function, to avoid a proc call on every token */
- hash = HASHSTEP (hash, c);
- break;
-
- case '\n':
- if (ip->fname == 0 && *ibp == '-') {
- /* Newline - inhibits expansion of preceding token.
- If expanding a macro arg, we keep the newline -.
- In final output, it is deleted.
- We recognize Newline - in macro bodies and macro args. */
- if (! concatenated) {
- ident_length = 0;
- hash = 0;
- }
- ibp++;
- if (!output_marks) {
- obp--;
- } else {
- /* If expanding a macro arg, keep the newline -. */
- *obp++ = '-';
- }
- break;
- }
-
- /* If reprocessing a macro expansion, newline is a special marker. */
- else if (ip->macro != 0) {
- /* Newline White is a "funny space" to separate tokens that are
- supposed to be separate but without space between.
- Here White means any whitespace character.
- Newline - marks a recursive macro use that is not
- supposed to be expandable. */
-
- if (is_space[*ibp]) {
- /* Newline Space does not prevent expansion of preceding token
- so expand the preceding token and then come back. */
- if (ident_length > 0)
- goto specialchar;
-
- /* If generating final output, newline space makes a space. */
- if (!output_marks) {
- obp[-1] = *ibp++;
- /* And Newline Newline makes a newline, so count it. */
- if (obp[-1] == '\n')
- op->lineno++;
- } else {
- /* If expanding a macro arg, keep the newline space.
- If the arg gets stringified, newline space makes nothing. */
- *obp++ = *ibp++;
- }
- } else abort (); /* Newline followed by something random? */
- break;
- }
-
- /* If there is a pending identifier, handle it and come back here. */
- if (ident_length > 0)
- goto specialchar;
-
- beg_of_line = ibp;
-
- /* Update the line counts and output a #line if necessary. */
- ++ip->lineno;
- ++op->lineno;
- if (ip->lineno != op->lineno) {
- op->bufp = obp;
- output_line_directive (ip, op, 1, same_file);
- check_expand (op, limit - ibp);
- obp = op->bufp;
- }
- break;
-
- /* Come here either after (1) a null character that is part of the input
- or (2) at the end of the input, because there is a null there. */
- case 0:
- if (ibp <= limit)
- /* Our input really contains a null character. */
- goto randomchar;
-
- limit_reached:
- /* At end of a macro-expansion level, pop it and read next level. */
- if (ip->macro != 0) {
- obp--;
- ibp--;
- /* If traditional, and we have an identifier that ends here,
- process it now, so we get the right error for recursion. */
- if (traditional && ident_length
- && ! is_idchar[*instack[indepth - 1].bufp]) {
- redo_char = 1;
- goto randomchar;
- }
- POPMACRO;
- RECACHE;
- break;
- }
-
- /* If we don't have a pending identifier,
- return at end of input. */
- if (ident_length == 0) {
- obp--;
- ibp--;
- op->bufp = obp;
- ip->bufp = ibp;
- goto ending;
- }
-
- /* If we do have a pending identifier, just consider this null
- a special character and arrange to dispatch on it again.
- The second time, IDENT_LENGTH will be zero so we will return. */
-
- /* Fall through */
-
-specialchar:
-
- /* Handle the case of a character such as /, ', " or null
- seen following an identifier. Back over it so that
- after the identifier is processed the special char
- will be dispatched on again. */
-
- ibp--;
- obp--;
- redo_char = 1;
-
- default:
-
-randomchar:
-
- if (ident_length > 0) {
- register HASHNODE *hp;
-
- /* We have just seen an identifier end. If it's a macro, expand it.
-
- IDENT_LENGTH is the length of the identifier
- and HASH is its hash code.
-
- The identifier has already been copied to the output,
- so if it is a macro we must remove it.
-
- If REDO_CHAR is 0, the char that terminated the identifier
- has been skipped in the output and the input.
- OBP-IDENT_LENGTH-1 points to the identifier.
- If the identifier is a macro, we must back over the terminator.
-
- If REDO_CHAR is 1, the terminating char has already been
- backed over. OBP-IDENT_LENGTH points to the identifier. */
-
- if (!pcp_outfile || pcp_inside_if) {
- for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL;
- hp = hp->next) {
-
- if (hp->length == ident_length) {
- int obufp_before_macroname;
- int op_lineno_before_macroname;
- register int i = ident_length;
- register U_CHAR *p = hp->name;
- register U_CHAR *q = obp - i;
- int disabled;
-
- if (! redo_char)
- q--;
-
- do { /* All this to avoid a strncmp () */
- if (*p++ != *q++)
- goto hashcollision;
- } while (--i);
-
- /* We found a use of a macro name.
- see if the context shows it is a macro call. */
-
- /* Back up over terminating character if not already done. */
- if (! redo_char) {
- ibp--;
- obp--;
- }
-
- /* Save this as a displacement from the beginning of the output
- buffer. We can not save this as a position in the output
- buffer, because it may get realloc'ed by RECACHE. */
- obufp_before_macroname = (obp - op->buf) - ident_length;
- op_lineno_before_macroname = op->lineno;
-
- if (hp->type == T_PCSTRING) {
- pcstring_used (hp); /* Mark the definition of this key
- as needed, ensuring that it
- will be output. */
- break; /* Exit loop, since the key cannot have a
- definition any longer. */
- }
-
- /* Record whether the macro is disabled. */
- disabled = hp->type == T_DISABLED;
-
- /* This looks like a macro ref, but if the macro was disabled,
- just copy its name and put in a marker if requested. */
-
- if (disabled) {
-#if 0
- /* This error check caught useful cases such as
- #define foo(x,y) bar (x (y,0), y)
- foo (foo, baz) */
- if (traditional)
- error ("recursive use of macro `%s'", hp->name);
-#endif
-
- if (output_marks) {
- op->bufp = obp;
- check_expand (op, limit - ibp + 2);
- obp = op->bufp;
- *obp++ = '\n';
- *obp++ = '-';
- }
- break;
- }
-
- /* If macro wants an arglist, verify that a '(' follows.
- first skip all whitespace, copying it to the output
- after the macro name. Then, if there is no '(',
- decide this is not a macro call and leave things that way. */
- if ((hp->type == T_MACRO || hp->type == T_DISABLED)
- && hp->value.defn->nargs >= 0)
- {
- U_CHAR *old_ibp = ibp;
- U_CHAR *old_obp = obp;
- int old_iln = ip->lineno;
- int old_oln = op->lineno;
-
- while (1) {
- /* Scan forward over whitespace, copying it to the output. */
- if (ibp == limit && ip->macro != 0) {
- POPMACRO;
- RECACHE;
- old_ibp = ibp;
- old_obp = obp;
- old_iln = ip->lineno;
- old_oln = op->lineno;
- }
- else if (is_space[*ibp]) {
- *obp++ = *ibp++;
- if (ibp[-1] == '\n') {
- if (ip->macro == 0) {
- /* Newline in a file. Count it. */
- ++ip->lineno;
- ++op->lineno;
- } else if (!output_marks) {
- /* A newline mark, and we don't want marks
- in the output. If it is newline-hyphen,
- discard it entirely. Otherwise, it is
- newline-whitechar, so keep the whitechar. */
- obp--;
- if (*ibp == '-')
- ibp++;
- else {
- if (*ibp == '\n')
- ++op->lineno;
- *obp++ = *ibp++;
- }
- } else {
- /* A newline mark; copy both chars to the output. */
- *obp++ = *ibp++;
- }
- }
- }
- else if (ip->macro)
- break;
- else if (*ibp == '/') {
- /* If a comment, copy it unchanged or discard it. */
- if (ibp[1] == '\\' && ibp[2] == '\n')
- newline_fix (ibp + 1);
- if (ibp[1] == '*') {
- if (put_out_comments) {
- *obp++ = '/';
- *obp++ = '*';
- } else if (! traditional) {
- *obp++ = ' ';
- }
- for (ibp += 2; ibp < limit; ibp++) {
- /* We need not worry about newline-marks,
- since they are never found in comments. */
- if (ibp[0] == '*') {
- if (ibp[1] == '\\' && ibp[2] == '\n')
- newline_fix (ibp + 1);
- if (ibp[1] == '/') {
- ibp += 2;
- if (put_out_comments) {
- *obp++ = '*';
- *obp++ = '/';
- }
- break;
- }
- }
- else if (*ibp == '\n') {
- /* Newline in a file. Count it. */
- ++ip->lineno;
- ++op->lineno;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- if (put_out_comments)
- {
- bcopy (ibp, obp, length - 1);
- obp += length - 1;
- }
- ibp += (length - 1);
- }
-#endif
- }
- if (put_out_comments)
- *obp++ = *ibp;
- }
- } else if (ibp[1] == '/' && cplusplus_comments) {
- if (put_out_comments) {
- *obp++ = '/';
- *obp++ = '/';
- } else if (! traditional) {
- *obp++ = ' ';
- }
- for (ibp += 2; ; ibp++)
- {
- if (*ibp == '\n')
- break;
- if (*ibp == '\\' && ibp[1] == '\n')
- {
- if (put_out_comments)
- *obp++ = *ibp++;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- if (put_out_comments)
- {
- bcopy (ibp, obp, length - 1);
- obp += length - 1;
- }
- ibp += (length - 1);
- }
-#endif
- }
- if (put_out_comments)
- *obp++ = *ibp;
- }
- } else
- break;
- }
- else if (ibp[0] == '\\' && ibp[1] == '\n') {
- ibp += 2;
- ++ip->lineno;
- }
- else break;
- }
- if (*ibp != '(') {
- /* It isn't a macro call.
- Put back the space that we just skipped. */
- ibp = old_ibp;
- obp = old_obp;
- ip->lineno = old_iln;
- op->lineno = old_oln;
- /* Exit the for loop. */
- break;
- }
- }
-
- /* This is now known to be a macro call.
- Discard the macro name from the output,
- along with any following whitespace just copied,
- but preserve newlines if not outputting marks since this
- is more likely to do the right thing with line numbers. */
- obp = op->buf + obufp_before_macroname;
- if (output_marks)
- op->lineno = op_lineno_before_macroname;
- else {
- int newlines = op->lineno - op_lineno_before_macroname;
- while (0 < newlines--)
- *obp++ = '\n';
- }
-
- /* Prevent accidental token-pasting with a character
- before the macro call. */
- if (!traditional && obp != op->buf) {
- switch (obp[-1]) {
- case '!': case '%': case '&': case '*':
- case '+': case '-': case '.': case '/':
- case ':': case '<': case '=': case '>':
- case '^': case '|':
- /* If we are expanding a macro arg, make a newline marker
- to separate the tokens. If we are making real output,
- a plain space will do. */
- if (output_marks)
- *obp++ = '\n';
- *obp++ = ' ';
- }
- }
-
- /* Expand the macro, reading arguments as needed,
- and push the expansion on the input stack. */
- ip->bufp = ibp;
- op->bufp = obp;
- macroexpand (hp, op);
-
- /* Reexamine input stack, since macroexpand has pushed
- a new level on it. */
- obp = op->bufp;
- RECACHE;
- break;
- }
-hashcollision:
- ;
- } /* End hash-table-search loop */
- }
- ident_length = hash = 0; /* Stop collecting identifier */
- redo_char = 0;
- concatenated = 0;
- } /* End if (ident_length > 0) */
- } /* End switch */
- } /* End per-char loop */
-
- /* Come here to return -- but first give an error message
- if there was an unterminated successful conditional. */
- ending:
- if (if_stack != ip->if_stack)
- {
- char *str;
-
- switch (if_stack->type)
- {
- case T_IF:
- str = "if";
- break;
- case T_IFDEF:
- str = "ifdef";
- break;
- case T_IFNDEF:
- str = "ifndef";
- break;
- case T_ELSE:
- str = "else";
- break;
- case T_ELIF:
- str = "elif";
- break;
- default:
- abort ();
- }
-
- error_with_line (line_for_error (if_stack->lineno),
- "unterminated `#%s' conditional", str);
- }
- if_stack = ip->if_stack;
-}
-
-/*
- * Rescan a string into a temporary buffer and return the result
- * as a FILE_BUF. Note this function returns a struct, not a pointer.
- *
- * OUTPUT_MARKS nonzero means keep Newline markers found in the input
- * and insert such markers when appropriate. See `rescan' for details.
- * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately
- * before substitution; it is 0 for other uses.
- */
-static FILE_BUF
-expand_to_temp_buffer (buf, limit, output_marks, assertions)
- U_CHAR *buf, *limit;
- int output_marks, assertions;
-{
- register FILE_BUF *ip;
- FILE_BUF obuf;
- int length = limit - buf;
- U_CHAR *buf1;
- int odepth = indepth;
- int save_assertions_flag = assertions_flag;
-
- assertions_flag = assertions;
-
- if (length < 0)
- abort ();
-
- /* Set up the input on the input stack. */
-
- buf1 = (U_CHAR *) alloca (length + 1);
- {
- register U_CHAR *p1 = buf;
- register U_CHAR *p2 = buf1;
-
- while (p1 != limit)
- *p2++ = *p1++;
- }
- buf1[length] = 0;
-
- /* Set up to receive the output. */
-
- obuf.length = length * 2 + 100; /* Usually enough. Why be stingy? */
- obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
- obuf.nominal_fname = 0;
- obuf.inc = 0;
- obuf.dir = 0;
- obuf.fname = 0;
- obuf.macro = 0;
- obuf.if_stack = 0;
- obuf.free_ptr = 0;
- obuf.system_header_p = 0;
-
- CHECK_DEPTH ({return obuf;});
-
- ++indepth;
-
- ip = &instack[indepth];
- ip->fname = 0;
- ip->nominal_fname = 0;
- ip->nominal_fname_len = 0;
- ip->inc = 0;
- ip->system_header_p = 0;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->length = length;
- ip->buf = ip->bufp = buf1;
- ip->if_stack = if_stack;
-
- ip->lineno = obuf.lineno = 1;
-
- /* Scan the input, create the output. */
- rescan (&obuf, output_marks);
-
- /* Pop input stack to original state. */
- --indepth;
-
- if (indepth != odepth)
- abort ();
-
- /* Record the output. */
- obuf.length = obuf.bufp - obuf.buf;
-
- assertions_flag = save_assertions_flag;
- return obuf;
-}
-
-/*
- * Process a # directive. Expects IP->bufp to point after the '#', as in
- * `#define foo bar'. Passes to the directive handler
- * (do_define, do_include, etc.): the addresses of the 1st and
- * last chars of the directive (starting immediately after the #
- * keyword), plus op and the keyword table pointer. If the directive
- * contains comments it is copied into a temporary buffer sans comments
- * and the temporary buffer is passed to the directive handler instead.
- * Likewise for backslash-newlines.
- *
- * Returns nonzero if this was a known # directive.
- * Otherwise, returns zero, without advancing the input pointer.
- */
-
-static int
-handle_directive (ip, op)
- FILE_BUF *ip, *op;
-{
- register U_CHAR *bp, *cp;
- register struct directive *kt;
- register int ident_length;
- U_CHAR *resume_p;
-
- /* Nonzero means we must copy the entire directive
- to get rid of comments or backslash-newlines. */
- int copy_directive = 0;
-
- U_CHAR *ident, *after_ident;
-
- bp = ip->bufp;
-
- /* Record where the directive started. do_xifdef needs this. */
- directive_start = bp - 1;
-
- ignore_escape_flag = 1;
-
- /* Skip whitespace and \-newline. */
- while (1) {
- if (is_hor_space[*bp]) {
- if (*bp != ' ' && *bp != '\t' && pedantic)
- pedwarn_strange_white_space (*bp);
- bp++;
- } else if (*bp == '/') {
- if (bp[1] == '\\' && bp[2] == '\n')
- newline_fix (bp + 1);
- if (! (bp[1] == '*' || (cplusplus_comments && bp[1] == '/')))
- break;
- ip->bufp = bp + 2;
- skip_to_end_of_comment (ip, &ip->lineno, 0);
- bp = ip->bufp;
- } else if (*bp == '\\' && bp[1] == '\n') {
- bp += 2; ip->lineno++;
- } else break;
- }
-
- /* Now find end of directive name.
- If we encounter a backslash-newline, exchange it with any following
- symbol-constituents so that we end up with a contiguous name. */
-
- cp = bp;
- while (1) {
- if (is_idchar[*cp])
- cp++;
- else {
- if (*cp == '\\' && cp[1] == '\n')
- name_newline_fix (cp);
- if (is_idchar[*cp])
- cp++;
- else break;
- }
- }
- ident_length = cp - bp;
- ident = bp;
- after_ident = cp;
-
- /* A line of just `#' becomes blank. */
-
- if (ident_length == 0 && *after_ident == '\n') {
- ip->bufp = after_ident;
- return 1;
- }
-
- if (ident_length == 0 || !is_idstart[*ident]) {
- U_CHAR *p = ident;
- while (is_idchar[*p]) {
- if (*p < '0' || *p > '9')
- break;
- p++;
- }
- /* Handle # followed by a line number. */
- if (p != ident && !is_idchar[*p]) {
- static struct directive line_directive_table[] = {
- { 4, do_line, "line", T_LINE},
- };
- if (pedantic)
- pedwarn ("`#' followed by integer");
- after_ident = ident;
- kt = line_directive_table;
- ignore_escape_flag = 0;
- goto old_linenum;
- }
-
- /* Avoid error for `###' and similar cases unless -pedantic. */
- if (p == ident) {
- while (*p == '#' || is_hor_space[*p]) p++;
- if (*p == '\n') {
- if (pedantic && !lang_asm)
- warning ("invalid preprocessing directive");
- return 0;
- }
- }
-
- if (!lang_asm)
- error ("invalid preprocessing directive name");
-
- return 0;
- }
-
- /*
- * Decode the keyword and call the appropriate expansion
- * routine, after moving the input pointer up to the next line.
- */
- for (kt = directive_table; kt->length > 0; kt++) {
- if (kt->length == ident_length && !bcmp (kt->name, ident, ident_length)) {
- register U_CHAR *buf;
- register U_CHAR *limit;
- int unterminated;
- int junk;
- int *already_output;
-
- /* Nonzero means do not delete comments within the directive.
- #define needs this when -traditional. */
- int keep_comments;
-
- old_linenum:
-
- limit = ip->buf + ip->length;
- unterminated = 0;
- already_output = 0;
- keep_comments = traditional && kt->type == T_DEFINE;
- /* #import is defined only in Objective C, or when on the NeXT. */
- if (kt->type == T_IMPORT
- && !(objc || lookup ((U_CHAR *) "__NeXT__", -1, -1)))
- break;
-
- /* Find the end of this directive (first newline not backslashed
- and not in a string or comment).
- Set COPY_DIRECTIVE if the directive must be copied
- (it contains a backslash-newline or a comment). */
-
- buf = bp = after_ident;
- while (bp < limit) {
- register U_CHAR c = *bp++;
- switch (c) {
- case '\\':
- if (bp < limit) {
- if (*bp == '\n') {
- ip->lineno++;
- copy_directive = 1;
- bp++;
- } else if (traditional)
- bp++;
- }
- break;
-
- case '"':
- /* "..." is special for #include. */
- if (IS_INCLUDE_DIRECTIVE_TYPE (kt->type)) {
- while (bp < limit && *bp != '\n') {
- if (*bp == '"') {
- bp++;
- break;
- }
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- copy_directive = 1;
- bp++;
- }
- bp++;
- }
- break;
- }
- /* Fall through. */
- case '\'':
- bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, &copy_directive, &unterminated);
- /* Don't bother calling the directive if we already got an error
- message due to unterminated string. Skip everything and pretend
- we called the directive. */
- if (unterminated) {
- if (traditional) {
- /* Traditional preprocessing permits unterminated strings. */
- ip->bufp = bp;
- goto endloop1;
- }
- ip->bufp = bp;
- return 1;
- }
- break;
-
- /* <...> is special for #include. */
- case '<':
- if (! IS_INCLUDE_DIRECTIVE_TYPE (kt->type))
- break;
- while (bp < limit && *bp != '>' && *bp != '\n') {
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- copy_directive = 1;
- bp++;
- }
- bp++;
- }
- break;
-
- case '/':
- if (*bp == '\\' && bp[1] == '\n')
- newline_fix (bp);
- if (*bp == '*'
- || (cplusplus_comments && *bp == '/')) {
- U_CHAR *obp = bp - 1;
- ip->bufp = bp + 1;
- skip_to_end_of_comment (ip, &ip->lineno, 0);
- bp = ip->bufp;
- /* No need to copy the directive because of a comment at the end;
- just don't include the comment in the directive. */
- if (!put_out_comments) {
- U_CHAR *p;
- for (p = bp; *p == ' ' || *p == '\t'; p++)
- continue;
- if (*p == '\n') {
- bp = obp;
- goto endloop1;
- }
- }
- /* Don't remove the comments if -traditional. */
- if (! keep_comments)
- copy_directive++;
- }
- break;
-
- case '\f':
- case '\r':
- case '\v':
- if (pedantic)
- pedwarn_strange_white_space (c);
- break;
-
- case '\n':
- --bp; /* Point to the newline */
- ip->bufp = bp;
- goto endloop1;
- }
- }
- ip->bufp = bp;
-
- endloop1:
- resume_p = ip->bufp;
- /* BP is the end of the directive.
- RESUME_P is the next interesting data after the directive.
- A comment may come between. */
-
- /* If a directive should be copied through, and -C was given,
- pass it through before removing comments. */
- if (!no_output && put_out_comments
- && ((kt->type == T_DEFINE || kt->type == T_UNDEF)
- ? dump_macros == dump_definitions
- : IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes
- : kt->type == T_PRAGMA)) {
- int len;
-
- /* Output directive name. */
- check_expand (op, kt->length + 2);
- /* Make sure # is at the start of a line */
- if (op->bufp > op->buf && op->bufp[-1] != '\n') {
- op->lineno++;
- *op->bufp++ = '\n';
- }
- *op->bufp++ = '#';
- bcopy (kt->name, op->bufp, kt->length);
- op->bufp += kt->length;
-
- /* Output arguments. */
- len = (bp - buf);
- check_expand (op, len);
- bcopy (buf, (char *) op->bufp, len);
- op->bufp += len;
- /* Take account of any (escaped) newlines just output. */
- while (--len >= 0)
- if (buf[len] == '\n')
- op->lineno++;
-
- already_output = &junk;
- } /* Don't we need a newline or #line? */
-
- if (copy_directive) {
- register U_CHAR *xp = buf;
- /* Need to copy entire directive into temp buffer before dispatching */
-
- cp = (U_CHAR *) alloca (bp - buf + 5); /* room for directive plus
- some slop */
- buf = cp;
-
- /* Copy to the new buffer, deleting comments
- and backslash-newlines (and whitespace surrounding the latter). */
-
- while (xp < bp) {
- register U_CHAR c = *xp++;
- *cp++ = c;
-
- switch (c) {
- case '\n':
- abort (); /* A bare newline should never part of the line. */
- break;
-
- /* <...> is special for #include. */
- case '<':
- if (! IS_INCLUDE_DIRECTIVE_TYPE (kt->type))
- break;
- while (xp < bp && c != '>') {
- c = *xp++;
- if (c == '\\' && xp < bp && *xp == '\n')
- xp++;
- else
- *cp++ = c;
- }
- break;
-
- case '\\':
- if (*xp == '\n') {
- xp++;
- cp--;
- if (cp != buf && is_hor_space[cp[-1]]) {
- while (cp - 1 != buf && is_hor_space[cp[-2]])
- cp--;
- SKIP_WHITE_SPACE (xp);
- } else if (is_hor_space[*xp]) {
- *cp++ = *xp++;
- SKIP_WHITE_SPACE (xp);
- }
- } else if (traditional && xp < bp) {
- *cp++ = *xp++;
- }
- break;
-
- case '\'':
- case '\"':
- {
- int backslash_newlines_p = 0;
-
- register U_CHAR *bp1
- = skip_quoted_string (xp - 1, bp, ip->lineno,
- NULL_PTR, &backslash_newlines_p,
- NULL_PTR);
- if (backslash_newlines_p)
- while (xp != bp1)
- {
- /* With something like:
-
- #define X "a\
- b"
-
- we should still remove the backslash-newline
- pair as part of phase two. */
- if (xp[0] == '\\' && xp[1] == '\n')
- xp += 2;
- else
- *cp++ = *xp++;
- }
- else
- /* This is the same as the loop above, but taking
- advantage of the fact that we know there are no
- backslash-newline pairs. */
- while (xp != bp1)
- *cp++ = *xp++;
- }
- break;
-
- case '/':
- if (*xp == '*'
- || (cplusplus_comments && *xp == '/')) {
- ip->bufp = xp + 1;
- /* If we already copied the directive through,
- already_output != 0 prevents outputting comment now. */
- skip_to_end_of_comment (ip, already_output, 0);
- if (keep_comments)
- while (xp != ip->bufp)
- *cp++ = *xp++;
- /* Delete or replace the slash. */
- else if (traditional)
- cp--;
- else
- cp[-1] = ' ';
- xp = ip->bufp;
- }
- }
- }
-
- /* Null-terminate the copy. */
-
- *cp = 0;
- } else
- cp = bp;
-
- ip->bufp = resume_p;
-
- /* Some directives should be written out for cc1 to process,
- just as if they were not defined. And sometimes we're copying
- directives through. */
-
- if (!no_output && already_output == 0
- && (kt->type == T_DEFINE ? (int) dump_names <= (int) dump_macros
- : IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes
- : kt->type == T_PRAGMA)) {
- int len;
-
- /* Output directive name. */
- check_expand (op, kt->length + 1);
- *op->bufp++ = '#';
- bcopy (kt->name, (char *) op->bufp, kt->length);
- op->bufp += kt->length;
-
- if (kt->type == T_DEFINE && dump_macros == dump_names) {
- /* Output `#define name' only. */
- U_CHAR *xp = buf;
- U_CHAR *yp;
- SKIP_WHITE_SPACE (xp);
- yp = xp;
- while (is_idchar[*xp]) xp++;
- len = (xp - yp);
- check_expand (op, len + 1);
- *op->bufp++ = ' ';
- bcopy (yp, (char *) op->bufp, len);
- } else {
- /* Output entire directive. */
- len = (cp - buf);
- check_expand (op, len);
- bcopy (buf, (char *) op->bufp, len);
- }
- op->bufp += len;
- } /* Don't we need a newline or #line? */
-
- /* Call the appropriate directive handler. buf now points to
- either the appropriate place in the input buffer, or to
- the temp buffer if it was necessary to make one. cp
- points to the first char after the contents of the (possibly
- copied) directive, in either case. */
- (*kt->func) (buf, cp, op, kt);
- check_expand (op, ip->length - (ip->bufp - ip->buf));
-
- return 1;
- }
- }
-
- /* It is deliberate that we don't warn about undefined directives.
- That is the responsibility of cc1. */
- return 0;
-}
-
-static struct tm *
-timestamp ()
-{
- static struct tm *timebuf;
- if (!timebuf) {
- time_t t = time ((time_t *) 0);
- timebuf = localtime (&t);
- }
- return timebuf;
-}
-
-static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
-
-/*
- * expand things like __FILE__. Place the expansion into the output
- * buffer *without* rescanning.
- */
-
-static void
-special_symbol (hp, op)
- HASHNODE *hp;
- FILE_BUF *op;
-{
- char *buf;
- int i, len;
- int true_indepth;
- FILE_BUF *ip = NULL;
- struct tm *timebuf;
-
- int paren = 0; /* For special `defined' keyword */
-
- if (pcp_outfile && pcp_inside_if
- && hp->type != T_SPEC_DEFINED && hp->type != T_CONST)
- error ("Predefined macro `%s' used inside `#if' during precompilation",
- hp->name);
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
- if (ip == NULL) {
- error ("cccp error: not in any file?!");
- return; /* the show must go on */
- }
-
- switch (hp->type) {
- case T_FILE:
- case T_BASE_FILE:
- {
- FILE_BUF *p = hp->type == T_FILE ? ip : &instack[0];
- char *string = p->nominal_fname;
-
- if (string)
- {
- size_t string_len = p->nominal_fname_len;
- buf = (char *) alloca (3 + 4 * string_len);
- quote_string (buf, string, string_len);
- }
- else
- buf = "\"\"";
-
- break;
- }
-
- case T_INCLUDE_LEVEL:
- true_indepth = 0;
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL)
- true_indepth++;
-
- buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */
- sprintf (buf, "%d", true_indepth - 1);
- break;
-
- case T_VERSION:
- buf = (char *) alloca (3 + strlen (version_string));
- sprintf (buf, "\"%s\"", version_string);
- break;
-
-#ifndef NO_BUILTIN_SIZE_TYPE
- case T_SIZE_TYPE:
- buf = SIZE_TYPE;
- break;
-#endif
-
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- case T_PTRDIFF_TYPE:
- buf = PTRDIFF_TYPE;
- break;
-#endif
-
- case T_WCHAR_TYPE:
- buf = wchar_type;
- break;
-
- case T_USER_LABEL_PREFIX_TYPE:
- buf = user_label_prefix;
- break;
-
- case T_REGISTER_PREFIX_TYPE:
- buf = REGISTER_PREFIX;
- break;
-
- case T_IMMEDIATE_PREFIX_TYPE:
- buf = IMMEDIATE_PREFIX;
- break;
-
- case T_CONST:
- buf = hp->value.cpval;
-#ifdef STDC_0_IN_SYSTEM_HEADERS
- if (ip->system_header_p
- && hp->length == 8 && bcmp (hp->name, "__STDC__", 8) == 0
- && !lookup ((U_CHAR *) "__STRICT_ANSI__", -1, -1))
- buf = "0";
-#endif
- if (pcp_inside_if && pcp_outfile)
- /* Output a precondition for this macro use */
- fprintf (pcp_outfile, "#define %s %s\n", hp->name, buf);
- break;
-
- case T_SPECLINE:
- buf = (char *) alloca (10);
- sprintf (buf, "%d", ip->lineno);
- break;
-
- case T_DATE:
- case T_TIME:
- buf = (char *) alloca (20);
- timebuf = timestamp ();
- if (hp->type == T_DATE)
- sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
- timebuf->tm_mday, timebuf->tm_year + 1900);
- else
- sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
- timebuf->tm_sec);
- break;
-
- case T_SPEC_DEFINED:
- buf = " 0 "; /* Assume symbol is not defined */
- ip = &instack[indepth];
- SKIP_WHITE_SPACE (ip->bufp);
- if (*ip->bufp == '(') {
- paren++;
- ip->bufp++; /* Skip over the paren */
- SKIP_WHITE_SPACE (ip->bufp);
- }
-
- if (!is_idstart[*ip->bufp])
- goto oops;
- if (ip->bufp[0] == 'L' && (ip->bufp[1] == '\'' || ip->bufp[1] == '"'))
- goto oops;
- if ((hp = lookup (ip->bufp, -1, -1))) {
- if (pcp_outfile && pcp_inside_if
- && (hp->type == T_CONST
- || (hp->type == T_MACRO && hp->value.defn->predefined)))
- /* Output a precondition for this macro use. */
- fprintf (pcp_outfile, "#define %s\n", hp->name);
- buf = " 1 ";
- }
- else
- if (pcp_outfile && pcp_inside_if) {
- /* Output a precondition for this macro use */
- U_CHAR *cp = ip->bufp;
- fprintf (pcp_outfile, "#undef ");
- while (is_idchar[*cp]) /* Ick! */
- fputc (*cp++, pcp_outfile);
- putc ('\n', pcp_outfile);
- }
- while (is_idchar[*ip->bufp])
- ++ip->bufp;
- SKIP_WHITE_SPACE (ip->bufp);
- if (paren) {
- if (*ip->bufp != ')')
- goto oops;
- ++ip->bufp;
- }
- break;
-
-oops:
-
- error ("`defined' without an identifier");
- break;
-
- default:
- error ("cccp error: invalid special hash type"); /* time for gdb */
- abort ();
- }
- len = strlen (buf);
- check_expand (op, len);
- bcopy (buf, (char *) op->bufp, len);
- op->bufp += len;
-
- return;
-}
-
-
-/* Routines to handle #directives */
-
-/* Handle #include and #import.
- This function expects to see "fname" or <fname> on the input. */
-
-static int
-do_include (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- U_CHAR *importing = keyword->type == T_IMPORT ? (U_CHAR *) "" : (U_CHAR *) 0;
- int skip_dirs = (keyword->type == T_INCLUDE_NEXT);
- static int import_warning = 0;
- char *fname; /* Dynamically allocated fname buffer */
- char *pcftry;
- char *pcfname;
- char *fbeg, *fend; /* Beginning and end of fname */
- U_CHAR *fin;
-
- struct file_name_list *search_start = include; /* Chain of dirs to search */
- struct file_name_list *dsp; /* First in chain, if #include "..." */
- struct file_name_list *searchptr = 0;
- size_t flen;
-
- int f = -3; /* file number */
- struct include_file *inc = 0;
-
- int retried = 0; /* Have already tried macro
- expanding the include line*/
- int angle_brackets = 0; /* 0 for "...", 1 for <...> */
-#ifdef VMS
- int vaxc_include = 0; /* 1 for token without punctuation */
-#endif
- int pcf = -1;
- char *pcfbuf;
- char *pcfbuflimit;
- int pcfnum;
-
- if (pedantic && !instack[indepth].system_header_p)
- {
- if (importing)
- pedwarn ("ANSI C does not allow `#import'");
- if (skip_dirs)
- pedwarn ("ANSI C does not allow `#include_next'");
- }
-
- if (importing && warn_import && !inhibit_warnings
- && !instack[indepth].system_header_p && !import_warning) {
- import_warning = 1;
- warning ("using `#import' is not recommended");
- notice ("The fact that a certain header file need not be processed more than once\n\
-should be indicated in the header file, not where it is used.\n\
-The best way to do this is with a conditional of this form:\n\
-\n\
- #ifndef _FOO_H_INCLUDED\n\
- #define _FOO_H_INCLUDED\n\
- ... <real contents of file> ...\n\
- #endif /* Not _FOO_H_INCLUDED */\n\
-\n\
-Then users can use `#include' any number of times.\n\
-GNU C automatically avoids processing the file more than once\n\
-when it is equipped with such a conditional.\n");
- }
-
-get_filename:
-
- fin = buf;
- SKIP_WHITE_SPACE (fin);
- /* Discard trailing whitespace so we can easily see
- if we have parsed all the significant chars we were given. */
- while (limit != fin && is_hor_space[limit[-1]]) limit--;
- fbeg = fend = (char *) alloca (limit - fin);
-
- switch (*fin++) {
- case '\"':
- {
- FILE_BUF *fp;
- /* Copy the operand text, concatenating the strings. */
- {
- for (;;) {
- for (;;) {
- if (fin == limit)
- goto invalid_include_file_name;
- *fend = *fin++;
- if (*fend == '"')
- break;
- fend++;
- }
- if (fin == limit)
- break;
- /* If not at the end, there had better be another string. */
- /* Skip just horiz space, and don't go past limit. */
- while (fin != limit && is_hor_space[*fin]) fin++;
- if (fin != limit && *fin == '\"')
- fin++;
- else
- goto fail;
- }
- }
-
- /* We have "filename". Figure out directory this source
- file is coming from and put it on the front of the list. */
-
- /* If -I- was specified, don't search current dir, only spec'd ones. */
- if (ignore_srcdir) break;
-
- for (fp = &instack[indepth]; fp >= instack; fp--)
- {
- int n;
- char *nam;
-
- if ((nam = fp->nominal_fname) != NULL) {
- /* Found a named file. Figure out dir of the file,
- and put it in front of the search list. */
- dsp = ((struct file_name_list *)
- alloca (sizeof (struct file_name_list)
- + fp->nominal_fname_len));
- strcpy (dsp->fname, nam);
- simplify_filename (dsp->fname);
- nam = base_name (dsp->fname);
- *nam = 0;
-#ifdef VMS
- /* for hack_vms_include_specification(), a local
- dir specification must start with "./" on VMS. */
- if (nam == dsp->fname)
- {
- *nam++ = '.';
- *nam++ = '/';
- *nam = 0;
- }
-#endif
- /* But for efficiency's sake, do not insert the dir
- if it matches the search list's first dir. */
- dsp->next = search_start;
- if (!search_start || strcmp (dsp->fname, search_start->fname)) {
- search_start = dsp;
- n = nam - dsp->fname;
- if (n + INCLUDE_LEN_FUDGE > max_include_len)
- max_include_len = n + INCLUDE_LEN_FUDGE;
- }
- dsp[0].got_name_map = 0;
- break;
- }
- }
- break;
- }
-
- case '<':
- while (fin != limit && *fin != '>')
- *fend++ = *fin++;
- if (*fin == '>' && fin + 1 == limit) {
- angle_brackets = 1;
- /* If -I-, start with the first -I dir after the -I-. */
- search_start = first_bracket_include;
- break;
- }
- goto fail;
-
- default:
-#ifdef VMS
- /*
- * Support '#include xyz' like VAX-C to allow for easy use of all the
- * decwindow include files. It defaults to '#include <xyz.h>' (so the
- * code from case '<' is repeated here) and generates a warning.
- * (Note: macro expansion of `xyz' takes precedence.)
- */
- /* Note: The argument of ISALPHA() can be evaluated twice, so do
- the pre-decrement outside of the macro. */
- if (retried && (--fin, ISALPHA(*(U_CHAR *) (fin)))) {
- while (fin != limit && (!ISSPACE(*fin)))
- *fend++ = *fin++;
- warning ("VAX-C-style include specification found, use '#include <filename.h>' !");
- vaxc_include = 1;
- if (fin == limit) {
- angle_brackets = 1;
- /* If -I-, start with the first -I dir after the -I-. */
- search_start = first_bracket_include;
- break;
- }
- }
-#endif
-
- fail:
- if (! retried) {
- /* Expand buffer and then remove any newline markers.
- We can't just tell expand_to_temp_buffer to omit the markers,
- since it would put extra spaces in include file names. */
- FILE_BUF trybuf;
- U_CHAR *src;
- int errors_before_expansion = errors;
- trybuf = expand_to_temp_buffer (buf, limit, 1, 0);
- if (errors != errors_before_expansion) {
- free (trybuf.buf);
- goto invalid_include_file_name;
- }
- src = trybuf.buf;
- buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
- limit = buf;
- while (src != trybuf.bufp) {
- switch ((*limit++ = *src++)) {
- case '\n':
- limit--;
- src++;
- break;
-
- case '\'':
- case '\"':
- {
- U_CHAR *src1 = skip_quoted_string (src - 1, trybuf.bufp, 0,
- NULL_PTR, NULL_PTR, NULL_PTR);
- while (src != src1)
- *limit++ = *src++;
- }
- break;
- }
- }
- *limit = 0;
- free (trybuf.buf);
- retried = 1;
- goto get_filename;
- }
-
- invalid_include_file_name:
- error ("`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name);
- return 0;
- }
-
- /* For #include_next, skip in the search path
- past the dir in which the containing file was found. */
- if (skip_dirs) {
- FILE_BUF *fp;
- for (fp = &instack[indepth]; fp >= instack; fp--)
- if (fp->fname != NULL) {
- /* fp->dir is null if the containing file was specified
- with an absolute file name. In that case, don't skip anything. */
- if (fp->dir)
- search_start = fp->dir->next;
- break;
- }
- }
-
- *fend = 0;
- flen = simplify_filename (fbeg);
-
- if (flen == 0)
- {
- error ("empty file name in `#%s'", keyword->name);
- return 0;
- }
-
- /* Allocate this permanently, because it gets stored in the definitions
- of macros. */
- fname = xmalloc (max_include_len + flen + 1);
- /* + 1 above for terminating null. */
-
- system_include_depth += angle_brackets;
-
- /* If specified file name is absolute, just open it. */
-
- if (absolute_filename (fbeg)) {
- strcpy (fname, fbeg);
- f = open_include_file (fname, NULL_PTR, importing, &inc);
- } else {
-
- struct bypass_dir {
- struct bypass_dir *next;
- char *fname;
- struct file_name_list *searchptr;
- } **bypass_slot = 0;
-
- /* Search directory path, trying to open the file.
- Copy each filename tried into FNAME. */
-
- for (searchptr = search_start; searchptr; searchptr = searchptr->next) {
-
- if (searchptr == first_bracket_include) {
- /* Go to bypass directory if we know we've seen this file before. */
- static struct bypass_dir *bypass_hashtab[INCLUDE_HASHSIZE];
- struct bypass_dir *p;
- bypass_slot = &bypass_hashtab[hashf ((U_CHAR *) fbeg, flen,
- INCLUDE_HASHSIZE)];
- for (p = *bypass_slot; p; p = p->next)
- if (!strcmp (fbeg, p->fname)) {
- searchptr = p->searchptr;
- bypass_slot = 0;
- break;
- }
- }
-
-#ifdef VMS
- /* Change this 1/2 Unix 1/2 VMS file specification into a
- full VMS file specification */
- if (searchptr->fname[0])
- {
- strcpy (fname, searchptr->fname);
- if (fname[strlen (fname) - 1] == ':')
- {
- char *slashp;
- slashp = strchr (fbeg, '/');
-
- /* start at root-dir of logical device if no path given. */
- if (slashp == 0)
- strcat (fname, "[000000]");
- }
- strcat (fname, fbeg);
-
- /* Fix up the filename */
- hack_vms_include_specification (fname, vaxc_include);
- }
- else
- {
- /* This is a normal VMS filespec, so use it unchanged. */
- strcpy (fname, fbeg);
- /* if it's '#include filename', add the missing .h */
- if (vaxc_include && index(fname,'.')==NULL)
- strcat (fname, ".h");
- }
-#else
- strcpy (fname, searchptr->fname);
- strcat (fname, fbeg);
-#endif /* VMS */
- f = open_include_file (fname, searchptr, importing, &inc);
- if (f != -1) {
- if (bypass_slot && searchptr != first_bracket_include) {
- /* This is the first time we found this include file,
- and we found it after first_bracket_include.
- Record its location so that we can bypass to here next time. */
- struct bypass_dir *p
- = (struct bypass_dir *) xmalloc (sizeof (struct bypass_dir));
- p->next = *bypass_slot;
- p->fname = fname + strlen (searchptr->fname);
- p->searchptr = searchptr;
- *bypass_slot = p;
- }
- break;
- }
-#ifdef VMS
- /* Our VMS hacks can produce invalid filespecs, so don't worry
- about errors other than EACCES. */
- if (errno == EACCES)
- break;
-#else
- if (errno != ENOENT && errno != ENOTDIR)
- break;
-#endif
- }
- }
-
-
- if (f < 0) {
-
- if (f == -2) {
- /* The file was already included. */
-
- /* If generating dependencies and -MG was specified, we assume missing
- files are leaf files, living in the same directory as the source file
- or other similar place; these missing files may be generated from
- other files and may not exist yet (eg: y.tab.h). */
- } else if (print_deps_missing_files
- && (system_include_depth != 0) < print_deps)
- {
- /* If it was requested as a system header file,
- then assume it belongs in the first place to look for such. */
- if (angle_brackets)
- {
- if (search_start) {
- char *p = (char *) alloca (strlen (search_start->fname)
- + strlen (fbeg) + 1);
- strcpy (p, search_start->fname);
- strcat (p, fbeg);
- deps_output (p, ' ');
- }
- }
- else
- {
- /* Otherwise, omit the directory, as if the file existed
- in the directory with the source. */
- deps_output (fbeg, ' ');
- }
- }
- /* If -M was specified, and this header file won't be added to the
- dependency list, then don't count this as an error, because we can
- still produce correct output. Otherwise, we can't produce correct
- output, because there may be dependencies we need inside the missing
- file, and we don't know what directory this missing file exists in. */
- else if (0 < print_deps && print_deps <= (system_include_depth != 0))
- warning ("No include path in which to find %s", fbeg);
- else if (f != -3)
- error_from_errno (fbeg);
- else
- error ("No include path in which to find %s", fbeg);
-
- } else {
-
- /* Actually process the file. */
-
- pcftry = (char *) alloca (strlen (fname) + 30);
- pcfbuf = 0;
- pcfnum = 0;
-
- if (!no_precomp)
- {
- do {
- sprintf (pcftry, "%s%d", fname, pcfnum++);
-
- pcf = open (pcftry, O_RDONLY, 0666);
- if (pcf != -1)
- {
- struct stat s;
-
- if (fstat (pcf, &s) != 0)
- pfatal_with_name (pcftry);
- if (! INO_T_EQ (inc->st.st_ino, s.st_ino)
- || inc->st.st_dev != s.st_dev)
- {
- pcfbuf = check_precompiled (pcf, &s, fname, &pcfbuflimit);
- /* Don't need it any more. */
- close (pcf);
- }
- else
- {
- /* Don't need it at all. */
- close (pcf);
- break;
- }
- }
- } while (pcf != -1 && !pcfbuf);
- }
-
- /* Actually process the file */
- if (pcfbuf) {
- pcfname = xmalloc (strlen (pcftry) + 1);
- strcpy (pcfname, pcftry);
- pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) fname, op);
- }
- else
- finclude (f, inc, op, is_system_include (fname), searchptr);
- }
-
- system_include_depth -= angle_brackets;
-
- return 0;
-}
-
-/* Return nonzero if the given FILENAME is an absolute pathname which
- designates a file within one of the known "system" include file
- directories. We assume here that if the given FILENAME looks like
- it is the name of a file which resides either directly in a "system"
- include file directory, or within any subdirectory thereof, then the
- given file must be a "system" include file. This function tells us
- if we should suppress pedantic errors/warnings for the given FILENAME.
-
- The value is 2 if the file is a C-language system header file
- for which C++ should (on most systems) assume `extern "C"'. */
-
-static int
-is_system_include (filename)
- register char *filename;
-{
- struct file_name_list *searchptr;
-
- for (searchptr = first_system_include; searchptr;
- searchptr = searchptr->next)
- if (! strncmp (searchptr->fname, filename, strlen (searchptr->fname)))
- return searchptr->c_system_include_path + 1;
- return 0;
-}
-
-/* Yield the non-directory suffix of a file name. */
-
-static char *
-base_name (fname)
- char *fname;
-{
- char *s = fname;
- char *p;
-#if defined (__MSDOS__) || defined (_WIN32)
- if (ISALPHA (s[0]) && s[1] == ':') s += 2;
-#endif
-#ifdef VMS
- if ((p = rindex (s, ':'))) s = p + 1; /* Skip device. */
- if ((p = rindex (s, ']'))) s = p + 1; /* Skip directory. */
- if ((p = rindex (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */
- if (s != fname)
- return s;
-#endif
- if ((p = rindex (s, '/'))) s = p + 1;
-#ifdef DIR_SEPARATOR
- if ((p = rindex (s, DIR_SEPARATOR))) s = p + 1;
-#endif
- return s;
-}
-
-/* Yield nonzero if FILENAME is absolute (i.e. not relative). */
-
-static int
-absolute_filename (filename)
- char *filename;
-{
-#if defined (__MSDOS__) \
- || (defined (_WIN32) && !defined (__CYGWIN__) && !defined (_UWIN))
- if (ISALPHA (filename[0]) && filename[1] == ':') filename += 2;
-#endif
-#if defined (__CYGWIN__)
- /* At present, any path that begins with a drive spec is absolute. */
- if (ISALPHA (filename[0]) && filename[1] == ':') return 1;
-#endif
-#ifdef VMS
- if (index (filename, ':') != 0) return 1;
-#endif
- if (filename[0] == '/') return 1;
-#ifdef DIR_SEPARATOR
- if (filename[0] == DIR_SEPARATOR) return 1;
-#endif
- return 0;
-}
-
-/* Returns whether or not a given character is a directory separator.
- Used by simplify_filename. */
-static inline
-int
-is_dir_separator(ch)
- char ch;
-{
- return (ch == DIR_SEPARATOR)
-#if defined (DIR_SEPARATOR_2)
- || (ch == DIR_SEPARATOR_2)
-#endif
- ;
-}
-
-/* Remove unnecessary characters from FILENAME in place,
- to avoid unnecessary filename aliasing.
- Return the length of the resulting string.
-
- Do only the simplifications allowed by Posix.
- It is OK to miss simplifications on non-Posix hosts,
- since this merely leads to suboptimal results. */
-
-static size_t
-simplify_filename (filename)
- char *filename;
-{
- register char *from = filename;
- register char *to = filename;
- char *to0;
-
- /* Remove redundant initial /s. */
- if (is_dir_separator (*from))
- {
- *to++ = DIR_SEPARATOR;
- if (is_dir_separator (*++from))
- {
- if (is_dir_separator (*++from))
- {
- /* 3 or more initial /s are equivalent to 1 /. */
- while (is_dir_separator (*++from))
- continue;
- }
- else
- {
- /* On some hosts // differs from /; Posix allows this. */
- *to++ = DIR_SEPARATOR;
- }
- }
- }
-
- to0 = to;
-
- for (;;)
- {
-#ifndef VMS
- if (from[0] == '.' && from[1] == '/')
- from += 2;
- else
-#endif
- {
- /* Copy this component and trailing DIR_SEPARATOR, if any. */
- while (!is_dir_separator (*to++ = *from++))
- {
- if (!to[-1])
- {
- /* Trim . component at end of nonempty name. */
- to -= filename <= to - 3 && to[-3] == DIR_SEPARATOR && to[-2] == '.';
-
- /* Trim unnecessary trailing /s. */
- while (to0 < --to && to[-1] == DIR_SEPARATOR)
- continue;
-
- *to = 0;
- return to - filename;
- }
- }
-#if defined(DIR_SEPARATOR_2)
- /* Simplify to one directory separator. */
- to[-1] = DIR_SEPARATOR;
-#endif
- }
-
- /* Skip /s after a /. */
- while (is_dir_separator (*from))
- from++;
- }
-}
-
-/* The file_name_map structure holds a mapping of file names for a
- particular directory. This mapping is read from the file named
- FILE_NAME_MAP_FILE in that directory. Such a file can be used to
- map filenames on a file system with severe filename restrictions,
- such as DOS. The format of the file name map file is just a series
- of lines with two tokens on each line. The first token is the name
- to map, and the second token is the actual name to use. */
-
-struct file_name_map
-{
- struct file_name_map *map_next;
- char *map_from;
- char *map_to;
-};
-
-#define FILE_NAME_MAP_FILE "header.gcc"
-
-/* Read a space delimited string of unlimited length from a stdio
- file. */
-
-static char *
-read_filename_string (ch, f)
- int ch;
- FILE *f;
-{
- char *alloc, *set;
- int len;
-
- len = 20;
- set = alloc = xmalloc (len + 1);
- if (! is_space[ch])
- {
- *set++ = ch;
- while ((ch = getc (f)) != EOF && ! is_space[ch])
- {
- if (set - alloc == len)
- {
- len *= 2;
- alloc = xrealloc (alloc, len + 1);
- set = alloc + len / 2;
- }
- *set++ = ch;
- }
- }
- *set = '\0';
- ungetc (ch, f);
- return alloc;
-}
-
-/* Read the file name map file for DIRNAME.
- If DIRNAME is empty, read the map file for the working directory;
- otherwise DIRNAME must end in '/'. */
-
-static struct file_name_map *
-read_name_map (dirname)
- char *dirname;
-{
- /* This structure holds a linked list of file name maps, one per
- directory. */
- struct file_name_map_list
- {
- struct file_name_map_list *map_list_next;
- char *map_list_name;
- struct file_name_map *map_list_map;
- };
- static struct file_name_map_list *map_list;
- register struct file_name_map_list *map_list_ptr;
- char *name;
- FILE *f;
- size_t dirlen;
-
- for (map_list_ptr = map_list; map_list_ptr;
- map_list_ptr = map_list_ptr->map_list_next)
- if (! strcmp (map_list_ptr->map_list_name, dirname))
- return map_list_ptr->map_list_map;
-
- map_list_ptr = ((struct file_name_map_list *)
- xmalloc (sizeof (struct file_name_map_list)));
- map_list_ptr->map_list_name = xstrdup (dirname);
- map_list_ptr->map_list_map = NULL;
-
- dirlen = strlen (dirname);
- name = (char *) alloca (dirlen + strlen (FILE_NAME_MAP_FILE) + 1);
- strcpy (name, dirname);
- strcat (name, FILE_NAME_MAP_FILE);
- f = fopen (name, "r");
- if (!f)
- map_list_ptr->map_list_map = NULL;
- else
- {
- int ch;
-
- while ((ch = getc (f)) != EOF)
- {
- char *from, *to;
- struct file_name_map *ptr;
- size_t tolen;
-
- if (is_space[ch])
- continue;
- from = read_filename_string (ch, f);
- while ((ch = getc (f)) != EOF && is_hor_space[ch])
- ;
- to = read_filename_string (ch, f);
-
- simplify_filename (from);
- tolen = simplify_filename (to);
-
- ptr = ((struct file_name_map *)
- xmalloc (sizeof (struct file_name_map)));
- ptr->map_from = from;
-
- /* Make the real filename absolute. */
- if (absolute_filename (to))
- ptr->map_to = to;
- else
- {
- ptr->map_to = xmalloc (dirlen + tolen + 1);
- strcpy (ptr->map_to, dirname);
- strcat (ptr->map_to, to);
- free (to);
- }
-
- ptr->map_next = map_list_ptr->map_list_map;
- map_list_ptr->map_list_map = ptr;
-
- while ((ch = getc (f)) != '\n')
- if (ch == EOF)
- break;
- }
- fclose (f);
- }
-
- map_list_ptr->map_list_next = map_list;
- map_list = map_list_ptr;
-
- return map_list_ptr->map_list_map;
-}
-
-/* Try to open include file FILENAME. SEARCHPTR is the directory
- being tried from the include file search path.
- IMPORTING is "" if we are importing, null otherwise.
- Return -2 if found, either a matching name or a matching inode.
- Otherwise, open the file and return a file descriptor if successful
- or -1 if unsuccessful.
- Unless unsuccessful, put a descriptor of the included file into *PINC.
- This function maps filenames on file systems based on information read by
- read_name_map. */
-
-static int
-open_include_file (filename, searchptr, importing, pinc)
- char *filename;
- struct file_name_list *searchptr;
- U_CHAR *importing;
- struct include_file **pinc;
-{
- char *fname = remap ? remap_include_file (filename, searchptr) : filename;
- int fd = -2;
-
- /* Look up FNAME in include_hashtab. */
- struct include_file **phead = &include_hashtab[hashf ((U_CHAR *) fname,
- strlen (fname),
- INCLUDE_HASHSIZE)];
- struct include_file *inc, *head = *phead;
- for (inc = head; inc; inc = inc->next)
- if (!strcmp (fname, inc->fname))
- break;
-
- if (!inc
- || ! inc->control_macro
- || (inc->control_macro[0] && ! lookup (inc->control_macro, -1, -1))) {
-
- fd = open (fname, O_RDONLY, 0);
-
- if (fd < 0)
- {
-#ifdef VMS
- /* if #include <dir/file> fails, try again with hacked spec. */
- if (!hack_vms_include_specification (fname, 0))
- return fd;
- fd = open (fname, O_RDONLY, 0);
- if (fd < 0)
-#endif
- return fd;
- }
-
- if (!inc) {
- /* FNAME was not in include_hashtab; insert a new entry. */
- inc = (struct include_file *) xmalloc (sizeof (struct include_file));
- inc->next = head;
- inc->fname = fname;
- inc->control_macro = 0;
- inc->deps_output = 0;
- if (fstat (fd, &inc->st) != 0)
- pfatal_with_name (fname);
- *phead = inc;
-
- /* Look for another file with the same inode and device. */
- if (lookup_ino_include (inc)
- && inc->control_macro
- && (!inc->control_macro[0] || lookup (inc->control_macro, -1, -1))) {
- close (fd);
- fd = -2;
- }
- }
-
- /* For -M, add this file to the dependencies. */
- if (! inc->deps_output && (system_include_depth != 0) < print_deps) {
- inc->deps_output = 1;
- deps_output (fname, ' ');
- }
-
- /* Handle -H option. */
- if (print_include_names)
- fprintf (stderr, "%*s%s\n", indepth, "", fname);
- }
-
- if (importing)
- inc->control_macro = importing;
-
- *pinc = inc;
- return fd;
-}
-
-/* Return the remapped name of the include file FILENAME.
- SEARCHPTR is the directory being tried from the include file path. */
-
-static char *
-remap_include_file (filename, searchptr)
- char *filename;
- struct file_name_list *searchptr;
-{
- register struct file_name_map *map;
- register char *from;
-
- if (searchptr)
- {
- if (! searchptr->got_name_map)
- {
- searchptr->name_map = read_name_map (searchptr->fname);
- searchptr->got_name_map = 1;
- }
-
- /* Check the mapping for the directory we are using. */
- from = filename + strlen (searchptr->fname);
- for (map = searchptr->name_map; map; map = map->map_next)
- if (! strcmp (map->map_from, from))
- return map->map_to;
- }
-
- from = base_name (filename);
-
- if (from != filename || !searchptr)
- {
- /* Try to find a mapping file for the particular directory we are
- looking in. Thus #include <sys/types.h> will look up sys/types.h
- in /usr/include/header.gcc and look up types.h in
- /usr/include/sys/header.gcc. */
-
- char *dir = (char *) alloca (from - filename + 1);
- bcopy (filename, dir, from - filename);
- dir[from - filename] = '\0';
-
- for (map = read_name_map (dir); map; map = map->map_next)
- if (! strcmp (map->map_from, from))
- return map->map_to;
- }
-
- return filename;
-}
-
-/* Insert INC into the include file table, hashed by device and inode number.
- If a file with different name but same dev+ino was already in the table,
- return 1 and set INC's control macro to the already-known macro. */
-
-static int
-lookup_ino_include (inc)
- struct include_file *inc;
-{
- int hash = ((unsigned) (inc->st.st_dev + INO_T_HASH (inc->st.st_ino))
- % INCLUDE_HASHSIZE);
- struct include_file *i = include_ino_hashtab[hash];
- inc->next_ino = i;
- include_ino_hashtab[hash] = inc;
-
- for (; i; i = i->next_ino)
- if (INO_T_EQ (inc->st.st_ino, i->st.st_ino)
- && inc->st.st_dev == i->st.st_dev) {
- inc->control_macro = i->control_macro;
- return 1;
- }
-
- return 0;
-}
-
-/* Process file descriptor F, which corresponds to include file INC,
- with output to OP.
- SYSTEM_HEADER_P is 1 if this file resides in any one of the known
- "system" include directories (as decided by the `is_system_include'
- function above).
- DIRPTR is the link in the dir path through which this file was found,
- or 0 if the file name was absolute. */
-
-static void
-finclude (f, inc, op, system_header_p, dirptr)
- int f;
- struct include_file *inc;
- FILE_BUF *op;
- int system_header_p;
- struct file_name_list *dirptr;
-{
- char *fname = inc->fname;
- int i;
- FILE_BUF *fp; /* For input stack frame */
- int missing_newline = 0;
-
- CHECK_DEPTH (return;);
-
- fp = &instack[indepth + 1];
- bzero ((char *) fp, sizeof (FILE_BUF));
- fp->nominal_fname = fp->fname = fname;
- fp->nominal_fname_len = strlen (fname);
- fp->inc = inc;
- fp->length = 0;
- fp->lineno = 1;
- fp->if_stack = if_stack;
- fp->system_header_p = system_header_p;
- fp->dir = dirptr;
-
- if (S_ISREG (inc->st.st_mode)) {
- size_t s = (size_t) inc->st.st_size;
- if (s != inc->st.st_size || s + 2 < s)
- memory_full ();
- fp->buf = (U_CHAR *) xmalloc (s + 2);
- fp->bufp = fp->buf;
-
- /* Read the file contents, knowing that s is an upper bound
- on the number of bytes we can read. */
- fp->length = safe_read (f, (char *) fp->buf, s);
- if (fp->length < 0) goto nope;
- }
- else if (S_ISDIR (inc->st.st_mode)) {
- error ("directory `%s' specified in #include", fname);
- close (f);
- return;
- } else {
- /* Cannot count its file size before reading.
- First read the entire file into heap and
- copy them into buffer on stack. */
-
- int bsize = 2000;
- int st_size = 0;
-
- fp->buf = (U_CHAR *) xmalloc (bsize + 2);
-
- for (;;) {
- i = safe_read (f, (char *) fp->buf + st_size, bsize - st_size);
- if (i < 0)
- goto nope; /* error! */
- st_size += i;
- if (st_size != bsize)
- break; /* End of file */
- bsize *= 2;
- fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
- }
- fp->bufp = fp->buf;
- fp->length = st_size;
- }
-
- if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
- /* Backslash-newline at end is not good enough. */
- || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
- fp->buf[fp->length++] = '\n';
- missing_newline = 1;
- }
- fp->buf[fp->length] = '\0';
-
- /* Close descriptor now, so nesting does not use lots of descriptors. */
- close (f);
-
- /* Must do this before calling trigraph_pcp, so that the correct file name
- will be printed in warning messages. */
-
- indepth++;
- input_file_stack_tick++;
-
- if (!no_trigraphs)
- trigraph_pcp (fp);
-
- output_line_directive (fp, op, 0, enter_file);
- rescan (op, 0);
-
- if (missing_newline)
- fp->lineno--;
-
- if (pedantic && missing_newline)
- pedwarn ("file does not end in newline");
-
- indepth--;
- input_file_stack_tick++;
- output_line_directive (&instack[indepth], op, 0, leave_file);
- free (fp->buf);
- return;
-
- nope:
-
- perror_with_name (fname);
- close (f);
- free (fp->buf);
-}
-
-/* Record that inclusion of the include file INC
- should be controlled by the macro named MACRO_NAME.
- This means that trying to include the file again
- will do something if that macro is defined. */
-
-static void
-record_control_macro (inc, macro_name)
- struct include_file *inc;
- U_CHAR *macro_name;
-{
- if (!inc->control_macro || inc->control_macro[0])
- inc->control_macro = macro_name;
-}
-
-/* Load the specified precompiled header into core, and verify its
- preconditions. PCF indicates the file descriptor to read, which must
- be a regular file. *ST is its file status.
- FNAME indicates the file name of the original header.
- *LIMIT will be set to an address one past the end of the file.
- If the preconditions of the file are not satisfied, the buffer is
- freed and we return 0. If the preconditions are satisfied, return
- the address of the buffer following the preconditions. The buffer, in
- this case, should never be freed because various pieces of it will
- be referred to until all precompiled strings are output at the end of
- the run. */
-
-static char *
-check_precompiled (pcf, st, fname, limit)
- int pcf;
- struct stat *st;
- char *fname ATTRIBUTE_UNUSED;
- char **limit;
-{
- int length = 0;
- char *buf;
- char *cp;
-
- if (pcp_outfile)
- return 0;
-
- if (S_ISREG (st->st_mode))
- {
- size_t s = (size_t) st->st_size;
- if (s != st->st_size || s + 2 < s)
- memory_full ();
- buf = xmalloc (s + 2);
- length = safe_read (pcf, buf, s);
- if (length < 0)
- goto nope;
- }
- else
- abort ();
-
- if (length > 0 && buf[length-1] != '\n')
- buf[length++] = '\n';
- buf[length] = '\0';
-
- *limit = buf + length;
-
- /* File is in core. Check the preconditions. */
- if (!check_preconditions (buf))
- goto nope;
- for (cp = buf; *cp; cp++)
- ;
-#ifdef DEBUG_PCP
- fprintf (stderr, "Using preinclude %s\n", fname);
-#endif
- return cp + 1;
-
- nope:
-#ifdef DEBUG_PCP
- fprintf (stderr, "Cannot use preinclude %s\n", fname);
-#endif
- free (buf);
- return 0;
-}
-
-/* PREC (null terminated) points to the preconditions of a
- precompiled header. These are a series of #define and #undef
- lines which must match the current contents of the hash
- table. */
-
-static int
-check_preconditions (prec)
- char *prec;
-{
- MACRODEF mdef;
- char *lineend;
-
- while (*prec) {
- lineend = index (prec, '\n');
-
- if (*prec++ != '#') {
- error ("Bad format encountered while reading precompiled file");
- return 0;
- }
- if (!strncmp (prec, "define", 6)) {
- HASHNODE *hp;
-
- prec += 6;
- mdef = create_definition ((U_CHAR *) prec, (U_CHAR *) lineend, NULL_PTR);
-
- if (mdef.defn == 0)
- abort ();
-
- if ((hp = lookup (mdef.symnam, mdef.symlen, -1)) == NULL
- || (hp->type != T_MACRO && hp->type != T_CONST)
- || (hp->type == T_MACRO
- && !compare_defs (mdef.defn, hp->value.defn)
- && (mdef.defn->length != 2
- || mdef.defn->expansion[0] != '\n'
- || mdef.defn->expansion[1] != ' ')))
- return 0;
- } else if (!strncmp (prec, "undef", 5)) {
- char *name;
- int len;
-
- prec += 5;
- while (is_hor_space[(U_CHAR) *prec])
- prec++;
- name = prec;
- while (is_idchar[(U_CHAR) *prec])
- prec++;
- len = prec - name;
-
- if (lookup ((U_CHAR *) name, len, -1))
- return 0;
- } else {
- error ("Bad format encountered while reading precompiled file");
- return 0;
- }
- prec = lineend + 1;
- }
- /* They all passed successfully */
- return 1;
-}
-
-/* Process the main body of a precompiled file. BUF points to the
- string section of the file, following the preconditions. LIMIT is one
- character past the end. NAME is the name of the file being read
- in. OP is the main output buffer. */
-
-static void
-pcfinclude (buf, name, op)
- U_CHAR *buf, *name;
- FILE_BUF *op;
-{
- FILE_BUF tmpbuf;
- int nstrings;
- U_CHAR *cp = buf;
-
- /* First in the file comes 4 bytes indicating the number of strings, */
- /* in network byte order. (MSB first). */
- nstrings = *cp++;
- nstrings = (nstrings << 8) | *cp++;
- nstrings = (nstrings << 8) | *cp++;
- nstrings = (nstrings << 8) | *cp++;
-
- /* Looping over each string... */
- while (nstrings--) {
- U_CHAR *string_start;
- U_CHAR *endofthiskey;
- STRINGDEF *str;
- int nkeys;
-
- /* Each string starts with a STRINGDEF structure (str), followed */
- /* by the text of the string (string_start) */
-
- /* First skip to a longword boundary */
- /* ??? Why a 4-byte boundary? On all machines? */
- /* NOTE: This works correctly even if size_t
- is narrower than a pointer.
- Do not try risky measures here to get another type to use!
- Do not include stddef.h--it will fail! */
- if ((size_t) cp & 3)
- cp += 4 - ((size_t) cp & 3);
-
- /* Now get the string. */
- str = (STRINGDEF *) (GENERIC_PTR) cp;
- string_start = cp += sizeof (STRINGDEF);
-
- for (; *cp; cp++) /* skip the string */
- ;
-
- /* We need to macro expand the string here to ensure that the
- proper definition environment is in place. If it were only
- expanded when we find out it is needed, macros necessary for
- its proper expansion might have had their definitions changed. */
- tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0);
- /* Lineno is already set in the precompiled file */
- str->contents = tmpbuf.buf;
- str->len = tmpbuf.length;
- str->writeflag = 0;
- str->filename = name;
- str->output_mark = outbuf.bufp - outbuf.buf;
-
- str->chain = 0;
- *stringlist_tailp = str;
- stringlist_tailp = &str->chain;
-
- /* Next comes a fourbyte number indicating the number of keys
- for this string. */
- nkeys = *cp++;
- nkeys = (nkeys << 8) | *cp++;
- nkeys = (nkeys << 8) | *cp++;
- nkeys = (nkeys << 8) | *cp++;
-
- /* If this number is -1, then the string is mandatory. */
- if (nkeys == -1)
- str->writeflag = 1;
- else
- /* Otherwise, for each key, */
- for (; nkeys--; free (tmpbuf.buf), cp = endofthiskey + 1) {
- KEYDEF *kp = (KEYDEF *) (GENERIC_PTR) cp;
- HASHNODE *hp;
-
- /* It starts with a KEYDEF structure */
- cp += sizeof (KEYDEF);
-
- /* Find the end of the key. At the end of this for loop we
- advance CP to the start of the next key using this variable. */
- endofthiskey = cp + strlen ((char *) cp);
- kp->str = str;
-
- /* Expand the key, and enter it into the hash table. */
- tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0);
- tmpbuf.bufp = tmpbuf.buf;
-
- while (is_hor_space[*tmpbuf.bufp])
- tmpbuf.bufp++;
- if (!is_idstart[*tmpbuf.bufp]
- || tmpbuf.bufp == tmpbuf.buf + tmpbuf.length) {
- str->writeflag = 1;
- continue;
- }
-
- hp = lookup (tmpbuf.bufp, -1, -1);
- if (hp == NULL) {
- kp->chain = 0;
- install (tmpbuf.bufp, -1, T_PCSTRING, (char *) kp, -1);
- }
- else if (hp->type == T_PCSTRING) {
- kp->chain = hp->value.keydef;
- hp->value.keydef = kp;
- }
- else
- str->writeflag = 1;
- }
- }
- /* This output_line_directive serves to switch us back to the current
- input file in case some of these strings get output (which will
- result in line directives for the header file being output). */
- output_line_directive (&instack[indepth], op, 0, enter_file);
-}
-
-/* Called from rescan when it hits a key for strings. Mark them all
- used and clean up. */
-
-static void
-pcstring_used (hp)
- HASHNODE *hp;
-{
- KEYDEF *kp;
-
- for (kp = hp->value.keydef; kp; kp = kp->chain)
- kp->str->writeflag = 1;
- delete_macro (hp);
-}
-
-/* Write the output, interspersing precompiled strings in their
- appropriate places. */
-
-static void
-write_output ()
-{
- STRINGDEF *next_string;
- U_CHAR *cur_buf_loc;
- int line_directive_len = 80;
- char *line_directive = xmalloc (line_directive_len);
- int len;
-
- /* In each run through the loop, either cur_buf_loc ==
- next_string_loc, in which case we print a series of strings, or
- it is less than next_string_loc, in which case we write some of
- the buffer. */
- cur_buf_loc = outbuf.buf;
- next_string = stringlist;
-
- while (cur_buf_loc < outbuf.bufp || next_string) {
- if (next_string
- && cur_buf_loc - outbuf.buf == next_string->output_mark) {
- if (next_string->writeflag) {
- len = 4 * strlen ((char *) next_string->filename) + 32;
- while (len > line_directive_len)
- line_directive = xrealloc (line_directive,
- line_directive_len *= 2);
- sprintf (line_directive, "\n# %d ", next_string->lineno);
- strcpy (quote_string (line_directive + strlen (line_directive),
- (char *) next_string->filename,
- strlen ((char *) next_string->filename)),
- "\n");
- safe_write (fileno (stdout), line_directive, strlen (line_directive));
- safe_write (fileno (stdout),
- (char *) next_string->contents, next_string->len);
- }
- next_string = next_string->chain;
- }
- else {
- len = (next_string
- ? (next_string->output_mark
- - (cur_buf_loc - outbuf.buf))
- : outbuf.bufp - cur_buf_loc);
-
- safe_write (fileno (stdout), (char *) cur_buf_loc, len);
- cur_buf_loc += len;
- }
- }
- free (line_directive);
-}
-
-/* Pass a directive through to the output file.
- BUF points to the contents of the directive, as a contiguous string.
- LIMIT points to the first character past the end of the directive.
- KEYWORD is the keyword-table entry for the directive. */
-
-static void
-pass_thru_directive (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- register int keyword_length = keyword->length;
-
- check_expand (op, 1 + keyword_length + (limit - buf));
- *op->bufp++ = '#';
- bcopy (keyword->name, (char *) op->bufp, keyword_length);
- op->bufp += keyword_length;
- if (limit != buf && buf[0] != ' ')
- *op->bufp++ = ' ';
- bcopy ((char *) buf, (char *) op->bufp, limit - buf);
- op->bufp += (limit - buf);
-#if 0
- *op->bufp++ = '\n';
- /* Count the line we have just made in the output,
- to get in sync properly. */
- op->lineno++;
-#endif
-}
-
-/* The arglist structure is built by do_define to tell
- collect_definition where the argument names begin. That
- is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
- would contain pointers to the strings x, y, and z.
- Collect_definition would then build a DEFINITION node,
- with reflist nodes pointing to the places x, y, and z had
- appeared. So the arglist is just convenience data passed
- between these two routines. It is not kept around after
- the current #define has been processed and entered into the
- hash table. */
-
-struct arglist {
- struct arglist *next;
- U_CHAR *name;
- int length;
- int argno;
- char rest_args;
-};
-
-/* Create a DEFINITION node from a #define directive. Arguments are
- as for do_define. */
-
-static MACRODEF
-create_definition (buf, limit, op)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
-{
- U_CHAR *bp; /* temp ptr into input buffer */
- U_CHAR *symname; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
- int line = instack[indepth].lineno;
- char *file = instack[indepth].nominal_fname;
- size_t file_len = instack[indepth].nominal_fname_len;
- int rest_args = 0;
-
- DEFINITION *defn;
- int arglengths = 0; /* Accumulate lengths of arg names
- plus number of args. */
- MACRODEF mdef;
-
- bp = buf;
-
- while (is_hor_space[*bp])
- bp++;
-
- symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, 0);
- bp += sym_length;
-
- /* Lossage will occur if identifiers or control keywords are broken
- across lines using backslash. This is not the right place to take
- care of that. */
-
- if (*bp == '(') {
- struct arglist *arg_ptrs = NULL;
- int argno = 0;
-
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
-
- /* Loop over macro argument names. */
- while (*bp != ')') {
- struct arglist *temp;
-
- temp = (struct arglist *) alloca (sizeof (struct arglist));
- temp->name = bp;
- temp->next = arg_ptrs;
- temp->argno = argno++;
- temp->rest_args = 0;
- arg_ptrs = temp;
-
- if (rest_args)
- pedwarn ("another parameter follows `%s'",
- rest_extension);
-
- if (!is_idstart[*bp])
- {
- if (c9x && limit - bp > (long) REST_EXTENSION_LENGTH
- && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
- {
- /* This is the ISO C 9x way to write macros with variable
- number of arguments. */
- rest_args = 1;
- temp->rest_args = 1;
- }
- else
- pedwarn ("invalid character in macro parameter name");
- }
-
- /* Find the end of the arg name. */
- while (is_idchar[*bp]) {
- bp++;
- /* do we have a "special" rest-args extension here? */
- if (limit - bp > (long) REST_EXTENSION_LENGTH
- && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow macro with variable arguments");
- rest_args = 1;
- temp->rest_args = 1;
- break;
- }
- }
- if (bp == temp->name && rest_args == 1)
- {
- /* This is the ISO C 9x style. */
- temp->name = (U_CHAR *) va_args_name;
- temp->length = VA_ARGS_NAME_LENGTH;
- }
- else
- temp->length = bp - temp->name;
- if (rest_args == 1)
- bp += REST_EXTENSION_LENGTH;
- arglengths += temp->length + 2;
- SKIP_WHITE_SPACE (bp);
- if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
- error ("badly punctuated parameter list in `#define'");
- goto nope;
- }
- if (*bp == ',') {
- bp++;
- SKIP_WHITE_SPACE (bp);
- /* A comma at this point can only be followed by an identifier. */
- if (!is_idstart[*bp]
- && !(c9x && limit - bp > (long) REST_EXTENSION_LENGTH
- && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)) {
- error ("badly punctuated parameter list in `#define'");
- goto nope;
- }
- }
- if (bp >= limit) {
- error ("unterminated parameter list in `#define'");
- goto nope;
- }
- {
- struct arglist *otemp;
-
- for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
- if (temp->length == otemp->length
- && bcmp (temp->name, otemp->name, temp->length) == 0)
- {
- error ("duplicate argument name `%.*s' in `#define'",
- temp->length, temp->name);
- goto nope;
- }
- if (rest_args == 0 && temp->length == VA_ARGS_NAME_LENGTH
- && bcmp (temp->name, va_args_name, VA_ARGS_NAME_LENGTH) == 0)
- {
- error ("\
-reserved name `%s' used as argument name in `#define'", va_args_name);
- goto nope;
- }
- }
- }
-
- ++bp; /* skip paren */
- SKIP_WHITE_SPACE (bp);
- /* now everything from bp before limit is the definition. */
- defn = collect_expansion (bp, limit, argno, arg_ptrs);
- defn->rest_args = rest_args;
-
- /* Now set defn->args.argnames to the result of concatenating
- the argument names in reverse order
- with comma-space between them. */
- defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
- {
- struct arglist *temp;
- int i = 0;
- for (temp = arg_ptrs; temp; temp = temp->next) {
- bcopy (temp->name, &defn->args.argnames[i], temp->length);
- i += temp->length;
- if (temp->next != 0) {
- defn->args.argnames[i++] = ',';
- defn->args.argnames[i++] = ' ';
- }
- }
- defn->args.argnames[i] = 0;
- }
- } else {
- /* Simple expansion or empty definition. */
-
- if (bp < limit)
- {
- if (is_hor_space[*bp]) {
- bp++;
- SKIP_WHITE_SPACE (bp);
- } else if (sym_length) {
- switch (*bp) {
- case '!': case '"': case '#': case '%': case '&': case '\'':
- case ')': case '*': case '+': case ',': case '-': case '.':
- case '/': case ':': case ';': case '<': case '=': case '>':
- case '?': case '[': case '\\': case ']': case '^': case '{':
- case '|': case '}': case '~':
- warning ("missing white space after `#define %.*s'",
- sym_length, symname);
- break;
-
- default:
- pedwarn ("missing white space after `#define %.*s'",
- sym_length, symname);
- break;
- }
- }
- }
- /* Now everything from bp before limit is the definition. */
- defn = collect_expansion (bp, limit, -1, NULL_PTR);
- defn->args.argnames = (U_CHAR *) "";
- }
-
- defn->line = line;
- defn->file = file;
- defn->file_len = file_len;
-
- /* OP is null if this is a predefinition */
- defn->predefined = !op;
- mdef.defn = defn;
- mdef.symnam = symname;
- mdef.symlen = sym_length;
-
- return mdef;
-
- nope:
- mdef.defn = 0;
- return mdef;
-}
-
-/* Process a #define directive.
-BUF points to the contents of the #define directive, as a contiguous string.
-LIMIT points to the first character past the end of the definition.
-KEYWORD is the keyword-table entry for #define. */
-
-static int
-do_define (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- int hashcode;
- MACRODEF mdef;
-
- /* If this is a precompiler run (with -pcp) pass thru #define directives. */
- if (pcp_outfile && op)
- pass_thru_directive (buf, limit, op, keyword);
-
- mdef = create_definition (buf, limit, op);
- if (mdef.defn == 0)
- goto nope;
-
- hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
-
- {
- HASHNODE *hp;
- if ((hp = lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) {
- int ok = 0;
- /* Redefining a precompiled key is ok. */
- if (hp->type == T_PCSTRING)
- ok = 1;
- /* Redefining a macro is ok if the definitions are the same. */
- else if (hp->type == T_MACRO)
- ok = ! compare_defs (mdef.defn, hp->value.defn);
- /* Redefining a constant is ok with -D. */
- else if (hp->type == T_CONST)
- ok = ! done_initializing;
- /* Print the warning if it's not ok. */
- if (!ok) {
- /* If we are passing through #define and #undef directives, do
- that for this re-definition now. */
- if (debug_output && op)
- pass_thru_directive (buf, limit, op, keyword);
-
- pedwarn ("`%.*s' redefined", mdef.symlen, mdef.symnam);
- if (hp->type == T_MACRO)
- pedwarn_with_file_and_line (hp->value.defn->file,
- hp->value.defn->file_len,
- hp->value.defn->line,
- "this is the location of the previous definition");
- }
- /* Replace the old definition. */
- hp->type = T_MACRO;
- hp->value.defn = mdef.defn;
- } else {
- /* If we are passing through #define and #undef directives, do
- that for this new definition now. */
- if (debug_output && op)
- pass_thru_directive (buf, limit, op, keyword);
- install (mdef.symnam, mdef.symlen, T_MACRO,
- (char *) mdef.defn, hashcode);
- }
- }
-
- return 0;
-
-nope:
-
- return 1;
-}
-
-/* Check a purported macro name SYMNAME, and yield its length.
- ASSERTION is nonzero if this is really for an assertion name. */
-
-static int
-check_macro_name (symname, assertion)
- U_CHAR *symname;
- int assertion;
-{
- U_CHAR *p;
- int sym_length;
-
- for (p = symname; is_idchar[*p]; p++)
- ;
- sym_length = p - symname;
- if (sym_length == 0
- || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
- error (assertion ? "invalid assertion name" : "invalid macro name");
- else if (!is_idstart[*symname]
- || (sym_length == 7 && ! bcmp (symname, "defined", 7)))
- error ((assertion
- ? "invalid assertion name `%.*s'"
- : "invalid macro name `%.*s'"),
- sym_length, symname);
- return sym_length;
-}
-
-/* Return zero if two DEFINITIONs are isomorphic. */
-
-static int
-compare_defs (d1, d2)
- DEFINITION *d1, *d2;
-{
- register struct reflist *a1, *a2;
- register U_CHAR *p1 = d1->expansion;
- register U_CHAR *p2 = d2->expansion;
- int first = 1;
-
- if (d1->nargs != d2->nargs)
- return 1;
- if (pedantic
- && strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames))
- return 1;
- for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
- a1 = a1->next, a2 = a2->next) {
- if (!((a1->nchars == a2->nchars && ! bcmp (p1, p2, a1->nchars))
- || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
- || a1->argno != a2->argno
- || a1->stringify != a2->stringify
- || a1->raw_before != a2->raw_before
- || a1->raw_after != a2->raw_after)
- return 1;
- first = 0;
- p1 += a1->nchars;
- p2 += a2->nchars;
- }
- if (a1 != a2)
- return 1;
- if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
- p2, d2->length - (p2 - d2->expansion), 1))
- return 1;
- return 0;
-}
-
-/* Return 1 if two parts of two macro definitions are effectively different.
- One of the parts starts at BEG1 and has LEN1 chars;
- the other has LEN2 chars at BEG2.
- Any sequence of whitespace matches any other sequence of whitespace.
- FIRST means these parts are the first of a macro definition;
- so ignore leading whitespace entirely.
- LAST means these parts are the last of a macro definition;
- so ignore trailing whitespace entirely. */
-
-static int
-comp_def_part (first, beg1, len1, beg2, len2, last)
- int first;
- U_CHAR *beg1, *beg2;
- int len1, len2;
- int last;
-{
- register U_CHAR *end1 = beg1 + len1;
- register U_CHAR *end2 = beg2 + len2;
- if (first) {
- while (beg1 != end1 && is_space[*beg1]) beg1++;
- while (beg2 != end2 && is_space[*beg2]) beg2++;
- }
- if (last) {
- while (beg1 != end1 && is_space[end1[-1]]) end1--;
- while (beg2 != end2 && is_space[end2[-1]]) end2--;
- }
- while (beg1 != end1 && beg2 != end2) {
- if (is_space[*beg1] && is_space[*beg2]) {
- while (beg1 != end1 && is_space[*beg1]) beg1++;
- while (beg2 != end2 && is_space[*beg2]) beg2++;
- } else if (*beg1 == *beg2) {
- beg1++; beg2++;
- } else break;
- }
- return (beg1 != end1) || (beg2 != end2);
-}
-
-/* Read a replacement list for a macro with parameters.
- Build the DEFINITION structure.
- Reads characters of text starting at BUF until END.
- ARGLIST specifies the formal parameters to look for
- in the text of the definition; NARGS is the number of args
- in that list, or -1 for a macro name that wants no argument list.
- MACRONAME is the macro name itself (so we can avoid recursive expansion)
- and NAMELEN is its length in characters.
-
-Note that comments, backslash-newlines, and leading white space
-have already been deleted from the argument. */
-
-/* If there is no trailing whitespace, a Newline Space is added at the end
- to prevent concatenation that would be contrary to the standard. */
-
-static DEFINITION *
-collect_expansion (buf, end, nargs, arglist)
- U_CHAR *buf, *end;
- int nargs;
- struct arglist *arglist;
-{
- DEFINITION *defn;
- register U_CHAR *p, *limit, *lastp, *exp_p;
- struct reflist *endpat = NULL;
- /* Pointer to first nonspace after last ## seen. */
- U_CHAR *concat = 0;
- /* Pointer to first nonspace after last single-# seen. */
- U_CHAR *stringify = 0;
- /* How those tokens were spelled. */
- enum sharp_token_type concat_sharp_token_type = NO_SHARP_TOKEN;
- enum sharp_token_type stringify_sharp_token_type = NO_SHARP_TOKEN;
- int maxsize;
- int expected_delimiter = '\0';
-
- /* Scan thru the replacement list, ignoring comments and quoted
- strings, picking up on the macro calls. It does a linear search
- thru the arg list on every potential symbol. Profiling might say
- that something smarter should happen. */
-
- if (end < buf)
- abort ();
-
- /* Find the beginning of the trailing whitespace. */
- limit = end;
- p = buf;
- while (p < limit && is_space[limit[-1]]) limit--;
-
- /* Allocate space for the text in the macro definition.
- Each input char may or may not need 1 byte,
- so this is an upper bound.
- The extra 3 are for invented trailing newline-marker and final null. */
- maxsize = (sizeof (DEFINITION)
- + (limit - p) + 3);
- defn = (DEFINITION *) xcalloc (1, maxsize);
-
- defn->nargs = nargs;
- exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
- lastp = exp_p;
-
- if (p[0] == '#'
- ? p[1] == '#'
- : p[0] == '%' && p[1] == ':' && p[2] == '%' && p[3] == ':') {
- error ("`##' at start of macro definition");
- p += p[0] == '#' ? 2 : 4;
- }
-
- /* Process the main body of the definition. */
- while (p < limit) {
- int skipped_arg = 0;
- register U_CHAR c = *p++;
-
- *exp_p++ = c;
-
- if (!traditional) {
- switch (c) {
- case '\'':
- case '\"':
- if (expected_delimiter != '\0') {
- if (c == expected_delimiter)
- expected_delimiter = '\0';
- } else
- expected_delimiter = c;
- break;
-
- case '\\':
- if (p < limit && expected_delimiter) {
- /* In a string, backslash goes through
- and makes next char ordinary. */
- *exp_p++ = *p++;
- }
- break;
-
- case '%':
- if (!expected_delimiter && *p == ':') {
- /* %: is not a digraph if preceded by an odd number of '<'s. */
- U_CHAR *p0 = p - 1;
- while (buf < p0 && p0[-1] == '<')
- p0--;
- if ((p - p0) & 1) {
- /* Treat %:%: as ## and %: as #. */
- if (p[1] == '%' && p[2] == ':') {
- p += 2;
- goto sharp_sharp_token;
- }
- if (nargs >= 0) {
- p++;
- goto sharp_token;
- }
- }
- }
- break;
-
- case '#':
- /* # is ordinary inside a string. */
- if (expected_delimiter)
- break;
- if (*p == '#') {
- sharp_sharp_token:
- /* ##: concatenate preceding and following tokens. */
- /* Take out the first #, discard preceding whitespace. */
- exp_p--;
- while (exp_p > lastp && is_hor_space[exp_p[-1]])
- --exp_p;
- /* Skip the second #. */
- p++;
- concat_sharp_token_type = c;
- if (is_hor_space[*p]) {
- concat_sharp_token_type = c + 1;
- p++;
- SKIP_WHITE_SPACE (p);
- }
- concat = p;
- if (p == limit)
- error ("`##' at end of macro definition");
- } else if (nargs >= 0) {
- /* Single #: stringify following argument ref.
- Don't leave the # in the expansion. */
- sharp_token:
- exp_p--;
- stringify_sharp_token_type = c;
- if (is_hor_space[*p]) {
- stringify_sharp_token_type = c + 1;
- p++;
- SKIP_WHITE_SPACE (p);
- }
- if (! is_idstart[*p] || nargs == 0
- || (*p == 'L' && (p[1] == '\'' || p[1] == '"')))
- error ("`#' operator is not followed by a macro argument name");
- else
- stringify = p;
- }
- break;
- }
- } else {
- /* In -traditional mode, recognize arguments inside strings and
- character constants, and ignore special properties of #.
- Arguments inside strings are considered "stringified", but no
- extra quote marks are supplied. */
- switch (c) {
- case '\'':
- case '\"':
- if (expected_delimiter != '\0') {
- if (c == expected_delimiter)
- expected_delimiter = '\0';
- } else
- expected_delimiter = c;
- break;
-
- case '\\':
- /* Backslash quotes delimiters and itself, but not macro args. */
- if (expected_delimiter != 0 && p < limit
- && (*p == expected_delimiter || *p == '\\')) {
- *exp_p++ = *p++;
- continue;
- }
- break;
-
- case '/':
- if (expected_delimiter != '\0') /* No comments inside strings. */
- break;
- if (*p == '*') {
- /* If we find a comment that wasn't removed by handle_directive,
- this must be -traditional. So replace the comment with
- nothing at all. */
- exp_p--;
- while (++p < limit) {
- if (p[0] == '*' && p[1] == '/') {
- p += 2;
- break;
- }
- }
-#if 0
- /* Mark this as a concatenation-point, as if it had been ##. */
- concat = p;
-#endif
- }
- break;
- }
- }
-
-#ifdef MULTIBYTE_CHARS
- /* Handle multibyte characters inside string and character literals. */
- if (expected_delimiter != '\0')
- {
- int length;
- --p;
- length = local_mblen (p, limit - p);
- if (length > 1)
- {
- --exp_p;
- bcopy (p, exp_p, length);
- p += length;
- exp_p += length;
- continue;
- }
- ++p;
- }
-#endif
-
- /* Handle the start of a symbol. */
- if (is_idchar[c] && nargs > 0) {
- U_CHAR *id_beg = p - 1;
- int id_len;
-
- --exp_p;
- while (p != limit && is_idchar[*p]) p++;
- id_len = p - id_beg;
-
- if (is_idstart[c]
- && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
- register struct arglist *arg;
-
- for (arg = arglist; arg != NULL; arg = arg->next) {
- struct reflist *tpat;
-
- if (arg->name[0] == c
- && arg->length == id_len
- && bcmp (arg->name, id_beg, id_len) == 0) {
- enum sharp_token_type tpat_stringify;
- if (expected_delimiter) {
- if (warn_stringify) {
- if (traditional) {
- warning ("macro argument `%.*s' is stringified.",
- id_len, arg->name);
- } else {
- warning ("macro arg `%.*s' would be stringified with -traditional.",
- id_len, arg->name);
- }
- }
- /* If ANSI, don't actually substitute inside a string. */
- if (!traditional)
- break;
- tpat_stringify = SHARP_TOKEN;
- } else {
- tpat_stringify
- = (stringify == id_beg
- ? stringify_sharp_token_type : NO_SHARP_TOKEN);
- }
- /* make a pat node for this arg and append it to the end of
- the pat list */
- tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
- tpat->next = NULL;
- tpat->raw_before
- = concat == id_beg ? concat_sharp_token_type : NO_SHARP_TOKEN;
- tpat->raw_after = NO_SHARP_TOKEN;
- tpat->rest_args = arg->rest_args;
- tpat->stringify = tpat_stringify;
-
- if (endpat == NULL)
- defn->pattern = tpat;
- else
- endpat->next = tpat;
- endpat = tpat;
-
- tpat->argno = arg->argno;
- tpat->nchars = exp_p - lastp;
- {
- register U_CHAR *p1 = p;
- SKIP_WHITE_SPACE (p1);
- if (p1[0]=='#'
- ? p1[1]=='#'
- : p1[0]=='%' && p1[1]==':' && p1[2]=='%' && p1[3]==':')
- tpat->raw_after = p1[0] + (p != p1);
- }
- lastp = exp_p; /* place to start copying from next time */
- skipped_arg = 1;
- break;
- }
- }
- }
-
- /* If this was not a macro arg, copy it into the expansion. */
- if (! skipped_arg) {
- register U_CHAR *lim1 = p;
- p = id_beg;
- while (p != lim1)
- *exp_p++ = *p++;
- if (stringify == id_beg)
- error ("`#' operator should be followed by a macro argument name");
- }
- }
- }
-
- if (!traditional && expected_delimiter == 0) {
- /* If ANSI, put in a newline-space marker to prevent token pasting.
- But not if "inside a string" (which in ANSI mode happens only for
- -D option). */
- *exp_p++ = '\n';
- *exp_p++ = ' ';
- }
-
- *exp_p = '\0';
-
- defn->length = exp_p - defn->expansion;
-
- /* Crash now if we overrun the allocated size. */
- if (defn->length + 1 > maxsize)
- abort ();
-
-#if 0
-/* This isn't worth the time it takes. */
- /* give back excess storage */
- defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
-#endif
-
- return defn;
-}
-
-static int
-do_assert (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- U_CHAR *bp; /* temp ptr into input buffer */
- U_CHAR *symname; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
- struct arglist *tokens = NULL;
-
- if (pedantic && done_initializing && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#assert'");
-
- bp = buf;
-
- while (is_hor_space[*bp])
- bp++;
-
- symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, 1);
- bp += sym_length;
- /* #define doesn't do this, but we should. */
- SKIP_WHITE_SPACE (bp);
-
- /* Lossage will occur if identifiers or control tokens are broken
- across lines using backslash. This is not the right place to take
- care of that. */
-
- if (*bp != '(') {
- error ("missing token-sequence in `#assert'");
- return 1;
- }
-
- {
- int error_flag = 0;
-
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
-
- tokens = read_token_list (&bp, limit, &error_flag);
- if (error_flag)
- return 1;
- if (tokens == 0) {
- error ("empty token-sequence in `#assert'");
- return 1;
- }
-
- ++bp; /* skip paren */
- SKIP_WHITE_SPACE (bp);
- }
-
- /* If this name isn't already an assertion name, make it one.
- Error if it was already in use in some other way. */
-
- {
- ASSERTION_HASHNODE *hp;
- int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
- struct tokenlist_list *value
- = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list));
-
- hp = assertion_lookup (symname, sym_length, hashcode);
- if (hp == NULL) {
- if (sym_length == 7 && ! bcmp (symname, "defined", 7))
- error ("`defined' redefined as assertion");
- hp = assertion_install (symname, sym_length, hashcode);
- }
-
- /* Add the spec'd token-sequence to the list of such. */
- value->tokens = tokens;
- value->next = hp->value;
- hp->value = value;
- }
-
- return 0;
-}
-
-static int
-do_unassert (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- U_CHAR *bp; /* temp ptr into input buffer */
- U_CHAR *symname; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
-
- struct arglist *tokens = NULL;
- int tokens_specified = 0;
-
- if (pedantic && done_initializing && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#unassert'");
-
- bp = buf;
-
- while (is_hor_space[*bp])
- bp++;
-
- symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, 1);
- bp += sym_length;
- /* #define doesn't do this, but we should. */
- SKIP_WHITE_SPACE (bp);
-
- /* Lossage will occur if identifiers or control tokens are broken
- across lines using backslash. This is not the right place to take
- care of that. */
-
- if (*bp == '(') {
- int error_flag = 0;
-
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
-
- tokens = read_token_list (&bp, limit, &error_flag);
- if (error_flag)
- return 1;
- if (tokens == 0) {
- error ("empty token list in `#unassert'");
- return 1;
- }
-
- tokens_specified = 1;
-
- ++bp; /* skip paren */
- SKIP_WHITE_SPACE (bp);
- }
-
- {
- ASSERTION_HASHNODE *hp;
- int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
- struct tokenlist_list *tail, *prev;
-
- hp = assertion_lookup (symname, sym_length, hashcode);
- if (hp == NULL)
- return 1;
-
- /* If no token list was specified, then eliminate this assertion
- entirely. */
- if (! tokens_specified) {
- struct tokenlist_list *next;
- for (tail = hp->value; tail; tail = next) {
- next = tail->next;
- free_token_list (tail->tokens);
- free (tail);
- }
- delete_assertion (hp);
- } else {
- /* If a list of tokens was given, then delete any matching list. */
-
- tail = hp->value;
- prev = 0;
- while (tail) {
- struct tokenlist_list *next = tail->next;
- if (compare_token_lists (tail->tokens, tokens)) {
- if (prev)
- prev->next = next;
- else
- hp->value = tail->next;
- free_token_list (tail->tokens);
- free (tail);
- } else {
- prev = tail;
- }
- tail = next;
- }
- }
- }
-
- return 0;
-}
-
-/* Test whether there is an assertion named NAME
- and optionally whether it has an asserted token list TOKENS.
- NAME is not null terminated; its length is SYM_LENGTH.
- If TOKENS_SPECIFIED is 0, then don't check for any token list. */
-
-int
-check_assertion (name, sym_length, tokens_specified, tokens)
- U_CHAR *name;
- int sym_length;
- int tokens_specified;
- struct arglist *tokens;
-{
- ASSERTION_HASHNODE *hp;
- int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE);
-
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow testing assertions");
-
- hp = assertion_lookup (name, sym_length, hashcode);
- if (hp == NULL)
- /* It is not an assertion; just return false. */
- return 0;
-
- /* If no token list was specified, then value is 1. */
- if (! tokens_specified)
- return 1;
-
- {
- struct tokenlist_list *tail;
-
- tail = hp->value;
-
- /* If a list of tokens was given,
- then succeed if the assertion records a matching list. */
-
- while (tail) {
- if (compare_token_lists (tail->tokens, tokens))
- return 1;
- tail = tail->next;
- }
-
- /* Fail if the assertion has no matching list. */
- return 0;
- }
-}
-
-/* Compare two lists of tokens for equality including order of tokens. */
-
-static int
-compare_token_lists (l1, l2)
- struct arglist *l1, *l2;
-{
- while (l1 && l2) {
- if (l1->length != l2->length)
- return 0;
- if (bcmp (l1->name, l2->name, l1->length))
- return 0;
- l1 = l1->next;
- l2 = l2->next;
- }
-
- /* Succeed if both lists end at the same time. */
- return l1 == l2;
-}
-
-/* Read a space-separated list of tokens ending in a close parenthesis.
- Return a list of strings, in the order they were written.
- (In case of error, return 0 and store -1 in *ERROR_FLAG.)
- Parse the text starting at *BPP, and update *BPP.
- Don't parse beyond LIMIT. */
-
-static struct arglist *
-read_token_list (bpp, limit, error_flag)
- U_CHAR **bpp;
- U_CHAR *limit;
- int *error_flag;
-{
- struct arglist *token_ptrs = 0;
- U_CHAR *bp = *bpp;
- int depth = 1;
-
- *error_flag = 0;
-
- /* Loop over the assertion value tokens. */
- while (depth > 0) {
- struct arglist *temp;
- int eofp = 0;
- U_CHAR *beg = bp;
-
- /* Find the end of the token. */
- if (*bp == '(') {
- bp++;
- depth++;
- } else if (*bp == ')') {
- depth--;
- if (depth == 0)
- break;
- bp++;
- } else if (*bp == '"' || *bp == '\'')
- bp = skip_quoted_string (bp, limit, 0, NULL_PTR, NULL_PTR, &eofp);
- else
- while (! is_hor_space[*bp] && *bp != '(' && *bp != ')'
- && *bp != '"' && *bp != '\'' && bp != limit)
- bp++;
-
- temp = (struct arglist *) xmalloc (sizeof (struct arglist));
- temp->name = (U_CHAR *) xmalloc (bp - beg + 1);
- bcopy ((char *) beg, (char *) temp->name, bp - beg);
- temp->name[bp - beg] = 0;
- temp->next = token_ptrs;
- token_ptrs = temp;
- temp->length = bp - beg;
-
- SKIP_WHITE_SPACE (bp);
-
- if (bp >= limit) {
- error ("unterminated token sequence in `#assert' or `#unassert'");
- *error_flag = -1;
- return 0;
- }
- }
- *bpp = bp;
-
- /* We accumulated the names in reverse order.
- Now reverse them to get the proper order. */
- {
- register struct arglist *prev = 0, *this, *next;
- for (this = token_ptrs; this; this = next) {
- next = this->next;
- this->next = prev;
- prev = this;
- }
- return prev;
- }
-}
-
-static void
-free_token_list (tokens)
- struct arglist *tokens;
-{
- while (tokens) {
- struct arglist *next = tokens->next;
- free (tokens->name);
- free (tokens);
- tokens = next;
- }
-}
-
-/* Install a name in the assertion hash table.
-
- If LEN is >= 0, it is the length of the name.
- Otherwise, compute the length by scanning the entire name.
-
- If HASH is >= 0, it is the precomputed hash code.
- Otherwise, compute the hash code. */
-
-static ASSERTION_HASHNODE *
-assertion_install (name, len, hash)
- U_CHAR *name;
- int len;
- int hash;
-{
- register ASSERTION_HASHNODE *hp;
- register int i, bucket;
- register U_CHAR *p, *q;
-
- i = sizeof (ASSERTION_HASHNODE) + len + 1;
- hp = (ASSERTION_HASHNODE *) xmalloc (i);
- bucket = hash;
- hp->bucket_hdr = &assertion_hashtab[bucket];
- hp->next = assertion_hashtab[bucket];
- assertion_hashtab[bucket] = hp;
- hp->prev = NULL;
- if (hp->next != NULL)
- hp->next->prev = hp;
- hp->length = len;
- hp->value = 0;
- hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE);
- p = hp->name;
- q = name;
- for (i = 0; i < len; i++)
- *p++ = *q++;
- hp->name[len] = 0;
- return hp;
-}
-
-/* Find the most recent hash node for name "name" (ending with first
- non-identifier char) installed by install
-
- If LEN is >= 0, it is the length of the name.
- Otherwise, compute the length by scanning the entire name.
-
- If HASH is >= 0, it is the precomputed hash code.
- Otherwise, compute the hash code. */
-
-static ASSERTION_HASHNODE *
-assertion_lookup (name, len, hash)
- U_CHAR *name;
- int len;
- int hash;
-{
- register ASSERTION_HASHNODE *bucket;
-
- bucket = assertion_hashtab[hash];
- while (bucket) {
- if (bucket->length == len && bcmp (bucket->name, name, len) == 0)
- return bucket;
- bucket = bucket->next;
- }
- return NULL;
-}
-
-static void
-delete_assertion (hp)
- ASSERTION_HASHNODE *hp;
-{
-
- if (hp->prev != NULL)
- hp->prev->next = hp->next;
- if (hp->next != NULL)
- hp->next->prev = hp->prev;
-
- /* Make sure that the bucket chain header that the deleted guy was
- on points to the right thing afterwards. */
- if (hp == *hp->bucket_hdr)
- *hp->bucket_hdr = hp->next;
-
- free (hp);
-}
-
-/*
- * interpret #line directive. Remembers previously seen fnames
- * in its very own hash table.
- */
-#define FNAME_HASHSIZE 37
-
-static int
-do_line (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- register U_CHAR *bp;
- FILE_BUF *ip = &instack[indepth];
- FILE_BUF tem;
- int new_lineno;
- enum file_change_code file_change = same_file;
-
- /* Expand any macros. */
- tem = expand_to_temp_buffer (buf, limit, 0, 0);
-
- /* Point to macroexpanded line, which is null-terminated now. */
- bp = tem.buf;
- SKIP_WHITE_SPACE (bp);
-
- if (!ISDIGIT (*bp)) {
- error ("invalid format `#line' directive");
- return 0;
- }
-
- /* The Newline at the end of this line remains to be processed.
- To put the next line at the specified line number,
- we must store a line number now that is one less. */
- new_lineno = atoi ((char *) bp) - 1;
-
- /* NEW_LINENO is one less than the actual line number here. */
- if (pedantic && new_lineno < 0)
- pedwarn ("line number out of range in `#line' directive");
-
- /* skip over the line number. */
- while (ISDIGIT (*bp))
- bp++;
-
-#if 0 /* #line 10"foo.c" is supposed to be allowed. */
- if (*bp && !is_space[*bp]) {
- error ("invalid format `#line' directive");
- return;
- }
-#endif
-
- SKIP_WHITE_SPACE (bp);
-
- if (*bp == '\"') {
- static HASHNODE *fname_table[FNAME_HASHSIZE];
- HASHNODE *hp, **hash_bucket;
- U_CHAR *fname, *p;
- int fname_length;
-
- fname = ++bp;
-
- /* Turn the file name, which is a character string literal,
- into a null-terminated string. Do this in place. */
- p = bp;
- for (;;)
- switch ((*p++ = *bp++)) {
- case '\0':
- error ("invalid format `#line' directive");
- return 0;
-
- case '\\':
- if (! ignore_escape_flag)
- {
- char *bpc = (char *) bp;
- HOST_WIDEST_INT c = parse_escape (&bpc, (HOST_WIDEST_INT) (U_CHAR) (-1));
- bp = (U_CHAR *) bpc;
- if (c < 0)
- p--;
- else
- p[-1] = c;
- }
- break;
-
- case '\"':
- *--p = 0;
- goto fname_done;
- }
- fname_done:
- fname_length = p - fname;
-
- SKIP_WHITE_SPACE (bp);
- if (*bp) {
- if (pedantic)
- pedwarn ("garbage at end of `#line' directive");
- if (*bp == '1')
- file_change = enter_file;
- else if (*bp == '2')
- file_change = leave_file;
- else if (*bp == '3')
- ip->system_header_p = 1;
- else if (*bp == '4')
- ip->system_header_p = 2;
- else {
- error ("invalid format `#line' directive");
- return 0;
- }
-
- bp++;
- SKIP_WHITE_SPACE (bp);
- if (*bp == '3') {
- ip->system_header_p = 1;
- bp++;
- SKIP_WHITE_SPACE (bp);
- }
- if (*bp == '4') {
- ip->system_header_p = 2;
- bp++;
- SKIP_WHITE_SPACE (bp);
- }
- if (*bp) {
- error ("invalid format `#line' directive");
- return 0;
- }
- }
-
- hash_bucket = &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
- for (hp = *hash_bucket; hp != NULL; hp = hp->next)
- if (hp->length == fname_length &&
- bcmp (hp->value.cpval, fname, fname_length) == 0) {
- ip->nominal_fname = hp->value.cpval;
- ip->nominal_fname_len = fname_length;
- break;
- }
- if (hp == 0) {
- /* Didn't find it; cons up a new one. */
- hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
- hp->next = *hash_bucket;
- *hash_bucket = hp;
-
- ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
- ip->nominal_fname_len = hp->length = fname_length;
- bcopy (fname, hp->value.cpval, fname_length + 1);
- }
- } else if (*bp) {
- error ("invalid format `#line' directive");
- return 0;
- }
-
- ip->lineno = new_lineno;
- output_line_directive (ip, op, 0, file_change);
- check_expand (op, ip->length - (ip->bufp - ip->buf));
- return 0;
-}
-
-/* Remove the definition of a symbol from the symbol table.
- according to un*x /lib/cpp, it is not an error to undef
- something that has no definitions, so it isn't one here either. */
-
-static int
-do_undef (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- int sym_length;
- HASHNODE *hp;
- U_CHAR *orig_buf = buf;
-
- /* If this is a precompiler run (with -pcp) pass thru #undef directives. */
- if (pcp_outfile && op)
- pass_thru_directive (buf, limit, op, keyword);
-
- SKIP_WHITE_SPACE (buf);
- sym_length = check_macro_name (buf, 0);
-
- while ((hp = lookup (buf, sym_length, -1)) != NULL) {
- /* If we are generating additional info for debugging (with -g) we
- need to pass through all effective #undef directives. */
- if (debug_output && op)
- pass_thru_directive (orig_buf, limit, op, keyword);
- if (hp->type != T_MACRO)
- warning ("undefining `%s'", hp->name);
- delete_macro (hp);
- }
-
- if (pedantic) {
- buf += sym_length;
- SKIP_WHITE_SPACE (buf);
- if (buf != limit)
- pedwarn ("garbage after `#undef' directive");
- }
- return 0;
-}
-
-/* Report an error detected by the program we are processing.
- Use the text of the line in the error message.
- (We use error because it prints the filename & line#.) */
-
-static int
-do_error (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) alloca (length + 1);
- bcopy ((char *) buf, (char *) copy, length);
- copy[length] = 0;
- SKIP_WHITE_SPACE (copy);
- error ("#error %s", copy);
- return 0;
-}
-
-/* Report a warning detected by the program we are processing.
- Use the text of the line in the warning message, then continue.
- (We use error because it prints the filename & line#.) */
-
-static int
-do_warning (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) alloca (length + 1);
- bcopy ((char *) buf, (char *) copy, length);
- copy[length] = 0;
- SKIP_WHITE_SPACE (copy);
-
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#warning'");
-
- /* Use `pedwarn' not `warning', because #warning isn't in the C Standard;
- if -pedantic-errors is given, #warning should cause an error. */
- pedwarn ("#warning %s", copy);
- return 0;
-}
-
-/* Remember the name of the current file being read from so that we can
- avoid ever including it again. */
-
-static void
-do_once ()
-{
- int i;
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].inc) {
- record_control_macro (instack[i].inc, (U_CHAR *) "");
- break;
- }
-}
-
-/* Report program identification. */
-
-static int
-do_ident (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- FILE_BUF trybuf;
- int len;
-
- /* Allow #ident in system headers, since that's not user's fault. */
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#ident'");
-
- trybuf = expand_to_temp_buffer (buf, limit, 0, 0);
- buf = trybuf.buf;
- len = trybuf.bufp - buf;
-
- /* Output expanded directive. */
- check_expand (op, 7 + len);
- bcopy ("#ident ", (char *) op->bufp, 7);
- op->bufp += 7;
- bcopy ((char *) buf, (char *) op->bufp, len);
- op->bufp += len;
-
- free (buf);
- return 0;
-}
-
-/* #pragma and its argument line have already been copied to the output file.
- Just check for some recognized pragmas that need validation here. */
-
-static int
-do_pragma (buf, limit, op, keyword)
- U_CHAR *buf, *limit ATTRIBUTE_UNUSED;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- SKIP_WHITE_SPACE (buf);
- if (!strncmp ((char *) buf, "once", 4)) {
- /* Allow #pragma once in system headers, since that's not the user's
- fault. */
- if (!instack[indepth].system_header_p)
- warning ("`#pragma once' is obsolete");
- do_once ();
- }
-
- if (!strncmp ((char *) buf, "implementation", 14)) {
- /* Be quiet about `#pragma implementation' for a file only if it hasn't
- been included yet. */
-
- int h;
- U_CHAR *p = buf + 14, *fname;
- SKIP_WHITE_SPACE (p);
- if (*p != '\"')
- return 0;
-
- fname = p + 1;
- if ((p = (U_CHAR *) index ((char *) fname, '\"')))
- *p = '\0';
-
- for (h = 0; h < INCLUDE_HASHSIZE; h++) {
- struct include_file *inc;
- for (inc = include_hashtab[h]; inc; inc = inc->next) {
- if (!strcmp (base_name (inc->fname), (char *) fname)) {
- warning ("`#pragma implementation' for \"%s\" appears after its #include",fname);
- return 0;
- }
- }
- }
- }
- return 0;
-}
-
-#if 0
-/* This was a fun hack, but #pragma seems to start to be useful.
- By failing to recognize it, we pass it through unchanged to cc1. */
-
-/* The behavior of the #pragma directive is implementation defined.
- this implementation defines it as follows. */
-
-static int
-do_pragma ()
-{
- close (0);
- if (open ("/dev/tty", O_RDONLY, 0666) != 0)
- goto nope;
- close (1);
- if (open ("/dev/tty", O_WRONLY, 0666) != 1)
- goto nope;
- execl ("/usr/games/hack", "#pragma", 0);
- execl ("/usr/games/rogue", "#pragma", 0);
- execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
- execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
-nope:
- fatal ("You are in a maze of twisty compiler features, all different");
-}
-#endif
-
-#ifdef SCCS_DIRECTIVE
-
-/* Just ignore #sccs, on systems where we define it at all. */
-
-static int
-do_sccs (buf, limit, op, keyword)
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- if (pedantic)
- pedwarn ("ANSI C does not allow `#sccs'");
- return 0;
-}
-
-#endif /* defined (SCCS_DIRECTIVE) */
-
-/* Handle #if directive by
- 1) inserting special `defined' keyword into the hash table
- that gets turned into 0 or 1 by special_symbol (thus,
- if the luser has a symbol called `defined' already, it won't
- work inside the #if directive)
- 2) rescan the input into a temporary output buffer
- 3) pass the output buffer to the yacc parser and collect a value
- 4) clean up the mess left from steps 1 and 2.
- 5) call conditional_skip to skip til the next #endif (etc.),
- or not, depending on the value from step 3. */
-
-static int
-do_if (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- HOST_WIDEST_INT value;
- FILE_BUF *ip = &instack[indepth];
-
- value = eval_if_expression (buf, limit - buf);
- conditional_skip (ip, value == 0, T_IF, NULL_PTR, op);
- return 0;
-}
-
-/* Handle a #elif directive by not changing if_stack either.
- see the comment above do_else. */
-
-static int
-do_elif (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- HOST_WIDEST_INT value;
- FILE_BUF *ip = &instack[indepth];
-
- if (if_stack == instack[indepth].if_stack) {
- error ("`#elif' not within a conditional");
- return 0;
- } else {
- if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
- error ("`#elif' after `#else'");
- fprintf (stderr, " (matches line %d", if_stack->lineno);
- if (! (if_stack->fname_len == ip->nominal_fname_len
- && !bcmp (if_stack->fname, ip->nominal_fname,
- if_stack->fname_len))) {
- fprintf (stderr, ", file ");
- eprint_string (if_stack->fname, if_stack->fname_len);
- }
- fprintf (stderr, ")\n");
- }
- if_stack->type = T_ELIF;
- }
-
- if (if_stack->if_succeeded)
- skip_if_group (ip, 0, op);
- else {
- value = eval_if_expression (buf, limit - buf);
- if (value == 0)
- skip_if_group (ip, 0, op);
- else {
- ++if_stack->if_succeeded; /* continue processing input */
- output_line_directive (ip, op, 1, same_file);
- }
- }
- return 0;
-}
-
-/* Evaluate a #if expression in BUF, of length LENGTH, then parse the
- result as a C expression and return the value as an int. */
-
-static HOST_WIDEST_INT
-eval_if_expression (buf, length)
- U_CHAR *buf;
- int length;
-{
- FILE_BUF temp_obuf;
- HASHNODE *save_defined;
- HOST_WIDEST_INT value;
-
- save_defined = install ((U_CHAR *) "defined", -1, T_SPEC_DEFINED,
- NULL_PTR, -1);
- pcp_inside_if = 1;
- temp_obuf = expand_to_temp_buffer (buf, buf + length, 0, 1);
- pcp_inside_if = 0;
- delete_macro (save_defined); /* clean up special symbol */
-
- temp_obuf.buf[temp_obuf.length] = '\n';
- value = parse_c_expression ((char *) temp_obuf.buf,
- warn_undef && !instack[indepth].system_header_p);
-
- free (temp_obuf.buf);
-
- return value;
-}
-
-/* routine to handle ifdef/ifndef. Try to look up the symbol, then do
- or don't skip to the #endif/#else/#elif depending on what directive
- is actually being processed. */
-
-static int
-do_xifdef (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- int skip;
- FILE_BUF *ip = &instack[indepth];
- U_CHAR *end;
- int start_of_file = 0;
- U_CHAR *control_macro = 0;
-
- /* Detect a #ifndef at start of file (not counting comments). */
- if (ip->fname != 0 && keyword->type == T_IFNDEF) {
- U_CHAR *p = ip->buf;
- while (p != directive_start) {
- U_CHAR c = *p++;
- if (is_space[c])
- ;
- /* Make no special provision for backslash-newline here; this is
- slower if backslash-newlines are present, but it's correct,
- and it's not worth it to tune for the rare backslash-newline. */
- else if (c == '/'
- && (*p == '*' || (cplusplus_comments && *p == '/'))) {
- /* Skip this comment. */
- int junk = 0;
- U_CHAR *save_bufp = ip->bufp;
- ip->bufp = p + 1;
- p = skip_to_end_of_comment (ip, &junk, 1);
- ip->bufp = save_bufp;
- } else {
- goto fail;
- }
- }
- /* If we get here, this conditional is the beginning of the file. */
- start_of_file = 1;
- fail: ;
- }
-
- /* Discard leading and trailing whitespace. */
- SKIP_WHITE_SPACE (buf);
- while (limit != buf && is_hor_space[limit[-1]]) limit--;
-
- /* Find the end of the identifier at the beginning. */
- for (end = buf; is_idchar[*end]; end++);
-
- if (end == buf) {
- skip = (keyword->type == T_IFDEF);
- if (! traditional)
- pedwarn (end == limit ? "`#%s' with no argument"
- : "`#%s' argument starts with punctuation",
- keyword->name);
- } else {
- HASHNODE *hp;
-
- if (! traditional) {
- if (ISDIGIT (buf[0]))
- pedwarn ("`#%s' argument starts with a digit", keyword->name);
- else if (end != limit)
- pedwarn ("garbage at end of `#%s' argument", keyword->name);
- }
-
- hp = lookup (buf, end-buf, -1);
-
- if (pcp_outfile) {
- /* Output a precondition for this macro. */
- if (hp
- && (hp->type == T_CONST
- || (hp->type == T_MACRO && hp->value.defn->predefined)))
- fprintf (pcp_outfile, "#define %s\n", hp->name);
- else {
- U_CHAR *cp = buf;
- fprintf (pcp_outfile, "#undef ");
- while (is_idchar[*cp]) /* Ick! */
- fputc (*cp++, pcp_outfile);
- putc ('\n', pcp_outfile);
- }
- }
-
- skip = (hp == NULL) ^ (keyword->type == T_IFNDEF);
- if (start_of_file && !skip) {
- control_macro = (U_CHAR *) xmalloc (end - buf + 1);
- bcopy ((char *) buf, (char *) control_macro, end - buf);
- control_macro[end - buf] = 0;
- }
- }
-
- conditional_skip (ip, skip, T_IF, control_macro, op);
- return 0;
-}
-
-/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
- If this is a #ifndef starting at the beginning of a file,
- CONTROL_MACRO is the macro name tested by the #ifndef.
- Otherwise, CONTROL_MACRO is 0. */
-
-static void
-conditional_skip (ip, skip, type, control_macro, op)
- FILE_BUF *ip;
- int skip;
- enum node_type type;
- U_CHAR *control_macro;
- FILE_BUF *op;
-{
- IF_STACK_FRAME *temp;
-
- temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
- temp->fname = ip->nominal_fname;
- temp->fname_len = ip->nominal_fname_len;
- temp->lineno = ip->lineno;
- temp->next = if_stack;
- temp->control_macro = control_macro;
- if_stack = temp;
-
- if_stack->type = type;
-
- if (skip != 0) {
- skip_if_group (ip, 0, op);
- return;
- } else {
- ++if_stack->if_succeeded;
- output_line_directive (ip, &outbuf, 1, same_file);
- }
-}
-
-/* Skip to #endif, #else, or #elif. adjust line numbers, etc.
- Leaves input ptr at the sharp sign found.
- If ANY is nonzero, return at next directive of any sort. */
-
-static void
-skip_if_group (ip, any, op)
- FILE_BUF *ip;
- int any;
- FILE_BUF *op;
-{
- register U_CHAR *bp = ip->bufp, *cp;
- register U_CHAR *endb = ip->buf + ip->length;
- struct directive *kt;
- IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */
- U_CHAR *beg_of_line = bp;
- register int ident_length;
- U_CHAR *ident, *after_ident;
- /* Save info about where the group starts. */
- U_CHAR *beg_of_group = bp;
- int beg_lineno = ip->lineno;
- int skipping_include_directive = 0;
-
- if (output_conditionals && op != 0) {
- char *ptr = "#failed\n";
- int len = strlen (ptr);
-
- if (op->bufp > op->buf && op->bufp[-1] != '\n')
- {
- *op->bufp++ = '\n';
- op->lineno++;
- }
- check_expand (op, len);
- bcopy (ptr, (char *) op->bufp, len);
- op->bufp += len;
- op->lineno++;
- output_line_directive (ip, op, 1, 0);
- }
-
- while (bp < endb) {
- switch (*bp++) {
- case '/': /* possible comment */
- if (*bp == '\\' && bp[1] == '\n')
- newline_fix (bp);
- if (*bp == '*'
- || (cplusplus_comments && *bp == '/')) {
- ip->bufp = ++bp;
- bp = skip_to_end_of_comment (ip, &ip->lineno, 0);
- }
- break;
- case '<':
- if (skipping_include_directive) {
- while (bp < endb && *bp != '>' && *bp != '\n') {
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- bp++;
- }
- bp++;
- }
- }
- break;
- case '\"':
- if (skipping_include_directive) {
- while (bp < endb && *bp != '\n') {
- if (*bp == '"') {
- bp++;
- break;
- }
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- bp++;
- }
- bp++;
- }
- break;
- }
- /* Fall through. */
- case '\'':
- bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno,
- NULL_PTR, NULL_PTR);
- break;
- case '\\':
- /* Char after backslash loses its special meaning in some cases. */
- if (*bp == '\n') {
- ++ip->lineno;
- bp++;
- } else if (traditional && bp < endb)
- bp++;
- break;
- case '\n':
- ++ip->lineno;
- beg_of_line = bp;
- skipping_include_directive = 0;
- break;
- case '%':
- if (beg_of_line == 0 || traditional)
- break;
- ip->bufp = bp - 1;
- while (bp[0] == '\\' && bp[1] == '\n')
- bp += 2;
- if (*bp == ':')
- goto sharp_token;
- break;
- case '#':
- /* # keyword: a # must be first nonblank char on the line */
- if (beg_of_line == 0)
- break;
- ip->bufp = bp - 1;
- sharp_token:
- /* Scan from start of line, skipping whitespace, comments
- and backslash-newlines, and see if we reach this #.
- If not, this # is not special. */
- bp = beg_of_line;
- /* If -traditional, require # to be at beginning of line. */
- if (!traditional) {
- while (1) {
- if (is_hor_space[*bp])
- bp++;
- else if (*bp == '\\' && bp[1] == '\n')
- bp += 2;
- else if (*bp == '/' && bp[1] == '*') {
- bp += 2;
- while (1)
- {
- if (*bp == '*')
- {
- if (bp[1] == '/')
- {
- bp += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, endb - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- bp++;
- }
- }
- /* There is no point in trying to deal with C++ // comments here,
- because if there is one, then this # must be part of the
- comment and we would never reach here. */
- else break;
- }
- }
- if (bp != ip->bufp) {
- bp = ip->bufp + 1; /* Reset bp to after the #. */
- break;
- }
-
- bp = ip->bufp + 1; /* Point after the '#' */
- if (ip->bufp[0] == '%') {
- /* Skip past the ':' again. */
- while (*bp == '\\') {
- ip->lineno++;
- bp += 2;
- }
- bp++;
- }
-
- /* Skip whitespace and \-newline. */
- while (1) {
- if (is_hor_space[*bp])
- bp++;
- else if (*bp == '\\' && bp[1] == '\n')
- bp += 2;
- else if (*bp == '/') {
- if (bp[1] == '\\' && bp[2] == '\n')
- newline_fix (bp + 1);
- if (bp[1] == '*') {
- for (bp += 2; ; bp++) {
- if (*bp == '\n')
- ip->lineno++;
- else if (*bp == '*') {
- if (bp[-1] == '/' && warn_comments)
- warning ("`/*' within comment");
- if (bp[1] == '\\' && bp[2] == '\n')
- newline_fix (bp + 1);
- if (bp[1] == '/')
- break;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, endb - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- bp += 2;
- } else if (bp[1] == '/' && cplusplus_comments) {
- for (bp += 2; ; bp++) {
- if (*bp == '\n')
- break;
- if (*bp == '\\' && bp[1] == '\n')
- {
- if (warn_comments)
- warning ("multiline `//' comment");
- ip->lineno++;
- bp++;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, endb - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- } else
- break;
- } else
- break;
- }
-
- cp = bp;
-
- /* Now find end of directive name.
- If we encounter a backslash-newline, exchange it with any following
- symbol-constituents so that we end up with a contiguous name. */
-
- while (1) {
- if (is_idchar[*bp])
- bp++;
- else {
- if (*bp == '\\' && bp[1] == '\n')
- name_newline_fix (bp);
- if (is_idchar[*bp])
- bp++;
- else break;
- }
- }
- ident_length = bp - cp;
- ident = cp;
- after_ident = bp;
-
- /* A line of just `#' becomes blank. */
-
- if (ident_length == 0 && *after_ident == '\n') {
- continue;
- }
-
- if (ident_length == 0 || !is_idstart[*ident]) {
- U_CHAR *p = ident;
- while (is_idchar[*p]) {
- if (*p < '0' || *p > '9')
- break;
- p++;
- }
- /* Handle # followed by a line number. */
- if (p != ident && !is_idchar[*p]) {
- if (pedantic)
- pedwarn ("`#' followed by integer");
- continue;
- }
-
- /* Avoid error for `###' and similar cases unless -pedantic. */
- if (p == ident) {
- while (*p == '#' || is_hor_space[*p]) p++;
- if (*p == '\n') {
- if (pedantic && !lang_asm)
- pedwarn ("invalid preprocessing directive");
- continue;
- }
- }
-
- if (!lang_asm && pedantic)
- pedwarn ("invalid preprocessing directive name");
- continue;
- }
-
- for (kt = directive_table; kt->length >= 0; kt++) {
- IF_STACK_FRAME *temp;
- if (ident_length == kt->length
- && bcmp (cp, kt->name, kt->length) == 0) {
- /* If we are asked to return on next directive, do so now. */
- if (any)
- goto done;
-
- switch (kt->type) {
- case T_IF:
- case T_IFDEF:
- case T_IFNDEF:
- temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
- temp->next = if_stack;
- if_stack = temp;
- temp->lineno = ip->lineno;
- temp->fname = ip->nominal_fname;
- temp->fname_len = ip->nominal_fname_len;
- temp->type = kt->type;
- break;
- case T_ELSE:
- case T_ENDIF:
- if (pedantic && if_stack != save_if_stack)
- validate_else (bp, endb);
- case T_ELIF:
- if (if_stack == instack[indepth].if_stack) {
- error ("`#%s' not within a conditional", kt->name);
- break;
- }
- else if (if_stack == save_if_stack)
- goto done; /* found what we came for */
-
- if (kt->type != T_ENDIF) {
- if (if_stack->type == T_ELSE)
- error ("`#else' or `#elif' after `#else'");
- if_stack->type = kt->type;
- break;
- }
-
- temp = if_stack;
- if_stack = if_stack->next;
- free (temp);
- break;
-
- case T_INCLUDE:
- case T_INCLUDE_NEXT:
- case T_IMPORT:
- skipping_include_directive = 1;
- break;
-
- default:
- break;
- }
- break;
- }
- }
- /* Don't let erroneous code go by. */
- if (kt->length < 0 && !lang_asm && pedantic)
- pedwarn ("invalid preprocessing directive name");
- }
- }
-
- ip->bufp = bp;
- /* after this returns, rescan will exit because ip->bufp
- now points to the end of the buffer.
- rescan is responsible for the error message also. */
-
- done:
- if (output_conditionals && op != 0) {
- char *ptr = "#endfailed\n";
- int len = strlen (ptr);
-
- if (op->bufp > op->buf && op->bufp[-1] != '\n')
- {
- *op->bufp++ = '\n';
- op->lineno++;
- }
- check_expand (op, beg_of_line - beg_of_group);
- bcopy ((char *) beg_of_group, (char *) op->bufp,
- beg_of_line - beg_of_group);
- op->bufp += beg_of_line - beg_of_group;
- op->lineno += ip->lineno - beg_lineno;
- check_expand (op, len);
- bcopy (ptr, (char *) op->bufp, len);
- op->bufp += len;
- op->lineno++;
- }
-}
-
-/* Handle a #else directive. Do this by just continuing processing
- without changing if_stack ; this is so that the error message
- for missing #endif's etc. will point to the original #if. It
- is possible that something different would be better. */
-
-static int
-do_else (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- FILE_BUF *ip = &instack[indepth];
-
- if (pedantic) {
- SKIP_WHITE_SPACE (buf);
- if (buf != limit)
- pedwarn ("text following `#else' violates ANSI standard");
- }
-
- if (if_stack == instack[indepth].if_stack) {
- error ("`#else' not within a conditional");
- return 0;
- } else {
- /* #ifndef can't have its special treatment for containing the whole file
- if it has a #else clause. */
- if_stack->control_macro = 0;
-
- if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
- error ("`#else' after `#else'");
- fprintf (stderr, " (matches line %d", if_stack->lineno);
- if (! (if_stack->fname_len == ip->nominal_fname_len
- && !bcmp (if_stack->fname, ip->nominal_fname,
- if_stack->fname_len))) {
- fprintf (stderr, ", file ");
- eprint_string (if_stack->fname, if_stack->fname_len);
- }
- fprintf (stderr, ")\n");
- }
- if_stack->type = T_ELSE;
- }
-
- if (if_stack->if_succeeded)
- skip_if_group (ip, 0, op);
- else {
- ++if_stack->if_succeeded; /* continue processing input */
- output_line_directive (ip, op, 1, same_file);
- }
- return 0;
-}
-
-/* Unstack after #endif directive. */
-
-static int
-do_endif (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- if (pedantic) {
- SKIP_WHITE_SPACE (buf);
- if (buf != limit)
- pedwarn ("text following `#endif' violates ANSI standard");
- }
-
- if (if_stack == instack[indepth].if_stack)
- error ("unbalanced `#endif'");
- else {
- IF_STACK_FRAME *temp = if_stack;
- if_stack = if_stack->next;
- if (temp->control_macro != 0) {
- /* This #endif matched a #ifndef at the start of the file.
- See if it is at the end of the file. */
- FILE_BUF *ip = &instack[indepth];
- U_CHAR *p = ip->bufp;
- U_CHAR *ep = ip->buf + ip->length;
-
- while (p != ep) {
- U_CHAR c = *p++;
- if (!is_space[c]) {
- if (c == '/'
- && (*p == '*' || (cplusplus_comments && *p == '/'))) {
- /* Skip this comment. */
- int junk = 0;
- U_CHAR *save_bufp = ip->bufp;
- ip->bufp = p + 1;
- p = skip_to_end_of_comment (ip, &junk, 1);
- ip->bufp = save_bufp;
- } else
- goto fail;
- }
- }
- /* If we get here, this #endif ends a #ifndef
- that contains all of the file (aside from whitespace).
- Arrange not to include the file again
- if the macro that was tested is defined.
-
- Do not do this for the top-level file in a -include or any
- file in a -imacros. */
- if (indepth != 0
- && ! (indepth == 1 && no_record_file)
- && ! (no_record_file && no_output))
- record_control_macro (ip->inc, temp->control_macro);
- fail: ;
- }
- free (temp);
- output_line_directive (&instack[indepth], op, 1, same_file);
- }
- return 0;
-}
-
-/* When an #else or #endif is found while skipping failed conditional,
- if -pedantic was specified, this is called to warn about text after
- the directive name. P points to the first char after the directive
- name. */
-
-static void
-validate_else (p, limit)
- register U_CHAR *p;
- register U_CHAR *limit;
-{
- /* Advance P over whitespace and comments. */
- while (1) {
- while (*p == '\\' && p[1] == '\n')
- p += 2;
- if (is_hor_space[*p])
- p++;
- else if (*p == '/') {
- while (p[1] == '\\' && p[2] == '\n')
- p += 2;
- if (p[1] == '*') {
- /* Don't bother warning about unterminated comments
- since that will happen later. Just be sure to exit. */
- for (p += 2; ; p++) {
- if (p == limit)
- return;
- if (*p == '*') {
- while (p[1] == '\\' && p[2] == '\n')
- p += 2;
- if (p[1] == '/') {
- p += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (p, limit - p);
- if (length > 1)
- p += (length - 1);
-#endif
- }
- }
- }
- else if (cplusplus_comments && p[1] == '/')
- return;
- else break;
- } else break;
- }
- if (*p != '\n')
- pedwarn ("text following `#else' or `#endif' violates ANSI standard");
-}
-
-/* Skip a comment, assuming the input ptr immediately follows the
- initial slash-star. Bump *LINE_COUNTER for each newline.
- (The canonical line counter is &ip->lineno.)
- Don't use this routine (or the next one) if bumping the line
- counter is not sufficient to deal with newlines in the string.
-
- If NOWARN is nonzero, don't warn about slash-star inside a comment.
- This feature is useful when processing a comment that is going to
- be processed or was processed at another point in the preprocessor,
- to avoid a duplicate warning. Likewise for unterminated comment
- errors. */
-
-static U_CHAR *
-skip_to_end_of_comment (ip, line_counter, nowarn)
- register FILE_BUF *ip;
- int *line_counter; /* place to remember newlines, or NULL */
- int nowarn;
-{
- register U_CHAR *limit = ip->buf + ip->length;
- register U_CHAR *bp = ip->bufp;
- FILE_BUF *op = put_out_comments && !line_counter ? &outbuf : (FILE_BUF *) 0;
- int start_line = line_counter ? *line_counter : 0;
-
- /* JF this line_counter stuff is a crock to make sure the
- comment is only put out once, no matter how many times
- the comment is skipped. It almost works */
- if (op) {
- *op->bufp++ = '/';
- *op->bufp++ = bp[-1];
- }
- if (cplusplus_comments && bp[-1] == '/') {
- for (; bp < limit; bp++) {
- if (*bp == '\n')
- break;
- if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n')
- {
- if (!nowarn && warn_comments)
- warning ("multiline `//' comment");
- if (line_counter)
- ++*line_counter;
- if (op)
- {
- ++op->lineno;
- *op->bufp++ = *bp;
- }
- ++bp;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- {
- if (op)
- {
- bcopy (bp, op->bufp, length - 1);
- op->bufp += (length - 1);
- }
- bp += (length - 1);
- }
-#endif
- }
- if (op)
- *op->bufp++ = *bp;
- }
- ip->bufp = bp;
- return bp;
- }
- while (bp < limit) {
- if (op)
- *op->bufp++ = *bp;
- switch (*bp++) {
- case '\n':
- /* If this is the end of the file, we have an unterminated comment.
- Don't swallow the newline. We are guaranteed that there will be a
- trailing newline and various pieces assume it's there. */
- if (bp == limit)
- {
- --bp;
- --limit;
- break;
- }
- if (line_counter != NULL)
- ++*line_counter;
- if (op)
- ++op->lineno;
- break;
- case '*':
- if (bp[-2] == '/' && !nowarn && warn_comments)
- warning ("`/*' within comment");
- if (*bp == '\\' && bp[1] == '\n')
- newline_fix (bp);
- if (*bp == '/') {
- if (op)
- *op->bufp++ = '/';
- ip->bufp = ++bp;
- return bp;
- }
- break;
-#ifdef MULTIBYTE_CHARS
- default:
- {
- int length;
- bp--;
- length = local_mblen (bp, limit - bp);
- if (length <= 0)
- length = 1;
- if (op)
- {
- op->bufp--;
- bcopy (bp, op->bufp, length);
- op->bufp += length;
- }
- bp += length;
- }
-#endif
- }
- }
-
- if (!nowarn)
- error_with_line (line_for_error (start_line), "unterminated comment");
- ip->bufp = bp;
- return bp;
-}
-
-/* Skip over a quoted string. BP points to the opening quote.
- Returns a pointer after the closing quote. Don't go past LIMIT.
- START_LINE is the line number of the starting point (but it need
- not be valid if the starting point is inside a macro expansion).
-
- The input stack state is not changed.
-
- If COUNT_NEWLINES is nonzero, it points to an int to increment
- for each newline passed.
-
- If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
- if we pass a backslash-newline.
-
- If EOFP is nonzero, set *EOFP to 1 if the string is unterminated. */
-
-static U_CHAR *
-skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
- register U_CHAR *bp;
- register U_CHAR *limit;
- int start_line;
- int *count_newlines;
- int *backslash_newlines_p;
- int *eofp;
-{
- register U_CHAR c, match;
-
- match = *bp++;
- while (1) {
- if (bp >= limit) {
- error_with_line (line_for_error (start_line),
- "unterminated string or character constant");
- error_with_line (multiline_string_line,
- "possible real start of unterminated constant");
- multiline_string_line = 0;
- if (eofp)
- *eofp = 1;
- break;
- }
- c = *bp++;
- if (c == '\\') {
- while (*bp == '\\' && bp[1] == '\n') {
- if (backslash_newlines_p)
- *backslash_newlines_p = 1;
- if (count_newlines)
- ++*count_newlines;
- bp += 2;
- }
- if (*bp == '\n') {
- if (backslash_newlines_p)
- *backslash_newlines_p = 1;
- if (count_newlines)
- ++*count_newlines;
- }
- bp++;
- } else if (c == '\n') {
- if (traditional) {
- /* Unterminated strings and character constants are 'valid'. */
- bp--; /* Don't consume the newline. */
- if (eofp)
- *eofp = 1;
- break;
- }
- if (match == '\'') {
- error_with_line (line_for_error (start_line),
- "unterminated string or character constant");
- bp--;
- if (eofp)
- *eofp = 1;
- break;
- }
- /* If not traditional, then allow newlines inside strings. */
- if (count_newlines)
- ++*count_newlines;
- if (multiline_string_line == 0) {
- if (pedantic)
- pedwarn_with_line (line_for_error (start_line),
- "string constant runs past end of line");
- multiline_string_line = start_line;
- }
- } else if (c == match)
- break;
-#ifdef MULTIBYTE_CHARS
- {
- int length;
- --bp;
- length = local_mblen (bp, limit - bp);
- if (length <= 0)
- length = 1;
- bp += length;
- }
-#endif
- }
- return bp;
-}
-
-/* Place into DST a quoted string representing the string SRC.
- SRCLEN is the length of SRC; SRC may contain null bytes.
- Return the address of DST's terminating null. */
-
-static char *
-quote_string (dst, src, srclen)
- char *dst, *src;
- size_t srclen;
-{
- U_CHAR c;
- char *srclim = src + srclen;
-
- *dst++ = '\"';
- while (src != srclim)
- switch ((c = *src++))
- {
- default:
- if (ISPRINT (c))
- *dst++ = c;
- else
- {
- sprintf (dst, "\\%03o", c);
- dst += 4;
- }
- break;
-
- case '\"':
- case '\\':
- *dst++ = '\\';
- *dst++ = c;
- break;
- }
-
- *dst++ = '\"';
- *dst = '\0';
- return dst;
-}
-
-/* Skip across a group of balanced parens, starting from IP->bufp.
- IP->bufp is updated. Use this with IP->bufp pointing at an open-paren.
-
- This does not handle newlines, because it's used for the arg of #if,
- where there aren't any newlines. Also, backslash-newline can't appear. */
-
-static U_CHAR *
-skip_paren_group (ip)
- register FILE_BUF *ip;
-{
- U_CHAR *limit = ip->buf + ip->length;
- U_CHAR *p = ip->bufp;
- int depth = 0;
- int lines_dummy = 0;
-
- while (p != limit) {
- int c = *p++;
- switch (c) {
- case '(':
- depth++;
- break;
-
- case ')':
- depth--;
- if (depth == 0)
- return ip->bufp = p;
- break;
-
- case '/':
- if (*p == '*') {
- ip->bufp = p;
- p = skip_to_end_of_comment (ip, &lines_dummy, 0);
- p = ip->bufp;
- }
-
- case '"':
- case '\'':
- {
- int eofp = 0;
- p = skip_quoted_string (p - 1, limit, 0, NULL_PTR, NULL_PTR, &eofp);
- if (eofp)
- return ip->bufp = p;
- }
- break;
- }
- }
-
- ip->bufp = p;
- return p;
-}
-
-/* Write out a #line directive, for instance, after an #include file.
- If CONDITIONAL is nonzero, we can omit the #line if it would
- appear to be a no-op, and we can output a few newlines instead
- if we want to increase the line number by a small amount.
- FILE_CHANGE says whether we are entering a file, leaving, or neither. */
-
-static void
-output_line_directive (ip, op, conditional, file_change)
- FILE_BUF *ip, *op;
- int conditional;
- enum file_change_code file_change;
-{
- int len;
- char *line_directive_buf, *line_end;
-
- if (no_line_directives
- || ip->fname == NULL
- || no_output) {
- op->lineno = ip->lineno;
- return;
- }
-
- if (conditional) {
- if (ip->lineno == op->lineno)
- return;
-
- /* If the inherited line number is a little too small,
- output some newlines instead of a #line directive. */
- if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) {
- check_expand (op, 10);
- while (ip->lineno > op->lineno) {
- *op->bufp++ = '\n';
- op->lineno++;
- }
- return;
- }
- }
-
- /* Output a positive line number if possible. */
- while (ip->lineno <= 0 && ip->bufp - ip->buf < ip->length
- && *ip->bufp == '\n') {
- ip->lineno++;
- ip->bufp++;
- }
-
- line_directive_buf = (char *) alloca (4 * ip->nominal_fname_len + 100);
- sprintf (line_directive_buf, "# %d ", ip->lineno);
- line_end = quote_string (line_directive_buf + strlen (line_directive_buf),
- ip->nominal_fname, ip->nominal_fname_len);
- if (file_change != same_file) {
- *line_end++ = ' ';
- *line_end++ = file_change == enter_file ? '1' : '2';
- }
- /* Tell cc1 if following text comes from a system header file. */
- if (ip->system_header_p) {
- *line_end++ = ' ';
- *line_end++ = '3';
- }
-#ifndef NO_IMPLICIT_EXTERN_C
- /* Tell cc1plus if following text should be treated as C. */
- if (ip->system_header_p == 2 && cplusplus) {
- *line_end++ = ' ';
- *line_end++ = '4';
- }
-#endif
- *line_end++ = '\n';
- len = line_end - line_directive_buf;
- check_expand (op, len + 1);
- if (op->bufp > op->buf && op->bufp[-1] != '\n')
- *op->bufp++ = '\n';
- bcopy ((char *) line_directive_buf, (char *) op->bufp, len);
- op->bufp += len;
- op->lineno = ip->lineno;
-}
-
-/* This structure represents one parsed argument in a macro call.
- `raw' points to the argument text as written (`raw_length' is its length).
- `expanded' points to the argument's macro-expansion
- (its length is `expand_length').
- `stringified_length' is the length the argument would have
- if stringified.
- `use_count' is the number of times this macro arg is substituted
- into the macro. If the actual use count exceeds 10,
- the value stored is 10.
- `free1' and `free2', if nonzero, point to blocks to be freed
- when the macro argument data is no longer needed. */
-
-struct argdata {
- U_CHAR *raw, *expanded;
- int raw_length, expand_length;
- int stringified_length;
- U_CHAR *free1, *free2;
- char newlines;
- char use_count;
-};
-
-/* Expand a macro call.
- HP points to the symbol that is the macro being called.
- Put the result of expansion onto the input stack
- so that subsequent input by our caller will use it.
-
- If macro wants arguments, caller has already verified that
- an argument list follows; arguments come from the input stack. */
-
-static void
-macroexpand (hp, op)
- HASHNODE *hp;
- FILE_BUF *op;
-{
- int nargs;
- DEFINITION *defn = hp->value.defn;
- register U_CHAR *xbuf;
- int xbuf_len;
- int start_line = instack[indepth].lineno;
- int rest_args, rest_zero;
-
- CHECK_DEPTH (return;);
-
- /* it might not actually be a macro. */
- if (hp->type != T_MACRO) {
- special_symbol (hp, op);
- return;
- }
-
- /* This macro is being used inside a #if, which means it must be */
- /* recorded as a precondition. */
- if (pcp_inside_if && pcp_outfile && defn->predefined)
- dump_single_macro (hp, pcp_outfile);
-
- nargs = defn->nargs;
-
- if (nargs >= 0) {
- register int i;
- struct argdata *args;
- int parse_error = 0;
-
- args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
-
- for (i = 0; i < nargs; i++) {
- args[i].raw = (U_CHAR *) "";
- args[i].expanded = 0;
- args[i].raw_length = args[i].expand_length
- = args[i].stringified_length = 0;
- args[i].free1 = args[i].free2 = 0;
- args[i].use_count = 0;
- }
-
- /* Parse all the macro args that are supplied. I counts them.
- The first NARGS args are stored in ARGS.
- The rest are discarded.
- If rest_args is set then we assume macarg absorbed the rest of the args.
- */
- i = 0;
- rest_args = 0;
- do {
- /* Discard the open-parenthesis or comma before the next arg. */
- ++instack[indepth].bufp;
- if (rest_args)
- continue;
- if (i < nargs || (nargs == 0 && i == 0)) {
- /* If we are working on last arg which absorbs rest of args... */
- if (i == nargs - 1 && defn->rest_args)
- rest_args = 1;
- parse_error = macarg (&args[i], rest_args);
- }
- else
- parse_error = macarg (NULL_PTR, 0);
- if (parse_error) {
- error_with_line (line_for_error (start_line),
- "unterminated macro call");
- break;
- }
- i++;
- } while (*instack[indepth].bufp != ')');
-
- /* If we got one arg but it was just whitespace, call that 0 args. */
- if (i == 1) {
- register U_CHAR *bp = args[0].raw;
- register U_CHAR *lim = bp + args[0].raw_length;
- /* cpp.texi says for foo ( ) we provide one argument.
- However, if foo wants just 0 arguments, treat this as 0. */
- if (nargs == 0)
- while (bp != lim && is_space[*bp]) bp++;
- if (bp == lim)
- i = 0;
- }
-
- /* Don't output an error message if we have already output one for
- a parse error above. */
- rest_zero = 0;
- if (nargs == 0 && i > 0) {
- if (! parse_error)
- error ("arguments given to macro `%s'", hp->name);
- } else if (i < nargs) {
- /* traditional C allows foo() if foo wants one argument. */
- if (nargs == 1 && i == 0 && traditional)
- ;
- /* the rest args token is allowed to absorb 0 tokens */
- else if (i == nargs - 1 && defn->rest_args)
- rest_zero = 1;
- else if (parse_error)
- ;
- else if (i == 0)
- error ("macro `%s' used without args", hp->name);
- else if (i == 1)
- error ("macro `%s' used with just one arg", hp->name);
- else
- error ("macro `%s' used with only %d args", hp->name, i);
- } else if (i > nargs) {
- if (! parse_error)
- error ("macro `%s' used with too many (%d) args", hp->name, i);
- }
-
- /* Swallow the closeparen. */
- ++instack[indepth].bufp;
-
- /* If macro wants zero args, we parsed the arglist for checking only.
- Read directly from the macro definition. */
- if (nargs == 0) {
- xbuf = defn->expansion;
- xbuf_len = defn->length;
- } else {
- register U_CHAR *exp = defn->expansion;
- register int offset; /* offset in expansion,
- copied a piece at a time */
- register int totlen; /* total amount of exp buffer filled so far */
-
- register struct reflist *ap, *last_ap;
-
- /* Macro really takes args. Compute the expansion of this call. */
-
- /* Compute length in characters of the macro's expansion.
- Also count number of times each arg is used. */
- xbuf_len = defn->length;
- for (ap = defn->pattern; ap != NULL; ap = ap->next) {
- if (ap->stringify)
- xbuf_len += args[ap->argno].stringified_length;
- else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional)
- /* Add 4 for two newline-space markers to prevent
- token concatenation. */
- xbuf_len += args[ap->argno].raw_length + 4;
- else {
- /* We have an ordinary (expanded) occurrence of the arg.
- So compute its expansion, if we have not already. */
- if (args[ap->argno].expanded == 0) {
- FILE_BUF obuf;
- obuf = expand_to_temp_buffer (args[ap->argno].raw,
- args[ap->argno].raw + args[ap->argno].raw_length,
- 1, 0);
-
- args[ap->argno].expanded = obuf.buf;
- args[ap->argno].expand_length = obuf.length;
- args[ap->argno].free2 = obuf.buf;
- }
-
- /* Add 4 for two newline-space markers to prevent
- token concatenation. */
- xbuf_len += args[ap->argno].expand_length + 4;
- }
- if (args[ap->argno].use_count < 10)
- args[ap->argno].use_count++;
- }
-
- xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
-
- /* Generate in XBUF the complete expansion
- with arguments substituted in.
- TOTLEN is the total size generated so far.
- OFFSET is the index in the definition
- of where we are copying from. */
- offset = totlen = 0;
- for (last_ap = NULL, ap = defn->pattern; ap != NULL;
- last_ap = ap, ap = ap->next) {
- register struct argdata *arg = &args[ap->argno];
- int count_before = totlen;
-
- /* Add chars to XBUF. */
- for (i = 0; i < ap->nchars; i++, offset++)
- xbuf[totlen++] = exp[offset];
-
- /* If followed by an empty rest arg with concatenation,
- delete the last run of nonwhite chars. */
- if (rest_zero && totlen > count_before
- && ((ap->rest_args && ap->raw_before != 0)
- || (last_ap != NULL && last_ap->rest_args
- && last_ap->raw_after != 0))) {
- /* Delete final whitespace. */
- while (totlen > count_before && is_space[xbuf[totlen - 1]]) {
- totlen--;
- }
-
- /* Delete the nonwhites before them. */
- while (totlen > count_before && ! is_space[xbuf[totlen - 1]]) {
- totlen--;
- }
- }
-
- if (ap->stringify != 0) {
- int arglen = arg->raw_length;
- int escaped = 0;
- int in_string = 0;
- int c;
- i = 0;
- while (i < arglen
- && (c = arg->raw[i], is_space[c]))
- i++;
- while (i < arglen
- && (c = arg->raw[arglen - 1], is_space[c]))
- arglen--;
- if (!traditional)
- xbuf[totlen++] = '\"'; /* insert beginning quote */
- for (; i < arglen; i++) {
- c = arg->raw[i];
-
- if (! in_string) {
- /* Special markers Newline Space
- generate nothing for a stringified argument. */
- if (c == '\n' && arg->raw[i+1] != '\n') {
- i++;
- continue;
- }
-
- /* Internal sequences of whitespace are replaced by one space
- except within an string or char token. */
- if (c == '\n' ? arg->raw[i+1] == '\n' : is_space[c]) {
- while (1) {
- /* Note that Newline Space does occur within whitespace
- sequences; consider it part of the sequence. */
- if (c == '\n' && is_space[arg->raw[i+1]])
- i += 2;
- else if (c != '\n' && is_space[c])
- i++;
- else break;
- c = arg->raw[i];
- }
- i--;
- c = ' ';
- }
- }
-
- if (escaped)
- escaped = 0;
- else {
- if (c == '\\')
- escaped = 1;
- else if (in_string) {
- if (c == in_string)
- in_string = 0;
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (arg->raw + i, arglen - i);
- if (length > 1)
- {
- bcopy (arg->raw + i, xbuf + totlen, length);
- i += length - 1;
- totlen += length;
- continue;
- }
-#endif
- }
- } else if (c == '\"' || c == '\'')
- in_string = c;
- }
-
- /* Escape these chars */
- if (c == '\"' || (in_string && c == '\\'))
- xbuf[totlen++] = '\\';
- /* We used to output e.g. \008 for control characters here,
- but this doesn't conform to the C Standard.
- Just output the characters as-is. */
- xbuf[totlen++] = c;
- }
- if (!traditional)
- xbuf[totlen++] = '\"'; /* insert ending quote */
- } else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional) {
- U_CHAR *p1 = arg->raw;
- U_CHAR *l1 = p1 + arg->raw_length;
- if (ap->raw_before != 0) {
- while (p1 != l1 && is_space[*p1]) p1++;
- while (p1 != l1 && is_idchar[*p1])
- xbuf[totlen++] = *p1++;
- /* Delete any no-reexpansion marker that follows
- an identifier at the beginning of the argument
- if the argument is concatenated with what precedes it. */
- if (p1[0] == '\n' && p1[1] == '-')
- p1 += 2;
- } else if (!traditional) {
- /* Ordinary expanded use of the argument.
- Put in newline-space markers to prevent token pasting. */
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- if (ap->raw_after != 0) {
- /* Arg is concatenated after: delete trailing whitespace,
- whitespace markers, and no-reexpansion markers. */
- while (p1 != l1) {
- if (is_space[l1[-1]]) l1--;
- else if (l1[-1] == '-') {
- U_CHAR *p2 = l1 - 1;
- /* If a `-' is preceded by an odd number of newlines then it
- and the last newline are a no-reexpansion marker. */
- while (p2 != p1 && p2[-1] == '\n') p2--;
- if ((l1 - 1 - p2) & 1) {
- l1 -= 2;
- }
- else break;
- }
- else break;
- }
- }
-
- bcopy ((char *) p1, (char *) (xbuf + totlen), l1 - p1);
- totlen += l1 - p1;
- if (!traditional && ap->raw_after == 0) {
- /* Ordinary expanded use of the argument.
- Put in newline-space markers to prevent token pasting. */
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- } else {
- /* Ordinary expanded use of the argument.
- Put in newline-space markers to prevent token pasting. */
- if (!traditional) {
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- bcopy ((char *) arg->expanded, (char *) (xbuf + totlen),
- arg->expand_length);
- totlen += arg->expand_length;
- if (!traditional) {
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- /* If a macro argument with newlines is used multiple times,
- then only expand the newlines once. This avoids creating output
- lines which don't correspond to any input line, which confuses
- gdb and gcov. */
- if (arg->use_count > 1 && arg->newlines > 0) {
- /* Don't bother doing change_newlines for subsequent
- uses of arg. */
- arg->use_count = 1;
- arg->expand_length
- = change_newlines (arg->expanded, arg->expand_length);
- }
- }
-
- if (totlen > xbuf_len)
- abort ();
- }
-
- /* If there is anything left of the definition after handling
- the arg list, copy that in too. */
-
- for (i = offset; i < defn->length; i++) {
- /* if we've reached the end of the macro */
- if (exp[i] == ')')
- rest_zero = 0;
- if (! (rest_zero && last_ap != NULL && last_ap->rest_args
- && last_ap->raw_after != 0))
- xbuf[totlen++] = exp[i];
- }
-
- xbuf[totlen] = 0;
- xbuf_len = totlen;
-
- for (i = 0; i < nargs; i++) {
- if (args[i].free1 != 0)
- free (args[i].free1);
- if (args[i].free2 != 0)
- free (args[i].free2);
- }
- }
- } else {
- xbuf = defn->expansion;
- xbuf_len = defn->length;
- }
-
- /* Now put the expansion on the input stack
- so our caller will commence reading from it. */
- {
- register FILE_BUF *ip2;
-
- ip2 = &instack[++indepth];
-
- ip2->fname = 0;
- ip2->nominal_fname = 0;
- ip2->nominal_fname_len = 0;
- ip2->inc = 0;
- /* This may not be exactly correct, but will give much better error
- messages for nested macro calls than using a line number of zero. */
- ip2->lineno = start_line;
- ip2->buf = xbuf;
- ip2->length = xbuf_len;
- ip2->bufp = xbuf;
- ip2->free_ptr = (nargs > 0) ? xbuf : 0;
- ip2->macro = hp;
- ip2->if_stack = if_stack;
- ip2->system_header_p = 0;
-
- /* Recursive macro use sometimes works traditionally.
- #define foo(x,y) bar (x (y,0), y)
- foo (foo, baz) */
-
- if (!traditional)
- hp->type = T_DISABLED;
- }
-}
-
-/* Parse a macro argument and store the info on it into *ARGPTR.
- REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
- Return nonzero to indicate a syntax error. */
-
-static int
-macarg (argptr, rest_args)
- register struct argdata *argptr;
- int rest_args;
-{
- FILE_BUF *ip = &instack[indepth];
- int paren = 0;
- int newlines = 0;
- int comments = 0;
- int result = 0;
-
- /* Try to parse as much of the argument as exists at this
- input stack level. */
- U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length, ip->macro,
- &paren, &newlines, &comments, rest_args);
-
- /* If we find the end of the argument at this level,
- set up *ARGPTR to point at it in the input stack. */
- if (!(ip->fname != 0 && (newlines != 0 || comments != 0))
- && bp != ip->buf + ip->length) {
- if (argptr != 0) {
- argptr->raw = ip->bufp;
- argptr->raw_length = bp - ip->bufp;
- argptr->newlines = newlines;
- }
- ip->bufp = bp;
- } else {
- /* This input stack level ends before the macro argument does.
- We must pop levels and keep parsing.
- Therefore, we must allocate a temporary buffer and copy
- the macro argument into it. */
- int bufsize = bp - ip->bufp;
- int extra = newlines;
- U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1);
- int final_start = 0;
-
- bcopy ((char *) ip->bufp, (char *) buffer, bufsize);
- ip->bufp = bp;
- ip->lineno += newlines;
-
- while (bp == ip->buf + ip->length) {
- if (instack[indepth].macro == 0) {
- result = 1;
- break;
- }
- ip->macro->type = T_MACRO;
- if (ip->free_ptr)
- free (ip->free_ptr);
- ip = &instack[--indepth];
- newlines = 0;
- comments = 0;
- bp = macarg1 (ip->bufp, ip->buf + ip->length, ip->macro, &paren,
- &newlines, &comments, rest_args);
- final_start = bufsize;
- bufsize += bp - ip->bufp;
- extra += newlines;
- buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1);
- bcopy ((char *) ip->bufp, (char *) (buffer + bufsize - (bp - ip->bufp)),
- bp - ip->bufp);
- ip->bufp = bp;
- ip->lineno += newlines;
- }
-
- /* Now, if arg is actually wanted, record its raw form,
- discarding comments and duplicating newlines in whatever
- part of it did not come from a macro expansion.
- EXTRA space has been preallocated for duplicating the newlines.
- FINAL_START is the index of the start of that part. */
- if (argptr != 0) {
- argptr->raw = buffer;
- argptr->raw_length = bufsize;
- argptr->free1 = buffer;
- argptr->newlines = newlines;
- if ((newlines || comments) && ip->fname != 0)
- argptr->raw_length
- = final_start +
- discard_comments (argptr->raw + final_start,
- argptr->raw_length - final_start,
- newlines);
- argptr->raw[argptr->raw_length] = 0;
- if (argptr->raw_length > bufsize + extra)
- abort ();
- }
- }
-
- /* If we are not discarding this argument,
- macroexpand it and compute its length as stringified.
- All this info goes into *ARGPTR. */
-
- if (argptr != 0) {
- register U_CHAR *buf, *lim;
- register int totlen;
-
- buf = argptr->raw;
- lim = buf + argptr->raw_length;
-
- while (buf != lim && is_space[*buf])
- buf++;
- while (buf != lim && is_space[lim[-1]])
- lim--;
- totlen = traditional ? 0 : 2; /* Count opening and closing quote. */
- while (buf != lim) {
- register U_CHAR c = *buf++;
- totlen++;
- /* Internal sequences of whitespace are replaced by one space
- in most cases, but not always. So count all the whitespace
- in case we need to keep it all. */
-#if 0
- if (is_space[c])
- SKIP_ALL_WHITE_SPACE (buf);
- else
-#endif
- if (c == '\"' || c == '\\') /* escape these chars */
- totlen++;
- }
- argptr->stringified_length = totlen;
- }
- return result;
-}
-
-/* Scan text from START (inclusive) up to LIMIT (exclusive),
- taken from the expansion of MACRO,
- counting parens in *DEPTHPTR,
- and return if reach LIMIT
- or before a `)' that would make *DEPTHPTR negative
- or before a comma when *DEPTHPTR is zero.
- Single and double quotes are matched and termination
- is inhibited within them. Comments also inhibit it.
- Value returned is pointer to stopping place.
-
- Increment *NEWLINES each time a newline is passed.
- REST_ARGS notifies macarg1 that it should absorb the rest of the args.
- Set *COMMENTS to 1 if a comment is seen. */
-
-static U_CHAR *
-macarg1 (start, limit, macro, depthptr, newlines, comments, rest_args)
- U_CHAR *start;
- register U_CHAR *limit;
- struct hashnode *macro;
- int *depthptr, *newlines, *comments;
- int rest_args;
-{
- register U_CHAR *bp = start;
-
- while (bp < limit) {
- switch (*bp) {
- case '(':
- (*depthptr)++;
- break;
- case ')':
- if (--(*depthptr) < 0)
- return bp;
- break;
- case '\\':
- /* Traditionally, backslash makes following char not special. */
- if (traditional && bp + 1 < limit && bp[1] != '\n')
- bp++;
- break;
- case '\n':
- ++*newlines;
- break;
- case '/':
- if (macro)
- break;
- if (bp[1] == '\\' && bp[2] == '\n')
- newline_fix (bp + 1);
- if (bp[1] == '*') {
- *comments = 1;
- for (bp += 2; bp < limit; bp++) {
- if (*bp == '\n')
- ++*newlines;
- else if (*bp == '*') {
- if (bp[-1] == '/' && warn_comments)
- warning ("`/*' within comment");
- if (bp[1] == '\\' && bp[2] == '\n')
- newline_fix (bp + 1);
- if (bp[1] == '/') {
- bp++;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- } else if (bp[1] == '/' && cplusplus_comments) {
- *comments = 1;
- for (bp += 2; bp < limit; bp++) {
- if (*bp == '\n') {
- ++*newlines;
- break;
- }
- if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n')
- {
- ++*newlines;
- if (warn_comments)
- warning ("multiline `//' comment");
- ++bp;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- }
- break;
- case '\'':
- case '\"':
- {
- int quotec;
- for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) {
- if (*bp == '\\') {
- bp++;
- if (*bp == '\n')
- ++*newlines;
- if (!macro) {
- while (*bp == '\\' && bp[1] == '\n') {
- bp += 2;
- ++*newlines;
- }
- }
- } else if (*bp == '\n') {
- ++*newlines;
- if (quotec == '\'')
- break;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- }
- break;
- case ',':
- /* if we've returned to lowest level and we aren't absorbing all args */
- if ((*depthptr) == 0 && rest_args == 0)
- return bp;
- break;
- }
- bp++;
- }
-
- return bp;
-}
-
-/* Discard comments and duplicate newlines
- in the string of length LENGTH at START,
- except inside of string constants.
- The string is copied into itself with its beginning staying fixed.
-
- NEWLINES is the number of newlines that must be duplicated.
- We assume that that much extra space is available past the end
- of the string. */
-
-static int
-discard_comments (start, length, newlines)
- U_CHAR *start;
- int length;
- int newlines;
-{
- register U_CHAR *ibp;
- register U_CHAR *obp;
- register U_CHAR *limit;
- register int c;
-
- /* If we have newlines to duplicate, copy everything
- that many characters up. Then, in the second part,
- we will have room to insert the newlines
- while copying down.
- NEWLINES may actually be too large, because it counts
- newlines in string constants, and we don't duplicate those.
- But that does no harm. */
- if (newlines > 0) {
- ibp = start + length;
- obp = ibp + newlines;
- limit = start;
- while (limit != ibp)
- *--obp = *--ibp;
- }
-
- ibp = start + newlines;
- limit = start + length + newlines;
- obp = start;
-
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- switch (c) {
- case '\n':
- /* Duplicate the newline. */
- *obp++ = '\n';
- break;
-
- case '\\':
- if (*ibp == '\n') {
- obp--;
- ibp++;
- }
- break;
-
- case '/':
- if (*ibp == '\\' && ibp[1] == '\n')
- newline_fix (ibp);
- /* Delete any comment. */
- if (cplusplus_comments && ibp[0] == '/') {
- /* Comments are equivalent to spaces. */
- obp[-1] = ' ';
- ibp++;
- while (ibp < limit)
- {
- if (*ibp == '\n')
- break;
- if (*ibp == '\\' && ibp + 1 < limit && ibp[1] == '\n')
- ibp++;
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
-#endif
- }
- ibp++;
- }
- break;
- }
- if (ibp[0] != '*' || ibp + 1 >= limit)
- break;
- /* Comments are equivalent to spaces.
- For -traditional, a comment is equivalent to nothing. */
- if (traditional)
- obp--;
- else
- obp[-1] = ' ';
- while (++ibp < limit) {
- if (ibp[0] == '*') {
- if (ibp[1] == '\\' && ibp[2] == '\n')
- newline_fix (ibp + 1);
- if (ibp[1] == '/') {
- ibp += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
-#endif
- }
- }
- break;
-
- case '\'':
- case '\"':
- /* Notice and skip strings, so that we don't
- think that comments start inside them,
- and so we don't duplicate newlines in them. */
- {
- int quotec = c;
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- if (c == quotec)
- break;
- if (c == '\n')
- {
- if (quotec == '\'')
- break;
- }
- else if (c == '\\') {
- if (ibp < limit && *ibp == '\n') {
- ibp++;
- obp--;
- } else {
- while (*ibp == '\\' && ibp[1] == '\n')
- ibp += 2;
- if (ibp < limit)
- *obp++ = *ibp++;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- ibp--;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- obp--;
- bcopy (ibp, obp, length);
- ibp += length;
- obp += length;
- }
- else
- ibp++;
-#endif
- }
- }
- }
- break;
- }
- }
-
- return obp - start;
-}
-
-/* Turn newlines to spaces in the string of length LENGTH at START,
- except inside of string constants.
- The string is copied into itself with its beginning staying fixed. */
-
-static int
-change_newlines (start, length)
- U_CHAR *start;
- int length;
-{
- register U_CHAR *ibp;
- register U_CHAR *obp;
- register U_CHAR *limit;
- register int c;
-
- ibp = start;
- limit = start + length;
- obp = start;
-
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- switch (c) {
- case '\n':
- /* If this is a NEWLINE NEWLINE, then this is a real newline in the
- string. Skip past the newline and its duplicate.
- Put a space in the output. */
- if (*ibp == '\n')
- {
- ibp++;
- obp--;
- *obp++ = ' ';
- }
- break;
-
- case '\'':
- case '\"':
- /* Notice and skip strings, so that we don't delete newlines in them. */
- {
- int quotec = c;
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- if (c == quotec)
- break;
- else if (c == '\\' && ibp < limit && *ibp == '\n')
- *obp++ = *ibp++;
- else if (c == '\n')
- {
- if (quotec == '\'')
- break;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- ibp--;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- obp--;
- bcopy (ibp, obp, length);
- ibp += length;
- obp += length;
- }
- else
- ibp++;
-#endif
- }
- }
- }
- break;
- }
- }
-
- return obp - start;
-}
-
-/* my_strerror - return the descriptive text associated with an
- `errno' code. */
-
-static char *
-my_strerror (errnum)
- int errnum;
-{
- char *result;
-
-#ifndef VMS
-#ifndef HAVE_STRERROR
- result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0);
-#else
- result = strerror (errnum);
-#endif
-#else /* VMS */
- /* VAXCRTL's strerror() takes an optional second argument, which only
- matters when the first argument is EVMSERR. However, it's simplest
- just to pass it unconditionally. `vaxc$errno' is declared in
- <errno.h>, and maintained by the library in parallel with `errno'.
- We assume that caller's `errnum' either matches the last setting of
- `errno' by the library or else does not have the value `EVMSERR'. */
-
- result = strerror (errnum, vaxc$errno);
-#endif
-
- if (!result)
- result = "errno = ?";
-
- return result;
-}
-
-/* notice - output message to stderr */
-
-static void
-notice VPROTO ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- vnotice (msgid, args);
- va_end (args);
-}
-
-static void
-vnotice (msgid, args)
- const char *msgid;
- va_list args;
-{
- vfprintf (stderr, _(msgid), args);
-}
-
-/* error - print error message and increment count of errors. */
-
-void
-error VPROTO ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- verror (msgid, args);
- va_end (args);
-}
-
-void
-verror (msgid, args)
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
- fprintf (stderr, ":%d: ", ip->lineno);
- }
- vnotice (msgid, args);
- fprintf (stderr, "\n");
- errors++;
-}
-
-/* Error including a message from `errno'. */
-
-static void
-error_from_errno (name)
- char *name;
-{
- int e = errno;
- int i;
- FILE_BUF *ip = NULL;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
- fprintf (stderr, ":%d: ", ip->lineno);
- }
-
- fprintf (stderr, "%s: %s\n", name, my_strerror (e));
-
- errors++;
-}
-
-/* Print error message but don't count it. */
-
-void
-warning VPROTO ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- vwarning (msgid, args);
- va_end (args);
-}
-
-static void
-vwarning (msgid, args)
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- if (inhibit_warnings)
- return;
-
- if (warnings_are_errors)
- errors++;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
- fprintf (stderr, ":%d: ", ip->lineno);
- }
- notice ("warning: ");
- vnotice (msgid, args);
- fprintf (stderr, "\n");
-}
-
-static void
-error_with_line VPROTO ((int line, const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- verror_with_line (line, msgid, args);
- va_end (args);
-}
-
-
-static void
-verror_with_line (line, msgid, args)
- int line;
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
- fprintf (stderr, ":%d: ", line);
- }
- vnotice (msgid, args);
- fprintf (stderr, "\n");
- errors++;
-}
-
-static void
-warning_with_line VPROTO ((int line, const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- vwarning_with_line (line, msgid, args);
- va_end (args);
-}
-
-static void
-vwarning_with_line (line, msgid, args)
- int line;
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- if (inhibit_warnings)
- return;
-
- if (warnings_are_errors)
- errors++;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
- fprintf (stderr, line ? ":%d: " : ": ", line);
- }
- notice ("warning: ");
- vnotice (msgid, args);
- fprintf (stderr, "\n");
-}
-
-/* Print an error message and maybe count it. */
-
-void
-pedwarn VPROTO ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- if (pedantic_errors)
- verror (msgid, args);
- else
- vwarning (msgid, args);
- va_end (args);
-}
-
-void
-pedwarn_with_line VPROTO ((int line, const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- if (pedantic_errors)
- verror_with_line (line, msgid, args);
- else
- vwarning_with_line (line, msgid, args);
- va_end (args);
-}
-
-/* Report a warning (or an error if pedantic_errors)
- giving specified file name and line number, not current. */
-
-static void
-pedwarn_with_file_and_line VPROTO ((const char *file, size_t file_len, int line,
- const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *file;
- size_t file_len;
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- if (!pedantic_errors && inhibit_warnings)
- return;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- file = va_arg (args, const char *);
- file_len = va_arg (args, size_t);
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- if (file) {
- eprint_string (file, file_len);
- fprintf (stderr, ":%d: ", line);
- }
- if (pedantic_errors)
- errors++;
- if (!pedantic_errors)
- notice ("warning: ");
- vnotice (msgid, args);
- va_end (args);
- fprintf (stderr, "\n");
-}
-
-static void
-pedwarn_strange_white_space (ch)
- int ch;
-{
- switch (ch)
- {
- case '\f': pedwarn ("formfeed in preprocessing directive"); break;
- case '\r': pedwarn ("carriage return in preprocessing directive"); break;
- case '\v': pedwarn ("vertical tab in preprocessing directive"); break;
- default: abort ();
- }
-}
-
-/* Print the file names and line numbers of the #include
- directives which led to the current file. */
-
-static void
-print_containing_files ()
-{
- FILE_BUF *ip = NULL;
- int i;
- int first = 1;
-
- /* If stack of files hasn't changed since we last printed
- this info, don't repeat it. */
- if (last_error_tick == input_file_stack_tick)
- return;
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- /* Give up if we don't find a source file. */
- if (ip == NULL)
- return;
-
- /* Find the other, outer source files. */
- for (i--; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- if (first) {
- first = 0;
- notice ( "In file included from ");
- } else {
- notice (",\n from ");
- }
-
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
- fprintf (stderr, ":%d", ip->lineno);
- }
- if (! first)
- fprintf (stderr, ":\n");
-
- /* Record we have printed the status as of this time. */
- last_error_tick = input_file_stack_tick;
-}
-
-/* Return the line at which an error occurred.
- The error is not necessarily associated with the current spot
- in the input stack, so LINE says where. LINE will have been
- copied from ip->lineno for the current input level.
- If the current level is for a file, we return LINE.
- But if the current level is not for a file, LINE is meaningless.
- In that case, we return the lineno of the innermost file. */
-
-static int
-line_for_error (line)
- int line;
-{
- int i;
- int line1 = line;
-
- for (i = indepth; i >= 0; ) {
- if (instack[i].fname != 0)
- return line1;
- i--;
- if (i < 0)
- return 0;
- line1 = instack[i].lineno;
- }
- abort ();
- /*NOTREACHED*/
- return 0;
-}
-
-/*
- * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger.
- *
- * As things stand, nothing is ever placed in the output buffer to be
- * removed again except when it's KNOWN to be part of an identifier,
- * so flushing and moving down everything left, instead of expanding,
- * should work ok.
- */
-
-/* You might think void was cleaner for the return type,
- but that would get type mismatch in check_expand in strict ANSI. */
-
-static int
-grow_outbuf (obuf, needed)
- register FILE_BUF *obuf;
- register int needed;
-{
- register U_CHAR *p;
- int minsize;
-
- if (obuf->length - (obuf->bufp - obuf->buf) > needed)
- return 0;
-
- /* Make it at least twice as big as it is now. */
- obuf->length *= 2;
- /* Make it have at least 150% of the free space we will need. */
- minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf);
- if (minsize > obuf->length)
- obuf->length = minsize;
-
- if ((p = (U_CHAR *) xrealloc (obuf->buf, obuf->length)) == NULL)
- memory_full ();
-
- obuf->bufp = p + (obuf->bufp - obuf->buf);
- obuf->buf = p;
-
- return 0;
-}
-
-/* Symbol table for macro names and special symbols */
-
-/*
- * install a name in the main hash table, even if it is already there.
- * name stops with first non alphanumeric, except leading '#'.
- * caller must check against redefinition if that is desired.
- * delete_macro () removes things installed by install () in fifo order.
- * this is important because of the `defined' special symbol used
- * in #if, and also if pushdef/popdef directives are ever implemented.
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
-
-static HASHNODE *
-install (name, len, type, value, hash)
- U_CHAR *name;
- int len;
- enum node_type type;
- char *value;
- int hash;
-{
- register HASHNODE *hp;
- register int i, bucket;
- register U_CHAR *p, *q;
-
- if (len < 0) {
- p = name;
- while (is_idchar[*p])
- p++;
- len = p - name;
- }
-
- if (hash < 0)
- hash = hashf (name, len, HASHSIZE);
-
- i = sizeof (HASHNODE) + len + 1;
- hp = (HASHNODE *) xmalloc (i);
- bucket = hash;
- hp->bucket_hdr = &hashtab[bucket];
- hp->next = hashtab[bucket];
- hashtab[bucket] = hp;
- hp->prev = NULL;
- if (hp->next != NULL)
- hp->next->prev = hp;
- hp->type = type;
- hp->length = len;
- hp->value.cpval = value;
- hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
- p = hp->name;
- q = name;
- for (i = 0; i < len; i++)
- *p++ = *q++;
- hp->name[len] = 0;
- return hp;
-}
-
-/*
- * find the most recent hash node for name "name" (ending with first
- * non-identifier char) installed by install
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
-
-HASHNODE *
-lookup (name, len, hash)
- U_CHAR *name;
- int len;
- int hash;
-{
- register U_CHAR *bp;
- register HASHNODE *bucket;
-
- if (len < 0) {
- for (bp = name; is_idchar[*bp]; bp++) ;
- len = bp - name;
- }
-
- if (hash < 0)
- hash = hashf (name, len, HASHSIZE);
-
- bucket = hashtab[hash];
- while (bucket) {
- if (bucket->length == len && bcmp (bucket->name, name, len) == 0)
- return bucket;
- bucket = bucket->next;
- }
- return NULL;
-}
-
-/*
- * Delete a hash node. Some weirdness to free junk from macros.
- * More such weirdness will have to be added if you define more hash
- * types that need it.
- */
-
-/* Note that the DEFINITION of a macro is removed from the hash table
- but its storage is not freed. This would be a storage leak
- except that it is not reasonable to keep undefining and redefining
- large numbers of macros many times.
- In any case, this is necessary, because a macro can be #undef'd
- in the middle of reading the arguments to a call to it.
- If #undef freed the DEFINITION, that would crash. */
-
-static void
-delete_macro (hp)
- HASHNODE *hp;
-{
-
- if (hp->prev != NULL)
- hp->prev->next = hp->next;
- if (hp->next != NULL)
- hp->next->prev = hp->prev;
-
- /* Make sure that the bucket chain header that the deleted guy was
- on points to the right thing afterwards. */
- if (hp == *hp->bucket_hdr)
- *hp->bucket_hdr = hp->next;
-
-#if 0
- if (hp->type == T_MACRO) {
- DEFINITION *d = hp->value.defn;
- struct reflist *ap, *nextap;
-
- for (ap = d->pattern; ap != NULL; ap = nextap) {
- nextap = ap->next;
- free (ap);
- }
- free (d);
- }
-#endif
- free (hp);
-}
-
-/*
- * return hash function on name. must be compatible with the one
- * computed a step at a time, elsewhere
- */
-
-static int
-hashf (name, len, hashsize)
- register U_CHAR *name;
- register int len;
- int hashsize;
-{
- register int r = 0;
-
- while (len--)
- r = HASHSTEP (r, *name++);
-
- return MAKE_POS (r) % hashsize;
-}
-
-
-/* Dump the definition of a single macro HP to OF. */
-
-static void
-dump_single_macro (hp, of)
- register HASHNODE *hp;
- FILE *of;
-{
- register DEFINITION *defn = hp->value.defn;
- struct reflist *ap;
- int offset;
- int concat;
-
-
- /* Print the definition of the macro HP. */
-
- fprintf (of, "#define %s", hp->name);
-
- if (defn->nargs >= 0) {
- int i;
-
- fprintf (of, "(");
- for (i = 0; i < defn->nargs; i++) {
- dump_arg_n (defn, i, of);
- if (i + 1 < defn->nargs)
- fprintf (of, ", ");
- }
- fprintf (of, ")");
- }
-
- fprintf (of, " ");
-
- offset = 0;
- concat = 0;
- for (ap = defn->pattern; ap != NULL; ap = ap->next) {
- dump_defn_1 (defn->expansion, offset, ap->nchars, of);
- offset += ap->nchars;
- if (!traditional) {
- if (ap->nchars != 0)
- concat = 0;
- if (ap->stringify) {
- switch (ap->stringify) {
- case SHARP_TOKEN: fprintf (of, "#"); break;
- case WHITE_SHARP_TOKEN: fprintf (of, "# "); break;
- case PERCENT_COLON_TOKEN: fprintf (of, "%%:"); break;
- case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%%: "); break;
- default: abort ();
- }
- }
- if (ap->raw_before != 0) {
- if (concat) {
- switch (ap->raw_before) {
- case WHITE_SHARP_TOKEN:
- case WHITE_PERCENT_COLON_TOKEN:
- fprintf (of, " ");
- break;
- default:
- break;
- }
- } else {
- switch (ap->raw_before) {
- case SHARP_TOKEN: fprintf (of, "##"); break;
- case WHITE_SHARP_TOKEN: fprintf (of, "## "); break;
- case PERCENT_COLON_TOKEN: fprintf (of, "%%:%%:"); break;
- case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%%:%%: "); break;
- default: abort ();
- }
- }
- }
- concat = 0;
- }
- dump_arg_n (defn, ap->argno, of);
- if (!traditional && ap->raw_after != 0) {
- switch (ap->raw_after) {
- case SHARP_TOKEN: fprintf (of, "##"); break;
- case WHITE_SHARP_TOKEN: fprintf (of, " ##"); break;
- case PERCENT_COLON_TOKEN: fprintf (of, "%%:%%:"); break;
- case WHITE_PERCENT_COLON_TOKEN: fprintf (of, " %%:%%:"); break;
- default: abort ();
- }
- concat = 1;
- }
- }
- dump_defn_1 (defn->expansion, offset, defn->length - offset, of);
- fprintf (of, "\n");
-}
-
-/* Dump all macro definitions as #defines to stdout. */
-
-static void
-dump_all_macros ()
-{
- int bucket;
-
- for (bucket = 0; bucket < HASHSIZE; bucket++) {
- register HASHNODE *hp;
-
- for (hp = hashtab[bucket]; hp; hp= hp->next) {
- if (hp->type == T_MACRO)
- dump_single_macro (hp, stdout);
- }
- }
-}
-
-/* Output to OF a substring of a macro definition.
- BASE is the beginning of the definition.
- Output characters START thru LENGTH.
- Unless traditional, discard newlines outside of strings, thus
- converting funny-space markers to ordinary spaces. */
-
-static void
-dump_defn_1 (base, start, length, of)
- U_CHAR *base;
- int start;
- int length;
- FILE *of;
-{
- U_CHAR *p = base + start;
- U_CHAR *limit = base + start + length;
-
- if (traditional)
- fwrite (p, sizeof (*p), length, of);
- else {
- while (p < limit) {
- if (*p == '\"' || *p =='\'') {
- U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR,
- NULL_PTR, NULL_PTR);
- fwrite (p, sizeof (*p), p1 - p, of);
- p = p1;
- } else {
- if (*p != '\n')
- putc (*p, of);
- p++;
- }
- }
- }
-}
-
-/* Print the name of argument number ARGNUM of macro definition DEFN
- to OF.
- Recall that DEFN->args.argnames contains all the arg names
- concatenated in reverse order with comma-space in between. */
-
-static void
-dump_arg_n (defn, argnum, of)
- DEFINITION *defn;
- int argnum;
- FILE *of;
-{
- register U_CHAR *p = defn->args.argnames;
- while (argnum + 1 < defn->nargs) {
- p = (U_CHAR *) index ((char *) p, ' ') + 1;
- argnum++;
- }
-
- while (*p && *p != ',') {
- putc (*p, of);
- p++;
- }
-}
-
-/* Initialize syntactic classifications of characters. */
-
-static void
-initialize_char_syntax ()
-{
- register int i;
-
- /*
- * Set up is_idchar and is_idstart tables. These should be
- * faster than saying (is_alpha (c) || c == '_'), etc.
- * Set up these things before calling any routines tthat
- * refer to them.
- */
- for (i = 'a'; i <= 'z'; i++) {
- is_idchar[i - 'a' + 'A'] = 1;
- is_idchar[i] = 1;
- is_idstart[i - 'a' + 'A'] = 1;
- is_idstart[i] = 1;
- }
- for (i = '0'; i <= '9'; i++)
- is_idchar[i] = 1;
- is_idchar['_'] = 1;
- is_idstart['_'] = 1;
- is_idchar['$'] = 1;
- is_idstart['$'] = 1;
-
- /* horizontal space table */
- is_hor_space[' '] = 1;
- is_hor_space['\t'] = 1;
- is_hor_space['\v'] = 1;
- is_hor_space['\f'] = 1;
- is_hor_space['\r'] = 1;
-
- is_space[' '] = 1;
- is_space['\t'] = 1;
- is_space['\v'] = 1;
- is_space['\f'] = 1;
- is_space['\n'] = 1;
- is_space['\r'] = 1;
-}
-
-/* Initialize the built-in macros. */
-
-static void
-initialize_builtins (inp, outp)
- FILE_BUF *inp;
- FILE_BUF *outp;
-{
- install ((U_CHAR *) "__LINE__", -1, T_SPECLINE, NULL_PTR, -1);
- install ((U_CHAR *) "__DATE__", -1, T_DATE, NULL_PTR, -1);
- install ((U_CHAR *) "__FILE__", -1, T_FILE, NULL_PTR, -1);
- install ((U_CHAR *) "__BASE_FILE__", -1, T_BASE_FILE, NULL_PTR, -1);
- install ((U_CHAR *) "__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, NULL_PTR, -1);
- install ((U_CHAR *) "__VERSION__", -1, T_VERSION, NULL_PTR, -1);
-#ifndef NO_BUILTIN_SIZE_TYPE
- install ((U_CHAR *) "__SIZE_TYPE__", -1, T_SIZE_TYPE, NULL_PTR, -1);
-#endif
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- install ((U_CHAR *) "__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, NULL_PTR, -1);
-#endif
- install ((U_CHAR *) "__WCHAR_TYPE__", -1, T_WCHAR_TYPE, NULL_PTR, -1);
- install ((U_CHAR *) "__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE,
- NULL_PTR, -1);
- install ((U_CHAR *) "__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE,
- NULL_PTR, -1);
- install ((U_CHAR *) "__IMMEDIATE_PREFIX__", -1, T_IMMEDIATE_PREFIX_TYPE,
- NULL_PTR, -1);
- install ((U_CHAR *) "__TIME__", -1, T_TIME, NULL_PTR, -1);
- if (!traditional) {
- install ((U_CHAR *) "__STDC__", -1, T_CONST, "1", -1);
- install ((U_CHAR *) "__STDC_VERSION__", -1, T_CONST, "199409L", -1);
- }
-/* This is supplied using a -D by the compiler driver
- so that it is present only when truly compiling with GNU C. */
-/* install ((U_CHAR *) "__GNUC__", -1, T_CONST, "2", -1); */
- install ((U_CHAR *) "__HAVE_BUILTIN_SETJMP__", -1, T_CONST, "1", -1);
-
- if (debug_output)
- {
- char directive[2048];
- U_CHAR *udirective = (U_CHAR *) directive;
- register struct directive *dp = &directive_table[0];
- struct tm *timebuf = timestamp ();
-
- sprintf (directive, " __BASE_FILE__ \"%s\"\n",
- instack[0].nominal_fname);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
- sprintf (directive, " __VERSION__ \"%s\"\n", version_string);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
-#ifndef NO_BUILTIN_SIZE_TYPE
- sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-#endif
-
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-#endif
-
- sprintf (directive, " __WCHAR_TYPE__ %s\n", wchar_type);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
- sprintf (directive, " __DATE__ \"%s %2d %4d\"\n",
- monthnames[timebuf->tm_mon],
- timebuf->tm_mday, timebuf->tm_year + 1900);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
- sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n",
- timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
- if (!traditional)
- {
- sprintf (directive, " __STDC__ 1");
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
- }
- if (objc)
- {
- sprintf (directive, " __OBJC__ 1");
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
- }
- }
-}
-
-/*
- * process a given definition string, for initialization
- * If STR is just an identifier, define it with value 1.
- * If STR has anything after the identifier, then it should
- * be identifier=definition.
- */
-
-static void
-make_definition (str)
- char *str;
-{
- FILE_BUF *ip;
- struct directive *kt;
- U_CHAR *buf, *p;
-
- p = buf = (U_CHAR *) str;
- if (!is_idstart[*p]) {
- error ("malformed option `-D %s'", str);
- return;
- }
- while (is_idchar[*++p])
- ;
- if (*p == '(') {
- while (is_idchar[*++p] || *p == ',' || is_hor_space[*p])
- ;
- if (*p++ != ')')
- p = (U_CHAR *) str; /* Error */
- }
- if (*p == 0) {
- buf = (U_CHAR *) alloca (p - buf + 4);
- strcpy ((char *)buf, str);
- strcat ((char *)buf, " 1");
- } else if (*p != '=') {
- error ("malformed option `-D %s'", str);
- return;
- } else {
- U_CHAR *q;
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (2 * strlen (str) + 1);
- strncpy ((char *) buf, str, p - (U_CHAR *) str);
- /* Change the = to a space. */
- buf[p - (U_CHAR *) str] = ' ';
- /* Scan for any backslash-newline and remove it. */
- p++;
- q = &buf[p - (U_CHAR *) str];
- while (*p) {
- if (*p == '\"' || *p == '\'') {
- int unterminated = 0;
- U_CHAR *p1 = skip_quoted_string (p, p + strlen ((char *) p), 0,
- NULL_PTR, NULL_PTR, &unterminated);
- if (unterminated)
- return;
- while (p != p1)
- *q++ = *p++;
- } else if (*p == '\\' && p[1] == '\n')
- p += 2;
- /* Change newline chars into newline-markers. */
- else if (*p == '\n')
- {
- *q++ = '\n';
- *q++ = '\n';
- p++;
- }
- else
- *q++ = *p++;
- }
- *q = 0;
- }
-
- ip = &instack[++indepth];
- ip->nominal_fname = ip->fname = "*Initialization*";
- ip->nominal_fname_len = strlen (ip->nominal_fname);
-
- ip->buf = ip->bufp = buf;
- ip->length = strlen ((char *) buf);
- ip->lineno = 1;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->if_stack = if_stack;
- ip->system_header_p = 0;
-
- for (kt = directive_table; kt->type != T_DEFINE; kt++)
- ;
-
- /* Pass NULL instead of OP, since this is a "predefined" macro. */
- do_define (buf, buf + strlen ((char *) buf), NULL_PTR, kt);
- --indepth;
-}
-
-/* JF, this does the work for the -U option */
-
-static void
-make_undef (str, op)
- char *str;
- FILE_BUF *op;
-{
- FILE_BUF *ip;
- struct directive *kt;
-
- ip = &instack[++indepth];
- ip->nominal_fname = ip->fname = "*undef*";
- ip->nominal_fname_len = strlen (ip->nominal_fname);
-
- ip->buf = ip->bufp = (U_CHAR *) str;
- ip->length = strlen (str);
- ip->lineno = 1;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->if_stack = if_stack;
- ip->system_header_p = 0;
-
- for (kt = directive_table; kt->type != T_UNDEF; kt++)
- ;
-
- do_undef ((U_CHAR *) str, (U_CHAR *) str + strlen (str), op, kt);
- --indepth;
-}
-
-/* Process the string STR as if it appeared as the body of a #assert.
- OPTION is the option name for which STR was the argument. */
-
-static void
-make_assertion (option, str)
- const char *option;
- const char *str;
-{
- FILE_BUF *ip;
- struct directive *kt;
- U_CHAR *buf, *p, *q;
-
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (strlen (str) + 1);
- strcpy ((char *) buf, str);
- /* Scan for any backslash-newline and remove it. */
- p = q = buf;
- while (*p) {
- if (*p == '\\' && p[1] == '\n')
- p += 2;
- else
- *q++ = *p++;
- }
- *q = 0;
-
- p = buf;
- if (!is_idstart[*p]) {
- error ("malformed option `%s %s'", option, str);
- return;
- }
- while (is_idchar[*++p])
- ;
- SKIP_WHITE_SPACE (p);
- if (! (*p == 0 || *p == '(')) {
- error ("malformed option `%s %s'", option, str);
- return;
- }
-
- ip = &instack[++indepth];
- ip->nominal_fname = ip->fname = "*Initialization*";
- ip->nominal_fname_len = strlen (ip->nominal_fname);
-
- ip->buf = ip->bufp = buf;
- ip->length = strlen ((char *) buf);
- ip->lineno = 1;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->if_stack = if_stack;
- ip->system_header_p = 0;
-
- for (kt = directive_table; kt->type != T_ASSERT; kt++)
- ;
-
- /* Pass NULL as output ptr to do_define since we KNOW it never does
- any output.... */
- do_assert (buf, buf + strlen ((char *) buf) , NULL_PTR, kt);
- --indepth;
-}
-
-/* The previous include prefix, if any, is PREV_FILE_NAME.
- Translate any pathnames with COMPONENT.
- Allocate a new include prefix whose name is the
- simplified concatenation of PREFIX and NAME,
- with a trailing / added if needed.
- But return 0 if the include prefix should be ignored,
- e.g. because it is a duplicate of PREV_FILE_NAME. */
-
-static struct file_name_list *
-new_include_prefix (prev_file_name, component, prefix, name)
- struct file_name_list *prev_file_name;
- const char *component;
- const char *prefix;
- const char *name;
-{
- if (name == 0)
- fatal ("Directory name missing after command line option");
-
- if (*name == 0)
- /* Ignore the empty string. */
- return 0;
-
- prefix = update_path (prefix, component);
- name = update_path (name, component);
-
- {
- struct file_name_list *dir
- = ((struct file_name_list *)
- xmalloc (sizeof (struct file_name_list)
- + strlen (prefix) + strlen (name) + 2));
- size_t len;
- strcpy (dir->fname, prefix);
- strcat (dir->fname, name);
- len = simplify_filename (dir->fname);
-
- /* Convert directory name to a prefix. */
- if (len && dir->fname[len - 1] != DIR_SEPARATOR) {
- if (len == 1 && dir->fname[len - 1] == '.')
- len = 0;
- else
-#ifdef VMS
- /* must be '/', hack_vms_include_specification triggers on it. */
- dir->fname[len++] = '/';
-#else
- dir->fname[len++] = DIR_SEPARATOR;
-#endif
- dir->fname[len] = 0;
- }
-
- /* Ignore a directory whose name matches the previous one. */
- if (prev_file_name && !strcmp (prev_file_name->fname, dir->fname)) {
- /* But treat `-Idir -I- -Idir' as `-I- -Idir'. */
- if (!first_bracket_include)
- first_bracket_include = prev_file_name;
- free (dir);
- return 0;
- }
-
-#ifndef VMS
- /* VMS can't stat dir prefixes, so skip these optimizations in VMS. */
-
- /* Add a trailing "." if there is a filename. This increases the number
- of systems that can stat directories. We remove it below. */
- if (len != 0)
- {
- dir->fname[len] = '.';
- dir->fname[len + 1] = 0;
- }
-
- /* Ignore a nonexistent directory. */
- if (stat (len ? dir->fname : ".", &dir->st) != 0) {
- if (errno != ENOENT && errno != ENOTDIR)
- error_from_errno (dir->fname);
- free (dir);
- return 0;
- }
-
- if (len != 0)
- dir->fname[len] = 0;
-
- /* Ignore a directory whose identity matches the previous one. */
- if (prev_file_name
- && INO_T_EQ (prev_file_name->st.st_ino, dir->st.st_ino)
- && prev_file_name->st.st_dev == dir->st.st_dev) {
- /* But treat `-Idir -I- -Idir' as `-I- -Idir'. */
- if (!first_bracket_include)
- first_bracket_include = prev_file_name;
- free (dir);
- return 0;
- }
-#endif /* ! VMS */
-
- dir->next = 0;
- dir->c_system_include_path = 0;
- dir->got_name_map = 0;
-
- return dir;
- }
-}
-
-/* Append a chain of `struct file_name_list's
- to the end of the main include chain.
- FIRST is the beginning of the chain to append, and LAST is the end. */
-
-static void
-append_include_chain (first, last)
- struct file_name_list *first, *last;
-{
- struct file_name_list *dir;
-
- if (!first || !last)
- return;
-
- if (include == 0)
- include = first;
- else
- last_include->next = first;
-
- if (first_bracket_include == 0)
- first_bracket_include = first;
-
- for (dir = first; ; dir = dir->next) {
- int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
- if (len > max_include_len)
- max_include_len = len;
- if (dir == last)
- break;
- }
-
- last->next = NULL;
- last_include = last;
-}
-
-/* Place into DST a representation of the file named SRC that is suitable
- for `make'. Do not null-terminate DST. Return its length. */
-static int
-quote_string_for_make (dst, src)
- char *dst;
- const char *src;
-{
- const char *p = src;
- int i = 0;
- for (;;)
- {
- char c = *p++;
- switch (c)
- {
- case '\0':
- case ' ':
- case '\t':
- {
- /* GNU make uses a weird quoting scheme for white space.
- A space or tab preceded by 2N+1 backslashes represents
- N backslashes followed by space; a space or tab
- preceded by 2N backslashes represents N backslashes at
- the end of a file name; and backslashes in other
- contexts should not be doubled. */
- const char *q;
- for (q = p - 1; src < q && q[-1] == '\\'; q--)
- {
- if (dst)
- dst[i] = '\\';
- i++;
- }
- }
- if (!c)
- return i;
- if (dst)
- dst[i] = '\\';
- i++;
- goto ordinary_char;
-
- case '$':
- if (dst)
- dst[i] = c;
- i++;
- /* Fall through. This can mishandle things like "$(" but
- there's no easy fix. */
- default:
- ordinary_char:
- /* This can mishandle characters in the string "\0\n%*?[\\~";
- exactly which chars are mishandled depends on the `make' version.
- We know of no portable solution for this;
- even GNU make 3.76.1 doesn't solve the problem entirely.
- (Also, '\0' is mishandled due to our calling conventions.) */
- if (dst)
- dst[i] = c;
- i++;
- break;
- }
- }
-}
-
-
-/* Add output to `deps_buffer' for the -M switch.
- STRING points to the text to be output.
- SPACER is ':' for targets, ' ' for dependencies. */
-
-static void
-deps_output (string, spacer)
- const char *string;
- int spacer;
-{
- int size = quote_string_for_make ((char *) 0, string);
-
- if (size == 0)
- return;
-
-#ifndef MAX_OUTPUT_COLUMNS
-#define MAX_OUTPUT_COLUMNS 72
-#endif
- if (MAX_OUTPUT_COLUMNS - 1 /*spacer*/ - 2 /*` \'*/ < deps_column + size
- && 1 < deps_column) {
- bcopy (" \\\n ", &deps_buffer[deps_size], 4);
- deps_size += 4;
- deps_column = 1;
- if (spacer == ' ')
- spacer = 0;
- }
-
- if (deps_size + 2 * size + 8 > deps_allocated_size) {
- deps_allocated_size = (deps_size + 2 * size + 50) * 2;
- deps_buffer = xrealloc (deps_buffer, deps_allocated_size);
- }
- if (spacer == ' ') {
- deps_buffer[deps_size++] = ' ';
- deps_column++;
- }
- quote_string_for_make (&deps_buffer[deps_size], string);
- deps_size += size;
- deps_column += size;
- if (spacer == ':') {
- deps_buffer[deps_size++] = ':';
- deps_column++;
- }
- deps_buffer[deps_size] = 0;
-}
-
-void
-fatal VPROTO ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- fprintf (stderr, "%s: ", progname);
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
- vnotice (msgid, args);
- va_end (args);
- fprintf (stderr, "\n");
- exit (FATAL_EXIT_CODE);
-}
-
-/* More 'friendly' abort that prints the line and file.
- config.h can #define abort fancy_abort if you like that sort of thing. */
-
-void
-fancy_abort ()
-{
- fatal ("Internal gcc abort.");
-}
-
-static void
-perror_with_name (name)
- char *name;
-{
- fprintf (stderr, "%s: %s: %s\n", progname, name, my_strerror (errno));
- errors++;
-}
-
-static void
-pfatal_with_name (name)
- char *name;
-{
- perror_with_name (name);
-#ifdef VMS
- exit (vaxc$errno);
-#else
- exit (FATAL_EXIT_CODE);
-#endif
-}
-
-/* Handler for SIGPIPE. */
-
-static void
-pipe_closed (signo)
- /* If this is missing, some compilers complain. */
- int signo ATTRIBUTE_UNUSED;
-{
- fatal ("output pipe has been closed");
-}
-
-static void
-memory_full ()
-{
- fatal ("Memory exhausted.");
-}
-
-PTR
-xmalloc (size)
- size_t size;
-{
- register PTR ptr = (PTR) malloc (size);
- if (!ptr)
- memory_full ();
- return ptr;
-}
-
-PTR
-xrealloc (old, size)
- PTR old;
- size_t size;
-{
- register PTR ptr;
- if (old)
- ptr = (PTR) realloc (old, size);
- else
- ptr = (PTR) malloc (size);
- if (!ptr)
- memory_full ();
- return ptr;
-}
-
-PTR
-xcalloc (number, size)
- size_t number, size;
-{
- register size_t total = number * size;
- register PTR ptr = (PTR) malloc (total);
- if (!ptr)
- memory_full ();
- bzero (ptr, total);
- return ptr;
-}
-
-char *
-xstrdup (input)
- const char *input;
-{
- register size_t len = strlen (input) + 1;
- register char *output = xmalloc (len);
- memcpy (output, input, len);
- return output;
-}
-
-#ifdef VMS
-
-/* Under VMS we need to fix up the "include" specification filename.
-
- Rules for possible conversions
-
- fullname tried paths
-
- name name
- ./dir/name [.dir]name
- /dir/name dir:name
- /name [000000]name, name
- dir/name dir:[000000]name, dir:name, dir/name
- dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
- path:/name path:[000000]name, path:name
- path:/dir/name path:[000000.dir]name, path:[dir]name
- path:dir/name path:[dir]name
- [path]:[dir]name [path.dir]name
- path/[dir]name [path.dir]name
-
- The path:/name input is constructed when expanding <> includes.
-
- return 1 if name was changed, 0 else. */
-
-static int
-hack_vms_include_specification (fullname, vaxc_include)
- char *fullname;
- int vaxc_include;
-{
- register char *basename, *unixname, *local_ptr, *first_slash;
- int f, check_filename_before_returning, must_revert;
- char Local[512];
-
- check_filename_before_returning = 0;
- must_revert = 0;
- /* See if we can find a 1st slash. If not, there's no path information. */
- first_slash = index (fullname, '/');
- if (first_slash == 0)
- return 0; /* Nothing to do!!! */
-
- /* construct device spec if none given. */
-
- if (index (fullname, ':') == 0)
- {
-
- /* If fullname has a slash, take it as device spec. */
-
- if (first_slash == fullname)
- {
- first_slash = index (fullname+1, '/'); /* 2nd slash ? */
- if (first_slash)
- *first_slash = ':'; /* make device spec */
- for (basename = fullname; *basename != 0; basename++)
- *basename = *(basename+1); /* remove leading slash */
- }
- else if ((first_slash[-1] != '.') /* keep ':/', './' */
- && (first_slash[-1] != ':')
- && (first_slash[-1] != ']')) /* or a vms path */
- {
- *first_slash = ':';
- }
- else if ((first_slash[1] == '[') /* skip './' in './[dir' */
- && (first_slash[-1] == '.'))
- fullname += 2;
- }
-
- /* Get part after first ':' (basename[-1] == ':')
- or last '/' (basename[-1] == '/'). */
-
- basename = base_name (fullname);
-
- /*
- * Check if we have a vax-c style '#include filename'
- * and add the missing .h
- */
-
- if (vaxc_include && !index (basename,'.'))
- strcat (basename, ".h");
-
- local_ptr = Local; /* initialize */
-
- /* We are trying to do a number of things here. First of all, we are
- trying to hammer the filenames into a standard format, such that later
- processing can handle them.
-
- If the file name contains something like [dir.], then it recognizes this
- as a root, and strips the ".]". Later processing will add whatever is
- needed to get things working properly.
-
- If no device is specified, then the first directory name is taken to be
- a device name (or a rooted logical). */
-
- /* Point to the UNIX filename part (which needs to be fixed!)
- but skip vms path information.
- [basename != fullname since first_slash != 0]. */
-
- if ((basename[-1] == ':') /* vms path spec. */
- || (basename[-1] == ']')
- || (basename[-1] == '>'))
- unixname = basename;
- else
- unixname = fullname;
-
- if (*unixname == '/')
- unixname++;
-
- /* If the directory spec is not rooted, we can just copy
- the UNIX filename part and we are done. */
-
- if (((basename - fullname) > 1)
- && ( (basename[-1] == ']')
- || (basename[-1] == '>')))
- {
- if (basename[-2] != '.')
- {
-
- /* The VMS part ends in a `]', and the preceding character is not a `.'.
- -> PATH]:/name (basename = '/name', unixname = 'name')
- We strip the `]', and then splice the two parts of the name in the
- usual way. Given the default locations for include files in cccp.c,
- we will only use this code if the user specifies alternate locations
- with the /include (-I) switch on the command line. */
-
- basename -= 1; /* Strip "]" */
- unixname--; /* backspace */
- }
- else
- {
-
- /* The VMS part has a ".]" at the end, and this will not do. Later
- processing will add a second directory spec, and this would be a syntax
- error. Thus we strip the ".]", and thus merge the directory specs.
- We also backspace unixname, so that it points to a '/'. This inhibits the
- generation of the 000000 root directory spec (which does not belong here
- in this case). */
-
- basename -= 2; /* Strip ".]" */
- unixname--; /* backspace */
- }
- }
-
- else
-
- {
-
- /* We drop in here if there is no VMS style directory specification yet.
- If there is no device specification either, we make the first dir a
- device and try that. If we do not do this, then we will be essentially
- searching the users default directory (as if they did a #include "asdf.h").
-
- Then all we need to do is to push a '[' into the output string. Later
- processing will fill this in, and close the bracket. */
-
- if ((unixname != fullname) /* vms path spec found. */
- && (basename[-1] != ':'))
- *local_ptr++ = ':'; /* dev not in spec. take first dir */
-
- *local_ptr++ = '['; /* Open the directory specification */
- }
-
- if (unixname == fullname) /* no vms dir spec. */
- {
- must_revert = 1;
- if ((first_slash != 0) /* unix dir spec. */
- && (*unixname != '/') /* not beginning with '/' */
- && (*unixname != '.')) /* or './' or '../' */
- *local_ptr++ = '.'; /* dir is local ! */
- }
-
- /* at this point we assume that we have the device spec, and (at least
- the opening "[" for a directory specification. We may have directories
- specified already.
-
- If there are no other slashes then the filename will be
- in the "root" directory. Otherwise, we need to add
- directory specifications. */
-
- if (index (unixname, '/') == 0)
- {
- /* if no directories specified yet and none are following. */
- if (local_ptr[-1] == '[')
- {
- /* Just add "000000]" as the directory string */
- strcpy (local_ptr, "000000]");
- local_ptr += strlen (local_ptr);
- check_filename_before_returning = 1; /* we might need to fool with this later */
- }
- }
- else
- {
-
- /* As long as there are still subdirectories to add, do them. */
- while (index (unixname, '/') != 0)
- {
- /* If this token is "." we can ignore it
- if it's not at the beginning of a path. */
- if ((unixname[0] == '.') && (unixname[1] == '/'))
- {
- /* remove it at beginning of path. */
- if ( ((unixname == fullname) /* no device spec */
- && (fullname+2 != basename)) /* starts with ./ */
- /* or */
- || ((basename[-1] == ':') /* device spec */
- && (unixname-1 == basename))) /* and ./ afterwards */
- *local_ptr++ = '.'; /* make '[.' start of path. */
- unixname += 2;
- continue;
- }
-
- /* Add a subdirectory spec. Do not duplicate "." */
- if ( local_ptr[-1] != '.'
- && local_ptr[-1] != '['
- && local_ptr[-1] != '<')
- *local_ptr++ = '.';
-
- /* If this is ".." then the spec becomes "-" */
- if ( (unixname[0] == '.')
- && (unixname[1] == '.')
- && (unixname[2] == '/'))
- {
- /* Add "-" and skip the ".." */
- if ((local_ptr[-1] == '.')
- && (local_ptr[-2] == '['))
- local_ptr--; /* prevent [.- */
- *local_ptr++ = '-';
- unixname += 3;
- continue;
- }
-
- /* Copy the subdirectory */
- while (*unixname != '/')
- *local_ptr++= *unixname++;
-
- unixname++; /* Skip the "/" */
- }
-
- /* Close the directory specification */
- if (local_ptr[-1] == '.') /* no trailing periods */
- local_ptr--;
-
- if (local_ptr[-1] == '[') /* no dir needed */
- local_ptr--;
- else
- *local_ptr++ = ']';
- }
-
- /* Now add the filename. */
-
- while (*unixname)
- *local_ptr++ = *unixname++;
- *local_ptr = 0;
-
- /* Now append it to the original VMS spec. */
-
- strcpy ((must_revert==1)?fullname:basename, Local);
-
- /* If we put a [000000] in the filename, try to open it first. If this fails,
- remove the [000000], and return that name. This provides flexibility
- to the user in that they can use both rooted and non-rooted logical names
- to point to the location of the file. */
-
- if (check_filename_before_returning)
- {
- f = open (fullname, O_RDONLY, 0666);
- if (f >= 0)
- {
- /* The file name is OK as it is, so return it as is. */
- close (f);
- return 1;
- }
-
- /* The filename did not work. Try to remove the [000000] from the name,
- and return it. */
-
- basename = index (fullname, '[');
- local_ptr = index (fullname, ']') + 1;
- strcpy (basename, local_ptr); /* this gets rid of it */
-
- }
-
- return 1;
-}
-#endif /* VMS */
-
-#ifdef VMS
-
-/* The following wrapper functions supply additional arguments to the VMS
- I/O routines to optimize performance with file handling. The arguments
- are:
- "mbc=16" - Set multi-block count to 16 (use a 8192 byte buffer).
- "deq=64" - When extending the file, extend it in chunks of 32Kbytes.
- "fop=tef"- Truncate unused portions of file when closing file.
- "shr=nil"- Disallow file sharing while file is open. */
-
-static FILE *
-VMS_freopen (fname, type, oldfile)
- char *fname;
- char *type;
- FILE *oldfile;
-{
-#undef freopen /* Get back the real freopen routine. */
- if (strcmp (type, "w") == 0)
- return freopen (fname, type, oldfile,
- "mbc=16", "deq=64", "fop=tef", "shr=nil");
- return freopen (fname, type, oldfile, "mbc=16");
-}
-
-static FILE *
-VMS_fopen (fname, type)
- char *fname;
- char *type;
-{
-#undef fopen /* Get back the real fopen routine. */
- /* The gcc-vms-1.42 distribution's header files prototype fopen with two
- fixed arguments, which matches ANSI's specification but not VAXCRTL's
- pre-ANSI implementation. This hack circumvents the mismatch problem. */
- FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;
-
- if (*type == 'w')
- return (*vmslib_fopen) (fname, type, "mbc=32",
- "deq=64", "fop=tef", "shr=nil");
- else
- return (*vmslib_fopen) (fname, type, "mbc=32");
-}
-
-static int
-VMS_open (fname, flags, prot)
- char *fname;
- int flags;
- int prot;
-{
-#undef open /* Get back the real open routine. */
- return open (fname, flags, prot, "mbc=16", "deq=64", "fop=tef");
-}
-
-/* more VMS hackery */
-#include <fab.h>
-#include <nam.h>
-
-extern unsigned long SYS$PARSE(), SYS$SEARCH();
-
-/* Work around another library bug. If a file is located via a searchlist,
- and if the device it's on is not the same device as the one specified
- in the first element of that searchlist, then both stat() and fstat()
- will fail to return info about it. `errno' will be set to EVMSERR, and
- `vaxc$errno' will be set to SS$_NORMAL due yet another bug in stat()!
- We can get around this by fully parsing the filename and then passing
- that absolute name to stat().
-
- Without this fix, we can end up failing to find header files, which is
- bad enough, but then compounding the problem by reporting the reason for
- failure as "normal successful completion." */
-
-#undef fstat /* Get back to the library version. */
-
-static int
-VMS_fstat (fd, statbuf)
- int fd;
- struct stat *statbuf;
-{
- int result = fstat (fd, statbuf);
-
- if (result < 0)
- {
- FILE *fp;
- char nambuf[NAM$C_MAXRSS+1];
-
- if ((fp = fdopen (fd, "r")) != 0 && fgetname (fp, nambuf) != 0)
- result = VMS_stat (nambuf, statbuf);
- /* No fclose(fp) here; that would close(fd) as well. */
- }
-
- return result;
-}
-
-static int
-VMS_stat (name, statbuf)
- const char *name;
- struct stat *statbuf;
-{
- int result = stat (name, statbuf);
-
- if (result < 0)
- {
- struct FAB fab;
- struct NAM nam;
- char exp_nam[NAM$C_MAXRSS+1], /* expanded name buffer for SYS$PARSE */
- res_nam[NAM$C_MAXRSS+1]; /* resultant name buffer for SYS$SEARCH */
-
- fab = cc$rms_fab;
- fab.fab$l_fna = (char *) name;
- fab.fab$b_fns = (unsigned char) strlen (name);
- fab.fab$l_nam = (void *) &nam;
- nam = cc$rms_nam;
- nam.nam$l_esa = exp_nam, nam.nam$b_ess = sizeof exp_nam - 1;
- nam.nam$l_rsa = res_nam, nam.nam$b_rss = sizeof res_nam - 1;
- nam.nam$b_nop = NAM$M_PWD | NAM$M_NOCONCEAL;
- if (SYS$PARSE (&fab) & 1)
- {
- if (SYS$SEARCH (&fab) & 1)
- {
- res_nam[nam.nam$b_rsl] = '\0';
- result = stat (res_nam, statbuf);
- }
- /* Clean up searchlist context cached by the system. */
- nam.nam$b_nop = NAM$M_SYNCHK;
- fab.fab$l_fna = 0, fab.fab$b_fns = 0;
- (void) SYS$PARSE (&fab);
- }
- }
-
- return result;
-}
-#endif /* VMS */
diff --git a/contrib/gcc/cexp.y b/contrib/gcc/cexp.y
deleted file mode 100644
index 9364ac3a8a03..000000000000
--- a/contrib/gcc/cexp.y
+++ /dev/null
@@ -1,1222 +0,0 @@
-/* Parse C expressions for CCCP.
- Copyright (C) 1987, 92, 94-98, 1999 Free Software Foundation.
-
-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, 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
-
- Adapted from expread.y of GDB by Paul Rubin, July 1986. */
-
-/* Parse a C expression from text in a string */
-
-%{
-#include "config.h"
-
-#include "system.h"
-#include "intl.h"
-#include <setjmp.h>
-/* #define YYDEBUG 1 */
-
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif /* MULTIBYTE_CHARS */
-
-typedef unsigned char U_CHAR;
-
-/* This is used for communicating lists of keywords with cccp.c. */
-struct arglist {
- struct arglist *next;
- U_CHAR *name;
- int length;
- int argno;
-};
-
-HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
-
-static int yylex PROTO((void));
-static void yyerror PVPROTO((const char *, ...))
- ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-static HOST_WIDEST_INT expression_value;
-#ifdef TEST_EXP_READER
-static int expression_signedp;
-#endif
-
-static jmp_buf parse_return_error;
-
-/* Nonzero means count most punctuation as part of a name. */
-static int keyword_parsing = 0;
-
-/* Nonzero means do not evaluate this expression.
- This is a count, since unevaluated expressions can nest. */
-static int skip_evaluation;
-
-/* Nonzero means warn if undefined identifiers are evaluated. */
-static int warn_undef;
-
-/* some external tables of character types */
-extern unsigned char is_idstart[], is_idchar[], is_space[];
-
-/* Flag for -pedantic. */
-extern int pedantic;
-
-/* Flag for -traditional. */
-extern int traditional;
-
-/* Flag for -lang-c89. */
-extern int c89;
-
-#ifndef CHAR_TYPE_SIZE
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-#endif
-
-#ifndef INT_TYPE_SIZE
-#define INT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef LONG_TYPE_SIZE
-#define LONG_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
-#endif
-
-#ifndef MAX_CHAR_TYPE_SIZE
-#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
-#endif
-
-#ifndef MAX_INT_TYPE_SIZE
-#define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
-#endif
-
-#ifndef MAX_LONG_TYPE_SIZE
-#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
-#endif
-
-#ifndef MAX_WCHAR_TYPE_SIZE
-#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
-#endif
-
-#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
- : ~ (HOST_WIDEST_INT) 0)
-
-#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
- : ~ (HOST_WIDEST_INT) 0)
-
-/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
- Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
- Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
- Then this yields nonzero if overflow occurred during the addition.
- Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
- and SIGNEDP is negative.
- Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
-#define overflow_sum_sign(a, b, sum, signedp) \
- ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
-
-struct constant;
-
-HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
-int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
-struct hashnode *lookup PROTO((U_CHAR *, int, int));
-void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void verror PROTO((const char *, va_list));
-void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
-
-static int parse_number PROTO((int));
-static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
-static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
-static void integer_overflow PROTO((void));
-
-/* `signedp' values */
-#define SIGNED (~0)
-#define UNSIGNED 0
-%}
-
-%union {
- struct constant {HOST_WIDEST_INT value; int signedp;} integer;
- struct name {U_CHAR *address; int length;} name;
- struct arglist *keywords;
-}
-
-%type <integer> exp exp1 start
-%type <keywords> keywords
-%token <integer> INT CHAR
-%token <name> NAME
-%token <integer> ERROR
-
-%right '?' ':'
-%left ','
-%left OR
-%left AND
-%left '|'
-%left '^'
-%left '&'
-%left EQUAL NOTEQUAL
-%left '<' '>' LEQ GEQ
-%left LSH RSH
-%left '+' '-'
-%left '*' '/' '%'
-%right UNARY
-
-/* %expect 40 */
-
-%%
-
-start : exp1
- {
- expression_value = $1.value;
-#ifdef TEST_EXP_READER
- expression_signedp = $1.signedp;
-#endif
- }
- ;
-
-/* Expressions, including the comma operator. */
-exp1 : exp
- | exp1 ',' exp
- { if (pedantic)
- pedwarn ("comma operator in operand of `#if'");
- $$ = $3; }
- ;
-
-/* Expressions, not including the comma operator. */
-exp : '-' exp %prec UNARY
- { $$.value = - $2.value;
- $$.signedp = $2.signedp;
- if (($$.value & $2.value & $$.signedp) < 0)
- integer_overflow (); }
- | '!' exp %prec UNARY
- { $$.value = ! $2.value;
- $$.signedp = SIGNED; }
- | '+' exp %prec UNARY
- { $$ = $2; }
- | '~' exp %prec UNARY
- { $$.value = ~ $2.value;
- $$.signedp = $2.signedp; }
- | '#' NAME
- { $$.value = check_assertion ($2.address, $2.length,
- 0, NULL_PTR);
- $$.signedp = SIGNED; }
- | '#' NAME
- { keyword_parsing = 1; }
- '(' keywords ')'
- { $$.value = check_assertion ($2.address, $2.length,
- 1, $5);
- keyword_parsing = 0;
- $$.signedp = SIGNED; }
- | '(' exp1 ')'
- { $$ = $2; }
- ;
-
-/* Binary operators in order of decreasing precedence. */
-exp : exp '*' exp
- { $$.signedp = $1.signedp & $3.signedp;
- if ($$.signedp)
- {
- $$.value = $1.value * $3.value;
- if ($1.value
- && ($$.value / $1.value != $3.value
- || ($$.value & $1.value & $3.value) < 0))
- integer_overflow ();
- }
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- * $3.value); }
- | exp '/' exp
- { if ($3.value == 0)
- {
- if (!skip_evaluation)
- error ("division by zero in #if");
- $3.value = 1;
- }
- $$.signedp = $1.signedp & $3.signedp;
- if ($$.signedp)
- {
- $$.value = $1.value / $3.value;
- if (($$.value & $1.value & $3.value) < 0)
- integer_overflow ();
- }
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- / $3.value); }
- | exp '%' exp
- { if ($3.value == 0)
- {
- if (!skip_evaluation)
- error ("division by zero in #if");
- $3.value = 1;
- }
- $$.signedp = $1.signedp & $3.signedp;
- if ($$.signedp)
- $$.value = $1.value % $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- % $3.value); }
- | exp '+' exp
- { $$.value = $1.value + $3.value;
- $$.signedp = $1.signedp & $3.signedp;
- if (overflow_sum_sign ($1.value, $3.value,
- $$.value, $$.signedp))
- integer_overflow (); }
- | exp '-' exp
- { $$.value = $1.value - $3.value;
- $$.signedp = $1.signedp & $3.signedp;
- if (overflow_sum_sign ($$.value, $3.value,
- $1.value, $$.signedp))
- integer_overflow (); }
- | exp LSH exp
- { $$.signedp = $1.signedp;
- if (($3.value & $3.signedp) < 0)
- $$.value = right_shift (&$1, -$3.value);
- else
- $$.value = left_shift (&$1, $3.value); }
- | exp RSH exp
- { $$.signedp = $1.signedp;
- if (($3.value & $3.signedp) < 0)
- $$.value = left_shift (&$1, -$3.value);
- else
- $$.value = right_shift (&$1, $3.value); }
- | exp EQUAL exp
- { $$.value = ($1.value == $3.value);
- $$.signedp = SIGNED; }
- | exp NOTEQUAL exp
- { $$.value = ($1.value != $3.value);
- $$.signedp = SIGNED; }
- | exp LEQ exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value <= $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- <= $3.value); }
- | exp GEQ exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value >= $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- >= $3.value); }
- | exp '<' exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value < $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- < $3.value); }
- | exp '>' exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value > $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- > $3.value); }
- | exp '&' exp
- { $$.value = $1.value & $3.value;
- $$.signedp = $1.signedp & $3.signedp; }
- | exp '^' exp
- { $$.value = $1.value ^ $3.value;
- $$.signedp = $1.signedp & $3.signedp; }
- | exp '|' exp
- { $$.value = $1.value | $3.value;
- $$.signedp = $1.signedp & $3.signedp; }
- | exp AND
- { skip_evaluation += !$1.value; }
- exp
- { skip_evaluation -= !$1.value;
- $$.value = ($1.value && $4.value);
- $$.signedp = SIGNED; }
- | exp OR
- { skip_evaluation += !!$1.value; }
- exp
- { skip_evaluation -= !!$1.value;
- $$.value = ($1.value || $4.value);
- $$.signedp = SIGNED; }
- | exp '?'
- { skip_evaluation += !$1.value; }
- exp ':'
- { skip_evaluation += !!$1.value - !$1.value; }
- exp
- { skip_evaluation -= !!$1.value;
- $$.value = $1.value ? $4.value : $7.value;
- $$.signedp = $4.signedp & $7.signedp; }
- | INT
- { $$ = yylval.integer; }
- | CHAR
- { $$ = yylval.integer; }
- | NAME
- { if (warn_undef && !skip_evaluation)
- warning ("`%.*s' is not defined",
- $1.length, $1.address);
- $$.value = 0;
- $$.signedp = SIGNED; }
- ;
-
-keywords :
- { $$ = 0; }
- | '(' keywords ')' keywords
- { struct arglist *temp;
- $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
- $$->next = $2;
- $$->name = (U_CHAR *) "(";
- $$->length = 1;
- temp = $$;
- while (temp != 0 && temp->next != 0)
- temp = temp->next;
- temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
- temp->next->next = $4;
- temp->next->name = (U_CHAR *) ")";
- temp->next->length = 1; }
- | NAME keywords
- { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
- $$->name = $1.address;
- $$->length = $1.length;
- $$->next = $2; }
- ;
-%%
-
-/* During parsing of a C expression, the pointer to the next character
- is in this variable. */
-
-static char *lexptr;
-
-/* Take care of parsing a number (anything that starts with a digit).
- Set yylval and return the token type; update lexptr.
- LEN is the number of characters in it. */
-
-/* maybe needs to actually deal with floating point numbers */
-
-static int
-parse_number (olen)
- int olen;
-{
- register char *p = lexptr;
- register int c;
- register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
- register int base = 10;
- register int len = olen;
- register int overflow = 0;
- register int digit, largest_digit = 0;
- int spec_long = 0;
-
- yylval.integer.signedp = SIGNED;
-
- if (*p == '0') {
- base = 8;
- if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
- p += 2;
- base = 16;
- len -= 2;
- }
- }
-
- max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
-
- for (; len > 0; len--) {
- c = *p++;
-
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (base == 16 && c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (base == 16 && c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else {
- /* `l' means long, and `u' means unsigned. */
- while (1) {
- if (c == 'l' || c == 'L')
- {
- if (!pedantic < spec_long)
- yyerror ("too many `l's in integer constant");
- spec_long++;
- }
- else if (c == 'u' || c == 'U')
- {
- if (! yylval.integer.signedp)
- yyerror ("two `u's in integer constant");
- yylval.integer.signedp = UNSIGNED;
- }
- else {
- if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
- yyerror ("Floating point numbers not allowed in #if expressions");
- else
- yyerror ("missing white space after number `%.*s'",
- (int) (p - lexptr - 1), lexptr);
- }
-
- if (--len == 0)
- break;
- c = *p++;
- }
- /* Don't look for any more digits after the suffixes. */
- break;
- }
- if (largest_digit < digit)
- largest_digit = digit;
- nd = n * base + digit;
- overflow |= (max_over_base < n) | (nd < n);
- n = nd;
- }
-
- if (base <= largest_digit)
- pedwarn ("integer constant contains digits beyond the radix");
-
- if (overflow)
- pedwarn ("integer constant out of range");
-
- /* If too big to be signed, consider it unsigned. */
- if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
- {
- if (base == 10)
- warning ("integer constant is so large that it is unsigned");
- yylval.integer.signedp = UNSIGNED;
- }
-
- lexptr = p;
- yylval.integer.value = n;
- return INT;
-}
-
-struct token {
- const char *operator;
- int token;
-};
-
-static struct token tokentab2[] = {
- {"&&", AND},
- {"||", OR},
- {"<<", LSH},
- {">>", RSH},
- {"==", EQUAL},
- {"!=", NOTEQUAL},
- {"<=", LEQ},
- {">=", GEQ},
- {"++", ERROR},
- {"--", ERROR},
- {NULL, ERROR}
-};
-
-/* Read one token, getting characters through lexptr. */
-
-static int
-yylex ()
-{
- register int c;
- register int namelen;
- register unsigned char *tokstart;
- register struct token *toktab;
- int wide_flag;
- HOST_WIDEST_INT mask;
-
- retry:
-
- tokstart = (unsigned char *) lexptr;
- c = *tokstart;
- /* See if it is a special token of length 2. */
- if (! keyword_parsing)
- for (toktab = tokentab2; toktab->operator != NULL; toktab++)
- if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
- lexptr += 2;
- if (toktab->token == ERROR)
- yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
- return toktab->token;
- }
-
- switch (c) {
- case '\n':
- return 0;
-
- case ' ':
- case '\t':
- case '\r':
- lexptr++;
- goto retry;
-
- case 'L':
- /* Capital L may start a wide-string or wide-character constant. */
- if (lexptr[1] == '\'')
- {
- lexptr++;
- wide_flag = 1;
- mask = MAX_WCHAR_TYPE_MASK;
- goto char_constant;
- }
- if (lexptr[1] == '"')
- {
- lexptr++;
- wide_flag = 1;
- mask = MAX_WCHAR_TYPE_MASK;
- goto string_constant;
- }
- break;
-
- case '\'':
- wide_flag = 0;
- mask = MAX_CHAR_TYPE_MASK;
- char_constant:
- lexptr++;
- if (keyword_parsing) {
- char *start_ptr = lexptr - 1;
- while (1) {
- c = *lexptr++;
- if (c == '\\')
- c = parse_escape (&lexptr, mask);
- else if (c == '\'')
- break;
- }
- yylval.name.address = tokstart;
- yylval.name.length = lexptr - start_ptr;
- return NAME;
- }
-
- /* This code for reading a character constant
- handles multicharacter constants and wide characters.
- It is mostly copied from c-lex.c. */
- {
- register HOST_WIDEST_INT result = 0;
- register int num_chars = 0;
- int chars_seen = 0;
- unsigned width = MAX_CHAR_TYPE_SIZE;
- int max_chars;
-#ifdef MULTIBYTE_CHARS
- int longest_char = local_mb_cur_max ();
- char *token_buffer = (char *) alloca (longest_char);
- (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
-#endif
-
- max_chars = MAX_LONG_TYPE_SIZE / width;
- if (wide_flag)
- width = MAX_WCHAR_TYPE_SIZE;
-
- while (1)
- {
- c = *lexptr++;
-
- if (c == '\'' || c == EOF)
- break;
-
- ++chars_seen;
- if (c == '\\')
- {
- c = parse_escape (&lexptr, mask);
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- wchar_t wc;
- int i;
- int char_len = -1;
- for (i = 1; i <= longest_char; ++i)
- {
- token_buffer[i - 1] = c;
- char_len = local_mbtowc (& wc, token_buffer, i);
- if (char_len != -1)
- break;
- c = *lexptr++;
- }
- if (char_len > 1)
- {
- /* mbtowc sometimes needs an extra char before accepting */
- if (char_len < i)
- lexptr--;
- if (! wide_flag)
- {
- /* Merge character into result; ignore excess chars. */
- for (i = 1; i <= char_len; ++i)
- {
- if (i > max_chars)
- break;
- if (width < HOST_BITS_PER_INT)
- result = (result << width)
- | (token_buffer[i - 1]
- & ((1 << width) - 1));
- else
- result = token_buffer[i - 1];
- }
- num_chars += char_len;
- continue;
- }
- }
- else
- {
- if (char_len == -1)
- warning ("Ignoring invalid multibyte character");
- }
- if (wide_flag)
- c = wc;
-#endif /* ! MULTIBYTE_CHARS */
- }
-
- if (wide_flag)
- {
- if (chars_seen == 1) /* only keep the first one */
- result = c;
- continue;
- }
-
- /* Merge character into result; ignore excess chars. */
- num_chars++;
- if (num_chars <= max_chars)
- {
- if (width < HOST_BITS_PER_INT)
- result = (result << width) | (c & ((1 << width) - 1));
- else
- result = c;
- }
- }
-
- if (c != '\'')
- error ("malformatted character constant");
- else if (chars_seen == 0)
- error ("empty character constant");
- else if (num_chars > max_chars)
- {
- num_chars = max_chars;
- error ("character constant too long");
- }
- else if (chars_seen != 1 && ! traditional)
- warning ("multi-character character constant");
-
- /* If char type is signed, sign-extend the constant. */
- if (! wide_flag)
- {
- int num_bits = num_chars * width;
- if (num_bits == 0)
- /* We already got an error; avoid invalid shift. */
- yylval.integer.value = 0;
- else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
- sizeof ("__CHAR_UNSIGNED__") - 1, -1)
- || ((result >> (num_bits - 1)) & 1) == 0)
- yylval.integer.value
- = result & (~ (unsigned HOST_WIDEST_INT) 0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
- else
- yylval.integer.value
- = result | ~(~ (unsigned HOST_WIDEST_INT) 0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
- }
- else
- {
- yylval.integer.value = result;
- }
- }
-
- /* This is always a signed type. */
- yylval.integer.signedp = SIGNED;
-
- return CHAR;
-
- /* some of these chars are invalid in constant expressions;
- maybe do something about them later */
- case '/':
- case '+':
- case '-':
- case '*':
- case '%':
- case '|':
- case '&':
- case '^':
- case '~':
- case '!':
- case '@':
- case '<':
- case '>':
- case '[':
- case ']':
- case '.':
- case '?':
- case ':':
- case '=':
- case '{':
- case '}':
- case ',':
- case '#':
- if (keyword_parsing)
- break;
- case '(':
- case ')':
- lexptr++;
- return c;
-
- case '"':
- mask = MAX_CHAR_TYPE_MASK;
- string_constant:
- if (keyword_parsing) {
- char *start_ptr = lexptr;
- lexptr++;
- while (1) {
- c = *lexptr++;
- if (c == '\\')
- c = parse_escape (&lexptr, mask);
- else if (c == '"')
- break;
- }
- yylval.name.address = tokstart;
- yylval.name.length = lexptr - start_ptr;
- return NAME;
- }
- yyerror ("string constants not allowed in #if expressions");
- return ERROR;
- }
-
- if (c >= '0' && c <= '9' && !keyword_parsing) {
- /* It's a number */
- for (namelen = 1; ; namelen++) {
- int d = tokstart[namelen];
- if (! ((is_idchar[d] || d == '.')
- || ((d == '-' || d == '+')
- && (c == 'e' || c == 'E'
- || ((c == 'p' || c == 'P') && ! c89))
- && ! traditional)))
- break;
- c = d;
- }
- return parse_number (namelen);
- }
-
- /* It is a name. See how long it is. */
-
- if (keyword_parsing) {
- for (namelen = 0;; namelen++) {
- if (is_space[tokstart[namelen]])
- break;
- if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
- break;
- if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
- break;
- }
- } else {
- if (!is_idstart[c]) {
- yyerror ("Invalid token in expression");
- return ERROR;
- }
-
- for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
- ;
- }
-
- lexptr += namelen;
- yylval.name.address = tokstart;
- yylval.name.length = namelen;
- return NAME;
-}
-
-
-/* Parse a C escape sequence. STRING_PTR points to a variable
- containing a pointer to the string to parse. That pointer
- is updated past the characters we use. The value of the
- escape sequence is returned.
-
- RESULT_MASK is used to mask out the result;
- an error is reported if bits are lost thereby.
-
- A negative value means the sequence \ newline was seen,
- which is supposed to be equivalent to nothing at all.
-
- If \ is followed by a null character, we return a negative
- value and leave the string pointer pointing at the null character.
-
- If \ is followed by 000, we return 0 and leave the string pointer
- after the zeros. A value of 0 does not mean end of string. */
-
-HOST_WIDEST_INT
-parse_escape (string_ptr, result_mask)
- char **string_ptr;
- HOST_WIDEST_INT result_mask;
-{
- register int c = *(*string_ptr)++;
- switch (c)
- {
- case 'a':
- return TARGET_BELL;
- case 'b':
- return TARGET_BS;
- case 'e':
- case 'E':
- if (pedantic)
- pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
- return 033;
- case 'f':
- return TARGET_FF;
- case 'n':
- return TARGET_NEWLINE;
- case 'r':
- return TARGET_CR;
- case 't':
- return TARGET_TAB;
- case 'v':
- return TARGET_VT;
- case '\n':
- return -2;
- case 0:
- (*string_ptr)--;
- return 0;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- {
- register HOST_WIDEST_INT i = c - '0';
- register int count = 0;
- while (++count < 3)
- {
- c = *(*string_ptr)++;
- if (c >= '0' && c <= '7')
- i = (i << 3) + c - '0';
- else
- {
- (*string_ptr)--;
- break;
- }
- }
- if (i != (i & result_mask))
- {
- i &= result_mask;
- pedwarn ("octal escape sequence out of range");
- }
- return i;
- }
- case 'x':
- {
- register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
- register int digits_found = 0, digit;
- for (;;)
- {
- c = *(*string_ptr)++;
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else
- {
- (*string_ptr)--;
- break;
- }
- overflow |= i ^ (i << 4 >> 4);
- i = (i << 4) + digit;
- digits_found = 1;
- }
- if (!digits_found)
- yyerror ("\\x used with no following hex digits");
- if (overflow | (i != (i & result_mask)))
- {
- i &= result_mask;
- pedwarn ("hex escape sequence out of range");
- }
- return i;
- }
- default:
- return c;
- }
-}
-
-static void
-integer_overflow ()
-{
- if (!skip_evaluation && pedantic)
- pedwarn ("integer overflow in preprocessor expression");
-}
-
-static HOST_WIDEST_INT
-left_shift (a, b)
- struct constant *a;
- unsigned HOST_WIDEST_INT b;
-{
- /* It's unclear from the C standard whether shifts can overflow.
- The following code ignores overflow; perhaps a C standard
- interpretation ruling is needed. */
- if (b >= HOST_BITS_PER_WIDEST_INT)
- return 0;
- else
- return (unsigned HOST_WIDEST_INT) a->value << b;
-}
-
-static HOST_WIDEST_INT
-right_shift (a, b)
- struct constant *a;
- unsigned HOST_WIDEST_INT b;
-{
- if (b >= HOST_BITS_PER_WIDEST_INT)
- return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
- else if (a->signedp)
- return a->value >> b;
- else
- return (unsigned HOST_WIDEST_INT) a->value >> b;
-}
-
-/* This page contains the entry point to this file. */
-
-/* Parse STRING as an expression, and complain if this fails
- to use up all of the contents of STRING.
- STRING may contain '\0' bytes; it is terminated by the first '\n'
- outside a string constant, so that we can diagnose '\0' properly.
- If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
- We do not support C comments. They should be removed before
- this function is called. */
-
-HOST_WIDEST_INT
-parse_c_expression (string, warn_undefined)
- char *string;
- int warn_undefined;
-{
- lexptr = string;
- warn_undef = warn_undefined;
-
- /* if there is some sort of scanning error, just return 0 and assume
- the parsing routine has printed an error message somewhere.
- there is surely a better thing to do than this. */
- if (setjmp (parse_return_error))
- return 0;
-
- if (yyparse () != 0)
- abort ();
-
- if (*lexptr != '\n')
- error ("Junk after end of expression.");
-
- return expression_value; /* set by yyparse () */
-}
-
-static void
-yyerror VPROTO ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- verror (msgid, args);
- va_end (args);
- skip_evaluation = 0;
- longjmp (parse_return_error, 1);
-}
-
-
-#ifdef TEST_EXP_READER
-
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-int pedantic;
-int traditional;
-int c89;
-
-int main PROTO((int, char **));
-static void initialize_random_junk PROTO((void));
-static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT));
-
-/* Main program for testing purposes. */
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int n, c;
- char buf[1024];
- unsigned HOST_WIDEST_INT u;
-
- pedantic = 1 < argc;
- traditional = 2 < argc;
- c89 = 3 < argc;
-#if YYDEBUG
- yydebug = 4 < argc;
-#endif
- initialize_random_junk ();
-
- for (;;) {
- printf ("enter expression: ");
- n = 0;
- while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
- n++;
- if (c == EOF)
- break;
- parse_c_expression (buf, 1);
- printf ("parser returned ");
- u = (unsigned HOST_WIDEST_INT) expression_value;
- if (expression_value < 0 && expression_signedp) {
- u = -u;
- printf ("-");
- }
- if (u == 0)
- printf ("0");
- else
- print_unsigned_host_widest_int (u);
- if (! expression_signedp)
- printf("u");
- printf ("\n");
- }
-
- return 0;
-}
-
-static void
-print_unsigned_host_widest_int (u)
- unsigned HOST_WIDEST_INT u;
-{
- if (u) {
- print_unsigned_host_widest_int (u / 10);
- putchar ('0' + (int) (u % 10));
- }
-}
-
-/* table to tell if char can be part of a C identifier. */
-unsigned char is_idchar[256];
-/* table to tell if char can be first char of a c identifier. */
-unsigned char is_idstart[256];
-/* table to tell if c is horizontal or vertical space. */
-unsigned char is_space[256];
-
-/*
- * initialize random junk in the hash table and maybe other places
- */
-static void
-initialize_random_junk ()
-{
- register int i;
-
- /*
- * Set up is_idchar and is_idstart tables. These should be
- * faster than saying (is_alpha (c) || c == '_'), etc.
- * Must do set up these things before calling any routines tthat
- * refer to them.
- */
- for (i = 'a'; i <= 'z'; i++) {
- ++is_idchar[i - 'a' + 'A'];
- ++is_idchar[i];
- ++is_idstart[i - 'a' + 'A'];
- ++is_idstart[i];
- }
- for (i = '0'; i <= '9'; i++)
- ++is_idchar[i];
- ++is_idchar['_'];
- ++is_idstart['_'];
- ++is_idchar['$'];
- ++is_idstart['$'];
-
- ++is_space[' '];
- ++is_space['\t'];
- ++is_space['\v'];
- ++is_space['\f'];
- ++is_space['\n'];
- ++is_space['\r'];
-}
-
-void
-error VPROTO ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "error: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-void
-pedwarn VPROTO ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "pedwarn: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-void
-warning VPROTO ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "warning: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-
-int
-check_assertion (name, sym_length, tokens_specified, tokens)
- U_CHAR *name;
- int sym_length;
- int tokens_specified;
- struct arglist *tokens;
-{
- return 0;
-}
-
-struct hashnode *
-lookup (name, len, hash)
- U_CHAR *name;
- int len;
- int hash;
-{
- return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
-}
-
-PTR
-xmalloc (size)
- size_t size;
-{
- return (PTR) malloc (size);
-}
-#endif
diff --git a/contrib/gcc/config/alpha/netbsd-elf.h b/contrib/gcc/config/alpha/netbsd-elf.h
deleted file mode 100644
index 6e4f4daf62b2..000000000000
--- a/contrib/gcc/config/alpha/netbsd-elf.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Definitions of target machine for GNU compiler
- for Alpha NetBSD systems using ELF.
- Copyright (C) 1998 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. */
-
-#undef TARGET_VERSION
-#define TARGET_VERSION fprintf (stderr, " (Alpha NetBSD/ELF)");
-
-#undef SUB_CPP_PREDEFINES
-#define SUB_CPP_PREDEFINES "-D__ELF__"
-
-#undef SUBTARGET_EXTRA_SPECS
-#define SUBTARGET_EXTRA_SPECS \
-{ "elf_dynamic_linker", ELF_DYNAMIC_LINKER },
-
-#define ELF_DYNAMIC_LINKER "/usr/libexec/ld.elf_so"
diff --git a/contrib/gcc/config/alpha/t-crtbe b/contrib/gcc/config/alpha/t-crtbe
deleted file mode 100644
index 5e82b923c720..000000000000
--- a/contrib/gcc/config/alpha/t-crtbe
+++ /dev/null
@@ -1,9 +0,0 @@
-# Effectively disable the crtbegin/end rules using crtstuff.c
-T = disable
-
-# Assemble startup files.
-crtbegin.o: $(srcdir)/config/alpha/crtbegin.asm $(GCC_PASSES)
- $(GCC_FOR_TARGET) -c -o crtbegin.o -x assembler $(srcdir)/config/alpha/crtbegin.asm
-
-crtend.o: $(srcdir)/config/alpha/crtend.asm $(GCC_PASSES)
- $(GCC_FOR_TARGET) -c -o crtend.o -x assembler $(srcdir)/config/alpha/crtend.asm
diff --git a/contrib/gcc/config/alpha/vms-tramp.asm b/contrib/gcc/config/alpha/vms-tramp.asm
deleted file mode 100644
index fce9ec539cad..000000000000
--- a/contrib/gcc/config/alpha/vms-tramp.asm
+++ /dev/null
@@ -1,22 +0,0 @@
-;# New Alpha OpenVMS trampoline
-;#
- .set noreorder
- .set volatile
- .set noat
- .file 1 "tramp.s"
-.text
- .align 3
- .globl __tramp
- .ent __tramp
-__tramp..en:
-
-.link
- .align 3
-__tramp:
- .pdesc __tramp..en,null
-.text
- ldq $1,24($27)
- ldq $27,16($27)
- ldq $28,8($27)
- jmp $31,($28),0
- .end __tramp
diff --git a/contrib/gcc/config/alpha/x-alpha b/contrib/gcc/config/alpha/x-alpha
deleted file mode 100644
index 9686ab96472a..000000000000
--- a/contrib/gcc/config/alpha/x-alpha
+++ /dev/null
@@ -1,2 +0,0 @@
-CLIB=-lmld
-EXTRA_HEADERS = $(srcdir)/config/alpha/va_list.h
diff --git a/contrib/gcc/config/alpha/xm-alpha.h b/contrib/gcc/config/alpha/xm-alpha.h
deleted file mode 100644
index c04844fdacde..000000000000
--- a/contrib/gcc/config/alpha/xm-alpha.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Configuration for GNU C-compiler for DEC Alpha.
- Copyright (C) 1990, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
- Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu).
-
-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. */
-
-
-/* #defines that need visibility everywhere. */
-#define FALSE 0
-#define TRUE 1
-
-/* This describes the machine the compiler is hosted on. */
-#define HOST_BITS_PER_CHAR 8
-#define HOST_BITS_PER_SHORT 16
-#define HOST_BITS_PER_INT 32
-#define HOST_BITS_PER_LONG 64
-#define HOST_BITS_PER_LONGLONG 64
-
-/* #define HOST_WORDS_BIG_ENDIAN */
-
-/* target machine dependencies.
- tm.h is a symbolic link to the actual target specific file. */
-#include "tm.h"
-
-/* Arguments to use with `exit'. */
-#define SUCCESS_EXIT_CODE 0
-#define FATAL_EXIT_CODE 33
-
-/* If compiled with GNU C, use the builtin alloca. */
-#ifndef alloca
-#if defined(__GNUC__) && !defined(USE_C_ALLOCA)
-#define alloca __builtin_alloca
-#else
-#if !defined(_WIN32) && !defined(USE_C_ALLOCA) && !defined(OPEN_VMS) && !defined(__INTERIX)
-#include <alloca.h>
-#else
-extern void *alloca ();
-#endif
-#endif
-#endif
-
-/* The host compiler has problems with enum bitfields since it makes
- them signed so we can't fit all our codes in. */
-
-#ifndef __GNUC__
-#define ONLY_INT_FIELDS
-#endif
-
-/* Declare some functions needed for this machine. We don't want to
- include these in the sources since other machines might define them
- differently. */
-
-extern void *malloc (), *realloc (), *calloc ();
-
-#ifndef inhibit_libc
-#include "string.h"
-#endif
-
-/* OSF/1 is POSIX.1 compliant. */
-
-#define POSIX
diff --git a/contrib/gcc/config/alpha/xm-openbsd.h b/contrib/gcc/config/alpha/xm-openbsd.h
deleted file mode 100644
index 50f436695a71..000000000000
--- a/contrib/gcc/config/alpha/xm-openbsd.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Configuration file for an host running alpha OpenBSD.
- Copyright (C) 1999 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. */
-
-#include <xm-openbsd.h>
-#include <alpha/xm-alpha.h>
-
diff --git a/contrib/gcc/config/i386/config-nt.sed b/contrib/gcc/config/i386/config-nt.sed
deleted file mode 100644
index 6c86b27e99ce..000000000000
--- a/contrib/gcc/config/i386/config-nt.sed
+++ /dev/null
@@ -1,38 +0,0 @@
-/^Makefile/,/^ rm -f config.run/d
-s/rm -f/del/
-s/|| cp/|| copy/
-/^config.status/,/ fi/d
-s/config.status//g
-s/\/dev\/null/NUL/g
-s/$(srcdir)\/c-parse/c-parse/g
-s/$(srcdir)\/c-gperf/c-gperf/g
-/^multilib.h/ s/multilib/not-multilib/
-/^target=/ c\
-target=winnt3.5
-/^xmake_file=/ d
-/^tmake_file=/ d
-/^out_file/ c\
-out_file=config/i386/i386.c
-/^out_object_file/ c\
-out_object_file=i386.obj
-/^md_file/ c\
-md_file=config/i386/i386.md
-/^tm_file/ c\
-tm_file=config/i386/win-nt.h
-/^build_xm_file/ c\
-build_xm_file=config/i386/xm-winnt.h
-/^host_xm_file/ c\
-host_xm_file=config/i386/xm-winnt.h
-/^####target/ i\
-CC = cl \
-CLIB = libc.lib kernel32.lib \
-CFLAGS = -Di386 -DWIN32 -D_WIN32 -D_M_IX86=300 -D_X86_=1 \\\
- -DALMOST_STDC -D_MSC_VER=800 \
-LDFLAGS = -align:0x1000 -subsystem:console -entry:mainCRTStartup \\\
- -stack:1000000,1000 \
-\
-EXTRA_OBJS=winnt.obj \
-winnt.obj: $(srcdir)/config/i386/winnt.c \
-\ $(CC) $(CFLAGS) \\\
-\ -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/i386/winnt.c \
-
diff --git a/contrib/gcc/config/i386/dgux.c b/contrib/gcc/config/i386/dgux.c
deleted file mode 100644
index 638d1e0f60e6..000000000000
--- a/contrib/gcc/config/i386/dgux.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Subroutines for GNU compiler for Intel 80x86 running DG/ux
- Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
- Currently maintained by (gcc@dg-rtp.dg.com)
-
-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. */
-
-#include <time.h>
-#include "i386/i386.c"
-
-
-extern char *version_string;
-
-struct option
-{
- char *string;
- int *variable;
- int on_value;
- char *description;
-};
-
-static int
-output_option (file, sep, type, name, indent, pos, max)
- FILE *file;
- char *sep;
- char *type;
- char *name;
- char *indent;
- int pos;
- int max;
-{
- if (strlen (sep) + strlen (type) + strlen (name) + pos > max)
- {
- fprintf (file, indent);
- return fprintf (file, "%s%s", type, name);
- }
- return pos + fprintf (file, "%s%s%s", sep, type, name);
-}
-
-static struct { char *name; int value; } m_options[] = TARGET_SWITCHES;
-
-static void
-output_options (file, f_options, f_len, W_options, W_len,
- pos, max, sep, indent, term)
- FILE *file;
- struct option *f_options;
- struct option *W_options;
- int f_len, W_len;
- int pos;
- int max;
- char *indent;
- char *term;
-{
- register int j;
-
- if (optimize)
- pos = output_option (file, sep, "-O", "", indent, pos, max);
- if (write_symbols != NO_DEBUG)
- pos = output_option (file, sep, "-g", "", indent, pos, max);
-/* if (flag_traditional)
- pos = output_option (file, sep, "-traditional", "", indent, pos, max);*/
- if (profile_flag)
- pos = output_option (file, sep, "-p", "", indent, pos, max);
- if (profile_block_flag)
- pos = output_option (file, sep, "-a", "", indent, pos, max);
-
- for (j = 0; j < f_len; j++)
- if (*f_options[j].variable == f_options[j].on_value)
- pos = output_option (file, sep, "-f", f_options[j].string,
- indent, pos, max);
-
- for (j = 0; j < W_len; j++)
- if (*W_options[j].variable == W_options[j].on_value)
- pos = output_option (file, sep, "-W", W_options[j].string,
- indent, pos, max);
-
- for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++)
- if (m_options[j].name[0] != '\0'
- && m_options[j].value > 0
- && ((m_options[j].value & target_flags)
- == m_options[j].value))
- pos = output_option (file, sep, "-m", m_options[j].name,
- indent, pos, max);
-
- pos = output_option (file, sep, "-mcpu=", ix86_cpu_string, indent, pos, max);
- pos = output_option (file, sep, "-march=", ix86_arch_string, indent, pos, max);
- fprintf (file, term);
-}
-
-/* Output to FILE the start of the assembler file. */
-
-void
-output_file_start (file, f_options, f_len, W_options, W_len)
- FILE *file;
- struct option *f_options;
- struct option *W_options;
- int f_len, W_len;
-{
- register int pos;
-
- output_file_directive (file, main_input_filename);
- fprintf (file, "\t.version\t\"01.01\"\n"); \
- /* Switch to the data section so that the coffsem symbol and the
- gcc2_compiled. symbol aren't in the text section. */
- data_section ();
-
- pos = fprintf (file, "\n// cc1 (%s) arguments:", VERSION_STRING);
- output_options (file, f_options, f_len, W_options, W_len,
- pos, 75, " ", "\n// ", "\n\n");
-
-#ifdef TARGET_IDENTIFY_REVISION
- if (TARGET_IDENTIFY_REVISION)
- {
- char indent[256];
-
- time_t now = time ((time_t *)0);
- sprintf (indent, "]\"\n\t%s\t \"@(#)%s [", IDENT_ASM_OP, main_input_filename);
- fprintf (file, indent+3);
- pos = fprintf (file, "gcc %s, %.24s,", VERSION_STRING, ctime (&now));
- output_options (file, f_options, f_len, W_options, W_len,
- pos, 150 - strlen (indent), " ", indent, "]\"\n\n");
- }
-#endif /* TARGET_IDENTIFY_REVISION */
-}
-
-#ifndef CROSS_COMPILE
-#if defined (_abort_aux)
-/* Debugging aid to be registered via `atexit'. See the definition
- of abort in dgux.h. */
-void
-abort_aux ()
-{
- extern int insn_;
- extern char * file_;
- extern int line_;
- static int done;
- rtx line_note;
-
- if (done++)
- return;
- if (file_ || line_)
- {
- if (write_symbols != NO_DEBUG)
- {
- for (line_note = (rtx) insn_ ; line_note != 0 ; line_note = PREV_INSN (line_note))
- if (GET_CODE (line_note) == NOTE && NOTE_LINE_NUMBER (line_note) > 0)
- break;
- if (line_note != 0)
- {
- error_with_file_and_line (NOTE_SOURCE_FILE (line_note),
- NOTE_LINE_NUMBER (line_note),
- "Internal gcc abort from %s:%d",
- file_ ? file_ : "<nofile>", line_);
- if (insn_ && file_ && strcmp (file_, "toplev.c"))
- {
- error_with_file_and_line (NOTE_SOURCE_FILE (line_note),
- NOTE_LINE_NUMBER (line_note),
- "The local variable `insn' has the value:", 0);
- debug_rtx ((rtx) insn_);
- }
- }
- }
- if (write_symbols == NO_DEBUG || line_note == 0)
- {
- error ("Internal gcc abort from %s:%d",
- file_ ? file_ : "<nofile>", line_);
- if (insn_ && file_ && strcmp (file_, "toplev.c"))
- {
- error ("The local variable `insn' has the value:", 0);
- debug_rtx ((rtx) insn_);
- }
- }
- }
-}
-#endif
-#endif
-
-
diff --git a/contrib/gcc/config/i386/os2.h b/contrib/gcc/config/i386/os2.h
deleted file mode 100644
index 8bbab361f98f..000000000000
--- a/contrib/gcc/config/i386/os2.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Definitions of target machine for GNU compiler
- for an Intel i386 or later processor running OS/2 2.x.
- Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
- Contributed by Samuel Figueroa (figueroa@cs.nyu.edu)
-
-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. */
-
-#ifndef DEFAULT_TARGET_MACHINE
-#define DEFAULT_TARGET_MACHINE "i386-os2"
-#endif
-#ifndef LINK_SPEC
-#define LINK_SPEC "/st:1048576/pm:vio/noi/a:16/e/bas:65536/nol"
-#endif
-#ifndef LIB_SPEC
-#define LIB_SPEC "libgcc libc"
-#endif
-#ifndef STARTFILE_SPEC
-#define STARTFILE_SPEC "libcrt.lib"
-#endif
-#ifndef MD_EXEC_PREFIX
-#define MD_EXEC_PREFIX "\\gcc\\bin\\"
-#endif
-#ifndef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX "\\gcc\\lib\\"
-#endif
-#ifndef LOCAL_INCLUDE_DIR
-#define LOCAL_INCLUDE_DIR "\\gcc\\include"
-#endif
-
-#define YES_UNDERSCORES
-#include "i386/gstabs.h"
-
-#define USE_COLLECT
-
-#define BIGGEST_FIELD_ALIGNMENT \
- (maximum_field_alignment ? maximum_field_alignment : 32)
-
-extern int maximum_field_alignment;
-
-#undef PCC_BITFIELD_TYPE_MATTERS
-#define PCC_BITFIELD_TYPE_MATTERS (maximum_field_alignment == 0)
-
-/* Define this macro if it is advisable to hold scalars in registers
- in a wider mode than that declared by the program. In such cases,
- the value is constrained to be within the bounds of the declared
- type, but kept valid in the wider mode. The signedness of the
- extension may differ from that of the type. */
-
-#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
- if (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
- (MODE) = SImode;
-
-/* Define this if function arguments should also be promoted using the above
- procedure. */
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted. */
-
-#define PROMOTE_FUNCTION_RETURN
diff --git a/contrib/gcc/config/i386/perform.h b/contrib/gcc/config/i386/perform.h
deleted file mode 100644
index 8d6d0b71dfeb..000000000000
--- a/contrib/gcc/config/i386/perform.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Definitions for AT&T assembler syntax for the Intel 80386.
- Copyright (C) 1993 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. */
-
-/* Defines to be able to build libgcc.a with GCC. */
-
-/* It might seem that these are not important, since gcc 2 will never
- call libgcc for these functions. But programs might be linked with
- code compiled by gcc 1, and then these will be used. */
-
-/* The arg names used to be a and b, but `a' appears inside strings
- and that confuses non-ANSI cpp. */
-
-#define perform_udivsi3(arg0,arg1) \
-{ \
- register int dx asm("dx"); \
- register int ax asm("ax"); \
- \
- dx = 0; \
- ax = arg0; \
- asm ("divl %3" : "=a" (ax), "=d" (dx) : "a" (ax), "g" (arg1), "d" (dx)); \
- return ax; \
-}
-
-#define perform_divsi3(arg0,arg1) \
-{ \
- register int dx asm("dx"); \
- register int ax asm("ax"); \
- register int cx asm("cx"); \
- \
- ax = arg0; \
- cx = arg1; \
- asm ("cltd\n\tidivl %3" : "=a" (ax), "=&d" (dx) : "a" (ax), "c" (cx)); \
- return ax; \
-}
-
-#define perform_umodsi3(arg0,arg1) \
-{ \
- register int dx asm("dx"); \
- register int ax asm("ax"); \
- \
- dx = 0; \
- ax = arg0; \
- asm ("divl %3" : "=a" (ax), "=d" (dx) : "a" (ax), "g" (arg1), "d" (dx)); \
- return dx; \
-}
-
-#define perform_modsi3(arg0,arg1) \
-{ \
- register int dx asm("dx"); \
- register int ax asm("ax"); \
- register int cx asm("cx"); \
- \
- ax = arg0; \
- cx = arg1; \
- asm ("cltd\n\tidivl %3" : "=a" (ax), "=&d" (dx) : "a" (ax), "c" (cx)); \
- return dx; \
-}
-
-#define perform_fixdfsi(arg0) \
-{ \
- auto unsigned short ostatus; \
- auto unsigned short nstatus; \
- auto int ret; \
- auto double tmp; \
- \
- &ostatus; /* guarantee these land in memory */ \
- &nstatus; \
- &ret; \
- &tmp; \
- \
- asm volatile ("fnstcw %0" : "=m" (ostatus)); \
- nstatus = ostatus | 0x0c00; \
- asm volatile ("fldcw %0" : /* no outputs */ : "m" (nstatus)); \
- tmp = arg0; \
- asm volatile ("fldl %0" : /* no outputs */ : "m" (tmp)); \
- asm volatile ("fistpl %0" : "=m" (ret)); \
- asm volatile ("fldcw %0" : /* no outputs */ : "m" (ostatus)); \
- \
- return ret; \
-}
-
diff --git a/contrib/gcc/config/i386/sco.h b/contrib/gcc/config/i386/sco.h
deleted file mode 100644
index 55af64128a10..000000000000
--- a/contrib/gcc/config/i386/sco.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Definitions for Intel 386 running SCO Unix System V.
- Copyright (C) 1988, 92, 94, 95, 96, 1999 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. */
-
-/* Mostly it's like AT&T Unix System V. */
-
-#include "i386/sysv3.h"
-
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
- and returns float values in the 387, ie,
- (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387)
-
- SCO's software emulation of a 387 fails to handle the `fucomp'
- opcode. fucomp is only used when generating IEEE compliant code.
- So don't make TARGET_IEEE_FP default for SCO. */
-
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
-
-/* Let's guess that the SCO software FPU emulator can't handle
- 80-bit XFmode insns, so don't generate them. */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 64
-
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}} crtbegin.o%s"
-
-#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
-
-/* Library spec, including SCO international language support. */
-
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} %{scointl:libintl.a%s} -lc"
-
-/* Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dunix -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem(svr3)"
-
-#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu) %{scointl:-DM_INTERNAT}"
-
-/* This spec is used for telling cpp whether char is signed or not. */
-
-#undef SIGNED_CHAR_SPEC
-#if DEFAULT_SIGNED_CHAR
-#define SIGNED_CHAR_SPEC \
- "%{funsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#else
-#define SIGNED_CHAR_SPEC \
- "%{!fsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#endif
-
-/* Use atexit for static destructors, instead of defining
- our own exit function. */
-#define HAVE_ATEXIT
-
-/* Specify the size_t type. */
-#define SIZE_TYPE "unsigned int"
-
-#if 0 /* Not yet certain whether this is needed. */
-/* If no 387, use the general regs to return floating values,
- since this system does not emulate the 80387. */
-
-#undef VALUE_REGNO
-#define VALUE_REGNO(MODE) \
- ((TARGET_80387
- && ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode)
- ? FIRST_FLOAT_REG : 0)
-
-#undef HARD_REGNO_MODE_OK
-#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- ((REGNO) < 2 ? 1 \
- : (REGNO) < 4 ? 1 \
- : FP_REGNO_P (REGNO) ? ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
- && TARGET_80387 \
- && GET_MODE_UNIT_SIZE (MODE) <= 8) \
- : (MODE) != QImode)
-#endif
-
-/* caller has to pop the extra argument passed to functions that return
- structures. */
-
-#undef RETURN_POPS_ARGS
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
- ((FUNDECL) && TREE_CODE (FUNDECL) == IDENTIFIER_NODE ? 0 \
- : (TARGET_RTD \
- && (TYPE_ARG_TYPES (FUNTYPE) == 0 \
- || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
- == void_type_node))) ? (SIZE) \
- : 0)
-/* On other 386 systems, the last line looks like this:
- : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */
-
-/* Handle #pragma pack. */
-#define HANDLE_SYSV_PRAGMA
diff --git a/contrib/gcc/config/i386/sco4.h b/contrib/gcc/config/i386/sco4.h
deleted file mode 100644
index 5d1ea471dbf8..000000000000
--- a/contrib/gcc/config/i386/sco4.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Definitions for Intel 386 running SCO Unix System V 3.2 Version 4.
- Written by Chip Salzenberg.
- Copyright (C) 1992, 1994 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. */
-
-
-/* Mostly it's like earlier SCO UNIX. */
-
-#include "i386/sco.h"
-
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{scoxpg3:%{p:mcrt1X.o%s}%{!p:crt1X.o%s}} \
- %{!scoxpg3:\
- %{posix:%{p:mcrt1P.o%s}%{!p:crt1P.o%s}} \
- %{!posix:\
- %{ansi:%{p:mcrt1A.o%s}%{!p:crt1A.o%s}} \
- %{!ansi:%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}} \
- crtbegin.o%s"
-
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC \
- "crtend.o%s \
- %{scoxpg3:crtnX.o%s} \
- %{!scoxpg3:\
- %{posix:crtnP.o%s} \
- %{!posix:\
- %{ansi:crtnA.o%s} \
- %{!ansi:crtn.o%s}}}"
-
-/* Library spec. */
-
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} \
- %{scoxpg3:-lcX -lcP -lcA} \
- %{!scoxpg3:\
- %{posix:-lcP -lcA} \
- %{!posix:\
- %{ansi:-lcA} \
- %{!ansi:%{scointl:-lintl} -lc}}}"
-
-/* Macros, macros everywhere:
- Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES \
- "-Asystem(svr3)"
-
-#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu) \
- -D_i386 -D_M_I386 -D_M_I86 -D_M_I86SM -D_M_SDATA -D_M_STEXT \
- -D_unix -D_M_UNIX -D_M_XENIX \
- -D_M_SYS5 -D_M_SYSV -D_M_SYS3 -D_M_SYSIII \
- -D_M_COFF -D_M_BITFIELDS -D_M_WORDSWAP \
- %{scoxpg3:-D_XOPEN_SOURCE -D_STRICT_NAMES} \
- %{!scoxpg3:%{posix:-D_POSIX_SOURCE -D_STRICT_NAMES}} \
- %{!scoxpg3:%{!posix:\
- %{ansi:-D_STRICT_NAMES}%{!ansi:\
- -Di386 -DM_I386 -DM_I86 -DM_I86SM -DM_SDATA -DM_STEXT \
- -Dunix -DM_UNIX -DM_XENIX \
- -DM_SYS5 -DM_SYSV -DM_SYS3 -DM_SYSIII \
- -DM_COFF -DM_BITFIELDS -DM_WORDSWAP \
- %{scointl:-D_M_INTERNAT -DM_INTERNAT} \
- %{traditional:-D_KR -D_SVID -D_NO_PROTOTYPE}}}}"
-
-/* The system headers are C++-aware. */
-#define NO_IMPLICIT_EXTERN_C
diff --git a/contrib/gcc/config/i386/sco4dbx.h b/contrib/gcc/config/i386/sco4dbx.h
deleted file mode 100644
index 3d075b6a2e26..000000000000
--- a/contrib/gcc/config/i386/sco4dbx.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Definitions for Intel 386 running SCO Unix System V 3.2 Version 4.s,
- using dbx-in-coff encapsulation.
- Copyright (C) 1992 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. */
-
-
-/* Mostly it's like earlier SCO UNIX. */
-
-#include "i386/scodbx.h"
-
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{!r:%{!z:gcc.ifile%s}%{z:gccz.ifile%s}}\
- %{scoxpg3:%{p:mcrt1X.o%s}%{!p:crt1X.o%s}} \
- %{!scoxpg3:\
- %{posix:%{p:mcrt1P.o%s}%{!p:crt1P.o%s}} \
- %{!posix:\
- %{ansi:%{p:mcrt1A.o%s}%{!p:crt1A.o%s}} \
- %{!ansi:%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}}"
-
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC \
- "%{scoxpg3:crtnX.o%s} \
- %{!scoxpg3:\
- %{posix:crtnP.o%s} \
- %{!posix:\
- %{ansi:crtnA.o%s} \
- %{!ansi:crtn.o%s}}}"
-
-/* Library spec. */
-
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} \
- %{scoxpg3:-lcX -lcP -lcA} \
- %{!scoxpg3:\
- %{posix:-lcP -lcA} \
- %{!posix:\
- %{ansi:-lcA} \
- %{!ansi:%{scointl:-lintl} -lc}}}"
-
-/* Macros, macros everywhere:
- Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dunix -Asystem(svr3)"
-
-#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu) \
- -D_M_I386 -D_M_I86 -D_M_I86SM -D_M_SDATA -D_M_STEXT \
- -D_M_UNIX -D_M_XENIX \
- -D_M_SYS5 -D_M_SYSV -D_M_SYS3 -D_M_SYSIII \
- -D_M_COFF -D_M_BITFIELDS -D_M_WORDSWAP \
- %{scoxpg3:-D_XOPEN_SOURCE -D_STRICT_NAMES} \
- %{!scoxpg3:%{posix:-D_POSIX_SOURCE -D_STRICT_NAMES}} \
- %{!scoxpg3:%{!posix:\
- %{ansi:-D_STRICT_NAMES}%{!ansi:\
- -DM_I386 -DM_I86 -DM_I86SM -DM_SDATA -DM_STEXT \
- -DM_UNIX -DM_XENIX \
- -DM_SYS5 -DM_SYSV -DM_SYS3 -DM_SYSIII \
- -DM_COFF -DM_BITFIELDS -DM_WORDSWAP \
- %{scointl:-D_M_INTERNAT -DM_INTERNAT} \
- %{traditional:-D_KR -D_SVID -D_NO_PROTOTYPE}}}}"
diff --git a/contrib/gcc/config/i386/sco5gas.h b/contrib/gcc/config/i386/sco5gas.h
deleted file mode 100644
index de3e5d5570f1..000000000000
--- a/contrib/gcc/config/i386/sco5gas.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Definitions for Intel x86 running SCO OpenServer, running GNU assembler
- Copyright (C) 1998 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. */
-
-
-/* Just set a single flag we can test for inside of sco5.h and include it. */
-
-#define USE_GAS 1
diff --git a/contrib/gcc/config/i386/scodbx.h b/contrib/gcc/config/i386/scodbx.h
deleted file mode 100644
index 7da93053256f..000000000000
--- a/contrib/gcc/config/i386/scodbx.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Definitions for Intel 386 running SCO Unix System V,
- using dbx-in-coff encapsulation.
- Copyright (C) 1992, 1995, 1996, 1999 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. */
-
-#include "i386/svr3dbx.h"
-
-/* Overridden defines for SCO systems from sco.h. */
-
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
- and returns float values in the 387, ie,
- (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387)
-
- SCO's software emulation of a 387 fails to handle the `fucomp'
- opcode. fucomp is only used when generating IEEE compliant code.
- So don't make TARGET_IEEE_FP default for SCO. */
-
-#undef TARGET_SUBTARGET_DEFAULT
-#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
-
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{!r:%{!z:svr3.ifile%s}%{z:svr3z.ifile%s}}\
- %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
-
-/* Library spec, including SCO international language support. */
-
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} %{scointl:libintl.a%s} -lc"
-
-/* Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dunix -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem=svr3"
-
-#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu) %{scointl:-DM_INTERNAT}"
-
-/* This spec is used for telling cpp whether char is signed or not. */
-
-#undef SIGNED_CHAR_SPEC
-#if DEFAULT_SIGNED_CHAR
-#define SIGNED_CHAR_SPEC \
- "%{funsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#else
-#define SIGNED_CHAR_SPEC \
- "%{!fsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#endif
-
-/* caller has to pop the extra argument passed to functions that return
- structures. */
-
-#undef RETURN_POPS_ARGS
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
- ((FUNDECL) && TREE_CODE (FUNDECL) == IDENTIFIER_NODE ? 0 \
- : (TARGET_RTD \
- && (TYPE_ARG_TYPES (FUNTYPE) == 0 \
- || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
- == void_type_node))) ? (SIZE) \
- : 0)
-/* On other 386 systems, the last line looks like this:
- : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */
-
-/* Handle #pragma pack. */
-#define HANDLE_SYSV_PRAGMA
diff --git a/contrib/gcc/config/i386/t-i386bare b/contrib/gcc/config/i386/t-i386bare
deleted file mode 100644
index 2970fa714155..000000000000
--- a/contrib/gcc/config/i386/t-i386bare
+++ /dev/null
@@ -1,3 +0,0 @@
-# The i386 md has all of these taken care of, according to sef.
-LIBGCC1 =
-CROSS_LIBGCC1 =
diff --git a/contrib/gcc/config/i386/t-vsta b/contrib/gcc/config/i386/t-vsta
deleted file mode 100644
index 6160b7ec945d..000000000000
--- a/contrib/gcc/config/i386/t-vsta
+++ /dev/null
@@ -1,2 +0,0 @@
-LIBGCC1 = libgcc1.null
-CROSS_LIBGCC1 = libgcc1.null
diff --git a/contrib/gcc/config/i386/t-winnt b/contrib/gcc/config/i386/t-winnt
deleted file mode 100644
index 1e3557c1822a..000000000000
--- a/contrib/gcc/config/i386/t-winnt
+++ /dev/null
@@ -1,6 +0,0 @@
-winnt.o: $(srcdir)/config/i386/winnt.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c
-oldnames.o: $(srcdir)/config/winnt/oldnames.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/winnt/oldnames.c
-spawnv.o: $(srcdir)/config/winnt/spawnv.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/winnt/spawnv.c
diff --git a/contrib/gcc/config/i386/win-nt.h b/contrib/gcc/config/i386/win-nt.h
deleted file mode 100644
index 97f10c39d002..000000000000
--- a/contrib/gcc/config/i386/win-nt.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Operating system specific defines to be used when targeting GCC for
- Windows NT 3.x on an i386.
- Copyright (C) 1994, 1995 Free Software Foundation, Inc.
- Contributed by Douglas B. Rupp (drupp@cs.washington.edu).
-
-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. */
-
-#define YES_UNDERSCORES
-
-#include "i386/gas.h"
-
-#ifdef CPP_PREDEFINES
-#undef CPP_PREDEFINES
-#endif
-#define CPP_PREDEFINES "-Dunix -Di386 -DWIN32 -D_WIN32 \
- -DWINNT -D_M_IX86=300 -D_X86_=1 -D__STDC__=0 -DALMOST_STDC -D_MSC_VER=800 \
- -D__stdcall=__attribute__((__stdcall__)) \
- -D__cdecl=__attribute__((__cdecl__)) \
- -D_cdecl=__attribute__((__cdecl__)) \
- -Asystem(unix) -Asystem(winnt) -Acpu(i386) -Amachine(i386)"
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-#define WCHAR_UNSIGNED 1
-#define WCHAR_TYPE_SIZE 16
-#define WCHAR_TYPE "short unsigned int"
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 64
-#define HAVE_ATEXIT 1
-
-#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_ctor, in_dtor
-
-#undef EXTRA_SECTION_FUNCTIONS
-#define EXTRA_SECTION_FUNCTIONS \
- CTOR_SECTION_FUNCTION \
- DTOR_SECTION_FUNCTION
-
-#define CTOR_SECTION_FUNCTION \
-void \
-ctor_section () \
-{ \
- if (in_section != in_ctor) \
- { \
- fprintf (asm_out_file, "\t.section .ctor\n"); \