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