]> pd.if.org Git - pdclib/blob - internals/_PDCLIB_int.h
Fix for #42 - free( NULL ) must not fail.
[pdclib] / internals / _PDCLIB_int.h
1 /* $Id$ */
2
3 /* PDCLib internal integer logic <_PDCLIB_int.h>
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 /* -------------------------------------------------------------------------- */
10 /* You should not have to edit anything in this file; if you DO have to, it   */
11 /* would be considered a bug / missing feature: notify the author(s).         */
12 /* -------------------------------------------------------------------------- */
13
14 #ifndef _PDCLIB_CONFIG_H
15 #define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
16 #include <_PDCLIB_config.h>
17 #endif
18
19 #ifndef _PDCLIB_AUX_H
20 #define _PDCLIB_AUX_H _PDCLIB_AUX_H
21 #include <_PDCLIB_aux.h>
22 #endif
23
24 /* null pointer constant */
25 #define _PDCLIB_NULL 0
26
27 /* -------------------------------------------------------------------------- */
28 /* Limits of native datatypes                                                 */
29 /* -------------------------------------------------------------------------- */
30 /* The definition of minimum limits for unsigned datatypes is done because    */
31 /* later on we will "construct" limits for other abstract types:              */
32 /* USHRT -> _PDCLIB_ + USHRT + _MIN -> _PDCLIB_USHRT_MIN -> 0                 */
33 /* INT -> _PDCLIB_ + INT + _MIN -> _PDCLIB_INT_MIN -> ... you get the idea.   */
34 /* -------------------------------------------------------------------------- */
35
36 /* Setting 'char' limits                                                      */
37 #define _PDCLIB_CHAR_BIT    8
38 #define _PDCLIB_UCHAR_MIN   0
39 #define _PDCLIB_UCHAR_MAX   0xff
40 #define _PDCLIB_SCHAR_MIN   (-0x7f - 1)
41 #define _PDCLIB_SCHAR_MAX   0x7f
42 #ifdef  _PDCLIB_CHAR_SIGNED
43 #define _PDCLIB_CHAR_MIN    _PDCLIB_SCHAR_MIN
44 #define _PDCLIB_CHAR_MAX    _PDCLIB_SCHAR_MAX
45 #else
46 #define _PDCLIB_CHAR_MIN    0
47 #define _PDCLIB_CHAR_MAX    _PDCLIB_UCHAR_MAX
48 #endif
49
50 /* Setting 'short' limits                                                     */
51 #if     _PDCLIB_SHRT_BYTES == 2
52 #define _PDCLIB_SHRT_MAX      0x7fff
53 #define _PDCLIB_SHRT_MIN      (-0x7fff - 1)
54 #define _PDCLIB_USHRT_MAX     0xffff
55 #else
56 #error Unsupported width of 'short' (not 16 bit).
57 #endif
58 #define _PDCLIB_USHRT_MIN 0
59
60 #if _PDCLIB_INT_BYTES < _PDCLIB_SHRT_BYTES
61 #error Bogus setting: short > int? Check _PDCLIB_config.h.
62 #endif
63
64 /* Setting 'int' limits                                                       */
65 #if     _PDCLIB_INT_BYTES == 2
66 #define _PDCLIB_INT_MAX   0x7fff
67 #define _PDCLIB_INT_MIN   (-0x7fff - 1)
68 #define _PDCLIB_UINT_MAX  0xffffU
69 #elif   _PDCLIB_INT_BYTES == 4
70 #define _PDCLIB_INT_MAX   0x7fffffff
71 #define _PDCLIB_INT_MIN   (-0x7fffffff - 1)
72 #define _PDCLIB_UINT_MAX  0xffffffffU
73 #elif _PDCLIB_INT_BYTES   == 8
74 #define _PDCLIB_INT_MAX   0x7fffffffffffffff
75 #define _PDCLIB_INT_MIN   (-0x7fffffffffffffff - 1)
76 #define _PDCLIB_UINT_MAX  0xffffffffffffffff
77 #else
78 #error Unsupported width of 'int' (neither 16, 32, nor 64 bit).
79 #endif
80 #define _PDCLIB_UINT_MIN 0
81
82 /* Setting 'long' limits                                                      */
83 #if   _PDCLIB_LONG_BYTES   == 4
84 #define _PDCLIB_LONG_MAX   0x7fffffffL
85 #define _PDCLIB_LONG_MIN   (-0x7fffffffL - 1L)
86 #define _PDCLIB_ULONG_MAX  0xffffffffUL
87 #elif   _PDCLIB_LONG_BYTES == 8
88 #define _PDCLIB_LONG_MAX   0x7fffffffffffffffL
89 #define _PDCLIB_LONG_MIN   (-0x7fffffffffffffffL - 1L)
90 #define _PDCLIB_ULONG_MAX  0xffffffffffffffffUL
91 #else
92 #error Unsupported width of 'long' (neither 32 nor 64 bit).
93 #endif
94 #define _PDCLIB_ULONG_MIN 0
95
96 /* Setting 'long long' limits                                                 */
97 #if _PDCLIB_LLONG_BYTES    == 8
98 #define _PDCLIB_LLONG_MAX  0x7fffffffffffffffLL
99 #define _PDCLIB_LLONG_MIN  (-0x7fffffffffffffffLL - 1LL)
100 #define _PDCLIB_ULLONG_MAX 0xffffffffffffffffULL
101 #elif _PDCLIB_LLONG_BYTES  == 16
102 #define _PDCLIB_LLONG_MAX  0x7fffffffffffffffffffffffffffffffLL
103 #define _PDCLIB_LLONG_MIN  (-0x7fffffffffffffffffffffffffffffffLL - 1LL)
104 #define _PDCLIB_ULLONG_MAX 0xffffffffffffffffffffffffffffffffULL
105 #else
106 #error Unsupported width of 'long long' (neither 64 nor 128 bit).
107 #endif
108 #define _PDCLIB_ULLONG_MIN 0
109
110 /* -------------------------------------------------------------------------- */
111 /* <stdint.h> exact-width types and their limits                              */
112 /* -------------------------------------------------------------------------- */
113 /* Note that, for the "standard" widths of 8, 16, 32 and 64 bit, the "LEAST"  */
114 /* types are identical to the "exact-width" types, by definition.             */
115
116 /* Setting 'int8_t', its limits, its literal, and conversion macros.          */
117 #if     _PDCLIB_CHAR_BIT == 8
118 typedef signed char        _PDCLIB_int8_t;
119 typedef unsigned char      _PDCLIB_uint8_t;
120 #define _PDCLIB_INT8_MAX   _PDCLIB_CHAR_MAX
121 #define _PDCLIB_INT8_MIN   _PDCLIB_CHAR_MIN
122 #define _PDCLIB_UINT8_MAX  _PDCLIB_UCHAR_MAX
123 #define _PDCLIB_8_CONV     hh
124 #else
125 #error Unsupported width of char (not 8 bits).
126 #endif
127
128 /* Setting 'int16_t', its limits, its literal, and conversion macros.         */
129 #if     _PDCLIB_INT_BYTES  == 2
130 typedef signed int         _PDCLIB_int16_t;
131 typedef unsigned int       _PDCLIB_uint16_t;
132 #define _PDCLIB_INT16_MAX  _PDCLIB_INT_MAX
133 #define _PDCLIB_INT16_MIN  _PDCLIB_INT_MIN
134 #define _PDCLIB_UINT16_MAX _PDCLIB_UINT_MAX
135 #define _PDCLIB_16_CONV
136 #elif   _PDCLIB_SHRT_BYTES == 2
137 typedef signed short       _PDCLIB_int16_t;
138 typedef unsigned short     _PDCLIB_uint16_t;
139 #define _PDCLIB_INT16_MAX  _PDCLIB_SHRT_MAX
140 #define _PDCLIB_INT16_MIN  _PDCLIB_SHRT_MIN
141 #define _PDCLIB_UINT16_MAX _PDCLIB_USHRT_MAX
142 #define _PDCLIB_16_CONV    h
143 #else
144 #error Neither 'short' nor 'int' are 16-bit.
145 #endif
146
147 /* Setting 'int32_t', its limits, its literal, and conversion macros.         */
148 #if     _PDCLIB_INT_BYTES  == 4
149 typedef signed int         _PDCLIB_int32_t;
150 typedef unsigned int       _PDCLIB_uint32_t;
151 #define _PDCLIB_INT32_MAX  _PDCLIB_INT_MAX
152 #define _PDCLIB_INT32_MIN  _PDCLIB_INT_MIN
153 #define _PDCLIB_UINT32_MAX _PDCLIB_UINT_MAX
154 #define _PDCLIB_INT32_LITERAL
155 #define _PDCLIB_UINT32_LITERAL
156 #define _PDCLIB_32_CONV
157 #elif   _PDCLIB_LONG_BYTES == 4
158 typedef signed long        _PDCLIB_int32_t;
159 typedef unsigned long      _PDCLIB_uint32_t;
160 #define _PDCLIB_INT32_MAX  _PDCLIB_LONG_MAX
161 #define _PDCLIB_INT32_MIN  _PDCLIB_LONG_MIN
162 #define _PDCLIB_UINT32_MAX _PDCLIB_LONG_MAX
163 #define _PDCLIB_INT32_LITERAL  l
164 #define _PDCLIB_UINT32_LITERAL ul
165 #define _PDCLIB_32_CONV        l
166 #else
167 #error Neither 'int' nor 'long' are 32-bit.
168 #endif
169
170 /* Setting 'int64_t', its limits, its literal, and conversion macros.         */
171 #if     _PDCLIB_LONG_BYTES == 8
172 typedef signed long        _PDCLIB_int64_t;
173 typedef unsigned long      _PDCLIB_uint64_t;
174 #define _PDCLIB_INT64_MAX  _PDCLIB_LONG_MAX
175 #define _PDCLIB_INT64_MIN  _PDCLIB_LONG_MIN
176 #define _PDCLIB_UINT64_MAX  _PDCLIB_ULONG_MAX
177 #define _PDCLIB_INT64_LITERAL  l
178 #define _PDCLIB_UINT64_LITERAL ul
179 #define _PDCLIB_64_CONV        l
180 #elif _PDCLIB_LLONG_BYTES  == 8
181 typedef signed long long   _PDCLIB_int64_t;
182 typedef unsigned long long _PDCLIB_uint64_t;
183 #define _PDCLIB_INT64_MAX  _PDCLIB_LLONG_MAX
184 #define _PDCLIB_INT64_MIN  _PDCLIB_LLONG_MIN
185 #define _PDCLIB_UINT64_MAX  _PDCLIB_ULLONG_MAX
186 #define _PDCLIB_INT64_LITERAL  ll
187 #define _PDCLIB_UINT64_LITERAL ull
188 #define _PDCLIB_64_CONV        ll
189 #else
190 #error Neither 'long' nor 'long long' are 64-bit.
191 #endif
192
193 /* -------------------------------------------------------------------------- */
194 /* <stdint.h> "fastest" types and their limits                                */
195 /* -------------------------------------------------------------------------- */
196 /* This is, admittedly, butt-ugly. But at least it's ugly where the average   */
197 /* user of PDCLib will never see it, and makes <_PDCLIB_config.h> much        */
198 /* cleaner.                                                                   */
199 /* -------------------------------------------------------------------------- */
200
201 typedef _PDCLIB_fast8          _PDCLIB_int_fast8_t;
202 typedef unsigned _PDCLIB_fast8 _PDCLIB_uint_fast8_t;
203 #define _PDCLIB_INT_FAST8_MIN  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MIN )
204 #define _PDCLIB_INT_FAST8_MAX  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MAX )
205 #define _PDCLIB_UINT_FAST8_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST8 ), _MAX )
206
207 typedef _PDCLIB_fast16          _PDCLIB_int_fast16_t;
208 typedef unsigned _PDCLIB_fast16 _PDCLIB_uint_fast16_t;
209 #define _PDCLIB_INT_FAST16_MIN  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MIN )
210 #define _PDCLIB_INT_FAST16_MAX  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MAX )
211 #define _PDCLIB_UINT_FAST16_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST16 ), _MAX )
212
213 typedef _PDCLIB_fast32          _PDCLIB_int_fast32_t;
214 typedef unsigned _PDCLIB_fast32 _PDCLIB_uint_fast32_t;
215 #define _PDCLIB_INT_FAST32_MIN  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MIN )
216 #define _PDCLIB_INT_FAST32_MAX  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MAX )
217 #define _PDCLIB_UINT_FAST32_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST32 ), _MAX )
218
219 typedef _PDCLIB_fast64          _PDCLIB_int_fast64_t;
220 typedef unsigned _PDCLIB_fast64 _PDCLIB_uint_fast64_t;
221 #define _PDCLIB_INT_FAST64_MIN  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MIN )
222 #define _PDCLIB_INT_FAST64_MAX  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MAX )
223 #define _PDCLIB_UINT_FAST64_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST64 ), _MAX )
224
225 /* -------------------------------------------------------------------------- */
226 /* Various <stddef.h> typedefs and limits                                     */
227 /* -------------------------------------------------------------------------- */
228
229 typedef _PDCLIB_ptrdiff     _PDCLIB_ptrdiff_t;
230 #define _PDCLIB_PTRDIFF_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MIN )
231 #define _PDCLIB_PTRDIFF_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MAX )
232
233 #define _PDCLIB_SIG_ATOMIC_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MIN )
234 #define _PDCLIB_SIG_ATOMIC_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MAX )
235
236 typedef _PDCLIB_size     _PDCLIB_size_t;
237 #define _PDCLIB_SIZE_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIZE ), _MAX )
238
239 typedef _PDCLIB_wchar     _PDCLIB_wchar_t;
240 #define _PDCLIB_WCHAR_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MIN )
241 #define _PDCLIB_WCHAR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MAX )
242
243 typedef _PDCLIB_intptr          _PDCLIB_intptr_t;
244 typedef unsigned _PDCLIB_intptr _PDCLIB_uintptr_t;
245 #define _PDCLIB_INTPTR_MIN  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MIN )
246 #define _PDCLIB_INTPTR_MAX  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MAX )
247 #define _PDCLIB_UINTPTR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTPTR ), _MAX )
248
249 typedef _PDCLIB_intmax          _PDCLIB_intmax_t;
250 typedef unsigned _PDCLIB_intmax _PDCLIB_uintmax_t;
251 #define _PDCLIB_INTMAX_MIN  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MIN )
252 #define _PDCLIB_INTMAX_MAX  _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MAX )
253 #define _PDCLIB_UINTMAX_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTMAX ), _MAX )
254 #define _PDCLIB_INTMAX_C( value )  _PDCLIB_concat( value, _PDCLIB_INTMAX_LITERAL )
255 #define _PDCLIB_UINTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_concat( u, _PDCLIB_INTMAX_LITERAL ) )
256
257 /* -------------------------------------------------------------------------- */
258 /* Various <stdio.h> internals                                                */
259 /* -------------------------------------------------------------------------- */
260
261 /* Flags for representing mode (see fopen()). Note these must fit the same
262    status field as the _IO?BF flags in <stdio.h> and the internal flags below.
263 */
264 #define _PDCLIB_FREAD     8u
265 #define _PDCLIB_FWRITE   16u
266 #define _PDCLIB_FAPPEND  32u 
267 #define _PDCLIB_FRW      64u
268 #define _PDCLIB_FBIN    128u
269
270 /* Internal flags, made to fit the same status field as the flags above. */
271 /* -------------------------------------------------------------------------- */
272 /* free() the buffer memory on closing (false for user-supplied buffer) */
273 #define _PDCLIB_FREEBUFFER   512u
274 /* stream has encountered error / EOF */
275 #define _PDCLIB_ERRORFLAG   1024u
276 #define _PDCLIB_EOFFLAG     2048u
277 /* stream is wide-oriented */
278 #define _PDCLIB_WIDESTREAM  4096u
279 /* stream is byte-oriented */
280 #define _PDCLIB_BYTESTREAM  8192u
281 /* file associated with stream should be remove()d on closing (tmpfile()) */
282 #define _PDCLIB_DELONCLOSE 16384u
283 /* stream handle should not be free()d on close (stdin, stdout, stderr) */
284 #define _PDCLIB_STATIC     32768u
285
286 /* Position / status structure for getpos() / fsetpos(). */
287 struct _PDCLIB_fpos_t
288 {
289     _PDCLIB_uint64_t offset; /* File position offset */
290     int              status; /* Multibyte parsing state (unused, reserved) */
291 };
292
293 /* FILE structure */
294 struct _PDCLIB_file_t
295 {
296     _PDCLIB_fd_t            handle;   /* OS file handle */
297     char *                  buffer;   /* Pointer to buffer memory */
298     _PDCLIB_size_t          bufsize;  /* Size of buffer */
299     _PDCLIB_size_t          bufidx;   /* Index of current position in buffer */
300     _PDCLIB_size_t          bufend;   /* Index of last pre-read character in buffer */
301     struct _PDCLIB_fpos_t   pos;      /* Offset and multibyte parsing state */
302     _PDCLIB_size_t          ungetidx; /* Number of ungetc()'ed characters */
303     unsigned char *         ungetbuf; /* ungetc() buffer */
304     unsigned int            status;   /* Status flags; see above */
305     /* multibyte parsing status to be added later */
306     char *                  filename; /* Name the current stream has been opened with */
307     struct _PDCLIB_file_t * next;     /* Pointer to next struct (internal) */
308 };
309
310 /* -------------------------------------------------------------------------- */
311 /* Internal data types                                                        */
312 /* -------------------------------------------------------------------------- */
313
314 /* Structure required by both atexit() and exit() for handling atexit functions */
315 struct _PDCLIB_exitfunc_t
316 {
317     struct _PDCLIB_exitfunc_t * next;
318     void (*func)( void );
319 };
320
321 /* Structures required by malloc(), realloc(), and free(). */
322 struct _PDCLIB_headnode_t
323 {
324     struct _PDCLIB_memnode_t * first;
325     struct _PDCLIB_memnode_t * last;
326 };
327
328 struct _PDCLIB_memnode_t
329 {
330     _PDCLIB_size_t size;
331     struct _PDCLIB_memnode_t * next;
332 };
333
334 /* Status structure required by _PDCLIB_print(). */
335 struct _PDCLIB_status_t
336 {
337     int              base;   /* base to which the value shall be converted   */
338     _PDCLIB_int_fast32_t flags; /* flags and length modifiers                */
339     _PDCLIB_size_t   n;      /* print: maximum characters to be written      */
340                              /* scan:  number matched conversion specifiers  */
341     _PDCLIB_size_t   i;      /* number of characters read/written            */
342     _PDCLIB_size_t   current;/* chars read/written in the CURRENT conversion */
343     char *           s;      /* *sprintf(): target buffer                    */
344                              /* *sscanf():  source string                    */
345     _PDCLIB_size_t   width;  /* specified field width                        */
346     _PDCLIB_size_t   prec;   /* specified field precision                    */
347     struct _PDCLIB_file_t * stream; /* *fprintf() / *fscanf() stream         */
348     _PDCLIB_va_list  arg;    /* argument stack                               */
349 };
350
351 /* -------------------------------------------------------------------------- */
352 /* Declaration of helper functions (implemented in functions/_PDCLIB).        */
353 /* -------------------------------------------------------------------------- */
354
355 /* This is the main function called by atoi(), atol() and atoll().            */
356 _PDCLIB_intmax_t _PDCLIB_atomax( const char * s );
357
358 /* Two helper functions used by strtol(), strtoul() and long long variants.   */
359 const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base );
360 _PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, int limdigit, char * sign );
361
362 /* Digits arrays used by various integer conversion functions */
363 extern char _PDCLIB_digits[];
364 extern char _PDCLIB_Xdigits[];
365
366 /* The worker for all printf() type of functions. The pointer spec should point
367    to the introducing '%' of a conversion specifier. The status structure is to
368    be that of the current printf() function, of which the members n, s, stream
369    and arg will be preserved; i will be updated; and all others will be trashed
370    by the function.
371    Returns a pointer to the first character not parsed as conversion specifier.
372 */
373 const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );
374
375 /* The worker for all scanf() type of functions. The pointer spec should point
376    to the introducing '%' of a conversion specifier. The status structure is to
377    be that of the current scanf() function, of which the member stream will be
378    preserved; n, i, and s will be updated; and all others will be trashed by
379    the function.
380    Returns a pointer to the first character not parsed as conversion specifier,
381    or NULL in case of error.
382    FIXME: Should distinguish between matching and input error
383 */
384 const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status );
385
386 /* Parsing any fopen() style filemode string into a number of flags. */
387 unsigned int _PDCLIB_filemode( const char * mode );
388
389 /* Sanity checking and preparing of read buffer, should be called first thing 
390    by any stdio read-data function.
391    Returns 0 on success, EOF on error.
392    On error, EOF / error flags and errno are set appropriately.
393 */
394 int _PDCLIB_prepread( struct _PDCLIB_file_t * stream );
395
396 /* Sanity checking, should be called first thing by any stdio write-data
397    function.
398    Returns 0 on success, EOF on error.
399    On error, error flags and errno are set appropriately.
400 */
401 int _PDCLIB_prepwrite( struct _PDCLIB_file_t * stream );
402
403 /* Closing all streams on program exit */
404 void _PDCLIB_closeall( void );
405
406 /* -------------------------------------------------------------------------- */
407 /* errno                                                                      */
408 /* -------------------------------------------------------------------------- */
409
410 /* If PDCLib would call its error number "errno" directly, there would be no way
411    to catch its value from underlying system calls that also use it (i.e., POSIX
412    operating systems). That is why we use an internal name, providing a means to
413    access it through <errno.h>.
414 */
415 extern int _PDCLIB_errno;
416
417 /* A mechanism for delayed evaluation. (Not sure if this is really necessary, so
418    no detailed documentation on the "why".)
419 */
420 int * _PDCLIB_errno_func( void );
421
422 /* -------------------------------------------------------------------------- */
423 /* <ctype.h> lookup tables                                                    */
424 /* -------------------------------------------------------------------------- */
425
426 #define _PDCLIB_CTYPE_ALPHA   1
427 #define _PDCLIB_CTYPE_BLANK   2
428 #define _PDCLIB_CTYPE_CNTRL   4
429 #define _PDCLIB_CTYPE_GRAPH   8
430 #define _PDCLIB_CTYPE_PUNCT  16
431 #define _PDCLIB_CTYPE_SPACE  32
432 #define _PDCLIB_CTYPE_LOWER  64
433 #define _PDCLIB_CTYPE_UPPER 128
434 #define _PDCLIB_CTYPE_DIGIT 256
435 #define _PDCLIB_CTYPE_XDIGT 512
436
437 struct _PDCLIB_ctype_t
438 {
439     _PDCLIB_uint16_t flags;
440     unsigned char upper;
441     unsigned char lower;
442     unsigned char collation;
443 };
444