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