chiark / gitweb /
Expunge revision histories in files.
[catacomb] / mptypes.c
1 /* -*-c-*-
2  *
3  * $Id: mptypes.c,v 1.5 2004/04/08 01:36:15 mdw Exp $
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 <stdio.h>
34 #include <limits.h>
35 #if __STDC_VERSION__ >= 199900l
36 #  include <stdint.h>
37 #endif
38
39 /*----- Data types --------------------------------------------------------*/
40
41 /* --- Hack for GCC --- *
42  *
43  * WG14 in their infinite wisdom decided not to use the GCC constant name.
44  */
45
46 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
47 #  define EXT __extension__
48 #else
49 #  define EXT
50 #endif
51
52 #if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX)
53 #  define ULLONG_MAX ULONG_LONG_MAX
54 #endif
55
56 /* --- Choose the largest integer type --- */
57
58 #if defined(UINTMAX_MAX)
59   typedef uintmax_t umax;
60 # define P_UMAX PRIuMAX
61 #elif defined(ULLONG_MAX)
62   __extension__ typedef unsigned long long umax;
63 # define P_UMAX "%llu"
64 #else
65   typedef unsigned long umax;
66 # define P_UMAX "%lu"
67 #endif
68
69 /* --- Table of interesting types --- *
70  *
71  * These are in preference order.
72  */
73
74 enum {
75   f_stdint = 1u,
76   f_ext = 2u
77 };
78
79 struct itype {
80   const char *name;
81   const char *suff;
82   umax max;
83   unsigned flags;
84   unsigned bits;
85 } tytab[] = {
86   { "unsigned int",             "u",    UINT_MAX,               0 },
87   { "unsigned short",           "u",    USHRT_MAX,              0 },
88   { "unsigned long",            "ul",   ULONG_MAX,              0 },
89 #ifdef ULLONG_MAX
90   { "unsigned long long",       "ull",  EXT ULLONG_MAX,         f_ext },
91 #endif
92 #ifdef UINTMAX_MAX
93   { "uintmax_t",                "u",    UINTMAX_MAX,            f_stdint },
94 #endif
95   { 0,                          0 },
96 };
97
98 typedef struct itype itype;
99
100 /*----- Main code ---------------------------------------------------------*/
101
102 int main(int argc, char *argv[])
103 {
104   itype *i;
105   itype *largest, *mpw, *mpd;
106   const static char *extstr = "CATACOMB_MPTYPES_EXTENSION ";
107
108   /* --- Find the bitcounts --- */
109
110   for (i = tytab; i->name; i++) {
111     unsigned bits;
112     umax u = i->max;
113     for (bits = 0; u; bits++)
114       u >>= 1;
115     i->bits = bits;
116   }
117
118   /* --- Now try to find the interesting types --- *
119    *
120    * The first thing to do is to find the largest type.  Then I find the
121    * `best' type which is less than half that size, and then the `best' type
122    * which is twice as big as that one.
123    */
124
125   largest = tytab;
126   for (i = tytab; i->name; i++) {
127     if (i->bits > largest->bits)
128       largest = i;
129   }
130   for (mpw = 0, i = tytab; i->name; i++) {
131     if (i->bits * 2 <= largest->bits && (!mpw || i->bits > mpw->bits))
132       mpw = i;
133   }
134   if (!mpw)
135     mpw = tytab;
136   for (mpd = 0, i = tytab; i->name; i++) {
137     if (i->bits >= mpw->bits * 2 && (!mpd || i->bits < mpd->bits))
138       mpd = i;
139   }
140   if (!mpd) {
141     static itype w, d;
142     d = w = *mpw;
143     w.bits /= 2; w.max = ~(~((umax)0) << w.bits);
144     d.bits = w.bits * 2; d.max = ~(~((umax)0) << d.bits);
145     mpw = &w; mpd = &d;
146   }    
147
148   /* --- Output time --- */
149
150   puts("\
151 /* -*-c-*-\n\
152  *\n\
153  * mptypes.h [generated]\n\
154  */\n\
155 \n\
156 #ifndef CATACOMB_MPTYPES_H\n\
157 #define CATACOMB_MPTYPES_H\n\
158 ");
159   if ((mpd->flags | mpw->flags) & f_stdint) {
160     puts("\
161 #if __STDC_VERSION__ >= 199900l\n\
162 #  include <stdint.h>\n\
163 #endif\n\
164 ");
165   }
166   if ((mpd->flags | mpw->flags) & f_ext) {
167     printf("\
168 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)\n\
169 #  define %s __extension__\n\
170 #else\n\
171 #  define %s\n\
172 #endif\n\
173 ", extstr, extstr);
174   }
175   printf("\
176 %stypedef %s mpw;\n\
177 #define MPW_BITS %u\n\
178 #define MPW_MAX %s" P_UMAX "%s\n\
179 \n\
180 %stypedef %s mpd;\n\
181 #define MPD_BITS %u\n\
182 #define MPD_MAX %s" P_UMAX "%s\n\
183 \n\
184 #endif\n\
185 ",
186   mpw->flags & f_ext ? extstr : "", mpw->name,
187   mpw->bits,
188   mpw->flags & f_ext ? extstr : "", mpw->max, mpw->suff,
189   mpd->flags & f_ext ? extstr : "", mpd->name,
190   mpd->bits,
191   mpd->flags & f_ext ? extstr : "", mpd->max, mpd->suff);
192
193   return (0);
194 }
195
196 /*----- That's all, folks -------------------------------------------------*/