diff options
-rw-r--r-- | gcc/fixinc/fixfixes.c | 143 | ||||
-rw-r--r-- | gcc/fixinc/fixincl.tpl | 20 | ||||
-rw-r--r-- | gcc/fixinc/fixlib.h | 12 | ||||
-rw-r--r-- | gcc/fixinc/inclhack.def | 196 |
4 files changed, 252 insertions, 119 deletions
diff --git a/gcc/fixinc/fixfixes.c b/gcc/fixinc/fixfixes.c index dd08e80..4df5e65 100644 --- a/gcc/fixinc/fixfixes.c +++ b/gcc/fixinc/fixfixes.c @@ -58,11 +58,10 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "fixlib.h" +#define GTYPE_SE_CT 1 tSCC zNeedsArg[] = "fixincl error: `%s' needs %s argument (c_fix_arg[%d])\n"; -#define EXIT_BROKEN 3 - typedef struct { const char* fix_name; void (*fix_proc)(); @@ -73,7 +72,8 @@ typedef struct { _FT_( "char_macro_use", char_macro_use_fix ) \ _FT_( "format", format_fix ) \ _FT_( "machine_name", machine_name_fix ) \ - _FT_( "wrap", wrap_fix ) + _FT_( "wrap", wrap_fix ) \ + _FT_( "gnu_type", gnu_type_fix ) #define FIX_PROC_HEAD( fix ) \ @@ -127,6 +127,60 @@ print_quote( q, text ) /* + * 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 ( text, rm ) + const char* text; + regmatch_t* rm; +{ + extern t_gnu_type_map gnu_type_map[]; + extern int gnu_type_map_ct; + + const char* pzt = text + rm[GTYPE_SE_CT].rm_so; + t_gnu_type_map* p_tm = gnu_type_map; + int ct = gnu_type_map_ct; + + fwrite (text, rm[0].rm_so, 1, stdout); + text += rm[0].rm_eo; + + for (;;) + { + if (strncmp (pzt, p_tm->pz_type, p_tm->type_name_len) == 0) + break; + +#ifdef DEBUG + if (--ct <= 0) + return (const char*)NULL; +#else + if (--ct <= 0) + return text; +#endif + p_tm++; + } + + /* + * Now print out the reformed typedef + */ + printf ("#ifndef __%s_TYPE__\n" + "#define __%s_TYPE__ %s\n" + "#endif\n", + p_tm->pz_TYPE, p_tm->pz_TYPE, p_tm->pz_gtype ); + + printf ("#if !defined(_GCC_%s_T)%s\n" + "#define _GCC_%s_T\n" + "typedef __%s_TYPE__ %s_t;\n" + "#endif\n", + p_tm->pz_TYPE, p_tm->pz_cxx_guard, + p_tm->pz_TYPE, p_tm->pz_TYPE, p_tm->pz_type); + + return text; +} + + +/* * 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. @@ -593,6 +647,89 @@ FIX_PROC_HEAD( wrap_fix ) } +/* + * 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]; + + { + 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 (regexec (&re, text, GTYPE_SE_CT+1, rm, 0) == 0) + { +#ifndef DEBUG + text = emit_gnu_type (text, rm); +#else + tSCC z_mismatch[] = "``%s'' mismatched:\n"; + + /* + * Make sure we matched *all* subexpressions + */ + if (rm[GTYPE_SE_CT].rm_so == -1) + { + int i; + + fprintf (stderr, z_mismatch, pz_pat); + + for (i=0; i <= GTYPE_SE_CT; i++) + { + if (rm[i].rm_so != -1) + { + fprintf( stderr, "%4d: ``", i ); + fwrite( text + rm[i].rm_so, rm[i].rm_eo - rm[i].rm_so, + 1, stderr ); + fputs( "''\n", stderr ); + } + else + { + fprintf( stderr, "%4d: BROKEN\n", i ); + } + } + exit (EXIT_BROKEN); + } + + text = emit_gnu_type (text, rm); + if (text == NULL) + { + fprintf (stderr, z_mismatch, pz_pat); + exit (EXIT_BROKEN); + } +#endif + } + + /* + * Dump out the rest of the file + */ + fputs (text, stdout); +} + + /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = test for fix selector diff --git a/gcc/fixinc/fixincl.tpl b/gcc/fixinc/fixincl.tpl index a68dec8..ec7c812 100644 --- a/gcc/fixinc/fixincl.tpl +++ b/gcc/fixinc/fixincl.tpl @@ -203,3 +203,23 @@ _FOR fix ",\n" =] /fix=] }; + +#define GNU_TYPE_CT [=_eval type_map _count =] +int gnu_type_map_ct = GNU_TYPE_CT; + +tSCC z_cxx_guard[] = " && !defined(__cplusplus)"; +tSCC z_nil[] = ""; + +t_gnu_type_map gnu_type_map[ GNU_TYPE_CT ] = {[= + +_FOR type_map , + +=] + { [=_EVAL type_name _len=], "[=type_name=]", "[=type_name _up=]", "[= + gnu_type=]", [= + _IF cxx_type _exist =]z_cxx_guard[= + _ELSE =]z_nil[= + _ENDIF=] }[= + +/type_map=] +}; diff --git a/gcc/fixinc/fixlib.h b/gcc/fixinc/fixlib.h index 9997553..8134158 100644 --- a/gcc/fixinc/fixlib.h +++ b/gcc/fixinc/fixlib.h @@ -70,6 +70,8 @@ typedef int t_success; # define EXIT_FAILURE 1 #endif +#define EXIT_BROKEN 3 + #define NUL '\0' #ifndef NOPROCESS @@ -149,6 +151,16 @@ struct fix_desc long unused; }; +typedef struct { + int type_name_len; + tCC* pz_type; + tCC* pz_TYPE; + tCC* pz_gtype; + tCC* pz_cxx_guard; +} t_gnu_type_map; + +extern int gnu_type_map_ct; + /* * Exported procedures */ diff --git a/gcc/fixinc/inclhack.def b/gcc/fixinc/inclhack.def index a5b3b41..0dd80f5 100644 --- a/gcc/fixinc/inclhack.def +++ b/gcc/fixinc/inclhack.def @@ -987,8 +987,8 @@ fix = { /* - * Fix HP's use of ../machine/inline.h to refer to - * /usr/include/machine/inline.h + * Fix HP & Sony's use of "../machine/xxx.h" + * to refer to: <machine/xxx.h> */ fix = { hackname = hp_inline; @@ -1281,8 +1281,8 @@ fix = { /* * GNU libc1 string.h does not prototype memcpy and memcmp for gcc - * versions > 1. That's a problem. This fix will expose the prototype - * for C++. + * versions > 1. This fix will open up the declaration for all + * versions of GCC and for g++. */ fix = { hackname = libc1_ifdefd_memx; @@ -1493,12 +1493,13 @@ fix = { fix = { hackname = math_huge_val_from_dbl_max; files = math.h; + /* * IF HUGE_VAL is defined to be DBL_MAX *and* DBL_MAX is _not_ defined * in math.h, this fix applies. */ - select = "define[ \t]*HUGE_VAL[ \t]*DBL_MAX"; - bypass = "define[ \t]*DBL_MAX"; + select = "define[ \t]+HUGE_VAL[ \t]+DBL_MAX"; + bypass = "define[ \t]+DBL_MAX"; shell = /* @@ -1507,13 +1508,17 @@ fix = { */ "\tdbl_max_def=`egrep 'define[ \t]+DBL_MAX[ \t]+.*' float.h " - "2>/dev/null`\n\n" + "| sed 's/.*DBL_MAX[ \t]*//' 2>/dev/null`\n\n" "\tif ( test -n \"${dbl_max_def}\" ) > /dev/null 2>&1\n" "\tthen sed -e '/define[ \t]*HUGE_VAL[ \t]*DBL_MAX/" - "s/DBL_MAX/'\"$dbl_max_def/\"\n" + "s@DBL_MAX@'\"$dbl_max_def@\"\n" "\telse cat\n" "\tfi"; + + test_text = + "`echo '#define DBL_MAX\t3.1415e+9 /* really big */' >> float.h`\n" + "#define HUGE_VAL DBL_MAX"; }; @@ -1542,10 +1547,17 @@ fix = { mach = "m68k-motorola-sysv*"; files = sys/limits.h; files = limits.h; + select = "max # bytes atomic in write|error value returned by Math lib"; + sed = "s@^\\(#undef[ \t][ \t]*PIPE_BUF[ \t]*" "/\\* max # bytes atomic in write to a\\)$@\\1 */@"; sed = "s@\\(/\\*#define\tHUGE_VAL\t3.[0-9e+]* \\)" "\\(/\\*error value returned by Math lib\\*/\\)$@\\1*/ \\2@"; + + test_text = + "#undef PIPE_BUF /* max # bytes atomic in write to a\n" + "\t\t/* PIPE */\n" + "/*#define\tHUGE_VAL\t3.9e+9 /*error value returned by Math lib*/"; }; @@ -1876,17 +1888,6 @@ fix = { /* - * Incorrect #include in Sony News-OS 3.2. - */ -fix = { - hackname = sony_include; - files = machine/machparam.h; - select = '"\.\./machine/endian.h"'; - sed = 's@"../machine/endian.h"@<machine/endian.h>@'; -}; - - -/* * Sony NEWSOS 5.0 does not support the complete ANSI C standard. */ #ifdef SONY @@ -1982,6 +1983,7 @@ fix = { "s@_NEED___VA_LIST@_NEED___Va_LIST@\n" "s@VA_LIST@DUMMY_VA_LIST@\n" "s@_Va_LIST@_VA_LIST@"; + test_text = "extern void mumble( va_list);"; }; @@ -2213,8 +2215,6 @@ fix = { * Conditionalize some of <sys/endian.h> on __GNUC__ and __GNUG__. * On some systems (UnixWare 2, UnixWare 7), the file is byteorder.h * but we still "hijack" it and redirect it to the GNU byteorder.h.. - * - * */ #ifdef SVR5 fix = { @@ -2519,75 +2519,40 @@ fix = { /* * Fix these files to use the same types that we think they should. - * XXX - extremely dubious changes here. + * Each type must be present in two places: the select clause + * and a "type_map" entry below. */ fix = { - hackname = systypes; + hackname = gnu_types; files = "sys/types.h"; files = "stdlib.h"; files = "sys/stdtypes.h"; files = "stddef.h"; files = "memory.h"; files = "unistd.h"; - select = "typedef[ \t]+[a-z_][ \ta-z_]*[ \t]" - "(size|ptrdiff|wchar)_t"; - - sed = "/^[ \t]*\\*[ \t]*typedef unsigned int size_t;/N"; - - sed = "s/^\\([ \t]*\\*[ \t]*typedef unsigned int size_t;\\n" - "[ \t]*\\*\\/\\)/\\1\\\n" - "#ifndef __SIZE_TYPE__\\\n" - "#define __SIZE_TYPE__ long unsigned int\\\n" - "#endif\\\n" - "typedef __SIZE_TYPE__ size_t;\\\n/"; + bypass = '_GCC_(PTRDIFF|SIZE|WCHAR)_T'; + select = "^[ \t]*typedef[ \t]+.*[ \t](ptrdiff|size|wchar)_t;"; + c_fix = gnu_type; - sed = "/typedef[ \t][ \t]*[a-z_][ \ta-z_]*[ \t]size_t/i\\\n" - "#ifndef __SIZE_TYPE__\\\n" - "#define __SIZE_TYPE__ long unsigned int\\\n" - "#endif\n"; - - sed = "s/typedef[ \t][ \t]*[a-z_][ \ta-z_]*[ \t]size_t/" - "typedef __SIZE_TYPE__ size_t/"; - - sed = "/typedef[ \t][ \t]*[a-z_][ \ta-z_]*[ \t]ptrdiff_t/i\\\n" - "#ifndef __PTRDIFF_TYPE__\\\n" - "#define __PTRDIFF_TYPE__ long int\\\n" - "#endif\n"; - - sed = "s/typedef[ \t][ \t]*[a-z_][ \ta-z_]*[ \t]ptrdiff_t/" - "typedef __PTRDIFF_TYPE__ ptrdiff_t/"; - - sed = "/typedef[ \t][ \t]*[a-z_][ \ta-z_]*[ \t]wchar_t/i\\\n" - "#ifndef __WCHAR_TYPE__\\\n" - "#define __WCHAR_TYPE__ int\\\n" - "#endif\\\n" - "#ifndef __cplusplus\n"; - - sed = "/typedef[ \t][ \t]*[a-z_][ \ta-z_]*[ \t]wchar_t/a\\\n" - "#endif\n"; - - sed = "s/typedef[ \t][ \t]*[a-z_][ \ta-z_]*[ \t]wchar_t/" - "typedef __WCHAR_TYPE__ wchar_t/"; + test_text = "typedef long int ptrdiff_t; /* long int */\n" + "typedef uint_t size_t; /* uint_t */\n" + "typedef ushort_t wchar_t; /* ushort_t */"; }; +type_map = { + type_name = ptrdiff; + gnu_type = "long int"; +}; -/* - * Fix files that may contain a stray definition of size_t. Take care - * not to match ssize_t or mere uses of size_t. - */ -fix = { - hackname = systypes_stdlib_size_t; - files = sys/types.h; - files = stdlib.h; - select = "typedef[ \t]+[A-Za-z_][ \tA-Za-z_]*[ \t]size_t.*"; - bypass = "_(GCC|BSD)_SIZE_T"; - - c_fix = format; - c_fix_arg = - "#ifndef _GCC_SIZE_T\n" - "#define _GCC_SIZE_T\n%0\n#endif"; +type_map = { + type_name = size; + gnu_type = "long unsigned int"; +}; - test_text = "typedef unsigned int size_t; /* size of something */"; +type_map = { + type_name = wchar; + gnu_type = int; + cxx_type; }; @@ -2601,18 +2566,43 @@ fix = { */ fix = { hackname = sysv68_string; + files = testing.h; files = string.h; sed = "s/extern[ \t]*int[ \t]*strlen();/extern unsigned int strlen();/"; sed = "s/extern[ \t]*int[ \t]*ffs[ \t]*(long);/extern int ffs(int);/"; sed = "s/strdup(char \\*s1);/strdup(const char *s1);/"; + sed = "/^extern char$/N"; sed = "s/^extern char\\(\\n\t\\*memccpy(),\\)$/extern void\\1/"; + + /* + * This sed expression is broken inside fixincl. + * The same expression seems to work outside, however :-( + */ sed = "/^\tstrncmp(),$/N"; - sed = "s/^\\(\tstrncmp()\\),\\n\\(\tstrlen(),\\)$/\\1;\\\n" - "extern unsigned int\\\n\\2/"; + sed = 's/^\(' "\t" 'strncmp()\),\n\(' "\t" 'strlen(),\)$/' + '\1;' "\\\nextern unsigned int\\\n\\2/"; + sed = "/^extern int$/N"; sed = "s/^extern int\\(\\n\tstrlen(),\\)/extern size_t\\1/"; + + test_text = + "extern int strlen();\n" + + "extern int ffs(long);\n" + + "extern char\n" + "\t*memccpy(),\n" + "\tmemcpy();\n" + + "extern int\n" + "\tstrncmp(),\n" + "\tstrlen(),\n" + "\tstrspn();\n" + + "extern int\n" + "\tstrlen(), strspn();"; }; @@ -2636,40 +2626,6 @@ fix = { /* - * Fix this Sun file to avoid interfering with stddef.h. - * We use a funny name to ensure it follows 'systypes' fix. - */ -fix = { - hackname = sysz_stdtypes_for_sun; - files = sys/stdtypes.h; - sed = "/[\t ]size_t.*;/i\\\n" - "#ifndef _GCC_SIZE_T\\\n" - "#define _GCC_SIZE_T\n"; - - sed = "/[\t ]size_t.*;/a\\\n" - "#endif\n"; - - sed = "/[\t ]ptrdiff_t.*;/i\\\n" - "#ifndef _GCC_PTRDIFF_T\\\n" - "#define _GCC_PTRDIFF_T\n"; - - sed = "/[\t ]ptrdiff_t.*;/a\\\n" - "#endif\n"; - - sed = "/[\t ]wchar_t.*;/i\\\n" - "#ifndef _GCC_WCHAR_T\\\n" - "#define _GCC_WCHAR_T\n"; - - sed = "/[\t ]wchar_t.*;/a\\\n" - "#endif\n"; - - test_text = "typedef int size_t; /* ??? */\n" - "typedef int ptrdiff_t; /* result of subtracting two pointers */\n" - "typedef unsigned short wchar_t; /* big enough for biggest char set */\n"; -}; - - -/* * if the #if says _cplusplus, not the double underscore __cplusplus * that it should be */ @@ -2893,9 +2849,10 @@ fix = { * on those systems where the replacement byteorder header is installed. */ fix = { - hackname = unixware7_byteorder_fix; + hackname = uw7_byteorder_fix; files = arpa/inet.h; select = "in_port_t"; + test = "-f $DESTDIR/sys/byteorder.h"; #ifndef SVR5 mach = "*-*-sysv4*"; mach = "i?86-*-sysv5*"; @@ -2904,8 +2861,15 @@ fix = { mach = "powerpcle-*-solaris2.[0-4]"; mach = "sparc-*-solaris2.[0-4]"; #endif /* SVR5 */ - sed = '/^extern.*htons.*(in_port_t)/d'; - sed = '/^extern.*ntohs.*(in_port_t)/d'; + + c_fix = format; + c_fix_arg = ""; + c_fix_arg = "^extern.*(htons|ntohs).*\\(in_port_t\\).*\n"; + + test_text = "extern htons(in_port_t);" + "`[ ! -d $DESTDIR/sys ] && mkdir $DESTDIR/sys\n" + "echo '/* DUMMY */' >> sys/byteorder.h\n" + "touch $DESTDIR/sys/byteorder.h`"; }; |