#include <_PDCLIB_aux.h>
-#if _PDCLIB_C_VERSION == 99
-void _PDCLIB_assert( char const * const message1, char const * const function, char const * const message2 )
+void _PDCLIB_assert99( char const * const message1, char const * const function, char const * const message2 )
{
fputs( message1, stderr );
fputs( function, stderr );
fputs( message2, stderr );
abort();
}
-#else
-void _PDCLIB_assert( char const * const message )
+
+void _PDCLIB_assert89( char const * const message )
{
fputs( message, stderr );
abort();
}
-#endif
#endif
+++ /dev/null
-/* gets( char * )
-
- This file is part of the Public Domain C Library (PDCLib).
- Permission is granted to use, modify, and / or redistribute at will.
-*/
-
-#include <stdio.h>
-
-#ifndef REGTEST
-
-#include <_PDCLIB_glue.h>
-
-char * gets( char * s )
-{
- if ( _PDCLIB_prepread( stdin ) == EOF )
- {
- return NULL;
- }
- char * dest = s;
- while ( ( *dest = stdin->buffer[stdin->bufidx++] ) != '\n' )
- {
- ++dest;
- if ( stdin->bufidx == stdin->bufend )
- {
- if ( _PDCLIB_fillbuffer( stdin ) == EOF )
- {
- break;
- }
- }
- }
- *dest = '\0';
- return ( dest == s ) ? NULL : s;
-}
-
-#endif
-
-#ifdef TEST
-#include <_PDCLIB_test.h>
-#include <string.h>
-
-int main( void )
-{
- FILE * fh;
- char buffer[10];
- char const * gets_test = "foo\nbar\0baz\nweenie";
- TESTCASE( ( fh = fopen( testfile, "wb" ) ) != NULL );
- TESTCASE( fwrite( gets_test, 1, 18, fh ) == 18 );
- TESTCASE( fclose( fh ) == 0 );
- TESTCASE( ( fh = freopen( testfile, "rb", stdin ) ) != NULL );
- TESTCASE( gets( buffer ) == buffer );
- TESTCASE( strcmp( buffer, "foo" ) == 0 );
- TESTCASE( gets( buffer ) == buffer );
- TESTCASE( memcmp( buffer, "bar\0baz\0", 8 ) == 0 );
- TESTCASE( gets( buffer ) == buffer );
- TESTCASE( strcmp( buffer, "weenie" ) == 0 );
- TESTCASE( feof( fh ) );
- TESTCASE( fseek( fh, -1, SEEK_END ) == 0 );
- TESTCASE( gets( buffer ) == buffer );
- TESTCASE( strcmp( buffer, "e" ) == 0 );
- TESTCASE( feof( fh ) );
- TESTCASE( fseek( fh, 0, SEEK_END ) == 0 );
- TESTCASE( gets( buffer ) == NULL );
- TESTCASE( fclose( fh ) == 0 );
- TESTCASE( remove( testfile ) == 0 );
- return TEST_RESULTS;
-}
-
-#endif
-
*/
#include <_PDCLIB_aux.h>
-#include <_PDCLIB_config.h>
#ifndef _PDCLIB_ASSERT_H
#define _PDCLIB_ASSERT_H _PDCLIB_ASSERT_H
-#if _PDCLIB_C_VERSION == 99
-void _PDCLIB_assert( char const * const, char const * const, char const * const );
-#else
-void _PDCLIB_assert( char const * const );
-#endif
+void _PDCLIB_assert99( char const * const, char const * const, char const * const );
+void _PDCLIB_assert89( char const * const );
#endif
/* If NDEBUG is set, assert() is a null operation. */
#ifdef NDEBUG
#define assert( ignore ) ( (void) 0 )
#else
-#if _PDCLIB_C_VERSION == 99
+#if __STDC_VERSION__ >= 199901L
#define assert( expression ) ( ( expression ) ? (void) 0 \
- : _PDCLIB_assert( "Assertion failed: " #expression \
- ", function ", __func__, \
- ", file " __FILE__ \
- ", line " _PDCLIB_symbol2string( __LINE__ ) \
- "." _PDCLIB_endl ) )
+ : _PDCLIB_assert99( "Assertion failed: " #expression \
+ ", function ", __func__, \
+ ", file " __FILE__ \
+ ", line " _PDCLIB_symbol2string( __LINE__ ) \
+ "." _PDCLIB_endl ) )
#else
#define assert( expression ) ( ( expression ) ? (void) 0 \
- : _PDCLIB_assert( "Assertion failed: " #expression \
- ", file " __FILE__ \
- ", line " _PDCLIB_symbol2string( __LINE__ ) \
- "." _PDCLIB_endl ) )
+ : _PDCLIB_assert89( "Assertion failed: " #expression \
+ ", file " __FILE__ \
+ ", line " _PDCLIB_symbol2string( __LINE__ ) \
+ "." _PDCLIB_endl ) )
#endif
#endif
-
/* Equivalent to fgetc( stdin ). */
int getchar( void );
-/* Read characters from given stream into the array s, stopping at \n or EOF.
- The string read is terminated with \0. Returns s if successful. If EOF is
- encountered before any characters are read, the contents of s are unchanged,
- and NULL is returned. If a read error occurs, the contents of s are indeter-
- minate, and NULL is returned.
-*/
-char * gets( char * s );
-
/* Equivalent to fputc( c, stream ), but may be overloaded by a macro that
evaluates its parameter more than once.
*/
#error Compiler does not define _ _STDC_ _ to 1 (not standard-compliant)!
#endif
-#ifndef __STDC_VERSION__
-#define _PDCLIB_C_VERSION 90
+#if __STDC_VERSION__ < 199901L
#define _PDCLIB_restrict
#define _PDCLIB_inline
-#elif __STDC_VERSION__ == 199409L
-#define _PDCLIB_C_VERSION 95
-#define _PDCLIB_restrict
-#define _PDCLIB_inline
-#elif __STDC_VERSION__ == 199901L
-#define _PDCLIB_C_VERSION 99
+#error PDCLib might not be fully conforming to either C89 or C95 prior to v2.x.
+#else
#define _PDCLIB_restrict restrict
#define _PDCLIB_inline inline
-#else
-#error Unsupported _ _STDC_VERSION_ _ (__STDC_VERSION__) (supported: ISO/IEC 9899:1990, 9899/AMD1:1995, and 9899:1999).
#endif
#ifndef __STDC_HOSTED__
#error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
#endif
-#if _PDCLIB_C_VERSION != 99
-#error PDCLib might not be fully conforming to either C89 or C95 prior to v2.x.
-#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. */
/* -------------------------------------------------------------------------- */
#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_symbol2value( x ) #x
#define _PDCLIB_symbol2string( x ) _PDCLIB_symbol2value( x )
unsigned char collation;
};
+/* -------------------------------------------------------------------------- */
+/* Configuration asserts */
+/* -------------------------------------------------------------------------- */
+
+_PDCLIB_static_assert( _PDCLIB_CHAR_BIT == 8, "CHAR_BIT != 8 not supported." );
+
+_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." );
+
+int _PDCLIB_assert_array[2];
+
+_PDCLIB_static_assert( sizeof( &_PDCLIB_assert_array[1] - &_PDCLIB_assert_array[0] ) == sizeof( _PDCLIB_ptrdiff ), "Compiler disagrees on _PDCLIB_ptrdiff." );
+
#endif
/* to nothing. (This is to avoid warnings with the exit functions under GCC.) */
#define _PDCLIB_NORETURN __attribute__(( noreturn ))
-/* The maximum value that errno can be set to. This is used to set the size */
-/* of the array in struct lconv (<locale.h>) holding error messages for the */
-/* strerror() and perror() functions. (If you change this value because you */
-/* are using additional errno values, you *HAVE* to provide appropriate error */
-/* messages for *ALL* locales.) */
-/* Default is 4 (0, ERANGE, EDOM, EILSEQ). */
-#define _PDCLIB_ERRNO_MAX 4
-
/* -------------------------------------------------------------------------- */
/* Integers */
/* -------------------------------------------------------------------------- */
*/
#define _PDCLIB_ERROR 4
+/* The maximum value that errno can be set to. This is used to set the size */
+/* of the array in struct lconv (<locale.h>) holding error messages for the */
+/* strerror() and perror() functions. (If you change this value because you */
+/* are using additional errno values, you *HAVE* to provide appropriate error */
+/* messages for *ALL* locales.) */
+/* Default is 4 (0, ERANGE, EDOM, EILSEQ). */
+#define _PDCLIB_ERRNO_MAX 4
+
#endif
*/
#define _PDCLIB_UNGETCBUFSIZE 1
+/* errno -------------------------------------------------------------------- */
+
+/* These are the values that _PDCLIB_errno can be set to by the library.
+
+ By keeping PDCLib's errno in the _PDCLIB_* namespace, the library is capable
+ to "translate" between errno values used by the hosting operating system and
+ those used and passed out by the library.
+
+ Example: In the example platform, the remove() function uses the unlink()
+ system call as backend. Linux sets its errno to EISDIR if you try to unlink()
+ a directory, but POSIX demands EPERM. Within the remove() function, you can
+ catch the 'errno == EISDIR', and set '_PDCLIB_errno = _PDCLIB_EPERM'. Anyone
+ using PDCLib's <errno.h> will "see" EPERM instead of EISDIR (the _PDCLIB_*
+ prefix removed by <errno.h> mechanics).
+
+ If you do not want that kind of translation, you might want to "match" the
+ values used by PDCLib with those used by the host OS, as to avoid confusion.
+
+ The standard only defines three distinct errno values: ERANGE, EDOM, and
+ EILSEQ. The standard leaves it up to "the implementation" whether there are
+ any more beyond those three. There is some controversy as to whether errno is
+ such a good idea at all, so you might want to come up with a different error
+ reporting facility for your platform. Since errno values beyond the three
+ defined by the standard are not portable anyway (unless you look at POSIX),
+ having your own error reporting facility would not hurt anybody either.
+*/
+#define _PDCLIB_ERANGE 1
+#define _PDCLIB_EDOM 2
+#define _PDCLIB_EILSEQ 3
+
+/* The following is not strictly "configuration", but there is no better place
+ to explain it than here.
+
+ PDCLib strives to be as generic as possible, so by default it does NOT define
+ any values beyond the three standard ones above, even where it would have
+ been prudent and convenient to do so. Any errno "caught" from the host OS,
+ and some internal error conditions as well, are all lumped together into the
+ value of '_PDCLIB_ERROR'.
+
+ '_PDCLIB_ERROR' is STRICLY meant as a PLACEHOLDER only.
+
+ You should NEVER ship an adaption of PDCLib still using that particular
+ value. You should NEVER write code that *tests* for that value. Indeed it is
+ not even conforming, since errno values should be defined as beginning with
+ an uppercase 'E', and there is no mechanics in <errno.h> to unmask that
+ particular value (for exactly that reason).
+
+ There also is no error message available for this value through either the
+ strerror() or perror() functions. It is being reported as "unknown" error.
+
+ The idea is that you scan the source of PDCLib for occurrences of this macro
+ and replace _PDCLIB_ERROR with whatever additional errno value you came up
+ with for your platform.
+
+ If you cannot find it within you to do that, tell your clients to check for
+ an errno value larger than zero. That, at least, would be standard compliant
+ (and fully portable).
+*/
+#define _PDCLIB_ERROR 4
+
+/* The maximum value that errno can be set to. This is used to set the size */
+/* of the array in struct lconv (<locale.h>) holding error messages for the */
+/* strerror() and perror() functions. (If you change this value because you */
+/* are using additional errno values, you *HAVE* to provide appropriate error */
+/* messages for *ALL* locales.) */
+/* Default is 4 (0, ERANGE, EDOM, EILSEQ). */
+#define _PDCLIB_ERRNO_MAX 4
+
#endif
*/
#define _PDCLIB_UNGETCBUFSIZE 1
-typedef long wint_t;
+/* errno -------------------------------------------------------------------- */
+
+/* These are the values that _PDCLIB_errno can be set to by the library.
+
+ By keeping PDCLib's errno in the _PDCLIB_* namespace, the library is capable
+ to "translate" between errno values used by the hosting operating system and
+ those used and passed out by the library.
+
+ Example: In the example platform, the remove() function uses the unlink()
+ system call as backend. Linux sets its errno to EISDIR if you try to unlink()
+ a directory, but POSIX demands EPERM. Within the remove() function, you can
+ catch the 'errno == EISDIR', and set '_PDCLIB_errno = _PDCLIB_EPERM'. Anyone
+ using PDCLib's <errno.h> will "see" EPERM instead of EISDIR (the _PDCLIB_*
+ prefix removed by <errno.h> mechanics).
+
+ If you do not want that kind of translation, you might want to "match" the
+ values used by PDCLib with those used by the host OS, as to avoid confusion.
+
+ The standard only defines three distinct errno values: ERANGE, EDOM, and
+ EILSEQ. The standard leaves it up to "the implementation" whether there are
+ any more beyond those three. There is some controversy as to whether errno is
+ such a good idea at all, so you might want to come up with a different error
+ reporting facility for your platform. Since errno values beyond the three
+ defined by the standard are not portable anyway (unless you look at POSIX),
+ having your own error reporting facility would not hurt anybody either.
+*/
+#define _PDCLIB_ERANGE 1
+#define _PDCLIB_EDOM 2
+#define _PDCLIB_EILSEQ 3
+
+/* The following is not strictly "configuration", but there is no better place
+ to explain it than here.
+
+ PDCLib strives to be as generic as possible, so by default it does NOT define
+ any values beyond the three standard ones above, even where it would have
+ been prudent and convenient to do so. Any errno "caught" from the host OS,
+ and some internal error conditions as well, are all lumped together into the
+ value of '_PDCLIB_ERROR'.
+
+ '_PDCLIB_ERROR' is STRICLY meant as a PLACEHOLDER only.
+
+ You should NEVER ship an adaption of PDCLib still using that particular
+ value. You should NEVER write code that *tests* for that value. Indeed it is
+ not even conforming, since errno values should be defined as beginning with
+ an uppercase 'E', and there is no mechanics in <errno.h> to unmask that
+ particular value (for exactly that reason).
+
+ There also is no error message available for this value through either the
+ strerror() or perror() functions. It is being reported as "unknown" error.
+
+ The idea is that you scan the source of PDCLib for occurrences of this macro
+ and replace _PDCLIB_ERROR with whatever additional errno value you came up
+ with for your platform.
+
+ If you cannot find it within you to do that, tell your clients to check for
+ an errno value larger than zero. That, at least, would be standard compliant
+ (and fully portable).
+*/
+#define _PDCLIB_ERROR 4
+
+/* The maximum value that errno can be set to. This is used to set the size */
+/* of the array in struct lconv (<locale.h>) holding error messages for the */
+/* strerror() and perror() functions. (If you change this value because you */
+/* are using additional errno values, you *HAVE* to provide appropriate error */
+/* messages for *ALL* locales.) */
+/* Default is 4 (0, ERANGE, EDOM, EILSEQ). */
+#define _PDCLIB_ERRNO_MAX 4
#endif