Compare commits

...

7 Commits

Author SHA1 Message Date
Oliver Tappe
b16647ffb4 - fixed problem with bdb-compatibility when compiling libstdc++ without
inlining (compatibility functions were missing from libstdc++.r4.so in that
  case).


git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9835 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-11-07 19:16:03 +00:00
Oliver Tappe
1fd444a297 - fixed buglet with wrong include-folder being used during generation of
html-docs.


git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9653 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-10-29 18:44:53 +00:00
Oliver Tappe
acd66be8cd - added build-instructions, readme and distribution support files for gcc.
git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9624 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-10-28 20:58:17 +00:00
Oliver Tappe
7ee596e436 - added files that didn't make it in during the patch-session.
git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9623 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-10-28 19:26:41 +00:00
Oliver Tappe
78abf7bba0 avoid ICEing when encountering a (template-related) problem during
generation of debug-info.
	This is highly experimental and has a good chance of being removed
	at a later stage.


git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9621 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-10-28 18:36:41 +00:00
Oliver Tappe
552d1c2e8d avoid overoptimizing implicitly generated functions of local classes
in order to fix linking errors.


git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9620 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-10-28 18:36:18 +00:00
Oliver Tappe
cb1ff25317 fix position of source-line labels when generating debug info.
git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9619 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-10-28 18:35:59 +00:00
16 changed files with 2110 additions and 24 deletions

37
INSTALL-from-source-BeOS Normal file
View File

@@ -0,0 +1,37 @@
How to build gcc-2.95.3 for BeOS:
cd into the buildtools folder (where this file lives)
compile binutils:
mkdir binutils-obj
cd binutils-obj
CFLAGS="-O2" CXXFLAGS="-O2" ../binutils/configure --prefix=/boot/develop/tools/gnupro --enable-shared=yes
make
cd ..
compile gcc:
mkdir gcc-obj
cd gcc-obj
CFLAGS="-O2" CXXFLAGS="-O2" ../gcc/configure --prefix=/boot/develop/tools/gnupro --enable-shared=yes --enable-languages=c,c++
make bootstrap
cd ..
Ok, now everything is compiled and ready, waiting to be installed:
mv /boot/develop/tools/gnupro /boot/develop/tools/gnupro_...
mkdir /boot/develop/tools/gcc-2.95.3_binutils-2.15
ln -s /boot/develop/tools/gcc-2.95.3_binutils-2.15 /boot/develop/tools/gnupro
cd binutils-obj
make install
cd ..
cd gcc-obj
make install
cd ..
That's it, gcc-2.95.3 and binutils-2.15 are now installed and active.
So have fun!
Please send questions & bug-reports to: Oliver Tappe <gcc@hirschkaefer.de>

View File

@@ -2034,6 +2034,14 @@ cons_up_default_function (type, full_name, kind)
/* Show that this function was generated by the compiler. */
SET_DECL_ARTIFICIAL (fn);
/* [zooey] force functions of local classes into such a mode, that they
will be output even after being inlined. This circumvents a bug that
causes undefined symbols when linking against files using local classes. */
if (DECL_CONTEXT (fn) != NULL_TREE && hack_decl_function_context (fn))
// functions whose address is needed have to be put out even when inlined,
// so we use this to get the desired effect:
TREE_ADDRESSABLE(fn) = 1;
return fn;
}

View File

