aboutsummaryrefslogtreecommitdiffstats
path: root/src/pdclib/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdclib/include')
-rw-r--r--src/pdclib/include/assert.h35
-rw-r--r--src/pdclib/include/ctype.h95
-rw-r--r--src/pdclib/include/errno.h17
-rw-r--r--src/pdclib/include/inttypes.h249
-rw-r--r--src/pdclib/include/iso646.h22
-rw-r--r--src/pdclib/include/limits.h35
-rw-r--r--src/pdclib/include/locale.h99
-rw-r--r--src/pdclib/include/pdclib/_PDCLIB_aux.h65
-rw-r--r--src/pdclib/include/pdclib/_PDCLIB_glue.h71
-rw-r--r--src/pdclib/include/pdclib/_PDCLIB_int.h582
-rw-r--r--src/pdclib/include/stdalign.h17
-rw-r--r--src/pdclib/include/stdarg.h19
-rw-r--r--src/pdclib/include/stdbool.h15
-rw-r--r--src/pdclib/include/stddef.h28
-rw-r--r--src/pdclib/include/stdint.h207
-rw-r--r--src/pdclib/include/stdio.h786
-rw-r--r--src/pdclib/include/stdlib.h242
-rw-r--r--src/pdclib/include/stdnoreturn.h12
-rw-r--r--src/pdclib/include/string.h185
-rw-r--r--src/pdclib/include/time.h112
-rw-r--r--src/pdclib/include/wctype.h138
21 files changed, 3031 insertions, 0 deletions
diff --git a/src/pdclib/include/assert.h b/src/pdclib/include/assert.h
new file mode 100644
index 0000000..a5c1a8e
--- /dev/null
+++ b/src/pdclib/include/assert.h
@@ -0,0 +1,35 @@
+/* Diagnostics <assert.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include "pdclib/_PDCLIB_aux.h"
+
+#ifndef _PDCLIB_ASSERT_H
+#define _PDCLIB_ASSERT_H _PDCLIB_ASSERT_H
+void _PDCLIB_assert99( const char * const, const char * const, const char * const );
+void _PDCLIB_assert89( const char * const );
+#endif
+
+/* If NDEBUG is set, assert() is a null operation. */
+#undef assert
+
+#ifdef NDEBUG
+#define assert( ignore ) ( (void) 0 )
+#else
+#if __STDC_VERSION__ >= 199901L
+#define assert( expression ) ( ( expression ) ? (void) 0 \
+ : _PDCLIB_assert99( "Assertion failed: " #expression \
+ ", function ", __func__, \
+ ", file " __FILE__ \
+ ", line " _PDCLIB_symbol2string( __LINE__ ) \
+ "." _PDCLIB_endl ) )
+#else
+#define assert( expression ) ( ( expression ) ? (void) 0 \
+ : _PDCLIB_assert89( "Assertion failed: " #expression \
+ ", file " __FILE__ \
+ ", line " _PDCLIB_symbol2string( __LINE__ ) \
+ "." _PDCLIB_endl ) )
+#endif
+#endif
diff --git a/src/pdclib/include/ctype.h b/src/pdclib/include/ctype.h
new file mode 100644
index 0000000..07fad9c
--- /dev/null
+++ b/src/pdclib/include/ctype.h
@@ -0,0 +1,95 @@
+/* Character handling <ctype.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_CTYPE_H
+#define _PDCLIB_CTYPE_H _PDCLIB_CTYPE_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+/* Character classification functions */
+
+/* Note that there is a difference between "whitespace" (any printing, non-
+ graph character, like horizontal and vertical tab), and "blank" (the literal
+ ' ' space character).
+
+ There will be masking macros for each of these later on, but right now I
+ focus on the functions only.
+*/
+
+/* Returns isalpha( c ) || isdigit( c ) */
+int isalnum( int c );
+
+/* Returns isupper( c ) || islower( c ) in the "C" locale.
+ In any other locale, also returns true for a locale-specific set of
+ alphabetic characters which are neither control characters, digits,
+ punctation, or whitespace.
+*/
+int isalpha( int c );
+
+/* Returns true if the character isspace() and used for seperating words within
+ a line of text. In the "C" locale, only ' ' and '\t' are considered blanks.
+*/
+int isblank( int c );
+
+/* Returns true if the character is a control character. */
+int iscntrl( int c );
+
+/* Returns true if the character is a decimal digit. Locale-independent. */
+int isdigit( int c );
+
+/* Returns true for every printing character except space (' ').
+ NOTE: This definition differs from that of iswgraph() in <wctype.h>,
+ which considers any iswspace() character, not only ' '.
+*/
+int isgraph( int c );
+
+/* Returns true for lowercase letters in the "C" locale.
+ In any other locale, also returns true for a locale-specific set of
+ characters which are neither control characters, digits, punctation, or
+ space (' '). In a locale other than the "C" locale, a character might test
+ true for both islower() and isupper().
+*/
+int islower( int c );
+
+/* Returns true for every printing character including space (' '). */
+int isprint( int c );
+
+/* Returns true for a locale-specific set of punctuation charcters; these
+ may not be whitespace or alphanumeric. In the "C" locale, returns true
+ for every printing character that is not whitespace or alphanumeric.
+*/
+int ispunct( int c );
+
+/* Returns true for every standard whitespace character (' ', '\f', '\n', '\r',
+ '\t', '\v') in the "C" locale. In any other locale, also returns true for a
+ locale-specific set of characters for which isalnum() is false.
+*/
+int isspace( int c );
+
+/* Returns true for uppercase letters in the "C" locale.
+ In any other locale, also returns true for a locale-specific set of
+ characters which are neither control characters, digits, punctation, or
+ space (' '). In a locale other than the "C" locale, a character might test
+ true for both islower() and isupper().
+*/
+int isupper( int c );
+
+/* Returns true for any hexadecimal-digit character. Locale-independent. */
+int isxdigit( int c );
+
+/* Character case mapping functions */
+
+/* Converts an uppercase letter to a corresponding lowercase letter. Input that
+ is not an uppercase letter remains unchanged.
+*/
+int tolower( int c );
+
+/* Converts a lowercase letter to a corresponding uppercase letter. Input that
+ is not a lowercase letter remains unchanged.
+*/
+int toupper( int c );
+
+#endif
diff --git a/src/pdclib/include/errno.h b/src/pdclib/include/errno.h
new file mode 100644
index 0000000..bdc99aa
--- /dev/null
+++ b/src/pdclib/include/errno.h
@@ -0,0 +1,17 @@
+/* Errors <errno.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_ERRNO_H
+#define _PDCLIB_ERRNO_H _PDCLIB_ERRNO_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+#define errno (*_PDCLIB_errno_func())
+
+#define ERANGE _PDCLIB_ERANGE
+#define EDOM _PDCLIB_EDOM
+
+#endif
diff --git a/src/pdclib/include/inttypes.h b/src/pdclib/include/inttypes.h
new file mode 100644
index 0000000..5252937
--- /dev/null
+++ b/src/pdclib/include/inttypes.h
@@ -0,0 +1,249 @@
+/* Format conversion of integer types <inttypes.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_INTTYPES_H
+#define _PDCLIB_INTTYPES_H _PDCLIB_INTTYPES_H
+
+#include <stdint.h>
+
+typedef struct _PDCLIB_imaxdiv_t imaxdiv_t;
+
+#define PRId8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
+#define PRId16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
+#define PRId32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
+#define PRId64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
+
+#define PRIdLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
+#define PRIdLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
+#define PRIdLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
+#define PRIdLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
+
+#define PRIdFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, d ) )
+#define PRIdFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, d ) )
+#define PRIdFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, d ) )
+#define PRIdFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, d ) )
+
+#define PRIdMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, d ) )
+#define PRIdPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, d ) )
+
+#define PRIi8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
+#define PRIi16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
+#define PRIi32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
+#define PRIi64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
+
+#define PRIiLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
+#define PRIiLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
+#define PRIiLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
+#define PRIiLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
+
+#define PRIiFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, i ) )
+#define PRIiFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, i ) )
+#define PRIiFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, i ) )
+#define PRIiFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, i ) )
+
+#define PRIiMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, i ) )
+#define PRIiPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, i ) )
+
+#define PRIo8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
+#define PRIo16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
+#define PRIo32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
+#define PRIo64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
+
+#define PRIoLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
+#define PRIoLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
+#define PRIoLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
+#define PRIoLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
+
+#define PRIoFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, o ) )
+#define PRIoFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, o ) )
+#define PRIoFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, o ) )
+#define PRIoFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, o ) )
+
+#define PRIoMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, o ) )
+#define PRIoPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, o ) )
+
+#define PRIu8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
+#define PRIu16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
+#define PRIu32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
+#define PRIu64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
+
+#define PRIuLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
+#define PRIuLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
+#define PRIuLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
+#define PRIuLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
+
+#define PRIuFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, u ) )
+#define PRIuFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, u ) )
+#define PRIuFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, u ) )
+#define PRIuFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, u ) )
+
+#define PRIuMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, u ) )
+#define PRIuPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, u ) )
+
+#define PRIx8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
+#define PRIx16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
+#define PRIx32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
+#define PRIx64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
+
+#define PRIxLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
+#define PRIxLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
+#define PRIxLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
+#define PRIxLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
+
+#define PRIxFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, x ) )
+#define PRIxFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, x ) )
+#define PRIxFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, x ) )
+#define PRIxFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, x ) )
+
+#define PRIxMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, x ) )
+#define PRIxPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, x ) )
+
+#define PRIX8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, X ) )
+#define PRIX16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, X ) )
+#define PRIX32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, X ) )
+#define PRIX64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, X ) )
+
+#define PRIXLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, X ) )
+#define PRIXLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, X ) )
+#define PRIXLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, X ) )
+#define PRIXLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, X ) )
+
+#define PRIXFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, X ) )
+#define PRIXFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, X ) )
+#define PRIXFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, X ) )
+#define PRIXFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, X ) )
+
+#define PRIXMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, X ) )
+#define PRIXPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, X ) )
+
+#define SCNd8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
+#define SCNd16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
+#define SCNd32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
+#define SCNd64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
+
+#define SCNdLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
+#define SCNdLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
+#define SCNdLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
+#define SCNdLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
+
+#define SCNdFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, d ) )
+#define SCNdFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, d ) )
+#define SCNdFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, d ) )
+#define SCNdFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, d ) )
+
+#define SCNdMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, d ) )
+#define SCNdPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, d ) )
+
+#define SCNi8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
+#define SCNi16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
+#define SCNi32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
+#define SCNi64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
+
+#define SCNiLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
+#define SCNiLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
+#define SCNiLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
+#define SCNiLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
+
+#define SCNiFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, i ) )
+#define SCNiFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, i ) )
+#define SCNiFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, i ) )
+#define SCNiFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, i ) )
+
+#define SCNiMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, i ) )
+#define SCNiPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, i ) )
+
+#define SCNo8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
+#define SCNo16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
+#define SCNo32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
+#define SCNo64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
+
+#define SCNoLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
+#define SCNoLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
+#define SCNoLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
+#define SCNoLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
+
+#define SCNoFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, o ) )
+#define SCNoFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, o ) )
+#define SCNoFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, o ) )
+#define SCNoFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, o ) )
+
+#define SCNoMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, o ) )
+#define SCNoPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, o ) )
+
+#define SCNu8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
+#define SCNu16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
+#define SCNu32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
+#define SCNu64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
+
+#define SCNuLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
+#define SCNuLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
+#define SCNuLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
+#define SCNuLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
+
+#define SCNuFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, u ) )
+#define SCNuFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, u ) )
+#define SCNuFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, u ) )
+#define SCNuFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, u ) )
+
+#define SCNuMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, u ) )
+#define SCNuPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, u ) )
+
+#define SCNx8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
+#define SCNx16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
+#define SCNx32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
+#define SCNx64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
+
+#define SCNxLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
+#define SCNxLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
+#define SCNxLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
+#define SCNxLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
+
+#define SCNxFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, x ) )
+#define SCNxFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, x ) )
+#define SCNxFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, x ) )
+#define SCNxFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, x ) )
+
+#define SCNxMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, x ) )
+#define SCNxPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, x ) )
+
+/* 7.8.2 Functions for greatest-width integer types */
+
+/* Calculate the absolute value of j */
+intmax_t imaxabs( intmax_t j );
+
+/* Return quotient (quot) and remainder (rem) of an integer division in the
+ imaxdiv_t struct.
+*/
+imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom );
+
+/* Seperate the character array nptr into three parts: A (possibly empty)
+ sequence of whitespace characters, a character representation of an integer
+ to the given base, and trailing invalid characters (including the terminating
+ null character). If base is 0, assume it to be 10, unless the integer
+ representation starts with 0x / 0X (setting base to 16) or 0 (setting base to
+ 8). If given, base can be anything from 0 to 36, using the 26 letters of the
+ base alphabet (both lowercase and uppercase) as digits 10 through 35.
+ The integer representation is then converted into the return type of the
+ function. It can start with a '+' or '-' sign. If the sign is '-', the result
+ of the conversion is negated.
+ If the conversion is successful, the converted value is returned. If endptr
+ is not a NULL pointer, a pointer to the first trailing invalid character is
+ returned in *endptr.
+ If no conversion could be performed, zero is returned (and nptr in *endptr,
+ if endptr is not a NULL pointer). If the converted value does not fit into
+ the return type, the functions return INTMAX_MIN, INTMAX_MAX, or UINTMAX_MAX,
+ respectively, depending on the sign of the integer representation and the
+ return type, and errno is set to ERANGE.
+*/
+/* This function is equivalent to strtol() / strtoul() in <stdlib.h>, but on
+ the potentially larger type.
+*/
+intmax_t strtoimax( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base );
+uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base );
+
+/* TODO: wcstoimax(), wcstoumax() */
+
+#endif
diff --git a/src/pdclib/include/iso646.h b/src/pdclib/include/iso646.h
new file mode 100644
index 0000000..98a023f
--- /dev/null
+++ b/src/pdclib/include/iso646.h
@@ -0,0 +1,22 @@
+/* Alternative spellings <iso646.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_ISO646_H
+#define _PDCLIB_ISO646_H _PDCLIB_ISO646_H
+
+#define and &&
+#define and_eq &=
+#define bitand &
+#define bitor |
+#define compl ~
+#define not !
+#define not_eq !=
+#define or ||
+#define or_eq |=
+#define xor ^
+#define xor_eq ^=
+
+#endif
diff --git a/src/pdclib/include/limits.h b/src/pdclib/include/limits.h
new file mode 100644
index 0000000..4349acd
--- /dev/null
+++ b/src/pdclib/include/limits.h
@@ -0,0 +1,35 @@
+/* Sizes of integer types <limits.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_LIMITS_H
+#define _PDCLIB_LIMITS_H _PDCLIB_LIMITS_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+/* TODO: Defined to 1 as multibyte characters are not supported yet. */
+#define MB_LEN_MAX 1
+
+#define LLONG_MIN _PDCLIB_LLONG_MIN
+#define LLONG_MAX _PDCLIB_LLONG_MAX
+#define ULLONG_MAX _PDCLIB_ULLONG_MAX
+
+#define CHAR_BIT _PDCLIB_CHAR_BIT
+#define CHAR_MAX _PDCLIB_CHAR_MAX
+#define CHAR_MIN _PDCLIB_CHAR_MIN
+#define SCHAR_MAX _PDCLIB_SCHAR_MAX
+#define SCHAR_MIN _PDCLIB_SCHAR_MIN
+#define UCHAR_MAX _PDCLIB_UCHAR_MAX
+#define SHRT_MAX _PDCLIB_SHRT_MAX
+#define SHRT_MIN _PDCLIB_SHRT_MIN
+#define INT_MAX _PDCLIB_INT_MAX
+#define INT_MIN _PDCLIB_INT_MIN
+#define LONG_MAX _PDCLIB_LONG_MAX
+#define LONG_MIN _PDCLIB_LONG_MIN
+#define USHRT_MAX _PDCLIB_USHRT_MAX
+#define UINT_MAX _PDCLIB_UINT_MAX
+#define ULONG_MAX _PDCLIB_ULONG_MAX
+
+#endif
diff --git a/src/pdclib/include/locale.h b/src/pdclib/include/locale.h
new file mode 100644
index 0000000..c8467a8
--- /dev/null
+++ b/src/pdclib/include/locale.h
@@ -0,0 +1,99 @@
+/* Localization <locale.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_LOCALE_H
+#define _PDCLIB_LOCALE_H _PDCLIB_LOCALE_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+#ifndef _PDCLIB_NULL_DEFINED
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
+#define NULL _PDCLIB_NULL
+#endif
+
+/* The structure returned by localeconv().
+
+ The values for *_sep_by_space:
+ 0 - no space
+ 1 - if symbol and sign are adjacent, a space seperates them from the value;
+ otherwise a space seperates the symbol from the value
+ 2 - if symbol and sign are adjacent, a space seperates them; otherwise a
+ space seperates the sign from the value
+
+ The values for *_sign_posn:
+ 0 - Parentheses surround value and symbol
+ 1 - sign precedes value and symbol
+ 2 - sign succeeds value and symbol
+ 3 - sign immediately precedes symbol
+ 4 - sign immediately succeeds symbol
+*/
+struct lconv
+{
+ char * decimal_point; /* decimal point character */ /* LC_NUMERIC */
+ char * thousands_sep; /* character for seperating groups of digits */ /* LC_NUMERIC */
+ char * grouping; /* string indicating the size of digit groups */ /* LC_NUMERIC */
+ char * mon_decimal_point; /* decimal point for monetary quantities */ /* LC_MONETARY */
+ char * mon_thousands_sep; /* thousands_sep for monetary quantities */ /* LC_MONETARY */
+ char * mon_grouping; /* grouping for monetary quantities */ /* LC_MONETARY */
+ char * positive_sign; /* string indicating nonnegative mty. qty. */ /* LC_MONETARY */
+ char * negative_sign; /* string indicating negative mty. qty. */ /* LC_MONETARY */
+ char * currency_symbol; /* local currency symbol (e.g. '$') */ /* LC_MONETARY */
+ char * int_curr_symbol; /* international currency symbol (e.g. "USD" */ /* LC_MONETARY */
+ char frac_digits; /* fractional digits in local monetary qty. */ /* LC_MONETARY */
+ char p_cs_precedes; /* if currency_symbol precedes positive qty. */ /* LC_MONETARY */
+ char n_cs_precedes; /* if currency_symbol precedes negative qty. */ /* LC_MONETARY */
+ char p_sep_by_space; /* if it is seperated by space from pos. qty. */ /* LC_MONETARY */
+ char n_sep_by_space; /* if it is seperated by space from neg. qty. */ /* LC_MONETARY */
+ char p_sign_posn; /* positioning of positive_sign for mon. qty. */ /* LC_MONETARY */
+ char n_sign_posn; /* positioning of negative_sign for mon. qty. */ /* LC_MONETARY */
+ char int_frac_digits; /* Same as above, for international format */ /* LC_MONETARY */
+ char int_p_cs_precedes; /* Same as above, for international format */ /* LC_MONETARY */
+ char int_n_cs_precedes; /* Same as above, for international format */ /* LC_MONETARY */
+ char int_p_sep_by_space; /* Same as above, for international format */ /* LC_MONETARY */
+ char int_n_sep_by_space; /* Same as above, for international format */ /* LC_MONETARY */
+ char int_p_sign_posn; /* Same as above, for international format */ /* LC_MONETARY */
+ char int_n_sign_posn; /* Same as above, for international format */ /* LC_MONETARY */
+};
+
+/* First arguments to setlocale().
+ NOTE: If you add to / modify these, look at functions/locale/setlocale.c
+ and keep things in sync.
+*/
+/* Entire locale */
+#define LC_ALL _PDCLIB_LC_ALL
+/* Collation (strcoll(), strxfrm()) */
+#define LC_COLLATE _PDCLIB_LC_COLLATE
+/* Character types (<ctype.h>, <wctype.h>) */
+#define LC_CTYPE _PDCLIB_LC_CTYPE
+/* Monetary formatting (as returned by localeconv) */
+#define LC_MONETARY _PDCLIB_LC_MONETARY
+/* Decimal-point character (for printf() / scanf() functions), string
+ conversions, nonmonetary formatting as returned by localeconv
+*/
+#define LC_NUMERIC _PDCLIB_LC_NUMERIC
+/* Time formats (strftime(), wcsftime()) */
+#define LC_TIME _PDCLIB_LC_TIME
+/* Messages (not specified but allowed by C99, and specified by POSIX)
+ (used by perror() / strerror())
+*/
+#define LC_MESSAGES _PDCLIB_LC_MESSAGES
+
+/* The category parameter can be any of the LC_* macros to specify if the call
+ to setlocale() shall affect the entire locale or only a portion thereof.
+ The category locale specifies which locale should be switched to, with "C"
+ being the minimal default locale, and "" being the locale-specific native
+ environment. A NULL pointer makes setlocale() return the *current* setting.
+ Otherwise, returns a pointer to a string associated with the specified
+ category for the new locale.
+*/
+char * setlocale( int category, const char * locale );
+
+/* Returns a struct lconv initialized to the values appropriate for the current
+ locale setting.
+*/
+struct lconv * localeconv( void );
+
+#endif
diff --git a/src/pdclib/include/pdclib/_PDCLIB_aux.h b/src/pdclib/include/pdclib/_PDCLIB_aux.h
new file mode 100644
index 0000000..d6ca14e
--- /dev/null
+++ b/src/pdclib/include/pdclib/_PDCLIB_aux.h
@@ -0,0 +1,65 @@
+/* Auxiliary PDCLib code <_PDCLIB_aux.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_AUX_H
+#define _PDCLIB_AUX_H _PDCLIB_AUX_H
+
+/* -------------------------------------------------------------------------- */
+/* You should not have to edit anything in this file; if you DO have to, it */
+/* would be considered a bug / missing feature: notify the author(s). */
+/* -------------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------------- */
+/* Standard Version */
+/* -------------------------------------------------------------------------- */
+
+/* Many a compiler gets this wrong, so you might have to hardcode it instead. */
+
+#if __STDC__ != 1
+#error Compiler does not define _ _STDC_ _ to 1 (not standard-compliant)!
+#endif
+
+#if __STDC_VERSION__ < 199901L
+#define _PDCLIB_restrict
+#define _PDCLIB_inline
+#else
+#define _PDCLIB_restrict restrict
+#define _PDCLIB_inline inline
+#endif
+
+#ifndef __STDC_HOSTED__
+#error Compiler does not define _ _STDC_HOSTED_ _ (not standard-compliant)!
+#elif __STDC_HOSTED__ == 0
+#define _PDCLIB_HOSTED 0
+#elif __STDC_HOSTED__ == 1
+#define _PDCLIB_HOSTED 1
+#else
+#error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
+#endif
+
+/* -------------------------------------------------------------------------- */
+/* Helper macros: */
+/* _PDCLIB_cc( x, y ) concatenates two preprocessor tokens without extending */
+/* _PDCLIB_concat( x, y ) concatenates two preprocessor tokens with extending */
+/* _PDCLIB_static_assert( e, m ) does a compile-time assertion of expression */
+/* e, with m as the failure message. */
+/* _PDCLIB_TYPE_SIGNED( type ) resolves to true if type is signed. */
+/* _PDCLIB_TWOS_COMPLEMENT( type ) resolves to true if two's complement is */
+/* used for type. */
+/* -------------------------------------------------------------------------- */
+
+#define _PDCLIB_cc( x, y ) x ## y
+#define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
+
+#define _PDCLIB_static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
+
+#define _PDCLIB_TYPE_SIGNED( type ) (((type) -1) < 0)
+#define _PDCLIB_TWOS_COMPLEMENT( type ) ((type) ~ (type) 0 < 0 )
+
+#define _PDCLIB_symbol2value( x ) #x
+#define _PDCLIB_symbol2string( x ) _PDCLIB_symbol2value( x )
+
+#endif
diff --git a/src/pdclib/include/pdclib/_PDCLIB_glue.h b/src/pdclib/include/pdclib/_PDCLIB_glue.h
new file mode 100644
index 0000000..fc1bbb2
--- /dev/null
+++ b/src/pdclib/include/pdclib/_PDCLIB_glue.h
@@ -0,0 +1,71 @@
+/* OS glue functions declaration <_PDCLIB_glue.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_GLUE_H
+#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+/* -------------------------------------------------------------------------- */
+/* OS "glue", part 2 */
+/* These are the functions you will have to touch, as they are where PDCLib */
+/* interfaces with the operating system. */
+/* They operate on data types partially defined by _PDCLIB_config.h. */
+/* -------------------------------------------------------------------------- */
+
+/* stdlib.h */
+
+/* A system call that terminates the calling process, returning a given status
+ to the environment.
+*/
+void _PDCLIB_Exit( int status ) _PDCLIB_NORETURN;
+
+/* A system call that adds n pages of memory to the process heap (if n is
+ positive), or releases n pages from the process heap (if n is negative).
+ Return a (void *) pointing to the *former* end-of-heap if successful, NULL
+ otherwise.
+*/
+void * _PDCLIB_allocpages( int n );
+
+
+/* stdio.h */
+
+/* A system call that opens a file identified by name in a given mode. Return
+ a file descriptor uniquely identifying that file.
+ (The mode is the return value of the _PDCLIB_filemode() function.)
+*/
+_PDCLIB_fd_t _PDCLIB_open( const char * const filename, unsigned int mode );
+
+/* A system call that writes a stream's buffer.
+ Returns 0 on success, EOF on write error.
+ Sets stream error flags and errno appropriately on error.
+*/
+int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream );
+
+/* A system call that fills a stream's buffer.
+ Returns 0 on success, EOF on read error / EOF.
+ Sets stream EOF / error flags and errno appropriately on error.
+*/
+int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream );
+
+/* A system call that repositions within a file. Returns new offset on success,
+ -1 / errno on error.
+*/
+_PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t offset, int whence );
+
+/* A system call that closes a file identified by given file descriptor. Return
+ zero on success, non-zero otherwise.
+*/
+int _PDCLIB_close( _PDCLIB_fd_t fd );
+
+/* A system call that renames a file from given old name to given new name.
+ Return zero on success, non-zero otherwise. In case of failure, the file
+ must still be accessible by old name. Any handling of open files etc. is
+ done by standard rename() already.
+*/
+int _PDCLIB_rename( const char * old, const char * new );
+
+#endif
diff --git a/src/pdclib/include/pdclib/_PDCLIB_int.h b/src/pdclib/include/pdclib/_PDCLIB_int.h
new file mode 100644
index 0000000..6eaded1
--- /dev/null
+++ b/src/pdclib/include/pdclib/_PDCLIB_int.h
@@ -0,0 +1,582 @@
+/* PDCLib internal integer logic <_PDCLIB_int.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_INT_H
+#define _PDCLIB_INT_H _PDCLIB_INT_H
+
+/* -------------------------------------------------------------------------- */
+/* You should not have to edit anything in this file; if you DO have to, it */
+/* would be considered a bug / missing feature: notify the author(s). */
+/* -------------------------------------------------------------------------- */
+
+#include <stdbool.h>
+
+#include "pdclib/_PDCLIB_config.h"
+#include "pdclib/_PDCLIB_aux.h"
+
+/* null pointer constant */
+#define _PDCLIB_NULL 0
+
+/* -------------------------------------------------------------------------- */
+/* Limits of native datatypes */
+/* -------------------------------------------------------------------------- */
+/* The definition of minimum limits for unsigned datatypes is done because */
+/* later on we will "construct" limits for other abstract types: */
+/* USHRT -> _PDCLIB_ + USHRT + _MIN -> _PDCLIB_USHRT_MIN -> 0 */
+/* INT -> _PDCLIB_ + INT + _MIN -> _PDCLIB_INT_MIN -> ... you get the idea. */
+/* -------------------------------------------------------------------------- */
+
+/* Setting 'char' limits */
+#define _PDCLIB_CHAR_BIT 8
+#define _PDCLIB_UCHAR_MIN 0
+#define _PDCLIB_UCHAR_MAX 0xff
+#define _PDCLIB_SCHAR_MIN (-0x7f - 1)
+#define _PDCLIB_SCHAR_MAX 0x7f
+#if _PDCLIB_CHAR_SIGNED == 1
+#define _PDCLIB_CHAR_MIN _PDCLIB_SCHAR_MIN
+#define _PDCLIB_CHAR_MAX _PDCLIB_SCHAR_MAX
+#else
+#define _PDCLIB_CHAR_MIN 0
+#define _PDCLIB_CHAR_MAX _PDCLIB_UCHAR_MAX
+#endif
+
+/* Setting 'short' limits */
+#if _PDCLIB_SHRT_BYTES == 2
+#define _PDCLIB_SHRT_MAX 0x7fff
+#define _PDCLIB_SHRT_MIN (-0x7fff - 1)
+#define _PDCLIB_USHRT_MAX 0xffff
+#else
+#error Unsupported width of 'short' (not 16 bit).
+#endif
+#define _PDCLIB_USHRT_MIN 0
+
+#if _PDCLIB_INT_BYTES < _PDCLIB_SHRT_BYTES
+#error Bogus setting: short > int? Check _PDCLIB_config.h.
+#endif
+
+/* Setting 'int' limits */
+#if _PDCLIB_INT_BYTES == 2
+#define _PDCLIB_INT_MAX 0x7fff
+#define _PDCLIB_INT_MIN (-0x7fff - 1)
+#define _PDCLIB_UINT_MAX 0xffffU
+#elif _PDCLIB_INT_BYTES == 4
+#define _PDCLIB_INT_MAX 0x7fffffff
+#define _PDCLIB_INT_MIN (-0x7fffffff - 1)
+#define _PDCLIB_UINT_MAX 0xffffffffU
+#elif _PDCLIB_INT_BYTES == 8
+#define _PDCLIB_INT_MAX 0x7fffffffffffffff
+#define _PDCLIB_INT_MIN (-0x7fffffffffffffff - 1)
+#define _PDCLIB_UINT_MAX 0xffffffffffffffff
+#else
+#error Unsupported width of 'int' (neither 16, 32, nor 64 bit).
+#endif
+#define _PDCLIB_UINT_MIN 0
+
+/* Setting 'long' limits */
+#if _PDCLIB_LONG_BYTES == 4
+#define _PDCLIB_LONG_MAX 0x7fffffffL
+#define _PDCLIB_LONG_MIN (-0x7fffffffL - 1L)
+#define _PDCLIB_ULONG_MAX 0xffffffffUL
+#elif _PDCLIB_LONG_BYTES == 8
+#define _PDCLIB_LONG_MAX 0x7fffffffffffffffL
+#define _PDCLIB_LONG_MIN (-0x7fffffffffffffffL - 1L)
+#define _PDCLIB_ULONG_MAX 0xffffffffffffffffUL
+#else
+#error Unsupported width of 'long' (neither 32 nor 64 bit).
+#endif
+#define _PDCLIB_ULONG_MIN 0
+
+/* Setting 'long long' limits */
+#if _PDCLIB_LLONG_BYTES == 8
+#define _PDCLIB_LLONG_MAX 0x7fffffffffffffffLL
+#define _PDCLIB_LLONG_MIN (-0x7fffffffffffffffLL - 1LL)
+#define _PDCLIB_ULLONG_MAX 0xffffffffffffffffULL
+#elif _PDCLIB_LLONG_BYTES == 16
+#define _PDCLIB_LLONG_MAX 0x7fffffffffffffffffffffffffffffffLL
+#define _PDCLIB_LLONG_MIN (-0x7fffffffffffffffffffffffffffffffLL - 1LL)
+#define _PDCLIB_ULLONG_MAX 0xffffffffffffffffffffffffffffffffULL
+#else
+#error Unsupported width of 'long long' (neither 64 nor 128 bit).
+#endif
+#define _PDCLIB_ULLONG_MIN 0
+
+/* -------------------------------------------------------------------------- */
+/* <stdint.h> exact-width types and their limits */
+/* -------------------------------------------------------------------------- */
+/* Note that, for the "standard" widths of 8, 16, 32 and 64 bit, the "LEAST" */
+/* types are identical to the "exact-width" types, by definition. */
+
+/* Setting 'int8_t', its limits, its literal, and conversion macros. */
+#if _PDCLIB_CHAR_BIT == 8
+typedef signed char _PDCLIB_int8_t;
+typedef unsigned char _PDCLIB_uint8_t;
+#define _PDCLIB_INT8_MAX _PDCLIB_CHAR_MAX
+#define _PDCLIB_INT8_MIN _PDCLIB_CHAR_MIN
+#define _PDCLIB_UINT8_MAX _PDCLIB_UCHAR_MAX
+#define _PDCLIB_8_CONV hh
+#else
+#error Unsupported width of char (not 8 bits).
+#endif
+
+/* Setting 'int16_t', its limits, its literal, and conversion macros. */
+#if _PDCLIB_INT_BYTES == 2
+typedef signed int _PDCLIB_int16_t;
+typedef unsigned int _PDCLIB_uint16_t;
+#define _PDCLIB_INT16_MAX _PDCLIB_INT_MAX
+#define _PDCLIB_INT16_MIN _PDCLIB_INT_MIN
+#define _PDCLIB_UINT16_MAX _PDCLIB_UINT_MAX
+#define _PDCLIB_16_CONV
+#elif _PDCLIB_SHRT_BYTES == 2
+typedef signed short _PDCLIB_int16_t;
+typedef unsigned short _PDCLIB_uint16_t;
+#define _PDCLIB_INT16_MAX _PDCLIB_SHRT_MAX
+#define _PDCLIB_INT16_MIN _PDCLIB_SHRT_MIN
+#define _PDCLIB_UINT16_MAX _PDCLIB_USHRT_MAX
+#define _PDCLIB_16_CONV h
+#else
+#error Neither 'short' nor 'int' are 16-bit.
+#endif
+
+/* Setting 'int32_t', its limits, its literal, and conversion macros. */
+#if _PDCLIB_INT_BYTES == 4
+typedef signed int _PDCLIB_int32_t;
+typedef unsigned int _PDCLIB_uint32_t;
+#define _PDCLIB_INT32_MAX _PDCLIB_INT_MAX
+#define _PDCLIB_INT32_MIN _PDCLIB_INT_MIN
+#define _PDCLIB_UINT32_MAX _PDCLIB_UINT_MAX
+#define _PDCLIB_INT32_LITERAL
+#define _PDCLIB_UINT32_LITERAL
+#define _PDCLIB_32_CONV
+#elif _PDCLIB_LONG_BYTES == 4
+typedef signed long _PDCLIB_int32_t;
+typedef unsigned long _PDCLIB_uint32_t;
+#define _PDCLIB_INT32_MAX _PDCLIB_LONG_MAX
+#define _PDCLIB_INT32_MIN _PDCLIB_LONG_MIN
+#define _PDCLIB_UINT32_MAX _PDCLIB_LONG_MAX
+#define _PDCLIB_INT32_LITERAL l
+#define _PDCLIB_UINT32_LITERAL ul
+#define _PDCLIB_32_CONV l
+#else
+#error Neither 'int' nor 'long' are 32-bit.
+#endif
+
+/* Setting 'int64_t', its limits, its literal, and conversion macros. */
+#if _PDCLIB_LONG_BYTES == 8
+typedef signed long _PDCLIB_int64_t;
+typedef unsigned long _PDCLIB_uint64_t;
+#define _PDCLIB_INT64_MAX _PDCLIB_LONG_MAX
+#define _PDCLIB_INT64_MIN _PDCLIB_LONG_MIN
+#define _PDCLIB_UINT64_MAX _PDCLIB_ULONG_MAX
+#define _PDCLIB_INT64_LITERAL l
+#define _PDCLIB_UINT64_LITERAL ul
+#define _PDCLIB_64_CONV l
+#elif _PDCLIB_LLONG_BYTES == 8
+typedef signed long long _PDCLIB_int64_t;
+typedef unsigned long long _PDCLIB_uint64_t;
+#define _PDCLIB_INT64_MAX _PDCLIB_LLONG_MAX
+#define _PDCLIB_INT64_MIN _PDCLIB_LLONG_MIN
+#define _PDCLIB_UINT64_MAX _PDCLIB_ULLONG_MAX
+#define _PDCLIB_INT64_LITERAL ll
+#define _PDCLIB_UINT64_LITERAL ull
+#define _PDCLIB_64_CONV ll
+#else
+#error Neither 'long' nor 'long long' are 64-bit.
+#endif
+
+/* -------------------------------------------------------------------------- */
+/* <stdint.h> "fastest" types and their limits */
+/* -------------------------------------------------------------------------- */
+/* This is, admittedly, butt-ugly. But at least it's ugly where the average */
+/* user of PDCLib will never see it, and makes <_PDCLIB_config.h> much */
+/* cleaner. */
+/* -------------------------------------------------------------------------- */
+
+typedef _PDCLIB_fast8 _PDCLIB_int_fast8_t;
+typedef unsigned _PDCLIB_fast8 _PDCLIB_uint_fast8_t;
+#define _PDCLIB_INT_FAST8_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MIN )
+#define _PDCLIB_INT_FAST8_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MAX )
+#define _PDCLIB_UINT_FAST8_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST8 ), _MAX )
+
+typedef _PDCLIB_fast16 _PDCLIB_int_fast16_t;
+typedef unsigned _PDCLIB_fast16 _PDCLIB_uint_fast16_t;
+#define _PDCLIB_INT_FAST16_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MIN )
+#define _PDCLIB_INT_FAST16_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MAX )
+#define _PDCLIB_UINT_FAST16_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST16 ), _MAX )
+
+typedef _PDCLIB_fast32 _PDCLIB_int_fast32_t;
+typedef unsigned _PDCLIB_fast32 _PDCLIB_uint_fast32_t;
+#define _PDCLIB_INT_FAST32_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MIN )
+#define _PDCLIB_INT_FAST32_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MAX )
+#define _PDCLIB_UINT_FAST32_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST32 ), _MAX )
+
+typedef _PDCLIB_fast64 _PDCLIB_int_fast64_t;
+typedef unsigned _PDCLIB_fast64 _PDCLIB_uint_fast64_t;
+#define _PDCLIB_INT_FAST64_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MIN )
+#define _PDCLIB_INT_FAST64_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MAX )
+#define _PDCLIB_UINT_FAST64_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST64 ), _MAX )
+
+/* -------------------------------------------------------------------------- */
+/* Various <stddef.h> typedefs and limits */
+/* -------------------------------------------------------------------------- */
+
+typedef _PDCLIB_ptrdiff _PDCLIB_ptrdiff_t;
+#define _PDCLIB_PTRDIFF_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MIN )
+#define _PDCLIB_PTRDIFF_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MAX )
+
+#define _PDCLIB_SIG_ATOMIC_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MIN )
+#define _PDCLIB_SIG_ATOMIC_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MAX )
+
+typedef _PDCLIB_size _PDCLIB_size_t;
+#define _PDCLIB_SIZE_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIZE ), _MAX )
+
+typedef _PDCLIB_wchar _PDCLIB_wchar_t;
+#define _PDCLIB_WCHAR_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MIN )
+#define _PDCLIB_WCHAR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MAX )
+
+typedef _PDCLIB_wint _PDCLIB_wint_t;
+#define _PDCLIB_WINT_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WINT ), _MIN )
+#define _PDCLIB_WINT_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WINT ), _MAX )
+
+typedef _PDCLIB_intptr _PDCLIB_intptr_t;
+typedef unsigned _PDCLIB_intptr _PDCLIB_uintptr_t;
+#define _PDCLIB_INTPTR_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MIN )
+#define _PDCLIB_INTPTR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MAX )
+#define _PDCLIB_UINTPTR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTPTR ), _MAX )
+
+typedef _PDCLIB_intmax _PDCLIB_intmax_t;
+typedef unsigned _PDCLIB_intmax _PDCLIB_uintmax_t;
+#define _PDCLIB_INTMAX_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MIN )
+#define _PDCLIB_INTMAX_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MAX )
+#define _PDCLIB_UINTMAX_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTMAX ), _MAX )
+#define _PDCLIB_INTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_INTMAX_LITERAL )
+#define _PDCLIB_UINTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_concat( u, _PDCLIB_INTMAX_LITERAL ) )
+
+/* -------------------------------------------------------------------------- */
+/* Various <stdio.h> internals */
+/* -------------------------------------------------------------------------- */
+
+/* Flags for representing mode (see fopen()). Note these must fit the same
+ status field as the _IO?BF flags in <stdio.h> and the internal flags below.
+*/
+#define _PDCLIB_FREAD 8u
+#define _PDCLIB_FWRITE 16u
+#define _PDCLIB_FAPPEND 32u
+#define _PDCLIB_FRW 64u
+#define _PDCLIB_FBIN 128u
+
+/* Internal flags, made to fit the same status field as the flags above. */
+/* -------------------------------------------------------------------------- */
+/* free() the buffer memory on closing (false for user-supplied buffer) */
+#define _PDCLIB_FREEBUFFER 512u
+/* stream has encountered error / EOF */
+#define _PDCLIB_ERRORFLAG 1024u
+#define _PDCLIB_EOFFLAG 2048u
+/* stream is wide-oriented */
+#define _PDCLIB_WIDESTREAM 4096u
+/* stream is byte-oriented */
+#define _PDCLIB_BYTESTREAM 8192u
+/* file associated with stream should be remove()d on closing (tmpfile()) */
+#define _PDCLIB_DELONCLOSE 16384u
+/* stream handle should not be free()d on close (stdin, stdout, stderr) */
+#define _PDCLIB_STATIC 32768u
+
+/* Position / status structure for getpos() / fsetpos(). */
+struct _PDCLIB_fpos_t
+{
+ _PDCLIB_uint64_t offset; /* File position offset */
+ int status; /* Multibyte parsing state (unused, reserved) */
+};
+
+/* FILE structure */
+struct _PDCLIB_file_t
+{
+ _PDCLIB_fd_t handle; /* OS file handle */
+ char * buffer; /* Pointer to buffer memory */
+ _PDCLIB_size_t bufsize; /* Size of buffer */
+ _PDCLIB_size_t bufidx; /* Index of current position in buffer */
+ _PDCLIB_size_t bufend; /* Index of last pre-read character in buffer */
+ struct _PDCLIB_fpos_t pos; /* Offset and multibyte parsing state */
+ _PDCLIB_size_t ungetidx; /* Number of ungetc()'ed characters */
+ unsigned char * ungetbuf; /* ungetc() buffer */
+ unsigned int status; /* Status flags; see above */
+ /* multibyte parsing status to be added later */
+ char * filename; /* Name the current stream has been opened with */
+ struct _PDCLIB_file_t * next; /* Pointer to next struct (internal) */
+};
+
+/* -------------------------------------------------------------------------- */
+/* Various <time.h> internals */
+/* -------------------------------------------------------------------------- */
+
+typedef _PDCLIB_time _PDCLIB_time_t;
+typedef _PDCLIB_clock _PDCLIB_clock_t;
+
+/* -------------------------------------------------------------------------- */
+/* Internal data types */
+/* -------------------------------------------------------------------------- */
+
+/* Structure required by both atexit() and exit() for handling atexit functions */
+struct _PDCLIB_exitfunc_t
+{
+ struct _PDCLIB_exitfunc_t * next;
+ void (*func)( void );
+};
+
+/* Structures required by malloc(), realloc(), and free(). */
+struct _PDCLIB_headnode_t
+{
+ struct _PDCLIB_memnode_t * first;
+ struct _PDCLIB_memnode_t * last;
+};
+
+struct _PDCLIB_memnode_t
+{
+ _PDCLIB_size_t size;
+ struct _PDCLIB_memnode_t * next;
+};
+
+/* Status structure required by _PDCLIB_print(). */
+struct _PDCLIB_status_t
+{
+ int base; /* base to which the value shall be converted */
+ _PDCLIB_int_fast32_t flags; /* flags and length modifiers */
+ _PDCLIB_size_t n; /* print: maximum characters to be written */
+ /* scan: number matched conversion specifiers */
+ _PDCLIB_size_t i; /* number of characters read/written */
+ _PDCLIB_size_t current;/* chars read/written in the CURRENT conversion */
+ char * s; /* *sprintf(): target buffer */
+ /* *sscanf(): source string */
+ _PDCLIB_size_t width; /* specified field width */
+ int prec; /* specified field precision */
+ struct _PDCLIB_file_t * stream; /* *fprintf() / *fscanf() stream */
+ _PDCLIB_va_list arg; /* argument stack */
+};
+
+/* -------------------------------------------------------------------------- */
+/* Declaration of helper functions (implemented in functions/_PDCLIB). */
+/* -------------------------------------------------------------------------- */
+
+/* This is the main function called by atoi(), atol() and atoll(). */
+_PDCLIB_intmax_t _PDCLIB_atomax( const char * s );
+
+/* Two helper functions used by strtol(), strtoul() and long long variants. */
+const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base );
+_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, int limdigit, char * sign );
+
+/* Digits arrays used by various integer conversion functions */
+extern const char _PDCLIB_digits[];
+extern const char _PDCLIB_Xdigits[];
+
+/* The worker for all printf() type of functions. The pointer spec should point
+ to the introducing '%' of a conversion specifier. The status structure is to
+ be that of the current printf() function, of which the members n, s, stream
+ and arg will be preserved; i will be updated; and all others will be trashed
+ by the function.
+ Returns a pointer to the first character not parsed as conversion specifier.
+*/
+const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );
+
+/* The worker for all scanf() type of functions. The pointer spec should point
+ to the introducing '%' of a conversion specifier. The status structure is to
+ be that of the current scanf() function, of which the member stream will be
+ preserved; n, i, and s will be updated; and all others will be trashed by
+ the function.
+ Returns a pointer to the first character not parsed as conversion specifier,
+ or NULL in case of error.
+ FIXME: Should distinguish between matching and input error
+*/
+const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status );
+
+/* Parsing any fopen() style filemode string into a number of flags. */
+unsigned int _PDCLIB_filemode( const char * mode );
+
+/* Sanity checking and preparing of read buffer, should be called first thing
+ by any stdio read-data function.
+ Returns 0 on success, EOF on error.
+ On error, EOF / error flags and errno are set appropriately.
+*/
+int _PDCLIB_prepread( struct _PDCLIB_file_t * stream );
+
+/* Sanity checking, should be called first thing by any stdio write-data
+ function.
+ Returns 0 on success, EOF on error.
+ On error, error flags and errno are set appropriately.
+*/
+int _PDCLIB_prepwrite( struct _PDCLIB_file_t * stream );
+
+/* Closing all streams on program exit */
+void _PDCLIB_closeall( void );
+
+/* Check if a given year is a leap year. Parameter is offset to 1900. */
+int _PDCLIB_is_leap( int year_offset );
+
+/* Read a specified number of lines from a file stream; return a pointer to
+ allocated memory holding the lines (newlines replaced with zero terminators)
+ or NULL in case of error.
+*/
+char * _PDCLIB_load_lines( struct _PDCLIB_file_t * fh, _PDCLIB_size_t lines );
+
+/* -------------------------------------------------------------------------- */
+/* errno */
+/* -------------------------------------------------------------------------- */
+
+/* If PDCLib would call its error number "errno" directly, there would be no way
+ to catch its value from underlying system calls that also use it (i.e., POSIX
+ operating systems). That is why we use an internal name, providing a means to
+ access it through <errno.h>.
+*/
+extern int _PDCLIB_errno;
+
+/* A mechanism for delayed evaluation. (Not sure if this is really necessary, so
+ no detailed documentation on the "why".)
+*/
+int * _PDCLIB_errno_func( void );
+
+/* -------------------------------------------------------------------------- */
+/* <locale.h> support */
+/* -------------------------------------------------------------------------- */
+
+#define _PDCLIB_LC_ALL 0
+#define _PDCLIB_LC_COLLATE 1
+#define _PDCLIB_LC_CTYPE 2
+#define _PDCLIB_LC_MONETARY 3
+#define _PDCLIB_LC_NUMERIC 4
+#define _PDCLIB_LC_TIME 5
+#define _PDCLIB_LC_MESSAGES 6
+#define _PDCLIB_LC_COUNT 7
+
+#define _PDCLIB_CTYPE_ALPHA 1
+#define _PDCLIB_CTYPE_BLANK 2
+#define _PDCLIB_CTYPE_CNTRL 4
+#define _PDCLIB_CTYPE_GRAPH 8
+#define _PDCLIB_CTYPE_PUNCT 16
+#define _PDCLIB_CTYPE_SPACE 32
+#define _PDCLIB_CTYPE_LOWER 64
+#define _PDCLIB_CTYPE_UPPER 128
+
+#define _PDCLIB_CHARSET_SIZE ( 1 << _PDCLIB_CHAR_BIT )
+
+struct _PDCLIB_lc_lconv_numeric_t
+{
+ char * decimal_point;
+ char * thousands_sep;
+ char * grouping;
+};
+
+struct _PDCLIB_lc_lconv_monetary_t
+{
+ char * mon_decimal_point;
+ char * mon_thousands_sep;
+ char * mon_grouping;
+ char * positive_sign;
+ char * negative_sign;
+ char * currency_symbol;
+ char * int_curr_symbol;
+ char frac_digits;
+ char p_cs_precedes;
+ char n_cs_precedes;
+ char p_sep_by_space;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_frac_digits;
+ char int_p_cs_precedes;
+ char int_n_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+};
+
+struct _PDCLIB_lc_numeric_monetary_t
+{
+ struct lconv * lconv;
+ int numeric_alloced;
+ int monetary_alloced;
+};
+
+extern struct _PDCLIB_lc_numeric_monetary_t _PDCLIB_lc_numeric_monetary;
+
+struct _PDCLIB_lc_collate_t
+{
+ int alloced;
+ /* 1..3 code points */
+ /* 1..8, 18 collation elements of 3 16-bit integers */
+};
+
+extern struct _PDCLIB_lc_collate_t _PDCLIB_lc_collate;
+
+struct _PDCLIB_lc_ctype_entry_t
+{
+ _PDCLIB_uint16_t flags;
+ unsigned char upper;
+ unsigned char lower;
+};
+
+struct _PDCLIB_lc_ctype_t
+{
+ int alloced;
+ int digits_low;
+ int digits_high;
+ int Xdigits_low;
+ int Xdigits_high;
+ int xdigits_low;
+ int xdigits_high;
+ struct _PDCLIB_lc_ctype_entry_t * entry;
+};
+
+extern struct _PDCLIB_lc_ctype_t _PDCLIB_lc_ctype;
+
+struct _PDCLIB_lc_messages_t
+{
+ int alloced;
+ char * errno_texts[_PDCLIB_ERRNO_MAX]; /* strerror() / perror() */
+};
+
+extern struct _PDCLIB_lc_messages_t _PDCLIB_lc_messages;
+
+struct _PDCLIB_lc_time_t
+{
+ int alloced;
+ char * month_name_abbr[12]; /* month names, abbreviated */
+ char * month_name_full[12]; /* month names, full */
+ char * day_name_abbr[7]; /* weekday names, abbreviated */
+ char * day_name_full[7]; /* weekday names, full */
+ char * date_time_format; /* date / time format for strftime( "%c" ) */
+ char * time_format_12h; /* 12-hour time format for strftime( "%r" ) */
+ char * date_format; /* date format for strftime( "%x" ) */
+ char * time_format; /* time format for strftime( "%X" ) */
+ char * am_pm[2]; /* AM / PM designation */
+};
+
+extern struct _PDCLIB_lc_time_t _PDCLIB_lc_time;
+
+struct _PDCLIB_lc_lconv_numeric_t * _PDCLIB_load_lc_numeric( const char * path, const char * locale );
+struct _PDCLIB_lc_lconv_monetary_t * _PDCLIB_load_lc_monetary( const char * path, const char * locale );
+struct _PDCLIB_lc_collate_t * _PDCLIB_load_lc_collate( const char * path, const char * locale );
+struct _PDCLIB_lc_ctype_t * _PDCLIB_load_lc_ctype( const char * path, const char * locale );
+struct _PDCLIB_lc_time_t * _PDCLIB_load_lc_time( const char * path, const char * locale );
+struct _PDCLIB_lc_messages_t * _PDCLIB_load_lc_messages( const char * path, const char * locale );
+
+/* -------------------------------------------------------------------------- */
+/* Sanity checks */
+/* -------------------------------------------------------------------------- */
+
+_PDCLIB_static_assert( sizeof( short ) == _PDCLIB_SHRT_BYTES, "Compiler disagrees on _PDCLIB_SHRT_BYTES." );
+_PDCLIB_static_assert( sizeof( int ) == _PDCLIB_INT_BYTES, "Compiler disagrees on _PDCLIB_INT_BYTES." );
+_PDCLIB_static_assert( sizeof( long ) == _PDCLIB_LONG_BYTES, "Compiler disagrees on _PDCLIB_LONG_BYTES." );
+_PDCLIB_static_assert( sizeof( long long ) == _PDCLIB_LLONG_BYTES, "Compiler disagrees on _PDCLIB_LLONG_BYTES." );
+
+_PDCLIB_static_assert( ( (char)-1 < 0 ) == _PDCLIB_CHAR_SIGNED, "Compiler disagrees on _PDCLIB_CHAR_SIGNED." );
+_PDCLIB_static_assert( sizeof( sizeof( int ) ) == sizeof( _PDCLIB_size ), "Compiler disagrees on _PDCLIB_size." );
+
+_PDCLIB_static_assert( sizeof( _PDCLIB_wchar ) == sizeof( L'x' ), "Compiler disagrees on _PDCLIB_wchar." );
+
+_PDCLIB_static_assert( sizeof( void * ) == sizeof( _PDCLIB_intptr ), "Compiler disagrees on _PDCLIB_intptr." );
+
+_PDCLIB_static_assert( sizeof( &_PDCLIB_digits[1] - &_PDCLIB_digits[0] ) == sizeof( _PDCLIB_ptrdiff ), "Compiler disagrees on _PDCLIB_ptrdiff." );
+
+#endif
diff --git a/src/pdclib/include/stdalign.h b/src/pdclib/include/stdalign.h
new file mode 100644
index 0000000..de806a1
--- /dev/null
+++ b/src/pdclib/include/stdalign.h
@@ -0,0 +1,17 @@
+/* Alignment <stdalign.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDALIGN_H
+#define _PDCLIB_ALIGN_H _PDCLIB_ALIGN_H
+
+#define alignas _Alignas
+#define alignof _Alignof
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+
+#endif
+
diff --git a/src/pdclib/include/stdarg.h b/src/pdclib/include/stdarg.h
new file mode 100644
index 0000000..84c05d2
--- /dev/null
+++ b/src/pdclib/include/stdarg.h
@@ -0,0 +1,19 @@
+/* Variable arguments <stdarg.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDARG_H
+#define _PDCLIB_STDARG_H _PDCLIB_STDARG_H
+
+#include "pdclib/_PDCLIB_config.h"
+
+typedef _PDCLIB_va_list va_list;
+
+#define va_arg( ap, type ) _PDCLIB_va_arg( ap, type )
+#define va_copy( dest, src ) _PDCLIB_va_copy( dest, src )
+#define va_end( ap ) _PDCLIB_va_end( ap )
+#define va_start( ap, parmN ) _PDCLIB_va_start( ap, parmN )
+
+#endif
diff --git a/src/pdclib/include/stdbool.h b/src/pdclib/include/stdbool.h
new file mode 100644
index 0000000..8f6a1d0
--- /dev/null
+++ b/src/pdclib/include/stdbool.h
@@ -0,0 +1,15 @@
+/* Boolean type and values <stdbool.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDBOOL_H
+#define _PDCLIB_STDBOOL_H _PDCLIB_STDBOOL_H
+
+#define bool _Bool
+#define true 1
+#define false 0
+#define __bool_true_false_are_defined 1
+
+#endif
diff --git a/src/pdclib/include/stddef.h b/src/pdclib/include/stddef.h
new file mode 100644
index 0000000..7cba7c0
--- /dev/null
+++ b/src/pdclib/include/stddef.h
@@ -0,0 +1,28 @@
+/* Common definitions <stddef.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDDEF_H
+#define _PDCLIB_STDDEF_H _PDCLIB_STDDEF_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+typedef _PDCLIB_ptrdiff_t ptrdiff_t;
+
+#ifndef _PDCLIB_SIZE_T_DEFINED
+#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
+typedef _PDCLIB_size_t size_t;
+#endif
+
+typedef _PDCLIB_wchar_t wchar_t;
+
+#ifndef _PDCLIB_NULL_DEFINED
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
+#define NULL _PDCLIB_NULL
+#endif
+
+#define offsetof( type, member ) _PDCLIB_offsetof( type, member )
+
+#endif
diff --git a/src/pdclib/include/stdint.h b/src/pdclib/include/stdint.h
new file mode 100644
index 0000000..544d1dd
--- /dev/null
+++ b/src/pdclib/include/stdint.h
@@ -0,0 +1,207 @@
+/* Integer types <stdint.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDINT_H
+#define _PDCLIB_STDINT_H _PDCLIB_STDINT_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+/* 7.18.1.1 Exact-width integer types. */
+
+typedef _PDCLIB_int8_t int8_t;
+typedef _PDCLIB_int16_t int16_t;
+typedef _PDCLIB_int32_t int32_t;
+typedef _PDCLIB_int64_t int64_t;
+
+typedef _PDCLIB_uint8_t uint8_t;
+typedef _PDCLIB_uint16_t uint16_t;
+typedef _PDCLIB_uint32_t uint32_t;
+typedef _PDCLIB_uint64_t uint64_t;
+
+/* 7.18.1.2 Minimum-width integer types */
+
+/* You are allowed to add more types here, e.g. int_least24_t. For the standard
+ types, int_leastN_t is equivalent to the corresponding exact type intN_t by
+ definition.
+*/
+
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+/* 7.18.1.3 Fastest minimum-width integer types */
+
+/* You are allowed to add more types here, e.g. int_fast24_t. */
+
+typedef _PDCLIB_int_fast8_t int_fast8_t;
+typedef _PDCLIB_int_fast16_t int_fast16_t;
+typedef _PDCLIB_int_fast32_t int_fast32_t;
+typedef _PDCLIB_int_fast64_t int_fast64_t;
+
+typedef _PDCLIB_uint_fast8_t uint_fast8_t;
+typedef _PDCLIB_uint_fast16_t uint_fast16_t;
+typedef _PDCLIB_uint_fast32_t uint_fast32_t;
+typedef _PDCLIB_uint_fast64_t uint_fast64_t;
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+
+typedef _PDCLIB_intptr_t intptr_t;
+typedef _PDCLIB_uintptr_t uintptr_t;
+
+/* 7.18.1.5 Greatest-width integer types */
+
+typedef _PDCLIB_intmax_t intmax_t;
+typedef _PDCLIB_uintmax_t uintmax_t;
+
+/* 7.18.2 Limits of specified-width integer types */
+
+#ifdef __cplusplus
+#ifndef __STDC_LIMIT_MACROS
+#define _PDCLIB_NO_LIMIT_MACROS
+#endif
+#endif
+
+#ifndef _PDCLIB_NO_LIMIT_MACROS
+
+/* 7.18.2.1 Limits of exact-width integer types */
+
+#define INT8_MIN _PDCLIB_INT8_MIN
+#define INT8_MAX _PDCLIB_INT8_MAX
+#define UINT8_MAX _PDCLIB_UINT8_MAX
+
+#define INT16_MIN _PDCLIB_INT16_MIN
+#define INT16_MAX _PDCLIB_INT16_MAX
+#define UINT16_MAX _PDCLIB_UINT16_MAX
+
+#define INT32_MIN _PDCLIB_INT32_MIN
+#define INT32_MAX _PDCLIB_INT32_MAX
+#define UINT32_MAX _PDCLIB_UINT32_MAX
+
+#define INT64_MIN _PDCLIB_INT64_MIN
+#define INT64_MAX _PDCLIB_INT64_MAX
+#define UINT64_MAX _PDCLIB_UINT64_MAX
+
+/* 7.18.2.2 Limits of minimum-width integer types */
+
+/* For the standard widths, least and exact types are equivalent.
+ You are allowed to add more types here, e.g. int_least24_t.
+*/
+
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+/* 7.18.2.3 Limits of fastest minimum-width integer types */
+
+#define INT_FAST8_MIN _PDCLIB_INT_FAST8_MIN
+#define INT_FAST8_MAX _PDCLIB_INT_FAST8_MAX
+#define UINT_FAST8_MAX _PDCLIB_UINT_FAST8_MAX
+
+#define INT_FAST16_MIN _PDCLIB_INT_FAST16_MIN
+#define INT_FAST16_MAX _PDCLIB_INT_FAST16_MAX
+#define UINT_FAST16_MAX _PDCLIB_UINT_FAST16_MAX
+
+#define INT_FAST32_MIN _PDCLIB_INT_FAST32_MIN
+#define INT_FAST32_MAX _PDCLIB_INT_FAST32_MAX
+#define UINT_FAST32_MAX _PDCLIB_UINT_FAST32_MAX
+
+#define INT_FAST64_MIN _PDCLIB_INT_FAST64_MIN
+#define INT_FAST64_MAX _PDCLIB_INT_FAST64_MAX
+#define UINT_FAST64_MAX _PDCLIB_UINT_FAST64_MAX
+
+/* 7.18.2.4 Limits of integer types capable of holding object pointers */
+
+#define INTPTR_MIN _PDCLIB_INTPTR_MIN
+#define INTPTR_MAX _PDCLIB_INTPTR_MAX
+#define UINTPTR_MAX _PDCLIB_UINTPTR_MAX
+
+/* 7.18.2.5 Limits of greatest-width integer types */
+
+#define INTMAX_MIN _PDCLIB_INTMAX_MIN
+#define INTMAX_MAX _PDCLIB_INTMAX_MAX
+#define UINTMAX_MAX _PDCLIB_UINTMAX_MAX
+
+/* 7.18.3 Limits of other integer types */
+
+#define PTRDIFF_MIN _PDCLIB_PTRDIFF_MIN
+#define PTRDIFF_MAX _PDCLIB_PTRDIFF_MAX
+
+#define SIG_ATOMIC_MIN _PDCLIB_SIG_ATOMIC_MIN
+#define SIG_ATOMIC_MAX _PDCLIB_SIG_ATOMIC_MAX
+
+#define SIZE_MAX _PDCLIB_SIZE_MAX
+
+#define WCHAR_MIN _PDCLIB_WCHAR_MIN
+#define WCHAR_MAX _PDCLIB_WCHAR_MAX
+
+#define WINT_MIN _PDCLIB_WINT_MIN
+#define WINT_MAX _PDCLIB_WINT_MAX
+
+#endif
+
+/* 7.18.4 Macros for integer constants */
+
+#ifdef __cplusplus
+#ifndef __STDC_CONSTANT_MACROS
+#define _PDCLIB_NO_CONSTANT_MACROS
+#endif
+#endif
+
+#ifndef _PDCLIB_NO_CONSTANT_MACROS
+
+/* 7.18.4.1 Macros for minimum-width integer constants */
+
+/* As the minimum-width types - for the required widths of 8, 16, 32, and 64
+ bits - are expressed in terms of the exact-width types, the mechanism for
+ these macros is to append the literal of that exact-width type to the macro
+ parameter.
+ This is considered a hack, as the author is not sure his understanding of
+ the requirements of this macro is correct. Any input appreciated.
+*/
+
+/* Expand to an integer constant of specified value and type int_leastN_t */
+
+#define INT8_C( value ) value
+#define INT16_C( value ) value
+#define INT32_C( value ) _PDCLIB_concat( value, _PDCLIB_INT32_LITERAL )
+#define INT64_C( value ) _PDCLIB_concat( value, _PDCLIB_INT64_LITERAL )
+
+/* Expand to an integer constant of specified value and type uint_leastN_t */
+
+#define UINT8_C( value ) value
+#define UINT16_C( value ) value
+#define UINT32_C( value ) _PDCLIB_concat( value, _PDCLIB_UINT32_LITERAL )
+#define UINT64_C( value ) _PDCLIB_concat( value, _PDCLIB_UINT64_LITERAL )
+
+/* 7.18.4.2 Macros for greatest-width integer constants */
+
+/* Expand to an integer constant of specified value and type intmax_t */
+#define INTMAX_C( value ) _PDCLIB_INTMAX_C( value )
+
+/* Expand to an integer constant of specified value and type uintmax_t */
+#define UINTMAX_C( value ) _PDCLIB_UINTMAX_C( value )
+
+#endif
+
+#endif
diff --git a/src/pdclib/include/stdio.h b/src/pdclib/include/stdio.h
new file mode 100644
index 0000000..d3d0a64
--- /dev/null
+++ b/src/pdclib/include/stdio.h
@@ -0,0 +1,786 @@
+/* Input/output <stdio.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDIO_H
+#define _PDCLIB_STDIO_H _PDCLIB_STDIO_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+#ifndef _PDCLIB_SIZE_T_DEFINED
+#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
+typedef _PDCLIB_size_t size_t;
+#endif
+
+#ifndef _PDCLIB_NULL_DEFINED
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
+#define NULL _PDCLIB_NULL
+#endif
+
+/* See setvbuf(), third argument */
+#define _IOFBF 1
+#define _IOLBF 2
+#define _IONBF 4
+
+/* The following are platform-dependant, and defined in _PDCLIB_config.h. */
+typedef struct _PDCLIB_fpos_t fpos_t;
+typedef struct _PDCLIB_file_t FILE;
+#define EOF -1
+#define BUFSIZ _PDCLIB_BUFSIZ
+#define FOPEN_MAX _PDCLIB_FOPEN_MAX
+#define FILENAME_MAX _PDCLIB_FILENAME_MAX
+#define L_tmpnam _PDCLIB_L_tmpnam
+#define TMP_MAX _PDCLIB_TMP_MAX
+
+/* See fseek(), third argument */
+#define SEEK_CUR _PDCLIB_SEEK_CUR
+#define SEEK_END _PDCLIB_SEEK_END
+#define SEEK_SET _PDCLIB_SEEK_SET
+
+extern FILE * stdin;
+extern FILE * stdout;
+extern FILE * stderr;
+
+/* Operations on files */
+
+/* Remove the given file.
+ Returns zero if successful, non-zero otherwise.
+ This implementation does detect if a file of that name is currently open,
+ and fails the remove in this case. This does not detect two distinct names
+ that merely result in the same file (e.g. "/home/user/foo" vs. "~/foo").
+*/
+int remove( const char * filename );
+
+/* Rename the given old file to the given new name.
+ Returns zero if successful, non-zero otherwise.
+ This implementation does detect if the old filename corresponds to an open
+ file, and fails the rename in this case.
+ If there already is a file with the new filename, behaviour is defined by
+ the glue code (see functions/_PDCLIB/rename.c).
+*/
+int rename( const char * old, const char * new );
+
+/* Open a temporary file with mode "wb+", i.e. binary-update. Remove the file
+ automatically if it is closed or the program exits normally (by returning
+ from main() or calling exit()).
+ Returns a pointer to a FILE handle for this file.
+ This implementation does not remove temporary files if the process aborts
+ abnormally (e.g. abort()).
+*/
+FILE * tmpfile( void );
+
+/* Generate a file name that is not equal to any existing filename AT THE TIME
+ OF GENERATION. Generate a different name each time it is called.
+ Returns a pointer to an internal static buffer containing the filename if s
+ is a NULL pointer. (This is not thread-safe!)
+ Returns s if it is not a NULL pointer (s is then assumed to point to an array
+ of at least L_tmpnam characters).
+ Returns NULL if unable to generate a suitable name (because all possible
+ names already exist, or the function has been called TMP_MAX times already).
+ Note that this implementation cannot guarantee a file of the name generated
+ is not generated between the call to this function and a subsequent fopen().
+*/
+char * tmpnam( char * s );
+
+/* File access functions */
+
+/* Close the file associated with the given stream (after flushing its buffers).
+ Returns zero if successful, EOF if any errors occur.
+*/
+int fclose( FILE * stream );
+
+/* Flush the buffers of the given output stream. If the stream is an input
+ stream, or an update stream with the last operation being an input operation,
+ behaviour is undefined.
+ If stream is a NULL pointer, perform the buffer flushing for all applicable
+ streams.
+ Returns zero if successful, EOF if a write error occurs.
+ Sets the error indicator of the stream if a write error occurs.
+*/
+int fflush( FILE * stream );
+
+/* Open the file with the given filename in the given mode, and return a stream
+ handle for it in which error and end-of-file indicator are cleared. Defined
+ values for mode are:
+
+ READ MODES
+ text files binary files
+ without update "r" "rb"
+ with update "r+" "rb+" or "r+b"
+
+ Opening in read mode fails if no file with the given filename exists, or if
+ cannot be read.
+
+ WRITE MODES
+ text files binary files
+ without update "w" "wb"
+ with update "w+" "wb+" or "w+b"
+
+ With write modes, if a file with the given filename already exists, it is
+ truncated to zero length.
+
+ APPEND MODES
+ text files binary files
+ without update "a" "ab"
+ with update "a+" "ab+" or "a+b"
+
+ With update modes, if a file with the given filename already exists, it is
+ not truncated to zero length, but all writes are forced to end-of-file (this
+ regardless to fseek() calls). Note that binary files opened in append mode
+ might have their end-of-file padded with '\0' characters.
+
+ Update modes mean that both input and output functions can be performed on
+ the stream, but output must be terminated with a call to either fflush(),
+ fseek(), fsetpos(), or rewind() before input is performed, and input must
+ be terminated with a call to either fseek(), fsetpos(), or rewind() before
+ output is performed, unless input encountered end-of-file.
+
+ If a text file is opened with update mode, the implementation is at liberty
+ to open a binary stream instead. This implementation honors the exact mode
+ given.
+
+ The stream is fully buffered if and only if it can be determined not to
+ refer to an interactive device.
+
+ If the mode string begins with but is longer than one of the above sequences
+ the implementation is at liberty to ignore the additional characters, or do
+ implementation-defined things. This implementation only accepts the exact
+ modes above.
+
+ Returns a pointer to the stream handle if successfull, NULL otherwise.
+*/
+FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode );
+
+/* Close any file currently associated with the given stream. Open the file
+ identified by the given filename with the given mode (equivalent to fopen()),
+ and associate it with the given stream. If filename is a NULL pointer,
+ attempt to change the mode of the given stream.
+ This implementation allows any mode changes on "real" files, and associating
+ of the standard streams with files. It does *not* support mode changes on
+ standard streams.
+ (Primary use of this function is to redirect stdin, stdout, and stderr.)
+*/
+FILE * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, FILE * _PDCLIB_restrict stream );
+
+/* If buf is a NULL pointer, call setvbuf( stream, NULL, _IONBF, BUFSIZ ).
+ If buf is not a NULL pointer, call setvbuf( stream, buf, _IOFBF, BUFSIZ ).
+*/
+void setbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf );
+
+/* Set the given stream to the given buffering mode. If buf is not a NULL
+ pointer, use buf as file buffer (of given size). If buf is a NULL pointer,
+ use a buffer of given size allocated internally. _IONBF causes unbuffered
+ behaviour, _IOLBF causes line-buffered behaviour, _IOFBF causes fully
+ buffered behaviour. Calling this function is only valid right after a file is
+ opened, and before any other operation (except for any unsuccessful calls to
+ setvbuf()) has been performed.
+ Returns zero if successful, nonzero otherwise.
+*/
+int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size );
+
+/* Formatted input/output functions */
+
+/*
+ Write output to the given stream, as defined by the given format string and
+ 0..n subsequent arguments (the argument stack).
+
+ The format string is written to the given stream verbatim, except for any
+ conversion specifiers included, which start with the letter '%' and are
+ documented below. If the given conversion specifiers require more arguments
+ from the argument stack than provided, behaviour is undefined. Additional
+ arguments not required by conversion specifiers are evaluated but otherwise
+ ignored.
+
+ (The standard specifies the format string is allowed to contain multibyte
+ character sequences as long as it starts and ends in initial shift state,
+ but this is not yet supported by this implementation, which interprets the
+ format string as sequence of char.)
+ TODO: Add multibyte support to printf() functions.
+
+ A conversion specifier consists of:
+ - Zero or more flags (one of the characters "-+ #0").
+ - Optional minimum field width as decimal integer. Default is padding to the
+ left, using spaces. Note that 0 is taken as a flag, not the beginning of a
+ field width. Note also that a small field width will not result in the
+ truncation of a value.
+ - Optional precision (given as ".#" with # being a decimal integer),
+ specifying:
+ - the min. number of digits to appear (diouxX),
+ - the max. number of digits after the decimal point (aAeEfF),
+ - the max. number of significant digits (gG),
+ - the max. number of bytes to be written (s).
+ - behaviour with other conversion specifiers is undefined.
+ - Optional length modifier specifying the size of the argument (one of "hh",
+ "ll", or one of the characters "hljztL").
+ - Conversion specifier character specifying the type of conversion to be
+ applied (and the type of the next argument from the argument stack). One
+ of the characters "diouxXfFeEgGaAcspn%".
+
+ Minimum field width and/or precision may be given as asterisk ('*') instead
+ of a decimal integer. In this case, the next argument from the argument
+ stack is assumed to be an int value specifying the width / precision. A
+ negative field width is interpreted as flag '-' followed by a positive field
+ width. A negative precision is interpreted as if no precision was given.
+
+ FLAGS
+ - Left-justify the conversion result within its field width.
+ + Prefix a '+' on positive signed conversion results. Prefix a '-' on
+ floating conversions resulting in negative zero, or negative values
+ rounding to zero.
+ space Prefix a space on positive signed conversion results, or if a signed
+ conversion results in no characters. If both '+' and ' ' are given,
+ ' ' is ignored.
+ # Use an "alternative form" for
+ - 'o' conversion, increasing precision until the first digit of the
+ result is a zero;
+ - 'x' or 'X' conversion, prefixing "0x" or "0X" to nonzero results;
+ - "aAeEfF" conversions, always printing a decimal point even if no
+ digits are following;
+ - 'g' or 'G' conversions, always printing a decimal point even if no
+ digits are following, and not removing trailing zeroes.
+ - behaviour for other conversions is unspecified.
+ 0 Use leading zeroes instead of spaces for field width padding. If both
+ '-' and '0' are given, '0' is ignored. If a precision is specified for
+ any of the "diouxX" conversions, '0' is ignored. Behaviour is only
+ defined for "diouxXaAeEfFgG".
+
+ LENGTH MODIFIERS
+ hh For "diouxX" conversions, the argument from the argument stack is
+ assumed to be of char width. (It will have been subject to integer
+ promotion but will be converted back.) For 'n' conversions, the argument
+ is assumed to be a pointer to signed char.
+ h For "diouxX" conversions, the argument from the argument stack is
+ assumed to be of short int width. (It will have been subject to integer
+ promotion but will be converted back.) For 'n' conversions, the argument
+ is assumed to be a pointer to short int.
+ l For "diouxX" conversions, the argument from the argument stack is
+ assumed to be of long int width. For 'n' conversions, the argument is
+ assumed to be a pointer to short int. For 'c' conversions, the argument
+ is assumed to be a wint_t. For 's' conversions, the argument is assumed
+ to be a pointer to wchar_t. No effect on "aAeEfFgG" conversions.
+ ll For "diouxX" conversions, the argument from the argument stack is
+ assumed to be of long long int width. For 'n' conversions, the argument
+ is assumed to be a pointer to long long int.
+ j For "diouxX" conversions, the argument from the argument stack is
+ assumed to be of intmax_t width. For 'n' conversions, the argument is
+ assumed to be a pointer to intmax_t.
+ z For "diouxX" conversions, the argument from the argument stack is
+ assumed to be of size_t width. For 'n' conversions, the argument is
+ assumed to be a pointer to size_t.
+ t For "diouxX" conversions, the argument from the argument stack is
+ assumed to be of ptrdiff_t width. For 'n' conversions, the argument is
+ assumed to be a pointer to ptrdiff_t.
+ L For "aAeEfFgG" conversions, the argument from the argument stack is
+ assumed to be a long double.
+ Length modifiers appearing for any conversions not mentioned above will have
+ undefined behaviour.
+ If a length modifier appears with any conversion specifier other than as
+ specified above, the behavior is undefined.
+
+ CONVERSION SPECIFIERS
+ d,i The argument from the argument stack is assumed to be of type int, and
+ is converted to a signed decimal value with a minimum number of digits
+ as specified by the precision (default 1), padded with leading zeroes.
+ A zero value converted with precision zero yields no output.
+ o The argument from the argument stack is assumed to be of type unsigned
+ int, and is converted to an unsigned octal value, other behaviour being
+ as above.
+ u The argument from the argument stack is assumed to be of type unsigned
+ int, and converted to an unsigned decimal value, other behaviour being
+ as above.
+ x,X The argument from the argument stack is assumed to be of type unsigned
+ int, and converted to an unsigned hexadecimal value, using lowercase
+ "abcdef" for 'x' and uppercase "ABCDEF" for 'X' conversion, other
+ behaviour being as above.
+ f,F The argument from the argument stack is assumed to be of type double,
+ and converted to a decimal floating point in decimal-point notation,
+ with the number of digits after the decimal point as specified by the
+ precision (default 6) and the value being rounded appropriately. If
+ precision is zero (and the '#' flag is not given), no decimal point is
+ printed. At least one digit is always printed before the decimal point.
+ For 'f' conversions, an infinity value is printed as either [-]inf or
+ [-]infinity (, depending on the configuration of this implementation. A
+ NaN value is printed as [-]nan. For 'F' conversions uppercase characters
+ are used for these special values. The flags '-', '+' and ' ' apply as
+ usual to these special values, '#' and '0' have no effect.
+ e,E The argument from the argument stack is assumed to be of type double,
+ and converted to a decimal floating point in normalized exponential
+ notation ([?]d.ddd edd). "Normalized" means one nonzero digit before
+ the decimal point, unless the value is zero. The number of digits after
+ the decimal point is specified by the precision (default 6), the value
+ being rounded appropriately. If precision is zero (and the '#' flag is
+ not given), no decimal point is printed. The exponent has at least two
+ digits, and not more than necessary to represent the exponent. If the
+ value is zero, the exponent is zero. The 'e' written to indicate the
+ exponend is uppercase for 'E' conversions.
+ Infinity or NaN values are represented as for 'f' and 'F' conversions,
+ respectively.
+ g,G The argument from the argument stack is assumed to be of type double,
+ and converted according to either 'f' or 'e' format for 'g' conversions,
+ or 'F' or 'E' format for 'G' conversions, respectively, with the actual
+ conversion chosen depending on the value. 'e' / 'E' conversion is chosen
+ if the resulting exponent is < -4 or >= the precision (default 1).
+ Trailing zeroes are removed (unless the '#' flag is given). A decimal
+ point appears only if followed by a digit.
+ Infinity or NaN values are represented as for 'f' and 'F' conversions,
+ respectively.
+ a,A The argument from the argument stack is assumed to be of type double,
+ and converted to a floating point hexadecimal notation ([?]0xh.hhhh pd)
+ with one hexadecimal digit (being nonzero if the value is normalized,
+ and otherwise unspecified) before the decimal point, and the number of
+ digits after the decimal point being specified by the precision. If no
+ precision is given, the default is to print as many digits as nevessary
+ to give an exact representation of the value (if FLT_RADIX is a power of
+ 2). If no precision is given and FLT_RADIX is not a power of 2, the
+ default is to print as many digits to distinguish values of type double
+ (possibly omitting trailing zeroes). (A precision p is sufficient to
+ distinguish values of the source type if 16^p-1 > b^n where b is
+ FLT_RADIX and n is the number of digits in the significand (to base b)
+ of the source type. A smaller p might suffice depending on the
+ implementation's scheme for determining the digit to the left of the
+ decimal point.) The error has the correct sign for the current rounding
+ direction.
+ Unless the '#' flag is given, no decimal-point is given for zero
+ precision.
+ The 'a' conversion uses lowercase "abcdef", "0x" and 'p', the 'A'
+ conversion uppercase "ABCDEF", "0X" and 'P'.
+ The exponent always has at least one digit, and not more than necessary
+ to represent the decimal exponent of 2. If the value is zero, the
+ exponent is zero.
+ Infinity or NaN values are represented as for 'f' and 'F' conversions,
+ respectively.
+ Binary implementations are at liberty to chose the hexadecimal digit to
+ the left of the decimal point so that subsequent digits align to nibble
+ boundaries.
+ c The argument from the argument stack is assumed to be of type int, and
+ converted to a character after the value has been cast to unsigned char.
+ If the 'l' length modifier is given, the argument is assumed to be of
+ type wint_t, and converted as by a "%ls" conversion with no precision
+ and a pointer to a two-element wchar_t array, with the first element
+ being the wint_t argument and the second a '\0' wide character.
+ s The argument from the argument stack is assumed to be a char array (i.e.
+ pointer to char). Characters from that array are printed until a zero
+ byte is encountered or as many bytes as specified by a given precision
+ have been written.
+ If the l length modifier is given, the argument from the argument stack
+ is assumed to be a wchar_t array (i.e. pointer to wchar_t). Wide
+ characters from that array are converted to multibyte characters as by
+ calls to wcrtomb() (using a mbstate_t object initialized to zero prior
+ to the first conversion), up to and including the terminating null wide
+ character. The resulting multibyte character sequence is then printed up
+ to but not including the terminating null character. If a precision is
+ given, it specifies the maximum number of bytes to be written (including
+ shift sequences). If the given precision would require access to a wide
+ character one past the end of the array, the array shall contain a '\0'
+ wide character. In no case is a partial multibyte character written.
+ Redundant shift sequences may result if the multibyte characters have a
+ state-dependent encoding.
+ TODO: Clarify these statements regarding %ls.
+ p The argument from the argument stack is assumed to be a void pointer,
+ and converted to a sequence of printing characters in an implementation-
+ defined manner.
+ This implementation casts the pointer to type intptr_t, and prints the
+ value as if a %#x conversion specifier was given.
+ n The argument from the argument stack is assumed to be a pointer to a
+ signed integer, into which the number of characters written so far by
+ this call to fprintf is stored. The behaviour, should any flags, field
+ widths, or precisions be given is undefined.
+ % A verbatim '%' character is written. No argument is taken from the
+ argument stack.
+
+ Returns the number of characters written if successful, a negative value
+ otherwise.
+*/
+int fprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... );
+
+/* TODO: fscanf() documentation */
+/*
+ Read input from a given stream, as defined by the given format string, and
+ store converted input in the objects pointed to by 0..n subsequent arguments
+ (the argument stack).
+
+ The format string contains a sequence of directives that are expected to
+ match the input. If such a directive fails to match, the function returns
+ (matching error). It also returns if an input error occurs (input error).
+
+ Directives can be:
+ - one or more whitespaces, matching any number of whitespaces in the input;
+ - printing characters, matching the input verbatim;
+ - conversion specifications, which convert an input sequence into a value as
+ defined by the individual specifier, and store that value in a memory
+ location pointed to by the next pointer on the argument stack. Details are
+ documented below. If there is an insufficient number of pointers on the
+ argument stack, behaviour is undefined. Additional arguments not required
+ by any conversion specifications are evaluated, but otherwise ignored.
+
+ (The standard specifies the format string is allowed to contain multibyte
+ character sequences as long as it starts and ends in initial shift state,
+ but this is not yet supported by this implementation, which interprets the
+ format string as sequence of char.)
+ TODO: Add multibyte support to scanf() functions.
+
+ A conversion specifier consists of:
+ - Optional assignment-suppressing character ('*') that makes the conversion
+ read input as usual, but does not assign the conversion result.
+ - Optional maximum field width as decimal integer.
+ - Optional length modifier specifying the size of the argument (one of "hh",
+ "ll", or one of the characters "hljztL").
+ - Conversion specifier character specifying the type of conversion to be
+ applied (and the type of the next argument from the argument stack). One
+ of the characters "diouxXaAeEfFgGcs[pn%".
+
+ LENGTH MODIFIERS
+ hh For "diouxXn" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of of char width.
+ h For "diouxXn" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of short int width.
+ l For "diouxXn" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of long int width.
+ For "aAeEfFgG" conversions, it is assumed to point to a variable of type
+ double.
+ For "cs[" conversions, it is assumed to point to a variable of type
+ wchar_t.
+ ll For "diouxXn" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of long long int width.
+ j For "diouxXn" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of intmax_t width.
+ z For "diouxXn" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of size_t width.
+ t For "diouxXn" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of ptrdiff_t width.
+ L For "aAeEfFgG" conversions, the next pointer from the argument stack is
+ assumed to point to a variable of type long double.
+ Length modifiers appearing for any conversions not mentioned above will have
+ undefined behaviour.
+ If a length modifier appears with any conversion specifier other than as
+ specified above, the behavior is undefined.
+
+ CONVERSION SPECIFIERS
+ d Matches an (optionally signed) decimal integer of the format expected
+ by strtol() with base 10. The next pointer from the argument stack is
+ assumed to point to a signed integer.
+ i Matches an (optionally signed) integer of the format expected by
+ strtol() with base 0. The next pointer from the argument stack is
+ assumed to point to a signed integer.
+ o Matches an (optionally signed) octal integer of the format expected by
+ strtoul() with base 8. The next pointer from the argument stack is
+ assumed to point to an unsigned integer.
+ u Matches an (optionally signed) decimal integer of the format expected
+ by strtoul() with base 10. The next pointer from the argument stack is
+ assumed to point to an unsigned integer.
+ x Matches an (optionally signed) hexadecimal integer of the format
+ expected by strtoul() with base 16. The next pointer from the argument
+ stack is assumed to point to an unsigned integer.
+ aefg Matches an (optionally signed) floating point number, infinity, or not-
+ a-number-value of the format expected by strtod(). The next pointer
+ from the argument stack is assumed to point to a float.
+ c Matches a number of characters as specified by the field width (default
+ 1). The next pointer from the argument stack is assumed to point to a
+ character array large enough to hold that many characters.
+ If the 'l' length modifier is given, the input is assumed to match a
+ sequence of multibyte characters (starting in the initial shift state),
+ which will be converted to a wide character sequence as by successive
+ calls to mbrtowc() with a mbstate_t object initialized to zero prior to
+ the first conversion. The next pointer from the argument stack is
+ assumed to point to a wchar_t array large enough to hold that many
+ characters.
+ In either case, note that no '\0' character is added to terminate the
+ sequence.
+ s Matches a sequence of non-white-space characters. The next pointer from
+ the argument stack is assumed to point to a character array large
+ enough to hold the sequence including terminating '\0' character.
+ If the 'l' length modifier is given, the input is assumed to match a
+ sequence of multibyte characters (starting in the initial shift state),
+ which will be converted to a wide character sequence as by a call to
+ mbrtowc() with a mbstate_t object initialized to zero prior to the
+ first conversion. The next pointer from the argument stack is assumed
+ to point to a wchar_t array large enough to hold the sequence including
+ terminating '\0' character.
+ [ Matches a nonempty sequence consisting of any of those characters
+ specified between itself and a corresponding closing bracket (']').
+ If the first character in the list is a circumflex ('^'), this matches
+ a nonempty sequence consisting of any characters NOT specified. If the
+ closing bracket appears as the first character in the scanset ("[]" or
+ "[^]", it is assumed to belong to the scanset, which then ends with the
+ NEXT closing bracket.
+ If there is a '-' character in the scanset which is not the first after
+ the opening bracket (or the circumflex, see above) or the last in the
+ scanset, behaviour is implementation-defined. This implementation
+ handles this character like any other.
+
+ The extend of the input field is determined byte-by-byte for the above
+ conversions ('c', 's', '['), with no special provisions being made for
+ multibyte characters. The resulting field is nevertheless a multibyte
+ sequence begining in intial shift state.
+
+ p Matches a sequence of characters as produced by the printf() "%p"
+ conversion. The next pointer from the argument stack is assumed to
+ point to a void pointer, which will be filled with the same location
+ as the pointer used in the printf() statement. Note that behaviour is
+ undefined if the input value is not the result of an earlier printf()
+ call.
+ n Does not read input. The next pointer from the argument stack is
+ assumed to point to a signed integer, into which the number of
+ characters read from input so far by this call to fscanf() is stored.
+ This does not affect the return value of fscanf(). The behaviour,
+ should an assignment-supressing character of field width be given,
+ is undefined.
+ This can be used to test the success of literal matches and suppressed
+ assignments.
+ % Matches a single, verbatim '%' character.
+
+ A, E, F, G and X are valid, and equivalent to their lowercase counterparts.
+
+ All conversions except [, c, or n imply that whitespace characters from the
+ input stream are consumed until a non-whitespace character is encountered.
+ Such whitespaces do not count against a maximum field width.
+
+ Conversions push at most one character back into the input stream. That
+ implies that some character sequences converted by the strtol() and strtod()
+ function families are not converted identically by the scnaf() function
+ family.
+
+ Returns the number of input items successfully assigned. This can be zero if
+ an early mismatch occurs. Returns EOF if an input failure occurs before the
+ first conversion.
+*/
+int fscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... );
+
+/* Equivalent to fprintf( stdout, format, ... ). */
+int printf( const char * _PDCLIB_restrict format, ... );
+
+/* Equivalent to fscanf( stdin, format, ... ). */
+int scanf( const char * _PDCLIB_restrict format, ... );
+
+/* Equivalent to fprintf( stdout, format, ... ), except that the result is
+ written into the buffer pointed to by s, instead of stdout, and that any
+ characters beyond the (n-1)th are discarded. The (n)th character is
+ replaced by a '\0' character in this case.
+ Returns the number of characters that would have been written (not counting
+ the terminating '\0' character) if n had been sufficiently large, if
+ successful, and a negative number if an encoding error ocurred.
+*/
+int snprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, ... );
+
+/* Equivalent to fprintf( stdout, format, ... ), except that the result is
+ written into the buffer pointed to by s, instead of stdout.
+*/
+int sprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... );
+
+/* Equivalent to fscanf( stdin, format, ... ), except that the input is read
+ from the buffer pointed to by s, instead of stdin.
+*/
+int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... );
+
+/* Equivalent to fprintf( stream, format, ... ), except that the argument stack
+ is passed as va_list parameter. Note that va_list is not declared by
+ <stdio.h>.
+*/
+int vfprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
+
+/* Equivalent to fscanf( stream, format, ... ), except that the argument stack
+ is passed as va_list parameter. Note that va_list is not declared by
+ <stdio.h>.
+*/
+int vfscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
+
+/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack
+ is passed as va_list parameter. Note that va_list is not declared by
+ <stdio.h>.
+*/
+int vprintf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
+
+/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack
+ is passed as va_list parameter. Note that va_list is not declared by
+ <stdio.h>.
+*/
+int vscanf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
+
+/* Equivalent to snprintf( s, n, format, ... ), except that the argument stack
+ is passed as va_list parameter. Note that va_list is not declared by
+ <stdio.h>.
+ */
+int vsnprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
+
+/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack
+ is passed as va_list parameter, and the result is written to the buffer
+ pointed to by s, instead of stdout. Note that va_list is not declared by
+ <stdio.h>.
+*/
+int vsprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
+
+/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack
+ is passed as va_list parameter, and the input is read from the buffer
+ pointed to by s, instead of stdin. Note that va_list is not declared by
+ <stdio.h>.
+*/
+int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
+
+/* Character input/output functions */
+
+/* Retrieve the next character from given stream.
+ Returns the character, EOF otherwise.
+ If end-of-file is reached, the EOF indicator of the stream is set.
+ If a read error occurs, the error indicator of the stream is set.
+*/
+int fgetc( FILE * stream );
+
+/* Read at most n-1 characters from given stream into the array s, stopping at
+ \n or EOF. Terminate the read string with \n. If EOF is encountered before
+ any characters are read, leave the contents of s unchanged.
+ Returns s if successful, NULL otherwise.
+ If a read error occurs, the error indicator of the stream is set. In this
+ case, the contents of s are indeterminate.
+*/
+char * fgets( char * _PDCLIB_restrict s, int n, FILE * _PDCLIB_restrict stream );
+
+/* Write the value c (cast to unsigned char) to the given stream.
+ Returns c if successful, EOF otherwise.
+ If a write error occurs, sets the error indicator of the stream is set.
+*/
+int fputc( int c, FILE * stream );
+
+/* Write the string s (not including the terminating \0) to the given stream.
+ Returns a value >=0 if successful, EOF otherwise.
+ This implementation does set the error indicator of the stream if a write
+ error occurs.
+*/
+int fputs( const char * _PDCLIB_restrict s, FILE * _PDCLIB_restrict stream );
+
+/* Equivalent to fgetc( stream ), but may be overloaded by a macro that
+ evaluates its parameter more than once.
+*/
+int getc( FILE * stream );
+
+/* Equivalent to fgetc( stdin ). */
+int getchar( void );
+
+/* Equivalent to fputc( c, stream ), but may be overloaded by a macro that
+ evaluates its parameter more than once.
+*/
+int putc( int c, FILE * stream );
+
+/* Equivalent to fputc( c, stdout ), but may be overloaded by a macro that
+ evaluates its parameter more than once.
+*/
+int putchar( int c );
+
+/* Write the string s (not including the terminating \0) to stdout, and append
+ a newline to the output. Returns a value >= 0 when successful, EOF if a
+ write error occurred.
+*/
+int puts( const char * s );
+
+/* Push the value c (cast to unsigned char) back onto the given (input) stream.
+ A character pushed back in this way will be delivered by subsequent read
+ operations (and skipped by subsequent file positioning operations) as if it
+ has not been read. The external representation of the stream is unaffected
+ by this pushback (it is a buffer operation). One character of pushback is
+ guaranteed, further pushbacks may fail. EOF as value for c does not change
+ the input stream and results in failure of the function.
+ For text files, the file position indicator is indeterminate until all
+ pushed-back characters are read. For binary files, the file position
+ indicator is decremented by each successful call of ungetc(). If the file
+ position indicator for a binary file was zero before the call of ungetc(),
+ behaviour is undefined. (Older versions of the library allowed such a call.)
+ Returns the pushed-back character if successful, EOF if it fails.
+*/
+int ungetc( int c, FILE * stream );
+
+/* Direct input/output functions */
+
+/* Read up to nmemb elements of given size from given stream into the buffer
+ pointed to by ptr. Returns the number of elements successfully read, which
+ may be less than nmemb if a read error or EOF is encountered. If a read
+ error is encountered, the value of the file position indicator is
+ indeterminate. If a partial element is read, its value is indeterminate.
+ If size or nmemb are zero, the function does nothing and returns zero.
+*/
+size_t fread( void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream );
+
+/* Write up to nmemb elements of given size from buffer pointed to by ptr to
+ the given stream. Returns the number of elements successfully written, which
+ will be less than nmemb only if a write error is encountered. If a write
+ error is encountered, the value of the file position indicator is
+ indeterminate. If size or nmemb are zero, the function does nothing and
+ returns zero.
+*/
+size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream );
+
+/* File positioning functions */
+
+/* Store the current position indicator (and, where appropriate, the current
+ mbstate_t status object) for the given stream into the given pos object. The
+ actual contents of the object are unspecified, but it can be used as second
+ parameter to fsetpos() to reposition the stream to the exact position and
+ parse state at the time fgetpos() was called.
+ Returns zero if successful, nonzero otherwise.
+ TODO: Implementation-defined errno setting for fgetpos().
+*/
+int fgetpos( FILE * _PDCLIB_restrict stream, fpos_t * _PDCLIB_restrict pos );
+
+/* Set the position indicator for the given stream to the given offset from:
+ - the beginning of the file if whence is SEEK_SET,
+ - the current value of the position indicator if whence is SEEK_CUR,
+ - end-of-file if whence is SEEK_END.
+ On text streams, non-zero offsets are only allowed with SEEK_SET, and must
+ have been returned by ftell() for the same file.
+ Any characters buffered by ungetc() are dropped, the end-of-file indicator
+ for the stream is cleared. If the given stream is an update stream, the next
+ operation after a successful fseek() may be either input or output.
+ Returns zero if successful, nonzero otherwise. If a read/write error occurs,
+ the error indicator for the given stream is set.
+*/
+int fseek( FILE * stream, long int offset, int whence );
+
+/* Set the position indicator (and, where appropriate the mbstate_t status
+ object) for the given stream to the given pos object (created by an earlier
+ call to fgetpos() on the same file).
+ Any characters buffered by ungetc() are dropped, the end-of-file indicator
+ for the stream is cleared. If the given stream is an update stream, the next
+ operation after a successful fsetpos() may be either input or output.
+ Returns zero if successful, nonzero otherwise. If a read/write error occurs,
+ the error indicator for the given stream is set.
+ TODO: Implementation-defined errno setting for fsetpos().
+*/
+int fsetpos( FILE * stream, const fpos_t * pos );
+
+/* Return the current offset of the given stream from the beginning of the
+ associated file. For text streams, the exact value returned is unspecified
+ (and may not be equal to the number of characters), but may be used in
+ subsequent calls to fseek().
+ Returns -1L if unsuccessful.
+ TODO: Implementation-defined errno setting for ftell().
+*/
+long int ftell( FILE * stream );
+
+/* Equivalent to (void)fseek( stream, 0L, SEEK_SET ), except that the error
+ indicator for the stream is also cleared.
+*/
+void rewind( FILE * stream );
+
+/* Error-handling functions */
+
+/* Clear the end-of-file and error indicators for the given stream. */
+void clearerr( FILE * stream );
+
+/* Return zero if the end-of-file indicator for the given stream is not set,
+ nonzero otherwise.
+*/
+int feof( FILE * stream );
+
+/* Return zero if the error indicator for the given stream is not set, nonzero
+ otherwise.
+*/
+int ferror( FILE * stream );
+
+/* If s is neither a NULL pointer nor an empty string, print the string to
+ stderr (with appended colon (':') and a space) first. In any case, print an
+ error message depending on the current value of errno (being the same as if
+ strerror( errno ) had been called).
+*/
+void perror( const char * s );
+
+#endif
diff --git a/src/pdclib/include/stdlib.h b/src/pdclib/include/stdlib.h
new file mode 100644
index 0000000..5377bcd
--- /dev/null
+++ b/src/pdclib/include/stdlib.h
@@ -0,0 +1,242 @@
+/* General utilities <stdlib.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDLIB_H
+#define _PDCLIB_STDLIB_H _PDCLIB_STDLIB_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+#ifndef _PDCLIB_SIZE_T_DEFINED
+#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
+typedef _PDCLIB_size_t size_t;
+#endif
+
+#ifndef _PDCLIB_NULL_DEFINED
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
+#define NULL _PDCLIB_NULL
+#endif
+
+/* Numeric conversion functions */
+
+/* TODO: atof(), strtof(), strtod(), strtold() */
+
+double atof( const char * nptr );
+double strtod( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr );
+float strtof( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr );
+long double strtold( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr );
+
+/* Seperate the character array nptr into three parts: A (possibly empty)
+ sequence of whitespace characters, a character representation of an integer
+ to the given base, and trailing invalid characters (including the terminating
+ null character). If base is 0, assume it to be 10, unless the integer
+ representation starts with 0x / 0X (setting base to 16) or 0 (setting base to
+ 8). If given, base can be anything from 0 to 36, using the 26 letters of the
+ base alphabet (both lowercase and uppercase) as digits 10 through 35.
+ The integer representation is then converted into the return type of the
+ function. It can start with a '+' or '-' sign. If the sign is '-', the result
+ of the conversion is negated.
+ If the conversion is successful, the converted value is returned. If endptr
+ is not a NULL pointer, a pointer to the first trailing invalid character is
+ returned in *endptr.
+ If no conversion could be performed, zero is returned (and nptr in *endptr,
+ if endptr is not a NULL pointer). If the converted value does not fit into
+ the return type, the functions return LONG_MIN, LONG_MAX, ULONG_MAX,
+ LLONG_MIN, LLONG_MAX, or ULLONG_MAX respectively, depending on the sign of
+ the integer representation and the return type, and errno is set to ERANGE.
+*/
+/* There is strtoimax() and strtoumax() in <inttypes.h> operating on intmax_t /
+ uintmax_t, if the long long versions do not suit your needs.
+*/
+long int strtol( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base );
+long long int strtoll( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base );
+unsigned long int strtoul( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base );
+unsigned long long int strtoull( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base );
+
+/* These functions are the equivalent of (int)strtol( nptr, NULL, 10 ),
+ strtol( nptr, NULL, 10 ) and strtoll(nptr, NULL, 10 ) respectively, with the
+ exception that they do not have to handle overflow situations in any defined
+ way.
+ (PDCLib does not simply forward these to their strtox() equivalents, but
+ provides a simpler atox() function that saves a couple of tests and simply
+ continues with the conversion in case of overflow.)
+*/
+int atoi( const char * nptr );
+long int atol( const char * nptr );
+long long int atoll( const char * nptr );
+
+/* Pseudo-random sequence generation functions */
+
+extern unsigned long int _PDCLIB_seed;
+
+#define RAND_MAX 32767
+
+/* Returns the next number in a pseudo-random sequence, which is between 0 and
+ RAND_MAX.
+ (PDCLib uses the implementation suggested by the standard document, which is
+ next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;)
+*/
+int rand( void );
+
+/* Initialize a new pseudo-random sequence with the starting seed. Same seeds
+ result in the same pseudo-random sequence. The default seed is 1.
+*/
+void srand( unsigned int seed );
+
+/* Memory management functions */
+
+/* Allocate a chunk of heap memory of given size. If request could not be
+ satisfied, return NULL. Otherwise, return a pointer to the allocated
+ memory. Memory contents are undefined.
+*/
+void * malloc( size_t size );
+
+/* Allocate a chunk of heap memory that is large enough to hold nmemb elements
+ of the given size, and zero-initialize that memory. If request could not be
+ satisfied, return NULL. Otherwise, return a pointer to the allocated
+ memory.
+*/
+void * calloc( size_t nmemb, size_t size );
+
+/* De-allocate a chunk of heap memory previously allocated using malloc(),
+ calloc(), or realloc(), and pointed to by ptr. If ptr does not match a
+ pointer previously returned by the mentioned allocation functions, or
+ free() has already been called for this ptr, behaviour is undefined.
+*/
+void free( void * ptr );
+
+/* Resize a chunk of memory previously allocated with malloc() and pointed to
+ by ptr to the given size (which might be larger or smaller than the original
+ size). Returns a pointer to the reallocated memory, or NULL if the request
+ could not be satisfied. Note that the resizing might include a memcpy()
+ from the original location to a different one, so the return value might or
+ might not equal ptr. If size is larger than the original size, the value of
+ memory beyond the original size is undefined. If ptr is NULL, realloc()
+ behaves like malloc().
+*/
+void * realloc( void * ptr, size_t size );
+
+/* Communication with the environment */
+
+/* These two can be passed to exit() or _Exit() as status values, to signal
+ successful and unsuccessful program termination, respectively. EXIT_SUCCESS
+ can be replaced by 0. How successful or unsuccessful program termination are
+ signaled to the environment, and what happens if exit() or _Exit() are being
+ called with a value that is neither of the three, is defined by the hosting
+ OS and its glue function.
+*/
+#define EXIT_SUCCESS _PDCLIB_SUCCESS
+#define EXIT_FAILURE _PDCLIB_FAILURE
+
+/* Initiate abnormal process termination, unless programm catches SIGABRT and
+ does not return from the signal handler.
+ This implementantion flushes all streams, closes all files, and removes any
+ temporary files before exiting with EXIT_FAILURE.
+ abort() does not return.
+*/
+void abort( void );
+
+/* Register a function that will be called on exit(), or when main() returns.
+ At least 32 functions can be registered this way, and will be called in
+ reverse order of registration (last-in, first-out).
+ Returns zero if registration is successfull, nonzero if it failed.
+*/
+int atexit( void (*func)( void ) );
+
+/* Normal process termination. Functions registered by atexit() (see above) are
+ called, streams flushed, files closed and temporary files removed before the
+ program is terminated with the given status. (See comment for EXIT_SUCCESS
+ and EXIT_FAILURE above.)
+ exit() does not return.
+*/
+void exit( int status );
+
+/* Normal process termination. Functions registered by atexit() (see above) are
+ NOT CALLED. This implementation DOES flush streams, close files and removes
+ temporary files before the program is teminated with the given status. (See
+ comment for EXIT_SUCCESS and EXIT_FAILURE above.)
+ _Exit() does not return.
+*/
+void _Exit( int status );
+
+/* Search an environment-provided key-value map for the given key name, and
+ return a pointer to the associated value string (or NULL if key name cannot
+ be found). The value string pointed to might be overwritten by a subsequent
+ call to getenv(). The library never calls getenv() itself.
+ Details on the provided keys and how to set / change them are determined by
+ the hosting OS and its glue function.
+*/
+char * getenv( const char * name );
+
+/* If string is a NULL pointer, system() returns nonzero if a command processor
+ is available, and zero otherwise. If string is not a NULL pointer, it is
+ passed to the command processor. If system() returns, it does so with a
+ value that is determined by the hosting OS and its glue function.
+*/
+int system( const char * string );
+
+/* Searching and sorting */
+
+/* Do a binary search for a given key in the array with a given base pointer,
+ which consists of nmemb elements that are of the given size each. To compare
+ the given key with an element from the array, the given function compar is
+ called (with key as first parameter and a pointer to the array member as
+ second parameter); the function should return a value less than, equal to,
+ or greater than 0 if the key is considered to be less than, equal to, or
+ greater than the array element, respectively.
+ The function returns a pointer to the first matching element found, or NULL
+ if no match is found.
+*/
+void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) );
+
+/* Do a quicksort on an array with a given base pointer, which consists of
+ nmemb elements that are of the given size each. To compare two elements from
+ the array, the given function compar is called, which should return a value
+ less than, equal to, or greater than 0 if the first argument is considered
+ to be less than, equal to, or greater than the second argument, respectively.
+ If two elements are compared equal, their order in the sorted array is not
+ specified.
+*/
+void qsort( void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) );
+
+/* Integer arithmetic functions */
+
+/* Return the absolute value of the argument. Note that on machines using two-
+ complement's notation (most modern CPUs), the largest negative value cannot
+ be represented as positive value. In this case, behaviour is unspecified.
+*/
+int abs( int j );
+long int labs( long int j );
+long long int llabs( long long int j );
+
+/* These structures each have a member quot and a member rem, of type int (for
+ div_t), long int (for ldiv_t) and long long it (for lldiv_t) respectively.
+ The order of the members is platform-defined to allow the div() functions
+ below to be implemented efficiently.
+*/
+typedef struct _PDCLIB_div_t div_t;
+typedef struct _PDCLIB_ldiv_t ldiv_t;
+typedef struct _PDCLIB_lldiv_t lldiv_t;
+
+/* Return quotient (quot) and remainder (rem) of an integer division in one of
+ the structs above.
+*/
+div_t div( int numer, int denom );
+ldiv_t ldiv( long int numer, long int denom );
+lldiv_t lldiv( long long int numer, long long int denom );
+
+/* TODO: Multibyte / wide character conversion functions */
+
+/* TODO: Macro MB_CUR_MAX */
+
+/*
+int mblen( const char * s, size_t n );
+int mbtowc( wchar_t * _PDCLIB_restrict pwc, const char * _PDCLIB_restrict s, size_t n );
+int wctomb( char * s, wchar_t wc );
+size_t mbstowcs( wchar_t * _PDCLIB_restrict pwcs, const char * _PDCLIB_restrict s, size_t n );
+size_t wcstombs( char * _PDCLIB_restrict s, const wchar_t * _PDCLIB_restrict pwcs, size_t n );
+*/
+
+#endif
diff --git a/src/pdclib/include/stdnoreturn.h b/src/pdclib/include/stdnoreturn.h
new file mode 100644
index 0000000..8c18143
--- /dev/null
+++ b/src/pdclib/include/stdnoreturn.h
@@ -0,0 +1,12 @@
+/* _Noreturn <stdnoreturn.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDNORETURN_H
+#define _PDCLIB_STDNORETURN_H _PDCLIB_STDNORETURN_H
+
+#define noreturn _Noreturn
+
+#endif
diff --git a/src/pdclib/include/string.h b/src/pdclib/include/string.h
new file mode 100644
index 0000000..dc0af15
--- /dev/null
+++ b/src/pdclib/include/string.h
@@ -0,0 +1,185 @@
+/* String handling <string.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STRING_H
+#define _PDCLIB_STRING_H _PDCLIB_STRING_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+#ifndef _PDCLIB_SIZE_T_DEFINED
+#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
+typedef _PDCLIB_size_t size_t;
+#endif
+
+#ifndef _PDCLIB_NULL_DEFINED
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
+#define NULL _PDCLIB_NULL
+#endif
+
+/* String function conventions */
+
+/*
+ In any of the following functions taking a size_t n to specify the length of
+ an array or size of a memory region, n may be 0, but the pointer arguments to
+ the call shall still be valid unless otherwise stated.
+*/
+
+/* Copying functions */
+
+/* Copy a number of n characters from the memory area pointed to by s2 to the
+ area pointed to by s1. If the two areas overlap, behaviour is undefined.
+ Returns the value of s1.
+*/
+void * memcpy( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );
+
+/* Copy a number of n characters from the memory area pointed to by s2 to the
+ area pointed to by s1. The two areas may overlap.
+ Returns the value of s1.
+*/
+void * memmove( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );
+
+/* Copy the character array s2 (including terminating '\0' byte) into the
+ character array s1.
+ Returns the value of s1.
+*/
+char * strcpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
+
+/* Copy a maximum of n characters from the character array s2 into the character
+ array s1. If s2 is shorter than n characters, '\0' bytes will be appended to
+ the copy in s1 until n characters have been written. If s2 is longer than n
+ characters, NO terminating '\0' will be written to s1. If the arrays overlap,
+ behaviour is undefined.
+ Returns the value of s1.
+*/
+char * strncpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
+
+/* Concatenation functions */
+
+/* Append the contents of the character array s2 (including terminating '\0') to
+ the character array s1 (first character of s2 overwriting the '\0' of s1). If
+ the arrays overlap, behaviour is undefined.
+ Returns the value of s1.
+*/
+char * strcat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
+
+/* Append a maximum of n characters from the character array s1 to the character
+ array s1 (first character of s2 overwriting the '\0' of s1). A terminating
+ '\0' is ALWAYS appended, even if the full n characters have already been
+ written. If the arrays overlap, behaviour is undefined.
+ Returns the value of s1.
+*/
+char * strncat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
+
+/* Comparison functions */
+
+/* Compare the first n characters of the memory areas pointed to by s1 and s2.
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
+ s1 > s2.
+*/
+int memcmp( const void * s1, const void * s2, size_t n );
+
+/* Compare the character arrays s1 and s2.
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
+ s1 > s2.
+*/
+int strcmp( const char * s1, const char * s2 );
+
+/* Compare the character arrays s1 and s2, interpreted as specified by the
+ LC_COLLATE category of the current locale.
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
+ s1 > s2.
+ TODO: Currently a dummy wrapper for strcmp() as PDCLib does not yet support
+ locales.
+*/
+int strcoll( const char * s1, const char * s2 );
+
+/* Compare no more than the first n characters of the character arrays s1 and
+ s2.
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
+ s1 > s2.
+*/
+int strncmp( const char * s1, const char * s2, size_t n );
+
+/* Transform the character array s2 as appropriate for the LC_COLLATE setting of
+ the current locale. If length of resulting string is less than n, store it in
+ the character array pointed to by s1. Return the length of the resulting
+ string.
+*/
+size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
+
+/* Search functions */
+
+/* Search the first n characters in the memory area pointed to by s for the
+ character c (interpreted as unsigned char).
+ Returns a pointer to the first instance found, or NULL.
+*/
+void * memchr( const void * s, int c, size_t n );
+
+/* Search the character array s (including terminating '\0') for the character c
+ (interpreted as char).
+ Returns a pointer to the first instance found, or NULL.
+*/
+char * strchr( const char * s, int c );
+
+/* Determine the length of the initial substring of character array s1 which
+ consists only of characters not from the character array s2.
+ Returns the length of that substring.
+*/
+size_t strcspn( const char * s1, const char * s2 );
+
+/* Search the character array s1 for any character from the character array s2.
+ Returns a pointer to the first occurrence, or NULL.
+*/
+char * strpbrk( const char * s1, const char * s2 );
+
+/* Search the character array s (including terminating '\0') for the character c
+ (interpreted as char).
+ Returns a pointer to the last instance found, or NULL.
+*/
+char * strrchr( const char * s, int c );
+
+/* Determine the length of the initial substring of character array s1 which
+ consists only of characters from the character array s2.
+ Returns the length of that substring.
+*/
+size_t strspn( const char * s1, const char * s2 );
+
+/* Search the character array s1 for the substring in character array s2.
+ Returns a pointer to that sbstring, or NULL. If s2 is of length zero,
+ returns s1.
+*/
+char * strstr( const char * s1, const char * s2 );
+
+/* In a series of subsequent calls, parse a C string into tokens.
+ On the first call to strtok(), the first argument is a pointer to the to-be-
+ parsed C string. On subsequent calls, the first argument is NULL unless you
+ want to start parsing a new string. s2 holds an array of seperator characters
+ which can differ from call to call. Leading seperators are skipped, the first
+ trailing seperator overwritten with '\0'.
+ Returns a pointer to the next token.
+ WARNING: This function uses static storage, and as such is not reentrant.
+*/
+char * strtok( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
+
+/* Miscellaneous functions */
+
+/* Write the character c (interpreted as unsigned char) to the first n
+ characters of the memory area pointed to by s.
+ Returns s.
+*/
+void * memset( void * s, int c, size_t n );
+
+/* Map an error number to a (locale-specific) error message string. Error
+ numbers are typically errno values, but any number is mapped to a message.
+ TODO: PDCLib does not yet support locales.
+*/
+char * strerror( int errnum );
+
+/* Returns the length of the string s (excluding terminating '\0').
+*/
+size_t strlen( const char * s );
+
+#endif
diff --git a/src/pdclib/include/time.h b/src/pdclib/include/time.h
new file mode 100644
index 0000000..fb1af0b
--- /dev/null
+++ b/src/pdclib/include/time.h
@@ -0,0 +1,112 @@
+/* Date and time <time.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_TIME_H
+#define _PDCLIB_TIME_H _PDCLIB_TIMEH
+
+#include "pdclib/_PDCLIB_int.h"
+
+#ifndef _PDCLIB_SIZE_T_DEFINED
+#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
+typedef _PDCLIB_size_t size_t;
+#endif
+
+#ifndef _PDCLIB_NULL_DEFINED
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
+#define NULL _PDCLIB_NULL
+#endif
+
+/* These are defined to be "real types capable of representing types", with
+ "range and precision of times representable in [them being] implementation-
+ defined".
+ As part of struct timespec (see below), time_t is further defined as "a
+ linear count of seconds", with potentially different semantics from a
+ "normal" time_t.
+ For sake of simplicity, we used just that (common) definition of "seconds
+ since epoch" as integer.
+*/
+typedef _PDCLIB_time_t time_t;
+typedef _PDCLIB_clock_t clock_t;
+
+#define CLOCKS_PER_SEC _PDCLIB_CLOCKS_PER_SEC
+#define TIME_UTC _PDCLIB_TIME_UTC
+
+struct timespec
+{
+ time_t tv_sec;
+ long tv_nsec;
+};
+
+struct tm
+{
+ int tm_sec; /* 0-60 */
+ int tm_min; /* 0-59 */
+ int tm_hour; /* 0-23 */
+ int tm_mday; /* 1-31 */
+ int tm_mon; /* 0-11 */
+ int tm_year; /* years since 1900 */
+ int tm_wday; /* 0-6 */
+ int tm_yday; /* 0-365 */
+ int tm_isdst; /* >0 DST, 0 no DST, <0 information unavailable */
+};
+
+/* Returns the number of "clocks" in processor time since the invocation
+ of the program. Divide by CLOCKS_PER_SEC to get the value in seconds.
+ Returns -1 if the value cannot be represented in the return type or is
+ not available.
+*/
+clock_t clock( void );
+
+/* Returns the difference between two calendar times in seconds. */
+double difftime( time_t time1, time_t time0 );
+
+/* Normalizes the values in the broken-down time pointed to by timeptr.
+ Returns the calender time specified by the broken-down time.
+*/
+time_t mktime( struct tm * timeptr );
+
+/* Returns the current calender time. If timer is not a NULL pointer, stores
+ the current calender time at that address as well.
+*/
+time_t time( time_t * timer );
+
+/* Sets the interval pointed to by ts to the current calender time, based
+ on the specified base.
+ Returns base, if successful, otherwise zero.
+*/
+int timespec_get( struct timespec * ts, int base );
+
+/* Converts the broken-down time pointed to by timeptr into a string in the
+ form "Sun Sep 16 01:03:52 1973\n\0".
+*/
+char * asctime( const struct tm * timeptr );
+
+/* Equivalent to asctime( localtime( timer ) ). */
+char * ctime( const time_t * timer );
+
+/* Converts the calender time pointed to by timer into a broken-down time
+ expressed as UTC.
+ Returns a pointer to the broken-down time, or a NULL pointer if it
+ cannot be represented.
+*/
+struct tm * gmtime( const time_t * timer );
+
+/* Converts the calender time pointed to by timer into a broken-down time
+ expressed as local time.
+ Returns a pointer to the broken-down time, or a NULL pointer if if
+ cannot be represented.
+*/
+struct tm * localtime( const time_t * timer );
+
+/* Writes the broken-down time pointed to by timeptr into the character
+ array pointed to by s. The string pointed to by format controls the
+ exact output. No more than maxsize charactrs will be written.
+ Returns the number of characters written (excluding the terminating
+ null character), or zero on failure.
+*/
+size_t strftime( char * _PDCLIB_restrict s, size_t maxsize, const char * _PDCLIB_restrict format, const struct tm * _PDCLIB_restrict timeptr );
+
+#endif
diff --git a/src/pdclib/include/wctype.h b/src/pdclib/include/wctype.h
new file mode 100644
index 0000000..5449930
--- /dev/null
+++ b/src/pdclib/include/wctype.h
@@ -0,0 +1,138 @@
+/* Wide character classification and mapping utilities <wctype.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_WCTYPE_H
+#define _PDCLIB_WCTYPE_H _PDCLIB_WCTYPE_H
+
+#include "pdclib/_PDCLIB_int.h"
+
+typedef _PDCLIB_wint_t wint_t;
+
+// wctrans_t
+// wctype_t
+
+#ifndef _PDCLIB_WEOF_DEFINED
+#define _PDCLIB_WEOF_DEFINED _PDCLIB_WEOF_DEFINED
+#define WEOF (wint_t)-1
+#endif
+
+/* Wide character classification functions */
+
+/* Returns iswalpha( wc ) || iswdigit( wc ) */
+int iswalnum( wint_t wc );
+
+/* Returns true for wide characters for which either isupper( wc ) or
+ islower( wc ) is true, as well as a set of locale-specific wide
+ characters which are neither control characters, digits, punctuation,
+ or whitespace.
+*/
+int iswalpha( wint_t wc );
+
+/* Returns true if the character iswspace() and used for separating words
+ within a line of text. In the "C" locale, only L' ' and L'\t' are
+ considered blanks.
+*/
+int iswblank( wint_t wc );
+
+/* Returns true if the wide character is a control character. */
+int iswcntrl( wint_t wc );
+
+/* Returns true if the wide character is a decimal digit. Locale-
+ independent. */
+int iswdigit( wint_t wc );
+
+/* Returns iswprint( wc ) && ! iswspace( wc ).
+ NOTE: This definition differs from that of isgraph() in <ctype.h>,
+ which considers only ' ', not all isspace() characters.
+*/
+int iswgraph( wint_t wc );
+
+/* Returns true for lowerspace wide characters, as well as a set of
+ locale-specific wide characters which are neither control charcters,
+ digits, punctuation, or whitespace.
+*/
+int iswlower( wint_t wc );
+
+/* Returns true for every printing wide character. */
+int iswprint( wint_t wc );
+
+/* Returns true for a locale-specific set of punctuation characters that
+ are neither whitespace nor alphanumeric.
+*/
+int iswpunct( wint_t wc );
+
+/* Returns true for a locale-specific set of whitespace characters that
+ are neither alphanumeric, graphic, or punctuation.
+*/
+int iswspace( wint_t wc );
+
+/* Returns true for upperspace wide characters, as well as a set of
+ locale-specific wide characters which are neither control charcters,
+ digits, punctuation, or whitespace.
+*/
+int iswupper( wint_t wc );
+
+/* Returns true if the wide character is a hexadecimal digit. Locale-
+ independent. */
+int iswxdigit( wint_t wc );
+
+/* Extensible wide character classification functions */
+
+/* Returns true if the wide character wc has the property described by
+ desc (which was retrieved by a previous call to wctype() without
+ changing the LC_CTYPE locale setting between the two calls).
+*/
+int iswctype( wint_t wc, wctype_t desc );
+
+/* Returns a description object for a named character property, to be
+ used as parameter to the iswctype() function. Supported property
+ names are:
+ "alnum" -- alphanumeric, as per iswalnum()
+ "alpha" -- alphabetic, as per iswalpha()
+ "blank" -- blank, as per iswblank()
+ "cntrl" -- control, as per iswcntrl()
+ "digit" -- decimal digit, as per iswdigit()
+ "graph" -- graphic, as per iswgraph()
+ "lower" -- lowercase, as per iswlower()
+ "print" -- printing, as per iswprint()
+ "punct" -- punctuation, as per iswprint()
+ "space" -- whitespace, as per iswspace()
+ "upper" -- uppercase, as per iswupper()
+ "xdigit" -- hexadecimal digit, as per iswxdigit()
+ For unsupported properties, the function returns zero.
+*/
+wctype_t wctype( const char * property );
+
+/* Wide character case mapping utilities */
+
+/* Converts an uppercase letter to a corresponding lowercase letter. Input for
+ which no corresponding lowercase letter exists remains unchanged.
+*/
+wint_t towlower( wint_t wc );
+
+/* Converts a lowercase letter to a corresponding uppercase letter. Input for
+ which no corresponding uppercase letter exists remains unchanged.
+*/
+wint_t towupper( wint_t wc );
+
+/* Extensible wide character case mapping utilities */
+
+/* Converts the wide character wc according to the transition described
+ by desc (which was retrieved by a previous call to wctrans() without
+ changing the LC_CTYPE locale setting between the two calls).
+*/
+wint_t towctrans( wint_t wc, wctrans_t desc );
+
+/* Returns a description object for a named character transformation, to
+ be used as parameter to the towctrans() function. Supported transformation
+ properties are:
+ "tolower" -- lowercase mapping, as per towlower()
+ "toupper" -- uppercase mapping, as per towupper()
+ For unsupported properties, the function returns zero.
+*/
+wctrans_t wctrans( const char * property );
+
+#endif