2 #define __PDCLIB_INT_H __PDCLIB_INT_H
4 /* PDCLib internal integer logic <_PDCLIB_int.h>
6 This file is part of the Public Domain C Library (PDCLib).
7 Permission is granted to use, modify, and / or redistribute at will.
10 /* -------------------------------------------------------------------------- */
11 /* You should not have to edit anything in this file; if you DO have to, it */
12 /* would be considered a bug / missing feature: notify the author(s). */
13 /* -------------------------------------------------------------------------- */
15 #include <_PDCLIB_config.h>
16 #include <_PDCLIB_aux.h>
18 /* null pointer constant */
19 #define _PDCLIB_NULL 0
21 /* -------------------------------------------------------------------------- */
22 /* Limits of native datatypes */
23 /* -------------------------------------------------------------------------- */
24 /* The definition of minimum limits for unsigned datatypes is done because */
25 /* later on we will "construct" limits for other abstract types: */
26 /* USHRT -> _PDCLIB_ + USHRT + _MIN -> _PDCLIB_USHRT_MIN -> 0 */
27 /* INT -> _PDCLIB_ + INT + _MIN -> _PDCLIB_INT_MIN -> ... you get the idea. */
28 /* -------------------------------------------------------------------------- */
30 /* Setting 'char' limits */
31 #define _PDCLIB_CHAR_BIT 8
32 #define _PDCLIB_UCHAR_MIN 0
33 #define _PDCLIB_UCHAR_MAX 0xff
34 #define _PDCLIB_SCHAR_MIN (-0x7f - 1)
35 #define _PDCLIB_SCHAR_MAX 0x7f
36 #ifdef _PDCLIB_CHAR_SIGNED
37 #define _PDCLIB_CHAR_MIN _PDCLIB_SCHAR_MIN
38 #define _PDCLIB_CHAR_MAX _PDCLIB_SCHAR_MAX
40 #define _PDCLIB_CHAR_MIN 0
41 #define _PDCLIB_CHAR_MAX _PDCLIB_UCHAR_MAX
44 /* Setting 'short' limits */
45 #if _PDCLIB_SHRT_BYTES == 2
46 #define _PDCLIB_SHRT_MAX 0x7fff
47 #define _PDCLIB_SHRT_MIN (-0x7fff - 1)
48 #define _PDCLIB_USHRT_MAX 0xffff
50 #error Unsupported width of 'short' (not 16 bit).
52 #define _PDCLIB_USHRT_MIN 0
54 #if _PDCLIB_INT_BYTES < _PDCLIB_SHRT_BYTES
55 #error Bogus setting: short > int? Check _PDCLIB_config.h.
58 /* Setting 'int' limits */
59 #if _PDCLIB_INT_BYTES == 2
60 #define _PDCLIB_INT_MAX 0x7fff
61 #define _PDCLIB_INT_MIN (-0x7fff - 1)
62 #define _PDCLIB_UINT_MAX 0xffffU
63 #elif _PDCLIB_INT_BYTES == 4
64 #define _PDCLIB_INT_MAX 0x7fffffff
65 #define _PDCLIB_INT_MIN (-0x7fffffff - 1)
66 #define _PDCLIB_UINT_MAX 0xffffffffU
67 #elif _PDCLIB_INT_BYTES == 8
68 #define _PDCLIB_INT_MAX 0x7fffffffffffffff
69 #define _PDCLIB_INT_MIN (-0x7fffffffffffffff - 1)
70 #define _PDCLIB_UINT_MAX 0xffffffffffffffff
72 #error Unsupported width of 'int' (neither 16, 32, nor 64 bit).
74 #define _PDCLIB_UINT_MIN 0
76 /* Setting 'long' limits */
77 #if _PDCLIB_LONG_BYTES == 4
78 #define _PDCLIB_LONG_MAX 0x7fffffffL
79 #define _PDCLIB_LONG_MIN (-0x7fffffffL - 1L)
80 #define _PDCLIB_ULONG_MAX 0xffffffffUL
81 #elif _PDCLIB_LONG_BYTES == 8
82 #define _PDCLIB_LONG_MAX 0x7fffffffffffffffL
83 #define _PDCLIB_LONG_MIN (-0x7fffffffffffffffL - 1L)
84 #define _PDCLIB_ULONG_MAX 0xffffffffffffffffUL
86 #error Unsupported width of 'long' (neither 32 nor 64 bit).
88 #define _PDCLIB_ULONG_MIN 0
90 /* Setting 'long long' limits */
91 #if _PDCLIB_LLONG_BYTES == 8
92 #define _PDCLIB_LLONG_MAX 0x7fffffffffffffffLL
93 #define _PDCLIB_LLONG_MIN (-0x7fffffffffffffffLL - 1LL)
94 #define _PDCLIB_ULLONG_MAX 0xffffffffffffffffULL
95 #elif _PDCLIB_LLONG_BYTES == 16
96 #define _PDCLIB_LLONG_MAX 0x7fffffffffffffffffffffffffffffffLL
97 #define _PDCLIB_LLONG_MIN (-0x7fffffffffffffffffffffffffffffffLL - 1LL)
98 #define _PDCLIB_ULLONG_MAX 0xffffffffffffffffffffffffffffffffULL
100 #error Unsupported width of 'long long' (neither 64 nor 128 bit).
102 #define _PDCLIB_ULLONG_MIN 0
104 /* -------------------------------------------------------------------------- */
105 /* <stdint.h> exact-width types and their limits */
106 /* -------------------------------------------------------------------------- */
107 /* Note that, for the "standard" widths of 8, 16, 32 and 64 bit, the "LEAST" */
108 /* types are identical to the "exact-width" types, by definition. */
110 /* Setting 'int8_t', its limits, its literal, and conversion macros. */
111 #if _PDCLIB_CHAR_BIT == 8
112 typedef signed char _PDCLIB_int8_t;
113 typedef unsigned char _PDCLIB_uint8_t;
114 #define _PDCLIB_INT8_MAX _PDCLIB_CHAR_MAX
115 #define _PDCLIB_INT8_MIN _PDCLIB_CHAR_MIN
116 #define _PDCLIB_UINT8_MAX _PDCLIB_UCHAR_MAX
117 #define _PDCLIB_8_CONV hh
119 #error Unsupported width of char (not 8 bits).
122 /* Setting 'int16_t', its limits, its literal, and conversion macros. */
123 #if _PDCLIB_INT_BYTES == 2
124 typedef signed int _PDCLIB_int16_t;
125 typedef unsigned int _PDCLIB_uint16_t;
126 #define _PDCLIB_INT16_MAX _PDCLIB_INT_MAX
127 #define _PDCLIB_INT16_MIN _PDCLIB_INT_MIN
128 #define _PDCLIB_UINT16_MAX _PDCLIB_UINT_MAX
129 #define _PDCLIB_16_CONV
130 #elif _PDCLIB_SHRT_BYTES == 2
131 typedef signed short _PDCLIB_int16_t;
132 typedef unsigned short _PDCLIB_uint16_t;
133 #define _PDCLIB_INT16_MAX _PDCLIB_SHRT_MAX
134 #define _PDCLIB_INT16_MIN _PDCLIB_SHRT_MIN
135 #define _PDCLIB_UINT16_MAX _PDCLIB_USHRT_MAX
136 #define _PDCLIB_16_CONV h
138 #error Neither 'short' nor 'int' are 16-bit.
141 /* Setting 'int32_t', its limits, its literal, and conversion macros. */
142 #if _PDCLIB_INT_BYTES == 4
143 typedef signed int _PDCLIB_int32_t;
144 typedef unsigned int _PDCLIB_uint32_t;
145 #define _PDCLIB_INT32_MAX _PDCLIB_INT_MAX
146 #define _PDCLIB_INT32_MIN _PDCLIB_INT_MIN
147 #define _PDCLIB_UINT32_MAX _PDCLIB_UINT_MAX
148 #define _PDCLIB_INT32_LITERAL
149 #define _PDCLIB_UINT32_LITERAL
150 #define _PDCLIB_32_CONV
151 #elif _PDCLIB_LONG_BYTES == 4
152 typedef signed long _PDCLIB_int32_t;
153 typedef unsigned long _PDCLIB_uint32_t;
154 #define _PDCLIB_INT32_MAX _PDCLIB_LONG_MAX
155 #define _PDCLIB_INT32_MIN _PDCLIB_LONG_MIN
156 #define _PDCLIB_UINT32_MAX _PDCLIB_LONG_MAX
157 #define _PDCLIB_INT32_LITERAL l
158 #define _PDCLIB_UINT32_LITERAL ul
159 #define _PDCLIB_32_CONV l
161 #error Neither 'int' nor 'long' are 32-bit.
164 /* Setting 'int64_t', its limits, its literal, and conversion macros. */
165 #if _PDCLIB_LONG_BYTES == 8 && !defined(_PDCLIB_INT64_IS_LLONG)
166 typedef signed long _PDCLIB_int64_t;
167 typedef unsigned long _PDCLIB_uint64_t;
168 #define _PDCLIB_INT64_MAX _PDCLIB_LONG_MAX
169 #define _PDCLIB_INT64_MIN _PDCLIB_LONG_MIN
170 #define _PDCLIB_UINT64_MAX _PDCLIB_ULONG_MAX
171 #define _PDCLIB_INT64_LITERAL l
172 #define _PDCLIB_UINT64_LITERAL ul
173 #define _PDCLIB_64_CONV l
174 #elif _PDCLIB_LLONG_BYTES == 8
175 typedef signed long long _PDCLIB_int64_t;
176 typedef unsigned long long _PDCLIB_uint64_t;
177 #define _PDCLIB_INT64_MAX _PDCLIB_LLONG_MAX
178 #define _PDCLIB_INT64_MIN _PDCLIB_LLONG_MIN
179 #define _PDCLIB_UINT64_MAX _PDCLIB_ULLONG_MAX
180 #define _PDCLIB_INT64_LITERAL ll
181 #define _PDCLIB_UINT64_LITERAL ull
182 #define _PDCLIB_64_CONV ll
184 #error Neither 'long' nor 'long long' are 64-bit.
187 /* -------------------------------------------------------------------------- */
188 /* <stdint.h> "fastest" types and their limits */
189 /* -------------------------------------------------------------------------- */
190 /* This is, admittedly, butt-ugly. But at least it's ugly where the average */
191 /* user of PDCLib will never see it, and makes <_PDCLIB_config.h> much */
193 /* -------------------------------------------------------------------------- */
195 typedef _PDCLIB_fast8 _PDCLIB_int_fast8_t;
196 typedef unsigned _PDCLIB_fast8 _PDCLIB_uint_fast8_t;
197 #define _PDCLIB_INT_FAST8_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MIN )
198 #define _PDCLIB_INT_FAST8_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MAX )
199 #define _PDCLIB_UINT_FAST8_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST8 ), _MAX )
201 typedef _PDCLIB_fast16 _PDCLIB_int_fast16_t;
202 typedef unsigned _PDCLIB_fast16 _PDCLIB_uint_fast16_t;
203 #define _PDCLIB_INT_FAST16_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MIN )
204 #define _PDCLIB_INT_FAST16_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MAX )
205 #define _PDCLIB_UINT_FAST16_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST16 ), _MAX )
207 typedef _PDCLIB_fast32 _PDCLIB_int_fast32_t;
208 typedef unsigned _PDCLIB_fast32 _PDCLIB_uint_fast32_t;
209 #define _PDCLIB_INT_FAST32_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MIN )
210 #define _PDCLIB_INT_FAST32_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MAX )
211 #define _PDCLIB_UINT_FAST32_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST32 ), _MAX )
213 typedef _PDCLIB_fast64 _PDCLIB_int_fast64_t;
214 typedef unsigned _PDCLIB_fast64 _PDCLIB_uint_fast64_t;
215 #define _PDCLIB_INT_FAST64_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MIN )
216 #define _PDCLIB_INT_FAST64_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MAX )
217 #define _PDCLIB_UINT_FAST64_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST64 ), _MAX )
219 /* -------------------------------------------------------------------------- */
220 /* Various <stddef.h> typedefs and limits */
221 /* -------------------------------------------------------------------------- */
223 typedef _PDCLIB_ptrdiff _PDCLIB_ptrdiff_t;
224 #define _PDCLIB_PTRDIFF_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MIN )
225 #define _PDCLIB_PTRDIFF_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MAX )
227 #define _PDCLIB_SIG_ATOMIC_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MIN )
228 #define _PDCLIB_SIG_ATOMIC_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MAX )
230 typedef _PDCLIB_size _PDCLIB_size_t;
231 #define _PDCLIB_SIZE_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIZE ), _MAX )
233 typedef _PDCLIB_wint _PDCLIB_wint_t;
235 typedef _PDCLIB_wchar _PDCLIB_wchar_t;
237 typedef wchar_t _PDCLIB_wchar_t;
239 #define _PDCLIB_WCHAR_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MIN )
240 #define _PDCLIB_WCHAR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MAX )
242 typedef _PDCLIB_intptr _PDCLIB_intptr_t;
243 typedef unsigned _PDCLIB_intptr _PDCLIB_uintptr_t;
244 #define _PDCLIB_INTPTR_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MIN )
245 #define _PDCLIB_INTPTR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MAX )
246 #define _PDCLIB_UINTPTR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTPTR ), _MAX )
248 typedef _PDCLIB_intmax _PDCLIB_intmax_t;
249 typedef unsigned _PDCLIB_intmax _PDCLIB_uintmax_t;
250 #define _PDCLIB_INTMAX_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MIN )
251 #define _PDCLIB_INTMAX_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MAX )
252 #define _PDCLIB_UINTMAX_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTMAX ), _MAX )
253 #define _PDCLIB_INTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_INTMAX_LITERAL )
254 #define _PDCLIB_UINTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_concat( u, _PDCLIB_INTMAX_LITERAL ) )
256 /* -------------------------------------------------------------------------- */
257 /* Various <time.h> internals */
258 /* -------------------------------------------------------------------------- */
260 typedef _PDCLIB_time _PDCLIB_time_t;
261 typedef _PDCLIB_clock _PDCLIB_clock_t;
263 #if !defined(_PDCLIB_DEFINE_STRUCT_TIMESPEC)
264 #define _PDCLIB_DEFINE_STRUCT_TIMESPEC() \
271 #if !defined(_PDCLIB_DEFINE_STRUCT_TM)
272 #define _PDCLIB_DEFINE_STRUCT_TM() \
286 /* -------------------------------------------------------------------------- */
287 /* Internal data types */
288 /* -------------------------------------------------------------------------- */
290 /* Structure required by both atexit() and exit() for handling atexit functions */
291 struct _PDCLIB_exitfunc_t
293 struct _PDCLIB_exitfunc_t * next;
294 void (*func)( void );
297 /* -------------------------------------------------------------------------- */
298 /* Declaration of helper functions (implemented in functions/_PDCLIB). */
299 /* -------------------------------------------------------------------------- */
301 /* This is the main function called by atoi(), atol() and atoll(). */
302 _PDCLIB_intmax_t _PDCLIB_atomax( const char * s );
304 /* Two helper functions used by strtol(), strtoul() and long long variants. */
305 const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base );
306 _PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, int limdigit, char * sign );
308 /* Digits arrays used by various integer conversion functions */
309 extern char _PDCLIB_digits[];
310 extern char _PDCLIB_Xdigits[];
312 /* -------------------------------------------------------------------------- */
314 /* -------------------------------------------------------------------------- */
316 /* If PDCLib would call its error number "errno" directly, there would be no way
317 to catch its value from underlying system calls that also use it (i.e., POSIX
318 operating systems). That is why we use an internal name, providing a means to
319 access it through <errno.h>.
321 extern int _PDCLIB_errno;
323 /* A mechanism for delayed evaluation. (Not sure if this is really necessary, so
324 no detailed documentation on the "why".)
326 int * _PDCLIB_errno_func( void ) _PDCLIB_nothrow;
328 /* -------------------------------------------------------------------------- */
329 /* locale / wchar / uchar */
330 /* -------------------------------------------------------------------------- */
333 typedef _PDCLIB_int16_t _PDCLIB_char16_t;
334 typedef _PDCLIB_int32_t _PDCLIB_char32_t;
336 typedef char16_t _PDCLIB_char16_t;
337 typedef char32_t _PDCLIB_char32_t;
340 typedef struct _PDCLIB_mbstate {
342 /* Is this the best way to represent this? Is this big enough? */
343 _PDCLIB_uint64_t _St64[15];
344 _PDCLIB_uint32_t _St32[31];
345 _PDCLIB_uint16_t _St16[62];
346 unsigned char _StUC[124];
347 signed char _StSC[124];
351 /* c16/related functions: Surrogate storage
353 * If zero, no surrogate pending. If nonzero, surrogate.
355 _PDCLIB_uint16_t _Surrogate;
357 /* In cases where the underlying codec is capable of regurgitating a
358 * character without consuming any extra input (e.g. a surrogate pair in a
359 * UCS-4 to UTF-16 conversion) then these fields are used to track that
360 * state. In particular, they are used to buffer/fake the input for mbrtowc
361 * and similar functions.
363 * See _PDCLIB_encoding.h for values of _PendState and the resultant value
366 unsigned char _PendState;
370 typedef struct _PDCLIB_charcodec *_PDCLIB_charcodec_t;
371 typedef struct _PDCLIB_locale *_PDCLIB_locale_t;
372 typedef struct lconv _PDCLIB_lconv_t;
374 _PDCLIB_size_t _PDCLIB_mb_cur_max( void );
376 /* -------------------------------------------------------------------------- */
378 /* -------------------------------------------------------------------------- */
380 /* Position / status structure for getpos() / fsetpos(). */
381 typedef struct _PDCLIB_fpos
383 _PDCLIB_int_fast64_t offset; /* File position offset */
384 _PDCLIB_mbstate_t mbs; /* Multibyte parsing state */
387 typedef struct _PDCLIB_fileops _PDCLIB_fileops_t;
388 typedef union _PDCLIB_fd _PDCLIB_fd_t;
389 typedef struct _PDCLIB_file _PDCLIB_file_t; // Rename to _PDCLIB_FILE?
391 /* Status structure required by _PDCLIB_print(). */
392 struct _PDCLIB_status_t
394 int base; /* base to which the value shall be converted */
395 _PDCLIB_int_fast32_t flags; /* flags and length modifiers */
396 unsigned n; /* print: maximum characters to be written */
397 /* scan: number matched conversion specifiers */
398 unsigned i; /* number of characters read/written */
399 unsigned current;/* chars read/written in the CURRENT conversion */
400 char * s; /* *sprintf(): target buffer */
401 /* *sscanf(): source string */
402 unsigned width; /* specified field width */
403 int prec; /* specified field precision */
404 _PDCLIB_file_t * stream; /* *fprintf() / *fscanf() stream */
405 _PDCLIB_va_list arg; /* argument stack */