5084155b |
1 | /* -*-c-*- |
2 | * |
3 | * Program to find appropriate types for multiprecision integer stuff. |
4 | */ |
5 | |
6 | #define _GNU_SOURCE |
7 | #include <stdio.h> |
8 | #include <limits.h> |
9 | #if __STDC_VERSION__ >= 199900l |
10 | # include <stdint.h> |
11 | #endif |
12 | |
13 | /* --- Hack for GCC --- * |
14 | * |
15 | * WG14 in their infinite wisdom decided not to use the GCC constant name. |
16 | */ |
17 | |
18 | #if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX) |
19 | # define ULLONG_MAX ULONG_LONG_MAX |
20 | #endif |
21 | |
22 | /* --- Choose the largest integer type --- */ |
23 | |
24 | #if defined(UINTMAX_MAX) |
25 | typedef uintmax_t umax; |
26 | # define P_UMAX PRIuMAX |
27 | #elif defined(ULLONG_MAX) |
28 | typedef unsigned long long umax; |
29 | # define P_UMAX "%llu" |
30 | #else |
31 | typedef unsigned long umax; |
32 | # define P_UMAX "%lu" |
33 | #endif |
34 | |
35 | /* --- Table of interesting types --- * |
36 | * |
37 | * These are in preference order. |
38 | */ |
39 | |
40 | enum { |
41 | f_stdint |
42 | }; |
43 | |
44 | struct itype { |
45 | const char *name; |
46 | umax max; |
47 | unsigned flags; |
48 | unsigned bits; |
49 | } tytab[] = { |
50 | { "unsigned int", UINT_MAX, 0 }, |
51 | { "unsigned short", USHRT_MAX, 0 }, |
52 | { "unsigned long", ULONG_MAX, 0 }, |
53 | #ifdef ULLONG_MAX |
54 | { "unsigned long long", ULLONG_MAX, 0 }, |
55 | #endif |
56 | #ifdef UINTMAX_MAX |
57 | { "uintmax_t", UINTMAX_MAX, f_stdint }, |
58 | #endif |
59 | { 0, 0 }, |
60 | }; |
61 | |
62 | typedef struct itype itype; |
63 | |
64 | /* --- Main program --- */ |
65 | |
66 | int main(int argc, char *argv[]) |
67 | { |
68 | itype *i; |
69 | itype *largest, *mpw, *mpd; |
70 | |
71 | /* --- Find the bitcounts --- */ |
72 | |
73 | for (i = tytab; i->name; i++) { |
74 | unsigned bits; |
75 | umax u = i->max; |
76 | for (bits = 0; u; bits++) |
77 | u >>= 1; |
78 | i->bits = bits; |
79 | } |
80 | |
81 | /* --- Now try to find the interesting types --- * |
82 | * |
83 | * The first thing to do is to find the largest type. Then I find the |
84 | * `best' type which is less than half that size, and then the `best' type |
85 | * which is twice as big as that one. |
86 | */ |
87 | |
88 | largest = tytab; |
89 | for (i = tytab; i->name; i++) { |
90 | if (i->bits > largest->bits) |
91 | largest = i; |
92 | } |
93 | for (mpw = 0, i = tytab; i->name; i++) { |
94 | if (i->bits * 2 <= largest->bits && (!mpw || i->bits > mpw->bits)) |
95 | mpw = i; |
96 | } |
97 | if (!mpw) |
98 | mpw = tytab; |
99 | for (mpd = 0, i = tytab; i->name; i++) { |
100 | if (i->bits >= mpw->bits * 2 && (!mpd || i->bits < mpd->bits)) |
101 | mpd = i; |
102 | } |
103 | if (!mpd) { |
104 | static itype w, d; |
105 | d = w = *mpw; |
106 | w.bits /= 2; w.max = ~(~((umax)0) << w.bits); |
107 | d.bits = w.bits * 2; d.max = ~(~((umax)0) << d.bits); |
108 | mpw = &w; mpd = &d; |
109 | } |
110 | |
111 | /* --- Output time --- */ |
112 | |
113 | puts("\ |
114 | /* -*-c-*-\n\ |
115 | *\n\ |
116 | * mptypes.h [generated]\n\ |
117 | */\n\ |
118 | \n\ |
119 | #ifndef MPTYPES_H\n\ |
120 | #define MPTYPES_H\n\ |
121 | "); |
122 | if ((mpd->flags | mpw->flags) & f_stdint) { |
123 | puts("\ |
124 | #if __STDC_VERSION__ >= 199900l\n\ |
125 | # include <stdint.h>\n\ |
126 | #endif\n\ |
127 | "); |
128 | } |
129 | printf("\ |
130 | typedef %s mpw;\n\ |
131 | #define MPW_BITS %u\n\ |
132 | #define MPW_MAX " P_UMAX "\n\ |
133 | \n\ |
134 | typedef %s mpd;\n\ |
135 | #define MPD_BITS %u\n\ |
136 | #define MPD_MAX " P_UMAX "\n\ |
137 | \n\ |
138 | #endif\n\ |
139 | ", |
140 | mpw->name, mpw->bits, mpw->max, |
141 | mpd->name, mpd->bits, mpd->max); |
142 | |
143 | return (0); |
144 | } |