chiark / gitweb /
configure.ac: Replace with a new version.
[catacomb] / mptypes.c
1 /* -*-c-*-
2  *
3  * $Id$
4  *
5  * Generate `mptypes.h' header file for current architecture
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------*
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  *
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  *
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Header files ------------------------------------------------------*/
31
32 #define _GNU_SOURCE
33 #include "config.h"
34
35 #include <stdio.h>
36 #include <limits.h>
37 #if __STDC_VERSION__ >= 199900l
38 #  include <stdint.h>
39 #  include <inttypes.h>
40 #endif
41
42 /*----- Data types --------------------------------------------------------*/
43
44 /* --- Hack for GCC --- *
45  *
46  * WG14 in their infinite wisdom decided not to use the GCC constant name.
47  */
48
49 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
50 #  define EXT __extension__
51 #else
52 #  define EXT
53 #endif
54
55 #if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX)
56 #  define ULLONG_MAX ULONG_LONG_MAX
57 #endif
58
59 /* --- Choose the largest integer type --- */
60
61 #if defined(UINTMAX_MAX) && defined(PRIuMAX)
62   typedef uintmax_t umax;
63 # define P_UMAX PRIuMAX
64 #elif defined(ULLONG_MAX)
65   EXT typedef unsigned long long umax;
66 # define P_UMAX "llu"
67 #else
68   typedef unsigned long umax;
69 # define P_UMAX "lu"
70 #endif
71
72 /* --- Table of interesting types --- *
73  *
74  * These are in preference order.
75  */
76
77 enum {
78   f_stdint = 1u,
79   f_ext = 2u
80 };
81
82 struct itype {
83   const char *name;
84   const char *suff;
85   umax max;
86   unsigned flags;
87   unsigned bits;
88 } tytab[] = {
89   { "unsigned int",             "u",    UINT_MAX,               0 },
90   { "unsigned short",           "u",    USHRT_MAX,              0 },
91   { "unsigned long",            "ul",   ULONG_MAX,              0 },
92 #ifdef ULLONG_MAX
93   { "unsigned long long",       "ull",  EXT ULLONG_MAX,         f_ext },
94 #endif
95 #ifdef UINTMAX_MAX
96   { "uintmax_t",                "u",    UINTMAX_MAX,            f_stdint },
97 #endif
98   { 0,                          0 },
99 };
100
101 typedef struct itype itype;
102
103 /*----- Main code ---------------------------------------------------------*/
104
105 int main(int argc, char *argv[])
106 {
107   itype *i;
108   itype *largest, *mpw, *mpd;
109   const static char *extstr = "CATACOMB_MPTYPES_EXTENSION ";
110   unsigned p2;
111
112   /* --- Find the bitcounts --- */
113
114   for (i = tytab; i->name; i++) {
115     unsigned bits;
116     umax u = i->max;
117     for (bits = 0; u; bits++)
118       u >>= 1;
119     i->bits = bits;
120   }
121
122   /* --- Now try to find the interesting types --- *
123    *
124    * The first thing to do is to find the largest type.  Then I find the
125    * `best' type which is less than half that size, and then the `best' type
126    * which is twice as big as that one.
127    */
128
129 #if defined(FORCE_MPW_CUSSID)
130   largest = mpd = &tytab[3];
131   mpw = &tytab[2];
132   mpw->bits = 19; mpw->max = 0x7ffff;
133   mpd->bits = 38; mpd->max = 0x3fffffffffll;
134 #elif defined(FORCE_MPW_SHORT)
135   largest = mpd = &tytab[2];
136   mpw = &tytab[1];
137   mpw->bits = 16; mpw->max = 0xffff;
138   mpd->bits = 32; mpd->max = 0xffffffff;
139 #else
140   largest = tytab;
141   for (i = tytab; i->name; i++) {
142     if (i->bits > largest->bits)
143       largest = i;
144   }
145   for (mpw = 0, i = tytab; i->name; i++) {
146     if (i->bits * 2 <= largest->bits && (!mpw || i->bits > mpw->bits))
147       mpw = i;
148   }
149   if (!mpw)
150     mpw = tytab;
151   for (mpd = 0, i = tytab; i->name; i++) {
152     if (i->bits >= mpw->bits * 2 && (!mpd || i->bits < mpd->bits))
153       mpd = i;
154   }
155   if (!mpd) {
156     static itype w, d;
157     d = w = *mpw;
158     w.bits /= 2; w.max = ~(~((umax)0) << w.bits);
159     d.bits = w.bits * 2; d.max = ~(~((umax)0) << d.bits);
160     mpw = &w; mpd = &d;
161   }
162 #endif
163   for (p2 = 1; (p2 << 1) < mpw->bits; p2 <<= 1);
164
165   /* --- Output time --- */
166
167   puts("\
168 /* -*-c-*-\n\
169  *\n\
170  * mptypes.h [generated]\n\
171  */\n\
172 \n\
173 #ifndef CATACOMB_MPTYPES_H\n\
174 #define CATACOMB_MPTYPES_H\n\
175 ");
176   if ((mpd->flags | mpw->flags) & f_stdint) {
177     puts("\
178 #if __STDC_VERSION__ >= 199900l\n\
179 #  include <stdint.h>\n\
180 #endif\n\
181 ");
182   }
183   if ((mpd->flags | mpw->flags) & f_ext) {
184     printf("\
185 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)\n\
186 #  define %s __extension__\n\
187 #else\n\
188 #  define %s\n\
189 #endif\n\
190 ", extstr, extstr);
191   }
192   printf("\
193 %stypedef %s mpw;\n\
194 #define MPW_BITS %u\n\
195 #define MPW_P2 %u\n\
196 #define MPW_MAX %s%" P_UMAX "%s\n\
197 \n\
198 %stypedef %s mpd;\n\
199 #define MPD_BITS %u\n\
200 #define MPD_MAX %s%" P_UMAX "%s\n\
201 \n\
202 #endif\n\
203 ",
204   mpw->flags & f_ext ? extstr : "", mpw->name,
205   mpw->bits, p2,
206   mpw->flags & f_ext ? extstr : "", mpw->max, mpw->suff,
207   mpd->flags & f_ext ? extstr : "", mpd->name,
208   mpd->bits,
209   mpd->flags & f_ext ? extstr : "", mpd->max, mpd->suff);
210
211   return (0);
212 }
213
214 /*----- That's all, folks -------------------------------------------------*/