--- /dev/null
+/* -*-c-*-
+ *
+ * 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) && defined(PRIuMAX)
+ typedef uintmax_t umax;
+# define P_UMAX PRIuMAX
+#elif defined(ULLONG_MAX)
+ EXT typedef unsigned long long umax;
+# define P_UMAX "llu"
+#else
+ typedef unsigned long umax;
+# define P_UMAX "lu"
+#endif
+
+/* --- Table of interesting types --- *
+ *
+ * These are in preference order.
+ */
+
+enum {
+ f_stdint = 1u,
+ f_ext = 2u
+};
+
+struct itype {
+ const char *name;
+ const char *suff;
+ umax max;
+ unsigned flags;
+ unsigned bits;
+} tytab[] = {
+ { "unsigned int", "u", UINT_MAX, 0 },
+ { "unsigned short", "u", USHRT_MAX, 0 },
+ { "unsigned long", "ul", ULONG_MAX, 0 },
+#ifdef ULLONG_MAX
+ { "unsigned long long", "ull", EXT ULLONG_MAX, f_ext },
+#endif
+#ifdef UINTMAX_MAX
+ { "uintmax_t", "u", UINTMAX_MAX, f_stdint },
+#endif
+ { 0, 0 },
+};
+
+typedef struct itype itype;
+
+/*----- 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 --- */
+
+ for (i = tytab; i->name; i++) {
+ unsigned bits;
+ umax u = i->max;
+ for (bits = 0; u; bits++)
+ u >>= 1;
+ i->bits = bits;
+ }
+
+ /* --- Now try to find the interesting types --- *
+ *
+ * The first thing to do is to find the largest type. Then I find the
+ * `best' type which is less than half that size, and then the `best' type
+ * 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)
+ largest = i;
+ }
+ for (mpw = 0, i = tytab; i->name; i++) {
+ if (i->bits * 2 <= largest->bits && (!mpw || i->bits > mpw->bits))
+ mpw = i;
+ }
+ if (!mpw)
+ mpw = tytab;
+ for (mpd = 0, i = tytab; i->name; i++) {
+ if (i->bits >= mpw->bits * 2 && (!mpd || i->bits < mpd->bits))
+ mpd = i;
+ }
+ if (!mpd) {
+ static itype w, d;
+ d = w = *mpw;
+ 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 --- */
+
+ puts("\
+/* -*-c-*-\n\
+ *\n\
+ * mptypes.h [generated]\n\
+ */\n\
+\n\
+#ifndef CATACOMB_MPTYPES_H\n\
+#define CATACOMB_MPTYPES_H\n\
+");
+ if ((mpd->flags | mpw->flags) & f_stdint) {
+ puts("\
+#if __STDC_VERSION__ >= 199900l\n\
+# include <stdint.h>\n\
+#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("\
+%stypedef %s mpw;\n\
+#define MPW_BITS %u\n\
+#define MPW_P2 %u\n\
+#define MPW_MAX %s%" P_UMAX "%s\n\
+\n\
+%stypedef %s mpd;\n\
+#define MPD_BITS %u\n\
+#define MPD_MAX %s%" P_UMAX "%s\n\
+\n\
+#endif\n\
+",
+ 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 -------------------------------------------------*/