catcrypt.c: Don't close output file twice.
[u/mdw/catacomb] / mptypes.c
index 8751e2e..eb8b975 100644 (file)
--- a/mptypes.c
+++ b/mptypes.c
@@ -1,35 +1,72 @@
 /* -*-c-*-
  *
- * Program to find appropriate types for multiprecision integer stuff.
+ * $Id$
+ *
+ * Generate `mptypes.h' header file for current architecture
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Catacomb 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
  */
 
+/*----- Header files ------------------------------------------------------*/
+
 #define _GNU_SOURCE
+#include "config.h"
+
 #include <stdio.h>
 #include <limits.h>
 #if __STDC_VERSION__ >= 199900l
 #  include <stdint.h>
+#  include <inttypes.h>
 #endif
 
+/*----- Data types --------------------------------------------------------*/
+
 /* --- Hack for GCC --- *
  *
  * WG14 in their infinite wisdom decided not to use the GCC constant name.
  */
 
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
+#  define EXT __extension__
+#else
+#  define EXT
+#endif
+
 #if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX)
 #  define ULLONG_MAX ULONG_LONG_MAX
 #endif
 
 /* --- Choose the largest integer type --- */
 
-#if defined(UINTMAX_MAX)
+#if defined(UINTMAX_MAX) && defined(PRIuMAX)
   typedef uintmax_t umax;
 # define P_UMAX PRIuMAX
 #elif defined(ULLONG_MAX)
-  typedef unsigned long long umax;
-# define P_UMAX "%llu"
+  EXT typedef unsigned long long umax;
+# define P_UMAX "llu"
 #else
   typedef unsigned long umax;
-# define P_UMAX "%lu"
+# define P_UMAX "lu"
 #endif
 
 /* --- Table of interesting types --- *
  */
 
 enum {
-  f_stdint
+  f_stdint = 1u,
+  f_ext = 2u
 };
 
 struct itype {
   const char *name;
+  const char *suff;
   umax max;
   unsigned flags;
   unsigned bits;
 } tytab[] = {
-  { "unsigned int",            UINT_MAX,       0 },
-  { "unsigned short",          USHRT_MAX,      0 },
-  { "unsigned long",           ULONG_MAX,      0 },
+  { "unsigned int",            "u",    UINT_MAX,               0 },
+  { "unsigned short",          "u",    USHRT_MAX,              0 },
+  { "unsigned long",           "ul",   ULONG_MAX,              0 },
 #ifdef ULLONG_MAX
-  { "unsigned long long",      ULLONG_MAX,     0 },
+  { "unsigned long long",      "ull",  EXT ULLONG_MAX,         f_ext },
 #endif
 #ifdef UINTMAX_MAX
-  { "uintmax_t",               UINTMAX_MAX,    f_stdint },
+  { "uintmax_t",               "u",    UINTMAX_MAX,            f_stdint },
 #endif
   { 0,                         0 },
 };
 
 typedef struct itype itype;
 
-/* --- Main program --- */
+/*----- Main code ---------------------------------------------------------*/
 
 int main(int argc, char *argv[])
 {
   itype *i;
   itype *largest, *mpw, *mpd;
+  const static char *extstr = "CATACOMB_MPTYPES_EXTENSION ";
+  unsigned p2;
 
   /* --- Find the bitcounts --- */
 
@@ -85,6 +126,17 @@ int main(int argc, char *argv[])
    * which is twice as big as that one.
    */
 
+#if defined(FORCE_MPW_CUSSID)
+  largest = mpd = &tytab[3];
+  mpw = &tytab[2];
+  mpw->bits = 19; mpw->max = 0x7ffff;
+  mpd->bits = 38; mpd->max = 0x3fffffffffll;
+#elif defined(FORCE_MPW_SHORT)
+  largest = mpd = &tytab[2];
+  mpw = &tytab[1];
+  mpw->bits = 16; mpw->max = 0xffff;
+  mpd->bits = 32; mpd->max = 0xffffffff;
+#else
   largest = tytab;
   for (i = tytab; i->name; i++) {
     if (i->bits > largest->bits)
@@ -106,7 +158,9 @@ int main(int argc, char *argv[])
     w.bits /= 2; w.max = ~(~((umax)0) << w.bits);
     d.bits = w.bits * 2; d.max = ~(~((umax)0) << d.bits);
     mpw = &w; mpd = &d;
-  }    
+  }
+#endif
+  for (p2 = 1; (p2 << 1) < mpw->bits; p2 <<= 1);
 
   /* --- Output time --- */
 
@@ -116,8 +170,8 @@ int main(int argc, char *argv[])
  * mptypes.h [generated]\n\
  */\n\
 \n\
-#ifndef MPTYPES_H\n\
-#define MPTYPES_H\n\
+#ifndef CATACOMB_MPTYPES_H\n\
+#define CATACOMB_MPTYPES_H\n\
 ");
   if ((mpd->flags | mpw->flags) & f_stdint) {
     puts("\
@@ -126,19 +180,35 @@ int main(int argc, char *argv[])
 #endif\n\
 ");
   }
+  if ((mpd->flags | mpw->flags) & f_ext) {
+    printf("\
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)\n\
+#  define %s __extension__\n\
+#else\n\
+#  define %s\n\
+#endif\n\
+", extstr, extstr);
+  }
   printf("\
-typedef %s mpw;\n\
+%stypedef %s mpw;\n\
 #define MPW_BITS %u\n\
-#define MPW_MAX " P_UMAX "\n\
+#define MPW_P2 %u\n\
+#define MPW_MAX %s%" P_UMAX "%s\n\
 \n\
-typedef %s mpd;\n\
+%stypedef %s mpd;\n\
 #define MPD_BITS %u\n\
-#define MPD_MAX " P_UMAX "\n\
+#define MPD_MAX %s%" P_UMAX "%s\n\
 \n\
 #endif\n\
 ",
-  mpw->name, mpw->bits, mpw->max,
-  mpd->name, mpd->bits, mpd->max);
+  mpw->flags & f_ext ? extstr : "", mpw->name,
+  mpw->bits, p2,
+  mpw->flags & f_ext ? extstr : "", mpw->max, mpw->suff,
+  mpd->flags & f_ext ? extstr : "", mpd->name,
+  mpd->bits,
+  mpd->flags & f_ext ? extstr : "", mpd->max, mpd->suff);
 
   return (0);
 }
+
+/*----- That's all, folks -------------------------------------------------*/