implement various pre-processor guards around standard types
authorBruce Korb <korbb@gcc.gnu.org>
Thu, 13 Jul 2000 14:47:55 +0000 (14:47 +0000)
committerBruce Korb <korbb@gcc.gnu.org>
Thu, 13 Jul 2000 14:47:55 +0000 (14:47 +0000)
From-SVN: r35012

gcc/fixinc/fixfixes.c
gcc/fixinc/fixincl.tpl
gcc/fixinc/fixlib.h
gcc/fixinc/inclhack.def

index dd08e80..4df5e65 100644 (file)
@@ -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
index a68dec8..ec7c812 100644 (file)
@@ -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=]
+};
index 9997553..8134158 100644 (file)
@@ -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
  */
index a5b3b41..0dd80f5 100644 (file)
@@ -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`";
 };