5084155b |
1 | /* -*-c-*- |
2 | * |
add9d49f |
3 | * $Id: mptypes.c,v 1.4 2000/10/08 12:05:24 mdw Exp $ |
0b181057 |
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. |
5084155b |
28 | */ |
29 | |
0b181057 |
30 | /*----- Revision history --------------------------------------------------* |
31 | * |
32 | * $Log: mptypes.c,v $ |
add9d49f |
33 | * Revision 1.4 2000/10/08 12:05:24 mdw |
34 | * Make later versions of GCC shut up about @long long@. |
35 | * |
b3f05084 |
36 | * Revision 1.3 1999/12/10 23:29:48 mdw |
37 | * Change header file guard names. |
38 | * |
0b181057 |
39 | * Revision 1.2 1999/11/13 01:54:32 mdw |
40 | * Format source code properly ;-). Attach suffixes to the `max' |
41 | * constants. |
42 | * |
43 | */ |
44 | |
45 | /*----- Header files ------------------------------------------------------*/ |
46 | |
5084155b |
47 | #define _GNU_SOURCE |
48 | #include <stdio.h> |
49 | #include <limits.h> |
50 | #if __STDC_VERSION__ >= 199900l |
51 | # include <stdint.h> |
52 | #endif |
53 | |
0b181057 |
54 | /*----- Data types --------------------------------------------------------*/ |
55 | |
5084155b |
56 | /* --- Hack for GCC --- * |
57 | * |
58 | * WG14 in their infinite wisdom decided not to use the GCC constant name. |
59 | */ |
60 | |
add9d49f |
61 | #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91) |
62 | # define EXT __extension__ |
63 | #else |
64 | # define EXT |
65 | #endif |
66 | |
5084155b |
67 | #if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX) |
68 | # define ULLONG_MAX ULONG_LONG_MAX |
69 | #endif |
70 | |
71 | /* --- Choose the largest integer type --- */ |
72 | |
73 | #if defined(UINTMAX_MAX) |
74 | typedef uintmax_t umax; |
75 | # define P_UMAX PRIuMAX |
76 | #elif defined(ULLONG_MAX) |
add9d49f |
77 | __extension__ typedef unsigned long long umax; |
5084155b |
78 | # define P_UMAX "%llu" |
79 | #else |
80 | typedef unsigned long umax; |
81 | # define P_UMAX "%lu" |
82 | #endif |
83 | |
84 | /* --- Table of interesting types --- * |
85 | * |
86 | * These are in preference order. |
87 | */ |
88 | |
89 | enum { |
add9d49f |
90 | f_stdint = 1u, |
91 | f_ext = 2u |
5084155b |
92 | }; |
93 | |
94 | struct itype { |
95 | const char *name; |
0b181057 |
96 | const char *suff; |
5084155b |
97 | umax max; |
98 | unsigned flags; |
99 | unsigned bits; |
100 | } tytab[] = { |
add9d49f |
101 | { "unsigned int", "u", UINT_MAX, 0 }, |
102 | { "unsigned short", "u", USHRT_MAX, 0 }, |
103 | { "unsigned long", "ul", ULONG_MAX, 0 }, |
5084155b |
104 | #ifdef ULLONG_MAX |
add9d49f |
105 | { "unsigned long long", "ull", EXT ULLONG_MAX, f_ext }, |
5084155b |
106 | #endif |
107 | #ifdef UINTMAX_MAX |
add9d49f |
108 | { "uintmax_t", "u", UINTMAX_MAX, f_stdint }, |
5084155b |
109 | #endif |
110 | { 0, 0 }, |
111 | }; |
112 | |
113 | typedef struct itype itype; |
114 | |
0b181057 |
115 | /*----- Main code ---------------------------------------------------------*/ |
5084155b |
116 | |
117 | int main(int argc, char *argv[]) |
118 | { |
119 | itype *i; |
120 | itype *largest, *mpw, *mpd; |
add9d49f |
121 | const static char *extstr = "CATACOMB_MPTYPES_EXTENSION "; |
5084155b |
122 | |
123 | /* --- Find the bitcounts --- */ |
124 | |
125 | for (i = tytab; i->name; i++) { |
126 | unsigned bits; |
127 | umax u = i->max; |
128 | for (bits = 0; u; bits++) |
129 | u >>= 1; |
130 | i->bits = bits; |
131 | } |
132 | |
133 | /* --- Now try to find the interesting types --- * |
134 | * |
135 | * The first thing to do is to find the largest type. Then I find the |
136 | * `best' type which is less than half that size, and then the `best' type |
137 | * which is twice as big as that one. |
138 | */ |
139 | |
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 | |
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\ |
add9d49f |
193 | #define MPW_MAX %s" P_UMAX "%s\n\ |
5084155b |
194 | \n\ |
add9d49f |
195 | %stypedef %s mpd;\n\ |
5084155b |
196 | #define MPD_BITS %u\n\ |
add9d49f |
197 | #define MPD_MAX %s" P_UMAX "%s\n\ |
5084155b |
198 | \n\ |
199 | #endif\n\ |
200 | ", |
add9d49f |
201 | mpw->flags & f_ext ? extstr : "", mpw->name, |
202 | mpw->bits, |
203 | mpw->flags & f_ext ? extstr : "", mpw->max, mpw->suff, |
204 | mpd->flags & f_ext ? extstr : "", mpd->name, |
205 | mpd->bits, |
206 | mpd->flags & f_ext ? extstr : "", mpd->max, mpd->suff); |
5084155b |
207 | |
208 | return (0); |
209 | } |
add9d49f |
210 | |
0b181057 |
211 | /*----- That's all, folks -------------------------------------------------*/ |