5 * Generate limit MPs for C types
7 * (c) 2006 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Header files ------------------------------------------------------*/
38 #if __STDC_VERSION__ >= 199900l
40 # include <inttypes.h>
46 /*----- Data types --------------------------------------------------------*/
48 /* --- Hack for GCC --- *
50 * WG14 in their infinite wisdom decided not to use the GCC constant name.
53 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
54 # define EXT __extension__
59 #if defined(LONG_LONG_MIN) && !defined(LLONG_MIN)
60 # define LLONG_MIN EXT LONG_LONG_MIN
63 #if defined(LONG_LONG_MAX) && !defined(LLONG_MAX)
64 # define LLONG_MAX EXT LONG_LONG_MAX
67 #if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX)
68 # define ULLONG_MAX EXT ULONG_LONG_MAX
71 /* --- Choose the largest integer type --- */
73 #if defined(INTMAX_MAX)
74 typedef intmax_t imax
;
75 #elif defined(LLONG_MAX)
76 EXT
typedef long long imax
;
81 #if defined(UINTMAX_MAX)
82 typedef uintmax_t umax
;
83 #elif defined(ULLONG_MAX)
84 EXT
typedef unsigned long long umax
;
86 typedef unsigned long umax
;
89 /*----- Main code ---------------------------------------------------------*/
93 enum { NEG
, POS
, NSIGN
};
96 int gmap
[TABSZ
][NSIGN
];
97 struct { int g
, s
; } qmap
[TABSZ
];
102 static void dump(mp
*x
)
107 w
= (MPW_BITS
+ 3)/4;
109 while (2 + 2 * n
* (4 + w
) < 72) n
<<= 1;
112 printf("0x%0*x", w
, x
->v
[i
]);
114 if (i
>= MP_LEN(x
)) break;
116 if (i
% n
) fputs(" ", stdout
); else fputs("\n ", stdout
);
121 static void doemit(umax c
, int s
, int *gg
, int *qq
)
126 for (i
= 0; i
< n
; i
++) {
134 gmap
[i
][POS
] = gmap
[i
][NEG
] = -1;
136 MP_FROMINT(x
, umax
, c
);
137 printf("static mpw guts_%d[] = {\n", q
);
139 fputs("};\n\n", stdout
);
145 if (gmap
[i
][s
] < 0) {
155 static void emit(imax c
, int *gg
, int *qq
)
160 if (c
>= 0) { uc
= c
; s
= POS
; }
161 else { uc
= -c
; s
= NEG
; }
162 doemit(uc
, s
, gg
, qq
);
165 static void uemit(umax c
, int *gg
, int *qq
) { doemit(c
, POS
, gg
, qq
); }
174 { "SCHAR", SCHAR_MIN
, SCHAR_MAX
},
175 { "CHAR", CHAR_MIN
, CHAR_MAX
},
176 { "UCHAR", 0, UCHAR_MAX
},
177 { "UINT8", 0, 0xff },
178 { "SHRT", SHRT_MIN
, SHRT_MAX
},
179 { "USHRT", 0, USHRT_MAX
},
180 { "UINT16", 0, 0xffff },
181 { "INT", INT_MIN
, INT_MAX
},
182 { "UINT", 0, UINT_MAX
},
183 { "LONG", LONG_MIN
, LONG_MAX
},
184 { "ULONG", 0, ULONG_MAX
},
185 { "UINT32", 0, 0xffffffff },
187 { "LLONG", LLONG_MIN
, LLONG_MAX
},
188 { "ULLONG", 0, ULLONG_MAX
},
190 { "SIZET", 0, ~(size_t)0 },
194 static void dogen(void)
198 for (i
= 0; tab
[i
].name
; i
++) {
200 emit(tab
[i
].min
, &tab
[i
].gmin
, &tab
[i
].qmin
);
201 uemit(tab
[i
].max
, &tab
[i
].gmax
, &tab
[i
].qmax
);
205 static void cgen(void)
212 * C integer limits [generated]\n\
215 #include \"mplimits.h\"\n\
217 #define N(x) (sizeof(x)/sizeof(*x))\n\
218 #define MPpos(x) { x, x + N(x), N(x), 0, MP_CONST, 0 }\n\
219 #define MPneg(x) { x, x + N(x), N(x), 0, MP_CONST|MP_NEG, 0 }\n\
225 fputs("mp mp_limits[] = {\n", stdout
);
226 for (i
= 0; i
< q
; i
++)
227 printf(" MP%s(guts_%d),\n", qmap
[i
].s ?
"pos" : "neg", qmap
[i
].g
);
228 fputs("};\n", stdout
);
231 static void hgen(void)
238 * C integer limits [generated]\n\
241 #ifndef CATACOMB_MPLIMITS_H\n\
242 #define CATACOMB_MPLIMITS_H\n\
244 #ifndef CATACOMB_MP_H\n\
245 # include \"mp.h\"\n\
248 extern mp mp_limits[];\n\
253 for (i
= 0; tab
[i
].name
; i
++) {
255 printf("#define MP_%s_MIN (&mp_limits[%d])\n",
256 tab
[i
].name
, gmap
[tab
[i
].qmin
][NEG
]);
258 printf("#define MP_%s_MAX (&mp_limits[%d])\n",
259 tab
[i
].name
, gmap
[tab
[i
].qmax
][POS
]);
261 fputs("\n#endif\n", stdout
);
264 int main(int argc
, char *argv
[])
266 const char *what
= argc
== 2 ? argv
[1] : "<bogus>";
269 case 'c': cgen(); break;
270 case 'h': hgen(); break;
272 fprintf(stderr
, "unknown action `%s'\n", what
);
275 if (fflush(stdout
) || fclose(stdout
)) {
276 fprintf(stderr
, "error writing output: %s\n", strerror(errno
));
282 /*----- That's all, folks -------------------------------------------------*/