@@ -7797,11 +7797,13 @@ scope_die_for (t, context_die)
if (i < 0)
{
if (TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't')
abort ();
if (debug_info_level > DINFO_LEVEL_TERSE
&& !TREE_ASM_WRITTEN (containing_scope))
abort ();
if (TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't'
|| (debug_info_level > DINFO_LEVEL_TERSE
&& !TREE_ASM_WRITTEN (containing_scope)))
/* [zooey] avoid ICEing, return default instead: */
if (pedantic)
warning ("Trapped ICE during generation of debug-info, expect problems in debugger!\n");
// abort ();
/* If none of the current dies are suitable, we get file scope. */
scope_die = comp_unit_die;
@@ -8396,7 +8398,10 @@ gen_subprogram_die (decl, context_die)
extern int errorcount;
if (errorcount)
return;
abort ();
// [zooey]: avoid ICEing, since we *should* have trapped all
// executions paths leading here...
// abort ();
return;
}
/* If the definition comes from the same place as the declaration,

View File

@@ -1585,10 +1585,26 @@ final_start_function (first, file, optimize)
FILE *file;
int optimize;
{
rtx insn;
block_depth = 0;
this_is_asm_operands = 0;
/* [zooey]: gcc-2.95.3 generates incorrect source-line labels when generating
debug-info because this function is called with first pointing to an note-insn
that has been deleted (whose NOTE_LINE_NUMBER == NOTE_INSN_DELETED).
In order to generate correct source-line labels, we skip to the first insn
which has a line-number (if any).
The result of this is a much improved debugging experience...
*/
if (NOTE_LINE_NUMBER (first) == NOTE_INSN_DELETED)
for (insn = first; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
{
first = insn;
break;
}
#ifdef NON_SAVING_SETJMP
/* A function that calls setjmp should save and restore all the
call-saved registers on a system where longjmp clobbers them. */

176
gcc/gcc/fixinc/check.tpl Normal file
View File

@@ -0,0 +1,176 @@
[= autogen5 template sh=check.sh =]
[=
#
# This file contanes the shell template to run tests on the fixes
#
=]#!/bin/sh
set -e
TESTDIR=tests
TESTBASE=`cd $1;${PWDCMD-pwd}`
[ -d ${TESTDIR} ] || mkdir ${TESTDIR}
cd ${TESTDIR}
TESTDIR=`${PWDCMD-pwd}`
TARGET_MACHINE='*'
DESTDIR=`${PWDCMD-pwd}`/res
SRCDIR=`${PWDCMD-pwd}`/inc
FIND_BASE='.'
VERBOSE=[=` echo ${VERBOSE-1} `=]
INPUT=`${PWDCMD-pwd}`
ORIGDIR=${INPUT}
export TARGET_MACHINE DESTDIR SRCDIR FIND_BASE VERBOSE INPUT ORIGDIR
rm -rf ${DESTDIR} ${SRCDIR}
mkdir ${DESTDIR} ${SRCDIR}
(
[=
(shellf
"for f in %s
do case $f in
*/* ) echo $f | sed 's;/[^/]*$;;' ;;
esac
done | sort -u | \
while read g
do echo \" mkdir \\${SRCDIR}/$g || mkdir -p \\${SRCDIR}/$g || exit 1\"
done" (join " " (stack "fix.files")) ) =]
) 2> /dev/null[= # suppress 'No such file or directory' messages =]
cd inc
[=
(define sfile "")
(define HACK "")
(define dfile "") =][=
FOR fix =][=
IF (> (count "test_text") 1) =][=
(set! HACK (string-upcase! (get "hackname")))
(set! sfile (if (exist? "files") (get "files[]") "testing.h"))
(set! dfile (string-append
(if (*==* sfile "/")
(shellf "echo \"%s\"|sed 's,/[^/]*,/,'" sfile )
"" )
(string-tr! (get "hackname") "_A-Z" "-a-z")
) ) =][=
FOR test_text (for-from 1) =]
cat >> [=(. sfile)=] <<_HACK_EOF_
#if defined( [=(. HACK)=]_CHECK_[=(for-index)=] )
[=test_text=]
#endif /* [=(. HACK)=]_CHECK_[=(for-index)=] */
_HACK_EOF_
echo [=(. sfile)=] | ../../fixincl
mv -f [=(. sfile)=] [=(. dfile)=]-[=(for-index)=].h
[ -f ${DESTDIR}/[=(. sfile)=] ] && [=#
=]mv ${DESTDIR}/[=(. sfile)=] ${DESTDIR}/[=(. dfile)=]-[=(for-index)=].h[=
ENDFOR test_text =][=
ENDIF multi-test =][=
ENDFOR fix
=][=
FOR fix =][=
(set! HACK (string-upcase! (get "hackname"))) =][=
IF (not (exist? "test_text")) =][=
(if (not (exist? "replace"))
(error (sprintf "include fix '%s' has no test text"
(get "hackname") )) )
=][=
ELSE =]
cat >> [=
IF (exist? "files") =][=
files[0] =][=
ELSE =]testing.h[=
ENDIF =] <<_HACK_EOF_
#if defined( [=(. HACK)=]_CHECK )
[=test_text=]
#endif /* [=(. HACK)=]_CHECK */
_HACK_EOF_
[=ENDIF =][=
ENDFOR fix
=]
find . -type f | sed 's;^\./;;' | sort | ../../fixincl
cd ${DESTDIR}
exitok=true
find * -type f -print > ${TESTDIR}/LIST
# Special hack for sys/types.h: the #define-d types for size_t,
# ptrdiff_t and wchar_t are different for each port. Therefore,
# strip off the defined-to type so that the test results are the
# same for all platforms.
#
sed 's/\(#define __[A-Z_]*_TYPE__\).*/\1/' sys/types.h > XX
mv -f XX sys/types.h
# The following subshell weirdness is for saving an exit
# status from within a while loop that reads input. If you can
# think of a cleaner way, suggest away, please...
#
exitok=`
exec < ${TESTDIR}/LIST
while read f
do
if [ ! -f ${TESTBASE}/$f ]
then
echo "Newly fixed header: $f" >&2
exitok=false
elif cmp $f ${TESTBASE}/$f >&2
then
:
else
${DIFF:-diff} -c $f ${TESTBASE}/$f >&2 || :
exitok=false
fi
done
echo $exitok`
cd $TESTBASE
find * -type f -print | \
fgrep -v 'CVS/' > ${TESTDIR}/LIST
exitok=`
exec < ${TESTDIR}/LIST
while read f
do
if [ -s $f ] && [ ! -f ${DESTDIR}/$f ]
then
echo "Missing header fix: $f" >&2
exitok=false
fi
done
echo $exitok`
echo
if $exitok
then
cd ${TESTDIR}
rm -rf inc res LIST
cd ..
rmdir ${TESTDIR} > /dev/null 2>&1 || :
echo All fixinclude tests pass >&2
else
echo There were fixinclude test FAILURES >&2
fi
$exitok[=
(if (defined? 'set-writable) (set-writable))
=]

809
gcc/gcc/fixinc/fixfixes.c Normal file
View File

@@ -0,0 +1,809 @@
/*
Test to see if a particular fix should be applied to a header file.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
= = = = = = = = = = = = = = = = = = = = = = = = =
NOTE TO DEVELOPERS
The routines you write here must work closely with fixincl.c.
Here are the rules:
1. Every test procedure name must be suffixed with "_fix".
These routines will be referenced from inclhack.def, sans the suffix.
2. Use the "FIX_PROC_HEAD()" macro _with_ the "_fix" suffix
(I cannot use the ## magic from ANSI C) for defining your entry point.
3. Put your test name into the FIXUP_TABLE.
4. Do not read anything from stdin. It is closed.
5. Write to stderr only in the event of a reportable error
In such an event, call "exit (EXIT_FAILURE)".
6. You have access to the fixDescList entry for the fix in question.
This may be useful, for example, if there are interesting strings
or pre-compiled regular expressions stored there.
= = = = = = = = = = = = = = = = = = = = = = = = =
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "fixlib.h"
#define GTYPE_SE_CT 1
#ifdef SEPARATE_FIX_PROC
#include "fixincl.x"
#endif
void fatal (const char *s, ...)
{
fprintf (stderr, "%s: %s\n", s);
exit (1);
}
tSCC zNeedsArg[] = "fixincl error: `%s' needs %s argument (c_fix_arg[%d])\n";
typedef void t_fix_proc (const char *, const char *, tFixDesc *) ;
typedef struct {
const char* fix_name;
t_fix_proc* fix_proc;
} fix_entry_t;
#define FIXUP_TABLE \
_FT_( "char_macro_def", char_macro_def_fix ) \
_FT_( "char_macro_use", char_macro_use_fix ) \
_FT_( "format", format_fix ) \
_FT_( "machine_name", machine_name_fix ) \
_FT_( "wrap", wrap_fix ) \
_FT_( "gnu_type", gnu_type_fix )
#define FIX_PROC_HEAD( fix ) \
static void fix (const char* filname ATTRIBUTE_UNUSED , \
const char* text ATTRIBUTE_UNUSED , \
tFixDesc* p_fixd ATTRIBUTE_UNUSED )
#ifdef NEED_PRINT_QUOTE
/*
* Skip over a quoted string. Single quote strings may
* contain multiple characters if the first character is
* a backslash. Especially a backslash followed by octal digits.
* We are not doing a correctness syntax check here.
*/
static char*
print_quote(char q, char* text )
{
fputc( q, stdout );
for (;;)
{
char ch = *(text++);
fputc( ch, stdout );
switch (ch)
{
case '\\':
if (*text == NUL)
goto quote_done;
fputc( *(text++), stdout );
break;
case '"':
case '\'':
if (ch != q)
break;
/*FALLTHROUGH*/
case '\n':
case NUL:
goto quote_done;
}
} quote_done:;
return text;
}
#endif /* NEED_PRINT_QUOTE */
/*
* Emit the GNU standard type wrapped up in such a way that
* this thing can be encountered countless times during a compile
* and not cause even a warning.
*/
static const char*
emit_gnu_type (const char* text, regmatch_t* rm )
{
char z_TYPE[ 64 ];
char z_type[ 64 ];
fwrite (text, rm[0].rm_so, 1, stdout);
{
const char* ps = text + rm[1].rm_so;
const char* pe = text + rm[1].rm_eo;
char* pd = z_type;
char* pD = z_TYPE;
while (ps < pe)
*(pD++) = TOUPPER( *(pd++) = *(ps++) );
*pD = *pd = NUL;
}
/*
* Now print out the reformed typedef,
* with a C++ guard for WCHAR
*/
{
tSCC z_fmt[] = "\
#if !defined(_GCC_%s_T)%s\n\
#define _GCC_%s_T\n\
typedef __%s_TYPE__ %s_t;\n\
#endif\n";
const char *const pz_guard = (strcmp (z_type, "wchar") == 0)
? " && ! defined(__cplusplus)" : "";
printf (z_fmt, z_TYPE, pz_guard, z_TYPE, z_TYPE, z_type);
}
return text += rm[0].rm_eo;
}
/*
* Copy the `format' string to std out, replacing `%n' expressions
* with the matched text from a regular expression evaluation.
* Doubled '%' characters will be replaced with a single copy.
* '%' characters in other contexts and all other characters are
* copied out verbatim.
*/
static void
format_write (tCC* format, tCC* text, regmatch_t av[] )
{
int c;
while ((c = (unsigned)*(format++)) != NUL) {
if (c != '%')
{
putchar(c);
continue;
}
c = (unsigned)*(format++);
/*
* IF the character following a '%' is not a digit,
* THEN we will always emit a '%' and we may or may
* not emit the following character. We will end on
* a NUL and we will emit only one of a pair of '%'.
*/
if (! ISDIGIT ( c ))
{
putchar( '%' );
switch (c) {
case NUL:
return;
case '%':
break;
default:
putchar(c);
}
}
/*
* Emit the matched subexpression numbered 'c'.
* IF, of course, there was such a match...
*/
else {
regmatch_t* pRM = av + (c - (unsigned)'0');
size_t len;
if (pRM->rm_so < 0)
continue;
len = pRM->rm_eo - pRM->rm_so;
if (len > 0)
fwrite(text + pRM->rm_so, len, 1, stdout);
}
}
}
/*
* Search for multiple copies of a regular expression. Each block
* of matched text is replaced with the format string, as described
* above in `format_write'.
*/
FIX_PROC_HEAD( format_fix )
{
tCC* pz_pat = p_fixd->patch_args[2];
tCC* pz_fmt = p_fixd->patch_args[1];
regex_t re;
regmatch_t rm[10];
IGNORE_ARG(filname);
/*
* We must have a format
*/
if (pz_fmt == (tCC*)NULL)
{
fprintf( stderr, zNeedsArg, p_fixd->fix_name, "replacement format", 0 );
exit (EXIT_BROKEN);
}
/*
* IF we don't have a search text, then go find the first
* regular expression among the tests.
*/
if (pz_pat == (tCC*)NULL)
{
tTestDesc* pTD = p_fixd->p_test_desc;
int ct = p_fixd->test_ct;
for (;;)
{
if (ct-- <= 0)
{
fprintf( stderr, zNeedsArg, p_fixd->fix_name, "search text", 1 );
exit (EXIT_BROKEN);
}
if (pTD->type == TT_EGREP)
{
pz_pat = pTD->pz_test_text;
break;
}
pTD++;
}
}
/*
* Replace every copy of the text we find
*/
compile_re (pz_pat, &re, 1, "format search-text", "format_fix" );
while (xregexec (&re, text, 10, rm, 0) == 0)
{
fwrite( text, rm[0].rm_so, 1, stdout );
format_write( pz_fmt, text, rm );
text += rm[0].rm_eo;
}
/*
* Dump out the rest of the file
*/
fputs (text, stdout);
}
/* Scan the input file for all occurrences of text like this:
#define TIOCCONS _IO(T, 12)
and change them to read like this:
#define TIOCCONS _IO('T', 12)
which is the required syntax per the C standard. (The definition of
_IO also has to be tweaked - see below.) 'IO' is actually whatever you
provide as the `c_fix_arg' argument. */
FIX_PROC_HEAD( char_macro_use_fix )
{
/* This regexp looks for a traditional-syntax #define (# in column 1)
of an object-like macro. */
static const char pat[] =
"^#[ \t]*define[ \t]+[_A-Za-z][_A-Za-z0-9]*[ \t]+";
static regex_t re;
const char* str = p_fixd->patch_args[1];
regmatch_t rm[1];
const char *p, *limit;
size_t len;
IGNORE_ARG(filname);
if (str == NULL)
{
fprintf (stderr, zNeedsArg, p_fixd->fix_name, "ioctl type", 0);
exit (EXIT_BROKEN);
}
len = strlen (str);
compile_re (pat, &re, 1, "macro pattern", "char_macro_use_fix");
for (p = text;
xregexec (&re, p, 1, rm, 0) == 0;
p = limit + 1)
{
/* p + rm[0].rm_eo is the first character of the macro replacement.
Find the end of the macro replacement, and the STR we were
sent to look for within the replacement. */
p += rm[0].rm_eo;
limit = p - 1;
do
{
limit = strchr (limit + 1, '\n');
if (!limit)
goto done;
}
while (limit[-1] == '\\');
do
{
if (*p == str[0] && !strncmp (p+1, str+1, len-1))
goto found;
}
while (++p < limit - len);
/* Hit end of line. */
continue;
found:
/* Found STR on this line. If the macro needs fixing,
the next few chars will be whitespace or uppercase,
then an open paren, then a single letter. */
while ((ISSPACE (*p) || ISUPPER (*p)) && p < limit) p++;
if (*p++ != '(')
continue;
if (!ISALPHA (*p))
continue;
if (ISIDNUM (p[1]))
continue;
/* Splat all preceding text into the output buffer,
quote the character at p, then proceed. */
fwrite (text, 1, p - text, stdout);
putchar ('\'');
putchar (*p);
putchar ('\'');
text = p + 1;
}
done:
fputs (text, stdout);
}
/* Scan the input file for all occurrences of text like this:
#define xxxIOxx(x, y) (....'x'<<16....)
and change them to read like this:
#define xxxIOxx(x, y) (....x<<16....)
which is the required syntax per the C standard. (The uses of _IO
also has to be tweaked - see above.) 'IO' is actually whatever
you provide as the `c_fix_arg' argument. */
FIX_PROC_HEAD( char_macro_def_fix )
{
/* This regexp looks for any traditional-syntax #define (# in column 1). */
static const char pat[] =
"^#[ \t]*define[ \t]+";
static regex_t re;
const char* str = p_fixd->patch_args[1];
regmatch_t rm[1];
const char *p, *limit;
char arg;
size_t len;
IGNORE_ARG(filname);
if (str == NULL)
{
fprintf (stderr, zNeedsArg, p_fixd->fix_name, "ioctl type", 0);
exit (EXIT_BROKEN);
}
len = strlen (str);
compile_re (pat, &re, 1, "macro pattern", "fix_char_macro_defines");
for (p = text;
xregexec (&re, p, 1, rm, 0) == 0;
p = limit + 1)
{
/* p + rm[0].rm_eo is the first character of the macro name.
Find the end of the macro replacement, and the STR we were
sent to look for within the name. */
p += rm[0].rm_eo;
limit = p - 1;
do
{
limit = strchr (limit + 1, '\n');
if (!limit)
goto done;
}
while (limit[-1] == '\\');
do
{
if (*p == str[0] && !strncmp (p+1, str+1, len-1))
goto found;
p++;
}
while (ISIDNUM (*p));
/* Hit end of macro name without finding the string. */
continue;
found:
/* Found STR in this macro name. If the macro needs fixing,
there may be a few uppercase letters, then there will be an
open paren with _no_ intervening whitespace, and then a
single letter. */
while (ISUPPER (*p) && p < limit) p++;
if (*p++ != '(')
continue;
if (!ISALPHA (*p))
continue;
if (ISIDNUM (p[1]))
continue;
/* The character at P is the one to look for in the following
text. */
arg = *p;
p += 2;
while (p < limit)
{
if (p[-1] == '\'' && p[0] == arg && p[1] == '\'')
{
/* Remove the quotes from this use of ARG. */
p--;
fwrite (text, 1, p - text, stdout);
putchar (arg);
p += 3;
text = p;
}
else
p++;
}
}
done:
fputs (text, stdout);
}
/* Fix for machine name #ifdefs that are not in the namespace reserved
by the C standard. They won't be defined if compiling with -ansi,
and the headers will break. We go to some trouble to only change
#ifdefs where the macro is defined by GCC in non-ansi mode; this
minimizes the number of headers touched. */
#define SCRATCHSZ 64 /* hopefully long enough */
FIX_PROC_HEAD( machine_name_fix )
{
#ifndef MN_NAME_PAT
fputs( "The target machine has no needed machine name fixes\n", stderr );
#else
regmatch_t match[2];
const char *line, *base, *limit, *p, *q;
regex_t *label_re, *name_re;
char scratch[SCRATCHSZ];
size_t len;
IGNORE_ARG(filname);
IGNORE_ARG(p_fixd);
mn_get_regexps (&label_re, &name_re, "machine_name_fix");
scratch[0] = '_';
scratch[1] = '_';
for (base = text;
xregexec (label_re, base, 2, match, 0) == 0;
base = limit)
{
base += match[0].rm_eo;
/* We're looking at an #if or #ifdef. Scan forward for the
next non-escaped newline. */
line = limit = base;
do
{
limit++;
limit = strchr (limit, '\n');
if (!limit)
goto done;
}
while (limit[-1] == '\\');
/* If the 'name_pat' matches in between base and limit, we have
a bogon. It is not worth the hassle of excluding comments
because comments on #if/#ifdef lines are rare, and strings on
such lines are illegal.
REG_NOTBOL means 'base' is not at the beginning of a line, which
shouldn't matter since the name_re has no ^ anchor, but let's
be accurate anyway. */
for (;;)
{
again:
if (base == limit)
break;
if (xregexec (name_re, base, 1, match, REG_NOTBOL))
goto done; /* No remaining match in this file */
/* Match; is it on the line? */
if (match[0].rm_eo > limit - base)
break;
p = base + match[0].rm_so;
base += match[0].rm_eo;
/* One more test: if on the same line we have the same string
with the appropriate underscores, then leave it alone.
We want exactly two leading and trailing underscores. */
if (*p == '_')
{
len = base - p - ((*base == '_') ? 2 : 1);
q = p + 1;
}
else
{
len = base - p - ((*base == '_') ? 1 : 0);
q = p;
}
if (len + 4 > SCRATCHSZ)
abort ();
memcpy (&scratch[2], q, len);
len += 2;
scratch[len++] = '_';
scratch[len++] = '_';
for (q = line; q <= limit - len; q++)
if (*q == '_' && !strncmp (q, scratch, len))
goto again;
fwrite (text, 1, p - text, stdout);
fwrite (scratch, 1, len, stdout);
text = base;
}
}
done:
#endif
fputs (text, stdout);
}
FIX_PROC_HEAD( wrap_fix )
{
tSCC z_no_wrap_pat[] = "^#if.*__need_";
static regex_t no_wrapping_re; /* assume zeroed data */
tCC* pz_name = NULL;
if (no_wrapping_re.allocated == 0)
compile_re( z_no_wrap_pat, &no_wrapping_re, 0, "no-wrap pattern",
"wrap-fix" );
/*
* IF we do *not* match the no-wrap re, then we have a double negative.
* A double negative means YES.
*/
if (xregexec( &no_wrapping_re, text, 0, NULL, 0 ) != 0)
{
/*
* A single file can get wrapped more than once by different fixes.
* A single fix can wrap multiple files. Therefore, guard with
* *both* the fix name and the file name.
*/
size_t ln = strlen( filname ) + strlen( p_fixd->fix_name ) + 14;
char* pz = xmalloc( ln );
pz_name = pz;
sprintf( pz, "FIXINC_WRAP_%s-%s", filname, p_fixd->fix_name );
for (pz += 12; 1; pz++) {
char ch = *pz;
if (ch == NUL)
break;
if (! ISALNUM( ch )) {
*pz = '_';
}
else {
*pz = TOUPPER( ch );
}
}
printf( "#ifndef %s\n", pz_name );
printf( "#define %s 1\n\n", pz_name );
}
if (p_fixd->patch_args[1] == (tCC*)NULL)
fputs( text, stdout );
else {
fputs( p_fixd->patch_args[1], stdout );
fputs( text, stdout );
if (p_fixd->patch_args[2] != (tCC*)NULL)
fputs( p_fixd->patch_args[2], stdout );
}
if (pz_name != NULL) {
printf( "\n#endif /* %s */\n", pz_name );
free( (void*)pz_name );
}
}
/*
* Search for multiple copies of a regular expression. Each block
* of matched text is replaced with the format string, as described
* above in `format_write'.
*/
FIX_PROC_HEAD( gnu_type_fix )
{
const char* pz_pat;
regex_t re;
regmatch_t rm[GTYPE_SE_CT+1];
IGNORE_ARG(filname);
{
tTestDesc* pTD = p_fixd->p_test_desc;
int ct = p_fixd->test_ct;
for (;;)
{
if (ct-- <= 0)
{
fprintf (stderr, zNeedsArg, p_fixd->fix_name, "search text", 1);
exit (EXIT_BROKEN);
}
if (pTD->type == TT_EGREP)
{
pz_pat = pTD->pz_test_text;
break;
}
pTD++;
}
}
compile_re (pz_pat, &re, 1, "gnu type typedef", "gnu_type_fix");
while (xregexec (&re, text, GTYPE_SE_CT+1, rm, 0) == 0)
{
text = emit_gnu_type (text, rm);
}
/*
* Dump out the rest of the file
*/
fputs (text, stdout);
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
test for fix selector
THIS IS THE ONLY EXPORTED ROUTINE
*/
void
apply_fix( tFixDesc* p_fixd, tCC* filname )
{
#define _FT_(n,p) { n, p },
static fix_entry_t fix_table[] = { FIXUP_TABLE { NULL, NULL }};
#undef _FT_
#define FIX_TABLE_CT (ARRAY_SIZE (fix_table)-1)
tCC* fixname = p_fixd->patch_args[0];
char* buf;
int ct = FIX_TABLE_CT;
fix_entry_t* pfe = fix_table;
for (;;)
{
if (strcmp (pfe->fix_name, fixname) == 0)
break;
if (--ct <= 0)
{
fprintf (stderr, "fixincl error: the `%s' fix is unknown\n",
fixname );
exit (EXIT_BROKEN);
}
pfe++;
}
buf = load_file_data (stdin);
(*pfe->fix_proc)( filname, buf, p_fixd );
}
#ifdef SEPARATE_FIX_PROC
tSCC z_usage[] =
"USAGE: applyfix <fix-name> <file-to-fix> <file-source> <file-destination>\n";
tSCC z_reopen[] =
"FS error %d (%s) reopening %s as std%s\n";
int
main( int argc, char** argv )
{
tFixDesc* pFix;
char* pz_tmptmp;
char* pz_tmp_base;
char* pz_tmp_dot;
if (argc != 5)
{
usage_failure:
fputs (z_usage, stderr);
return EXIT_FAILURE;
}
{
char* pz = argv[1];
long idx;
if (! ISDIGIT ( *pz ))
goto usage_failure;
idx = strtol (pz, &pz, 10);
if ((*pz != NUL) || ((unsigned)idx >= FIX_COUNT))
goto usage_failure;
pFix = fixDescList + idx;
}
if (freopen (argv[3], "r", stdin) != stdin)
{
fprintf (stderr, z_reopen, errno, strerror( errno ), argv[3], "in");
return EXIT_FAILURE;
}
pz_tmptmp = xmalloc (strlen (argv[4]) + 5);
strcpy( pz_tmptmp, argv[4] );
/* Don't lose because "12345678" and "12345678X" map to the same
file under DOS restricted 8+3 file namespace. Note that DOS
doesn't allow more than one dot in the trunk of a file name. */
pz_tmp_base = basename( pz_tmptmp );
pz_tmp_dot = strchr( pz_tmp_base, '.' );
if (pathconf( pz_tmptmp, _PC_NAME_MAX ) <= 12 /* is this DOS or Windows9X? */
&& pz_tmp_dot != (char*)NULL)
strcpy (pz_tmp_dot+1, "X"); /* nuke the original extension */
else
strcat (pz_tmptmp, ".X");
if (freopen (pz_tmptmp, "w", stdout) != stdout)
{
fprintf (stderr, z_reopen, errno, strerror( errno ), pz_tmptmp, "out");
return EXIT_FAILURE;
}
apply_fix (pFix, argv[1]);
fclose (stdout);
fclose (stdin);
unlink (argv[4]);
if (rename (pz_tmptmp, argv[4]) != 0)
{
fprintf (stderr, "error %d (%s) renaming %s to %s\n", errno,
strerror( errno ), pz_tmptmp, argv[4]);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
#endif

283
gcc/gcc/fixinc/fixlib.c Normal file
View File

@@ -0,0 +1,283 @@
/* Install modified versions of certain ANSI-incompatible system header
files which are fixed to work correctly with ANSI C and placed in a
directory that GCC will search.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "fixlib.h"
/* * * * * * * * * * * * *
load_file_data loads all the contents of a file into malloc-ed memory.
Its argument is the file pointer of the file to read in; the returned
result is the NUL terminated contents of the file. The file
is presumed to be an ASCII text file containing no NULs. */
char *
load_file_data (FILE* fp)
{
char *pz_data = (char*)NULL;
int space_left = -1; /* allow for terminating NUL */
size_t space_used = 0;
if (fp == (FILE*)NULL)
return pz_data;
do
{
size_t size_read;
if (space_left < 1024)
{
space_left += 4096;
pz_data = xrealloc (pz_data, space_left + space_used + 1 );
}
size_read = fread (pz_data + space_used, 1, space_left, fp);
if (size_read == 0)
{
if (feof (fp))
break;
if (ferror (fp))
{
int err = errno;
if (err != EISDIR)
fprintf (stderr, "error %d (%s) reading input\n", err,
xstrerror (err));
free ((void *) pz_data);
return (char *) NULL;
}
}
space_left -= size_read;
space_used += size_read;
} while (! feof (fp));
pz_data = xrealloc (pz_data, space_used+1 );
pz_data[ space_used ] = NUL;
return pz_data;
}
#ifdef IS_CXX_HEADER_NEEDED
t_bool
is_cxx_header (tCC* fname, tCC* text)
{
/* First, check to see if the file is in a C++ directory */
for (;;)
{
switch (*(fname++))
{
case 'C': /* check for "CC/" */
if ((fname[0] == 'C') && (fname[1] == '/'))
return BOOL_TRUE;
break;
case 'x': /* check for "xx/" */
if ((fname[0] == 'x') && (fname[1] == '/'))
return BOOL_TRUE;
break;
case '+': /* check for "++" */
if (fname[0] == '+')
return BOOL_TRUE;
break;
case NUL:
goto not_cxx_name;
}
} not_cxx_name:;
/* Or it might contain one of several phrases which indicate C++ code.
Currently recognized are:
extern "C++"
-*- (Mode: )? C++ -*- (emacs mode marker)
template <
*/
{
tSCC cxxpat[] = "\
extern[ \t]*\"C\\+\\+\"|\
-\\*-[ \t]*([mM]ode:[ \t]*)?[cC]\\+\\+[; \t]*-\\*-|\
template[ \t]*<|\
^[ \t]*class[ \t]|\
(public|private|protected):|\
^[ \t]*#[ \t]*pragma[ \t]+(interface|implementation)\
";
static regex_t cxxre;
static int compiled;
if (!compiled)
compile_re (cxxpat, &cxxre, 0, "contents check", "is_cxx_header");
if (xregexec (&cxxre, text, 0, 0, 0) == 0)
return BOOL_TRUE;
}
return BOOL_FALSE;
}
#endif /* CXX_TYPE_NEEDED */
#ifdef SKIP_QUOTE_NEEDED
/*
* Skip over a quoted string. Single quote strings may
* contain multiple characters if the first character is
* a backslash. Especially a backslash followed by octal digits.
* We are not doing a correctness syntax check here.
*/
tCC*
skip_quote(char q, char* text )
{
for (;;)
{
char ch = *(text++);
switch (ch)
{
case '\\':
text++; /* skip over whatever character follows */
break;
case '"':
case '\'':
if (ch != q)
break;
/*FALLTHROUGH*/
case '\n':
case NUL:
goto skip_done;
}
} skip_done:;
return text;
}
#endif /* SKIP_QUOTE_NEEDED */
/* * * * * * * * * * * * *
Compile one regular expression pattern for later use. PAT contains
the pattern, RE points to a regex_t structure (which should have
been bzeroed). MATCH is 1 if we need to know where the regex
matched, 0 if not. If xregcomp fails, prints an error message and
aborts; E1 and E2 are strings to shove into the error message.
The patterns we search for are all egrep patterns.
REG_EXTENDED|REG_NEWLINE produces identical regex syntax/semantics
to egrep (verified from 4.4BSD Programmer's Reference Manual). */
void
compile_re( tCC* pat, regex_t* re, int match, tCC* e1, tCC* e2 )
{
tSCC z_bad_comp[] = "fixincl ERROR: cannot compile %s regex for %s\n\
\texpr = `%s'\n\terror %s\n";
int flags, err;
flags = (match ? REG_EXTENDED|REG_NEWLINE
: REG_EXTENDED|REG_NEWLINE|REG_NOSUB);
err = xregcomp (re, pat, flags);
if (err)
{
char rerrbuf[1024];
regerror (err, re, rerrbuf, 1024);
fprintf (stderr, z_bad_comp, e1, e2, pat, rerrbuf);
exit (EXIT_FAILURE);
}
}
/* * * * * * * * * * * * *
Helper routine and data for the machine_name test and fix.
machname.h is created by black magic in the Makefile. */
#ifdef MN_NAME_PAT
tSCC mn_label_pat[] = "^[ \t]*#[ \t]*(if|ifdef|ifndef)[ \t]+";
static regex_t mn_label_re;
tSCC mn_name_pat[] = MN_NAME_PAT;
static regex_t mn_name_re;
static int mn_compiled = 0;
void
mn_get_regexps(regex_t** label_re, regex_t** name_re, tCC* who )
{
if (! mn_compiled)
{
compile_re (mn_label_pat, &mn_label_re, 1, "label pattern", who);
compile_re (mn_name_pat, &mn_name_re, 1, "name pattern", who);
mn_compiled++;
}
*label_re = &mn_label_re;
*name_re = &mn_name_re;
}
#endif
#ifdef SEPARATE_FIX_PROC
char*
make_raw_shell_str( char* pz_d, tCC* pz_s, size_t smax )
{
tSCC zQ[] = "'\\''";
size_t dtaSize;
char* pz_d_start = pz_d;
smax--; /* adjust for trailing NUL */
dtaSize = strlen( pz_s ) + 3;
{
const char* pz = pz_s - 1;
for (;;) {
pz = strchr( pz+1, '\'' );
if (pz == (char*)NULL)
break;
dtaSize += sizeof( zQ )-1;
}
}
if (dtaSize > smax)
return (char*)NULL;
*(pz_d++) = '\'';
for (;;) {
if (pz_d - pz_d_start >= smax)
return (char*)NULL;
switch (*(pz_d++) = *(pz_s++)) {
case NUL:
goto loopDone;
case '\'':
if (pz_d - pz_d_start >= smax - sizeof( zQ )-1)
return (char*)NULL;
strcpy( pz_d-1, zQ );
pz_d += sizeof( zQ )-2;
}
} loopDone:;
pz_d[-1] = '\'';
*pz_d = NUL;
return pz_d;
}
#endif

232
gcc/gcc/fixinc/fixlib.h Normal file
View File

@@ -0,0 +1,232 @@
/* Install modified versions of certain ANSI-incompatible system header
files which are fixed to work correctly with ANSI C and placed in a
directory that GCC will search.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef GCC_FIXLIB_H
#define GCC_FIXLIB_H
#include "config.h"
#include "system.h"
#include "tm.h"
#include <signal.h>
#ifdef __BEOS__
#include "gnu-regex.h"
#define xregcomp regcomp
#define xregexec regexec
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
#define TOUPPER(c) toupper((c))
#define ISIDNUM(c) (isalnum((c))||(c)=='_')
#endif
#include "machname.h"
#include "libiberty.h"
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
#endif
typedef int t_success;
#define FAILURE (-1)
#define SUCCESS 0
#define PROBLEM 1
#define SUCCEEDED(p) ((p) == SUCCESS)
#define SUCCESSFUL(p) SUCCEEDED (p)
#define FAILED(p) ((p) < SUCCESS)
#define HADGLITCH(p) ((p) > SUCCESS)
#ifndef DEBUG
# define STATIC static
#else
# define STATIC
#endif
#define tSCC static const char
#define tCC const char
#define tSC static char
/* If this particular system's header files define the macro `MAXPATHLEN',
we happily take advantage of it; otherwise we use a value which ought
to be large enough. */
#ifndef MAXPATHLEN
# define MAXPATHLEN 4096
#endif
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
#endif
#define EXIT_BROKEN 3
#define NUL '\0'
#ifndef NOPROCESS
#define NOPROCESS ((pid_t) -1)
#define NULLPROCESS ((pid_t)0)
#define EXIT_PANIC 99
#endif /* NOPROCESS */
#define IGNORE_ARG(a) ((void)(a))
typedef enum t_bool
{
BOOL_FALSE, BOOL_TRUE
} t_bool;
typedef int apply_fix_p_t; /* Apply Fix Predicate Type */
#define APPLY_FIX 0
#define SKIP_FIX 1
#define ENV_TABLE \
_ENV_( pz_machine, BOOL_TRUE, "TARGET_MACHINE", \
"output from config.guess" ) \
\
_ENV_( pz_orig_dir, BOOL_TRUE, "ORIGDIR", \
"directory of fixincl and applyfix" ) \
\
_ENV_( pz_src_dir, BOOL_TRUE, "SRCDIR", \
"directory of original files" ) \
\
_ENV_( pz_input_dir, BOOL_TRUE, "INPUT", \
"current directory for fixincl" ) \
\
_ENV_( pz_dest_dir, BOOL_TRUE, "DESTDIR", \
"output directory" ) \
\
_ENV_( pz_verbose, BOOL_FALSE, "VERBOSE", \
"amount of user entertainment" ) \
\
_ENV_( pz_find_base, BOOL_TRUE, "FIND_BASE", \
"leader to trim from file names" )
/* Test Descriptor
Each fix may have associated tests that determine
whether the fix needs to be applied or not.
Each test has a type (from the te_test_type enumeration);
associated test text; and, if the test is TT_EGREP or
the negated form TT_NEGREP, a pointer to the compiled
version of the text string.
*/
typedef enum
{
TT_TEST, TT_EGREP, TT_NEGREP, TT_FUNCTION
} te_test_type;
typedef struct test_desc tTestDesc;
struct test_desc
{
te_test_type type;
const char *pz_test_text;
regex_t *p_test_regex;
};
typedef struct patch_desc tPatchDesc;
/* Fix Descriptor
Everything you ever wanted to know about how to apply
a particular fix (which files, how to qualify them,
how to actually make the fix, etc...)
NB: the FD_ defines are BIT FLAGS, even though
some are mutually exclusive
*/
#define FD_MACH_ONLY 0x0000
#define FD_MACH_IFNOT 0x0001
#define FD_SHELL_SCRIPT 0x0002
#define FD_SUBROUTINE 0x0004
#define FD_REPLACEMENT 0x0008
#define FD_SKIP_TEST 0x8000
typedef struct fix_desc tFixDesc;
struct fix_desc
{
tCC* fix_name; /* Name of the fix */
tCC* file_list; /* List of files it applies to */
tCC** papz_machs; /* List of machine/os-es it applies to */
int test_ct;
int fd_flags;
tTestDesc* p_test_desc;
tCC** patch_args;
long unused;
};
typedef struct {
int type_name_len;
tCC* pz_type;
tCC* pz_TYPE;
tCC* pz_gtype;
} t_gnu_type_map;
extern int gnu_type_map_ct;
#ifdef HAVE_MMAP_FILE
#define UNLOAD_DATA() do { if (curr_data_mapped) { \
munmap ((void*)pz_curr_data, data_map_size); close (data_map_fd); } \
else free ((void*)pz_curr_data); } while(0)
#else
#define UNLOAD_DATA() free ((void*)pz_curr_data)
#endif
/*
* Exported procedures
*/
char * load_file_data ( FILE* fp );
#ifdef IS_CXX_HEADER_NEEDED
t_bool is_cxx_header ( tCC* filename, tCC* filetext );
#endif /* IS_CXX_HEADER_NEEDED */
#ifdef SKIP_QUOTE_NEEDED
tCC* skip_quote ( char q, char* text );
#endif
void compile_re ( tCC* pat, regex_t* re, int match, tCC *e1, tCC *e2 );
void apply_fix ( tFixDesc* p_fixd, tCC* filname );
apply_fix_p_t
run_test ( tCC* t_name, tCC* f_name, tCC* text );
#ifdef SEPARATE_FIX_PROC
char* make_raw_shell_str ( char* pz_d, tCC* pz_s, size_t smax );
#endif
#ifdef MN_NAME_PAT
void mn_get_regexps ( regex_t** label_re, regex_t** name_re, tCC *who );
#endif
#endif /* ! GCC_FIXLIB_H */

158
gcc/gcc/fixinc/fixtests.c Normal file
View File

@@ -0,0 +1,158 @@
/*
Test to see if a particular fix should be applied to a header file.
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
= = = = = = = = = = = = = = = = = = = = = = = = =
NOTE TO DEVELOPERS
The routines you write here must work closely with fixincl.c.
Here are the rules:
1. Every test procedure name must be suffixed with "_test".
These routines will be referenced from inclhack.def, sans the suffix.
2. Use the "TEST_FOR_FIX_PROC_HEAD()" macro _with_ the "_test" suffix
(I cannot use the ## magic from ANSI C) for defining your entry point.
3. Put your test name into the FIX_TEST_TABLE
4. Do not write anything to stdout. It may be closed.
5. Write to stderr only in the event of a reportable error
In such an event, call "exit(1)".
= = = = = = = = = = = = = = = = = = = = = = = = =
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "fixlib.h"
#define _ENV_(v,m,n,t) extern tCC* v;
ENV_TABLE
#undef _ENV_
typedef apply_fix_p_t t_test_proc ( tCC* file, tCC* text );
typedef struct {
tCC* test_name;
t_test_proc* test_proc;
} test_entry_t;
#define FIX_TEST_TABLE \
_FT_( "machine_name", machine_name_test ) \
_FT_( "stdc_0_in_system_headers", stdc_0_in_system_headers_test )
#define TEST_FOR_FIX_PROC_HEAD( test ) \
static apply_fix_p_t test ( tCC* fname ATTRIBUTE_UNUSED, \
tCC* text ATTRIBUTE_UNUSED )
TEST_FOR_FIX_PROC_HEAD( machine_name_test )
{
#ifndef MN_NAME_PAT
return SKIP_FIX;
#else
regex_t *label_re, *name_re;
regmatch_t match[2];
tCC *base, *limit;
IGNORE_ARG(fname);
mn_get_regexps(&label_re, &name_re, "machine_name_test");
for (base = text;
xregexec (label_re, base, 2, match, 0) == 0;
base = limit)
{
base += match[0].rm_eo;
/* We're looking at an #if or #ifdef. Scan forward for the
next non-escaped newline. */
limit = base;
do
{
limit++;
limit = strchr (limit, '\n');
if (!limit)
return SKIP_FIX;
}
while (limit[-1] == '\\');
/* If the 'name_pat' matches in between base and limit, we have
a bogon. It is not worth the hassle of excluding comments,
because comments on #if/#ifdef/#ifndef lines are rare,
and strings on such lines are illegal.
REG_NOTBOL means 'base' is not at the beginning of a line, which
shouldn't matter since the name_re has no ^ anchor, but let's
be accurate anyway. */
if (xregexec (name_re, base, 1, match, REG_NOTBOL))
return SKIP_FIX; /* No match in file - no fix needed */
/* Match; is it on the line? */
if (match[0].rm_eo <= limit - base)
return APPLY_FIX; /* Yup */
/* Otherwise, keep looking... */
}
return SKIP_FIX;
#endif
}
TEST_FOR_FIX_PROC_HEAD( stdc_0_in_system_headers_test )
{
#ifdef STDC_0_IN_SYSTEM_HEADERS
return (pz_machine == NULL) ? APPLY_FIX : SKIP_FIX;
#else
return APPLY_FIX;
#endif
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
test for fix selector
THIS IS THE ONLY EXPORTED ROUTINE
*/
apply_fix_p_t
run_test( tCC* tname, tCC* fname, tCC* text )
{
#define _FT_(n,p) { n, p },
static test_entry_t test_table[] = { FIX_TEST_TABLE { NULL, NULL }};
#undef _FT_
#define TEST_TABLE_CT (ARRAY_SIZE (test_table)-1)
int ct = TEST_TABLE_CT;
test_entry_t* pte = test_table;
do
{
if (strcmp( pte->test_name, tname ) == 0)
return (*pte->test_proc)( fname, text );
pte++;
} while (--ct > 0);
fprintf( stderr, "fixincludes error: the `%s' fix test is unknown\n",
tname );
exit( 3 );
}

View File

@@ -2800,6 +2800,8 @@ wrapup_global_declarations (vec, len)
&& DECL_INITIAL (decl) != 0
&& DECL_SAVED_INSNS (decl) != 0
&& (flag_keep_inline_functions
// [zooey] always output addressable functions:
|| TREE_ADDRESSABLE (decl)
|| (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{

View File

@@ -102,6 +102,24 @@ int istream::peek()
return ch;
}
// [zooey]: added for R5-compatibility with bdb
istream& istream::read(char *ptr, int n)
{
return read((char*)ptr, (streamsize)n);
}
istream& istream::read(unsigned char *ptr, int n)
{
return read((char*)ptr, (streamsize)n);
}
istream& istream::read(signed char *ptr, int n)
{
return read((char*)ptr, (streamsize)n);
}
istream& istream::read(void *ptr, int n)
{
return read((char*)ptr, (streamsize)n);
}
istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
{
_gcount = 0;
@@ -1022,6 +1040,24 @@ ostream& ostream::write(const char *s, streamsize n)
return *this;
}
// [zooey]: added for R5-compatibility
ostream& ostream::write(const char *s, int n)
{
return write((const char*)s, (streamsize)n);
}
ostream& ostream::write(const unsigned char *s, int n)
{
return write((const char*)s, (streamsize)n);
}
ostream& ostream::write(const signed char *s, int n)
{
return write((const char*)s, (streamsize)n);
}
ostream& ostream::write(const void *s, int n)
{
return write((const char*)s, (streamsize)n);
}
void ostream::do_osfx()
{
if (flags() & ios::unitbuf)

View File

@@ -69,15 +69,12 @@ class ostream : virtual public ios
ostream& write(const void *s, streamsize n)
{ return write((const char*)s, n);}
#ifdef _STREAM_COMPAT
// [zooey]: added for R5-compatibility
ostream& write(const char *s, int n)
{ return write((const char*)s, (streamsize)n);}
ostream& write(const unsigned char *s, int n)
{ return write((const char*)s, (streamsize)n);}
ostream& write(const signed char *s, int n)
{ return write((const char*)s, (streamsize)n);}
ostream& write(const void *s, int n)
{ return write((const char*)s, (streamsize)n);}
// [zooey]: added for R5-compatibility with bdb,
// these can't be inlined as they wouldn't end up in the lib then.
ostream& write(const char *s, int n);
ostream& write(const unsigned char *s, int n);
ostream& write(const signed char *s, int n);
ostream& write(const void *s, int n);
#endif
ostream& seekp(streampos);
ostream& seekp(streamoff, _seek_dir);
@@ -153,15 +150,12 @@ protected:
istream& read(void *ptr, streamsize n)
{ return read((char*)ptr, n); }
#ifdef _STREAM_COMPAT
// [zooey]: added for R5-compatibility
istream& read(char *ptr, int n)
{ return read((char*)ptr, (streamsize)n); }
istream& read(unsigned char *ptr, int n)
{ return read((char*)ptr, (streamsize)n); }
istream& read(signed char *ptr, int n)
{ return read((char*)ptr, (streamsize)n); }
istream& read(void *ptr, int n)
{ return read((char*)ptr, (streamsize)n); }
// [zooey]: added for R5-compatibility with bdb,
// these can't be inlined as they wouldn't end up in the lib then.
istream& read(char *ptr, int n);
istream& read(unsigned char *ptr, int n);
istream& read(signed char *ptr, int n);
istream& read(void *ptr, int n);
#endif
istream& get(streambuf& sb, char delim = '\n');
istream& gets(char **s, char delim = '\n');

118
gcc_distribution/INSTALL Normal file
View File

@@ -0,0 +1,118 @@
How to install gcc-2.95.3 under different versions of BeOS.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BeOS R5 (with or without BONE):
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The compiler, linker and tools:
1. extract gcc-2.95.3_binutils-2.15.zip to /boot/develop/tools
2. if the folder /boot/develop/tools/gnupro exists, rename it
3. create the link:
/boot/develop/tools/gnupro
-> /boot/develop/tools/gcc-2.95.3_binutils-2.15
--------------------------------------------------------------------------
In order to switch between different compilers later, you just need to
adjust the link:
/boot/develop/tools/gnupro -> /boot/develop/tools/...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The new libstdc++ (optional but recommended):
1. rename /boot/develop/headers/cpp
2. execute this in Terminal (creates a link without dereferencing):
ln -snf /boot/develop/tools/gnupro/include/g++ /boot/develop/headers/cpp
3. rename /boot/beos/system/lib/libstdc++.r4.so (e.g. libstdc++.r4.so.R5)
4. copy /boot/develop/tools/gcc-2.95.3_binutils-2.15/lib/libstdc++.r4.so
to /boot/beos/system/lib/libstdc++.r4.so
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dano:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The compiler, linker and tools:
1. extract gcc-2.95.3_binutils-2.15.zip to /boot/develop/tools
2. if the folder /boot/develop/tools/gnupro exists, rename it
3. create the link:
/boot/develop/tools/gnupro
-> /boot/develop/tools/gcc-2.95.3_binutils-2.15
4. extract sdk_gcc-2.95.3_binutils-2.15.zip to /boot/develop/tools
5. if the folder /boot/develop/tools/sdk exists, rename it
6. create the link:
/boot/develop/tools/sdk
-> /boot/develop/tools/sdk_gcc-2.95.3_binutils-2.15
--------------------------------------------------------------------------
In order to switch between different compilers later, you just need to
adjust the two links:
/boot/develop/tools/gnupro -> /boot/develop/tools/...
/boot/develop/tools/sdk -> /boot/develop/tools/...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The new libstdc++ (optional but recommended):
1. rename /boot/develop/headers/cpp
2. execute this in Terminal (creates a link without dereferencing):
ln -snf /boot/develop/tools/gnupro/include/g++ /boot/develop/headers/cpp
3. rename /boot/beos/system/lib/libstdc++.r4.so (e.g. libstdc++.r4.so.Dano)
4. copy /boot/develop/tools/gcc-2.95.3_binutils-2.15/lib/libstdc++.r4.so
to /boot/beos/system/lib/libstdc++.r4.so
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Zeta (untested, please tell me if it doesn't work):
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The compiler, linker and tools (installed into the Zeta-devkit):
1. extract gcc-2.95.3_binutils-2.15.zip
to /etc/develop/zeta-r1-gcc2-x86/tools
2. if the folder /etc/develop/zeta-r1-gcc2-x86/tools/gnupro exists, rename it
3. create the link:
/etc/develop/zeta-r1-gcc2-x86/tools/gnupro
-> /etc/develop/zeta-r1-gcc2-x86/tools/gcc-2.95.3_binutils-2.15
4. extract sdk_gcc-2.95.3_binutils-2.15.zip
to /etc/develop/zeta-r1-gcc2-x86/tools
5. if the folder /etc/develop/zeta-r1-gcc2-x86/tools/sdk exists, rename it
6. create the link:
/etc/develop/zeta-r1-gcc2-x86/tools/sdk
-> /etc/develop/zeta-r1-gcc2-x86/tools/sdk_gcc-2.95.3_binutils-2.15
--------------------------------------------------------------------------
In order to switch between different compilers (for the Zeta target) later,
you just need to adjust the two links:
/etc/develop/zeta-r1-gcc2-x86/tools/gnupro
-> /etc/develop/zeta-r1-gcc2-x86/tools/...
/etc/develop/zeta-r1-gcc2-x86/tools/sdk
-> /etc/develop/zeta-r1-gcc2-x86/tools/...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The compiler, linker and tools (linked into the R5-devkit):
1. create the link:
/etc/develop/beos-r5-gcc2-x86/tools/gcc-2.95.3_binutils-2.15
-> /etc/develop/zeta-r1-gcc2-x86/tools/gcc-2.95.3_binutils-2.15
2. if the folder /etc/develop/beos-r5-gcc2-x86/tools/gnupro exists, rename it
3. create the link:
/etc/develop/beos-r5-gcc2-x86/tools/gnupro
-> /etc/develop/beos-r5-gcc2-x86/tools/gcc-2.95.3_binutils-2.15
--------------------------------------------------------------------------
In order to switch between different compilers (for the R5 target) later,
you just need to adjust the link:
/etc/develop/beos-r5-gcc2-x86/tools/gnupro
-> /etc/develop/beos-r5-gcc2-x86/tools/...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The new libstdc++ for target Zeta (optional but recommended):
1. rename /etc/develop/zeta-r1-gcc2-x86/headers/cpp
2. execute this in Terminal (creates a link without dereferencing):
ln -snf /etc/develop/zeta-r1-gcc2-x86/tools/gnupro/include/g++ /etc/develop/zeta-r1-gcc2-x86/headers/cpp
3. rename /boot/beos/system/lib/libstdc++.r4.so (e.g. libstdc++.r4.so.Zeta)
4. copy /etc/develop/zeta-r1-gcc2-x86/tools/gcc-2.95.3_binutils-2.15/lib/libstdc++.r4.so
to /boot/beos/system/lib/libstdc++.r4.so
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The new libstdc++ for target R5 (optional but recommended):
1. rename /etc/develop/beos-r5-gcc2-x86/headers/cpp
2. execute this in Terminal (creates a link without dereferencing):
ln -snf /etc/develop/beos-r5-gcc2-x86/tools/gnupro/include/g++ /etc/develop/beos-r5-gcc2-x86/headers/cpp
3. rename /etc/develop/beos-r5-gcc2-x86/lib/x86/libstdc++.r4.so (e.g. libstdc++.r4.so.R5)
4. copy /etc/develop/beos-r5-gcc2-x86/tools/gcc-2.95.3_binutils-2.15/lib/libstdc++.r4.so
to /etc/develop/beos-r5-gcc2-x86/lib/x86/libstdc++.r4.so
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Have fun!
Please send questions & bug-reports to: Oliver Tappe <gcc@hirschkaefer.de>

122
gcc_distribution/README Normal file
View File

@@ -0,0 +1,122 @@
This is a package of gcc-2.95.3 and binutils-2.15 for BeOS.
Please consult the file "INSTALL" for info about how to install this package.
This port is based on the work done by Takashi Toyoshima, which in turn is
based on the official gnupro-releases done by Fred Fish and others at Be.
Thanks to these guys and thanks to everyone who helped testing this new release!
Lots of patches have been applied to get gcc-2.95.3 working properly on BeOS,
you can find the gory details in the cvs-log-archives.
These are the main changes:
- this gcc-2.95.3 won't crash just because one is using iostreams and/or STL.
- an improved and less buggy libstdc++.r4.so is included (with new headers).
- the tool-chain now defaults to B_LOW_PRIORITY, such that you can do other
things while a large build is running. Thanks to Andrew Bachmann for
suggesting this. You can override the default with -priority=<prio>.
- optimization is much more reliable now (it really is a bad idea to
use -O2 or -O3 with older compilers, as the likelihood of things going
very wrong is high!).
This port should be more reliable when using -O2 or even -O3, but: YMMV!
- new html-documentation is included for all tools.
- the gcc-option '-shared' is now working again, '-nostart' is a (BeOS-
specific) synonym for it.
Bugs/Peculiarities:
- the default specs no longer include -lnet on R5, so some projects that are
relying on this implicit linking against libnet.so fail during linking
stage with messages like 'undefined reference to select' (or similar).
This can be fixed by explicitly adding -lnet to the build.
The reason for leaving out -lnet from the specs is that this is the way
things are done under Dano & Zeta and I'd like to avoid having to provide
different releases for each platform.
Anyway, if you really want to get back the original R5 behaviour, just change
the link
/boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/2.95.3-beos-xxx/specs
such that it points to specs.R5 and the R5-compatible specs should be active.
- gcc-2.95.3 (rightly) complains about code that calls delete on void*. This
code did not trigger any complaints with older compilers, but it probably
did not do what the programmer intended. If the pointer is in fact pointing
to an object, no destructors will be called, only the memory will be freed.
If that is the original intention, then the global operator delete should
be used instead:
void cleanup (void* cookie)
{
delete cookie;
}
becomes
void cleanup (void* cookie)
{
::operator delete cookie;
}
If the destructor should be called, you have to cast the void* to the
appropriate type (or preferably get rid of that void* cruft).
- the linker goes out of its way to avoid generating relocation entries of
type R_386_NONE with an offset of 0, as this crashes the dynamic loader
of BONE/Dan0/Zeta.
Part of the dynamic loading process is the relocation of several entries
inside the binary to its real position in memory. The linker generates the
neccessary relocation entries, telling the loader for each relocation, what
kind of relocation is to be done (type) and where the relocation takes place
(offset into the binary-section). These relocation entries live in several
sections named ".rel."...
The linker from binutils-2.15 seems to do some more optimization than older
linkers, converting unneeded relocation-entries (pointing to sections that
were discarded during the link) to the R_386_NONE type, which in fact
means: "do nothing". The offset of these relocation entries is set to 0.
[Sidenote: it would be better to remove this entries altogether, but
that could change the size of an already layed-out section, which -
according to the binutils maintainers - is difficult, so the free space
is not yet reclaimed by ld].
Now it seems that the newer dynamic loader is a bit peculiar about how to
handle these "do nothing" requests: it is perfectly happy to nothing at most
offsets, only offset 0 it doesn't like at all, as it then tries to execute
code like the following:
xor eax, eax
movl (eax), eax
which, naturally, crashes the machine.
The solution to this was to leave the original offset of these relocation
entries in place, just change the type to R_386_NONE. This hack seems to
work for all BeOS dynamic loaders.
- Every app is now automatically linked against a (new) object file named
fix_bdirectwin_typeinfo.o
Older compilers had the habit of generating typeinfo-functions in each
object file that uses them (dynamic_cast). My version of gcc only does that
if optimization is switched off. In optimizing mode, these functions are not
kept in each object file, but they are taken from the library which "defines"
the class that is the target of the dynamic_cast. This works fine for most
cases, but the Be-libraries seem to contain a broken version of the
BDirectWindow-typeinfo-function.
The difference here is that older compilers never used this function, as the
linker always linked to the (object-file-)internal version of this funtion.
Gcc-2.95.3 doesn't always generate these, so that the one living inside the
Be-libraries is being used, which in turn leads to a crash (an example is
GLTeapot).
As a solution to this problem, I have created a new object file, named
fix_bdirectwin_typeinfo.o, that contains an implementation of the
BDirectWindow-typeinfo-funtion. Every app is now linked against this file
automatically (by means of the specs-file), such that the broken
implementation from the libs isn't used.
What remains a mystery to me is how that broken function found its way into
the libs in the first place...
- I believe 2.95.3 improves upon the other available compilers for BeOS, but
this does not mean that it is better for all purposes, it is just different!
So don't be surprised if you encounter internal compiler errors with code
that worked for gnupro-000224 or gnupro-991026. Please send me info about
any such cases so that I can *try* to work out a solution.
Please send questions & bug-reports to: Oliver Tappe <gcc@hirschkaefer.de>

View File

@@ -0,0 +1,61 @@
#! /bin/sh
BINUTILS=binutils
GCC=gcc
echo generation html-docs for as...
ln -sf ../../$BINUTILS/gas/doc/all.texi asconfig.texi
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=as ../../$BINUTILS/gas/doc/as.texinfo
ln -sf as/index.html as.html
echo generation html-docs for as...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=as-internals ../../$BINUTILS/gas/doc/internals.texi
ln -sf as-internals/index.html as-internals.html
echo generation html-docs for bfd...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=bfd ../../$BINUTILS/bfd/doc/bfd.texinfo
ln -sf bfd/index.html bfd.html
echo generation html-docs for bfdint...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=bfd-internals ../../$BINUTILS/bfd/doc/bfdint.texi
ln -sf bfd-internals/index.html bfd-internals.html
echo generation html-docs for binutils...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=binutils -I ../../$BINUTILS-obj/binutils/doc ../../$BINUTILS/binutils/doc/binutils.texi
ln -sf binutils/index.html binutils.html
echo generation html-docs for configure...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=configure ../../$BINUTILS/etc/configure.texi
ln -sf configure/index.html configure.html
echo generation html-docs for cpp...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=cpp ../../$GCC/gcc/cpp.texi
ln -sf cpp/index.html cpp.html
echo generation html-docs for gcc...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=gcc ../../$GCC/gcc/gcc.texi
ln -sf gcc/index.html gcc.html
echo generation html-docs for g++int...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=g++-internals ../../$GCC/gcc/cp/gxxint.texi
ln -sf g++-internals/index.html g++-internals.html
echo generation html-docs for gprof...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=gprof ../../$BINUTILS/gprof/gprof.texi
ln -sf gprof/index.html gprof.html
echo generation html-docs for iostream...
texi2html -split=section -nonumber -top_file=index.html -toc_file=toc.html -subdir=iostream ../../$GCC/libio/iostream.texi
ln -sf iostream/index.html iostream.html
echo generation html-docs for ld...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=ld -I ../../$BINUTILS/bfd/doc ../../$BINUTILS/ld/ld.texinfo
ln -sf ld/index.html ld.html
echo generation html-docs for ldint...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=ld-internals ../../$BINUTILS/ld/ldint.texinfo
ln -sf ld-internals/index.html ld-internals.html
echo generation html-docs for libiberty...
texi2html -split=section -top_file=index.html -toc_file=toc.html -subdir=libiberty ../../$BINUTILS/libiberty/libiberty.texi
ln -sf libiberty/index.html libiberty.html

View File

@@ -0,0 +1,29 @@
# this script prepares the /boot/develop/tools/gnupro-folder for distribution
#
GCC_VER=`gcc --version`
# strip executables
strip --strip-unneeded /boot/develop/tools/gnupro/bin/*
strip --strip-unneeded /boot/develop/tools/gnupro/i586-pc-beos/bin/*
strip --strip-unneeded /boot/develop/tools/gnupro/lib/*
strip --strip-unneeded /boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/$GCC_VER/*
# remove info- and man-docs, install html-docs
rm -rf /boot/develop/tools/gnupro/info
rm -rf /boot/develop/tools/gnupro/man
rm -rf /boot/develop/tools/gnupro/html-docs
cp -a html-docs /boot/develop/tools/gnupro
rm /boot/develop/tools/gnupro/html-docs/asconfig.texi
rm /boot/develop/tools/gnupro/html-docs/create-docs.sh
# remove locale files
rm -rf /boot/develop/tools/gnupro/share
# install separate specs-files for R5 and Dano, use Dano by default
sed "s/-lroot/-lroot -lnet/" /boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/$GCC_VER/specs >/boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/$GCC_VER/specs.R5
mv /boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/$GCC_VER/specs /boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/$GCC_VER/specs.Default
ln -sf /boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/$GCC_VER/specs.Default /boot/develop/tools/gnupro/lib/gcc-lib/i586-pc-beos/$GCC_VER/specs
cp -a ../gcc/COPYING* /boot/develop/tools/gnupro/
# install readline lib, headers and html-docs
#strip --strip-unneeded ../../readline-5.0/lib*.a
#cp -a ../../readline-5.0/lib*.a /boot/develop/tools/gnupro/lib/
#cp -a /boot/home/config/include/readline /boot/develop/tools/gnupro/include/
#cp -a ../../readline-5.0/doc/readline.html /boot/develop/tools/gnupro/html-docs/
# identify all files
mimeset /boot/develop/tools/gnupro/