Commit | Line | Data |
---|---|---|
5084155b | 1 | /* -*-c-*- |
2 | * | |
e8776ccd | 3 | * $Id$ |
0b181057 | 4 | * |
5 | * Generate `mptypes.h' header file for current architecture | |
6 | * | |
7 | * (c) 1999 Straylight/Edgeware | |
8 | */ | |
9 | ||
45c0fd36 | 10 | /*----- Licensing notice --------------------------------------------------* |
0b181057 | 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. | |
45c0fd36 | 18 | * |
0b181057 | 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. | |
45c0fd36 | 23 | * |
0b181057 | 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. | |
5084155b | 28 | */ |
29 | ||
0b181057 | 30 | /*----- Header files ------------------------------------------------------*/ |
31 | ||
5084155b | 32 | #define _GNU_SOURCE |
c29970a7 MW |
33 | #include "config.h" |
34 | ||
5084155b | 35 | #include <stdio.h> |
36 | #include <limits.h> | |
37 | #if __STDC_VERSION__ >= 199900l | |
38 | # include <stdint.h> | |
e8776ccd | 39 | # include <inttypes.h> |
5084155b | 40 | #endif |
41 | ||
0b181057 | 42 | /*----- Data types --------------------------------------------------------*/ |
43 | ||
5084155b | 44 | /* --- Hack for GCC --- * |
45 | * | |
46 | * WG14 in their infinite wisdom decided not to use the GCC constant name. | |
47 | */ | |
48 | ||
add9d49f | 49 | #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91) |
50 | # define EXT __extension__ | |
51 | #else | |
52 | # define EXT | |
53 | #endif | |
54 | ||
5084155b | 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 | ||
8282072d | 61 | #if defined(UINTMAX_MAX) && defined(PRIuMAX) |
5084155b | 62 | typedef uintmax_t umax; |
63 | # define P_UMAX PRIuMAX | |
64 | #elif defined(ULLONG_MAX) | |
106b481c | 65 | EXT typedef unsigned long long umax; |
e8776ccd | 66 | # define P_UMAX "llu" |
5084155b | 67 | #else |
68 | typedef unsigned long umax; | |
e8776ccd | 69 | # define P_UMAX "lu" |
5084155b | 70 | #endif |
71 | ||
72 | /* --- Table of interesting types --- * | |
73 | * | |
74 | * These are in preference order. | |
75 | */ | |
76 | ||
77 | enum { | |
add9d49f | 78 | f_stdint = 1u, |
79 | f_ext = 2u | |
5084155b | 80 | }; |
81 | ||
82 | struct itype { | |
83 | const char *name; | |
0b181057 | 84 | const char *suff; |
5084155b | 85 | umax max; |
86 | unsigned flags; | |
87 | unsigned bits; | |
88 | } tytab[] = { | |
add9d49f | 89 | { "unsigned int", "u", UINT_MAX, 0 }, |
90 | { "unsigned short", "u", USHRT_MAX, 0 }, | |
91 | { "unsigned long", "ul", ULONG_MAX, 0 }, | |
5084155b | 92 | #ifdef ULLONG_MAX |
add9d49f | 93 | { "unsigned long long", "ull", EXT ULLONG_MAX, f_ext }, |
5084155b | 94 | #endif |
95 | #ifdef UINTMAX_MAX | |
add9d49f | 96 | { "uintmax_t", "u", UINTMAX_MAX, f_stdint }, |
5084155b | 97 | #endif |
98 | { 0, 0 }, | |
99 | }; | |
100 | ||
101 | typedef struct itype itype; | |
102 | ||
0b181057 | 103 | /*----- Main code ---------------------------------------------------------*/ |
5084155b | 104 | |
105 | int main(int argc, char *argv[]) | |
106 | { | |
107 | itype *i; | |
108 | itype *largest, *mpw, *mpd; | |
add9d49f | 109 | const static char *extstr = "CATACOMB_MPTYPES_EXTENSION "; |
c29970a7 | 110 | unsigned p2; |
5084155b | 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 | ||
c29970a7 MW |
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 | |
5084155b | 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; | |
45c0fd36 | 161 | } |
c29970a7 MW |
162 | #endif |
163 | for (p2 = 1; (p2 << 1) < mpw->bits; p2 <<= 1); | |
5084155b | 164 | |
165 | /* --- Output time --- */ | |
166 | ||
167 | puts("\ | |
168 | /* -*-c-*-\n\ | |
169 | *\n\ | |
170 | * mptypes.h [generated]\n\ | |
171 | */\n\ | |
172 | \n\ | |
b3f05084 | 173 | #ifndef CATACOMB_MPTYPES_H\n\ |
174 | #define CATACOMB_MPTYPES_H\n\ | |
5084155b | 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 | } | |
add9d49f | 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 | } | |
5084155b | 192 | printf("\ |
add9d49f | 193 | %stypedef %s mpw;\n\ |
5084155b | 194 | #define MPW_BITS %u\n\ |
c29970a7 | 195 | #define MPW_P2 %u\n\ |
e8776ccd | 196 | #define MPW_MAX %s%" P_UMAX "%s\n\ |
5084155b | 197 | \n\ |
add9d49f | 198 | %stypedef %s mpd;\n\ |
5084155b | 199 | #define MPD_BITS %u\n\ |
e8776ccd | 200 | #define MPD_MAX %s%" P_UMAX "%s\n\ |
5084155b | 201 | \n\ |
202 | #endif\n\ | |
203 | ", | |
add9d49f | 204 | mpw->flags & f_ext ? extstr : "", mpw->name, |
c29970a7 | 205 | mpw->bits, p2, |
add9d49f | 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); | |
5084155b | 210 | |
211 | return (0); | |
212 | } | |
add9d49f | 213 | |
0b181057 | 214 | /*----- That's all, folks -------------------------------------------------*/ |