From 0c316ee3b4dc0712797877f5dc0f4a789646154d Mon Sep 17 00:00:00 2001 From: solar Date: Fri, 12 Mar 2010 11:08:14 +0000 Subject: [PATCH] Compiling under Cygwin now. --- Makefile | 2 +- functions/stdio/fgetc.c | 4 +- functions/stdio/fputc.c | 4 +- functions/stdio/fread.c | 4 +- functions/stdio/fwrite.c | 4 +- functions/stdlib/div.c | 8 +- functions/stdlib/ldiv.c | 8 +- functions/stdlib/lldiv.c | 8 +- functions/stdlib/strtol.c | 9 +- functions/stdlib/strtoll.c | 9 +- platform/example_cygwin/Readme.txt | 24 ++ .../example_cygwin/functions/_PDCLIB/_Exit.c | 38 +++ .../functions/_PDCLIB/allocpages.c | 77 +++++ .../example_cygwin/functions/_PDCLIB/close.c | 36 +++ .../functions/_PDCLIB/fillbuffer.c | 74 +++++ .../functions/_PDCLIB/flushbuffer.c | 103 +++++++ .../example_cygwin/functions/_PDCLIB/open.c | 162 +++++++++++ .../example_cygwin/functions/_PDCLIB/rename.c | 128 +++++++++ .../example_cygwin/functions/_PDCLIB/seek.c | 66 +++++ .../functions/_PDCLIB/stdinit.c | 55 ++++ .../example_cygwin/functions/stdio/remove.c | 64 +++++ .../example_cygwin/functions/stdio/tmpfile.c | 30 ++ .../example_cygwin/functions/stdio/tmpnam.c | 31 ++ .../example_cygwin/functions/stdlib/getenv.c | 46 +++ .../example_cygwin/functions/stdlib/system.c | 47 +++ platform/example_cygwin/includes/float.h | 80 ++++++ .../example_cygwin/internals/_PDCLIB_config.h | 272 ++++++++++++++++++ 27 files changed, 1352 insertions(+), 41 deletions(-) create mode 100644 platform/example_cygwin/Readme.txt create mode 100644 platform/example_cygwin/functions/_PDCLIB/_Exit.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/allocpages.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/close.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/fillbuffer.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/flushbuffer.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/open.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/rename.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/seek.c create mode 100644 platform/example_cygwin/functions/_PDCLIB/stdinit.c create mode 100644 platform/example_cygwin/functions/stdio/remove.c create mode 100644 platform/example_cygwin/functions/stdio/tmpfile.c create mode 100644 platform/example_cygwin/functions/stdio/tmpnam.c create mode 100644 platform/example_cygwin/functions/stdlib/getenv.c create mode 100644 platform/example_cygwin/functions/stdlib/system.c create mode 100644 platform/example_cygwin/includes/float.h create mode 100644 platform/example_cygwin/internals/_PDCLIB_config.h diff --git a/Makefile b/Makefile index e9ba02e..6abc696 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ SRCFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.c") # All header files of the project HDRFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.h") # All .c files in functions/_PDCLIB that do not have a regression test driver -INTFILES := _Exit atomax digits open print scan remove rename seed stdinit strtox_main strtox_prelim cleanstream fflush filemode eol errno seek prepread prepwrite +INTFILES := _Exit atomax digits open print scan remove rename seed stdinit strtox_main strtox_prelim cleanstream fflush filemode eol errno seek prepread prepwrite allocpages # All object files in the library OBJFILES := $(patsubst %.c,%.o,$(SRCFILES)) # All test drivers (.t) diff --git a/functions/stdio/fgetc.c b/functions/stdio/fgetc.c index 1a90eb9..667bfed 100644 --- a/functions/stdio/fgetc.c +++ b/functions/stdio/fgetc.c @@ -8,10 +8,10 @@ #include -#include <_PDCLIB_glue.h> - #ifndef REGTEST +#include <_PDCLIB_glue.h> + int fgetc( struct _PDCLIB_file_t * stream ) { if ( _PDCLIB_prepread( stream ) == EOF ) diff --git a/functions/stdio/fputc.c b/functions/stdio/fputc.c index beff43a..818d45f 100644 --- a/functions/stdio/fputc.c +++ b/functions/stdio/fputc.c @@ -8,10 +8,10 @@ #include -#include <_PDCLIB_glue.h> - #ifndef REGTEST +#include <_PDCLIB_glue.h> + /* Write the value c (cast to unsigned char) to the given stream. Returns c if successful, EOF otherwise. If a write error occurs, the error indicator of the stream is set. diff --git a/functions/stdio/fread.c b/functions/stdio/fread.c index b77b5dd..53e22a6 100644 --- a/functions/stdio/fread.c +++ b/functions/stdio/fread.c @@ -7,13 +7,13 @@ */ #include -#include <_PDCLIB_glue.h> - #ifndef REGTEST #include #include +#include <_PDCLIB_glue.h> + size_t fread( void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, struct _PDCLIB_file_t * _PDCLIB_restrict stream ) { if ( _PDCLIB_prepread( stream ) == EOF ) diff --git a/functions/stdio/fwrite.c b/functions/stdio/fwrite.c index 8e5db3d..9cf3cad 100644 --- a/functions/stdio/fwrite.c +++ b/functions/stdio/fwrite.c @@ -7,13 +7,13 @@ */ #include -#include <_PDCLIB_glue.h> - #ifndef REGTEST #include #include +#include <_PDCLIB_glue.h> + size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, struct _PDCLIB_file_t * _PDCLIB_restrict stream ) { if ( _PDCLIB_prepwrite( stream ) == EOF ) diff --git a/functions/stdlib/div.c b/functions/stdlib/div.c index 2c6bbb5..b80c5c9 100644 --- a/functions/stdlib/div.c +++ b/functions/stdlib/div.c @@ -24,10 +24,6 @@ div_t div( int numer, int denom ) #ifdef TEST #include <_PDCLIB_test.h> -#ifndef _PDCLIB_CONFIG_H -#include <_PDCLIB_config.h> -#endif - int main( void ) { div_t result; @@ -37,8 +33,8 @@ int main( void ) TESTCASE( result.quot == -2 && result.rem == -1 ); result = div( 5, -2 ); TESTCASE( result.quot == -2 && result.rem == 1 ); - TESTCASE( sizeof( result.quot ) == _PDCLIB_INT_BYTES ); - TESTCASE( sizeof( result.rem ) == _PDCLIB_INT_BYTES ); + TESTCASE( sizeof( result.quot ) == sizeof( int ) ); + TESTCASE( sizeof( result.rem ) == sizeof( int ) ); return TEST_RESULTS; } diff --git a/functions/stdlib/ldiv.c b/functions/stdlib/ldiv.c index 4745446..7b9feee 100644 --- a/functions/stdlib/ldiv.c +++ b/functions/stdlib/ldiv.c @@ -24,10 +24,6 @@ ldiv_t ldiv( long int numer, long int denom ) #ifdef TEST #include <_PDCLIB_test.h> -#ifndef _PDCLIB_CONFIG_H -#include <_PDCLIB_config.h> -#endif - int main( void ) { ldiv_t result; @@ -37,8 +33,8 @@ int main( void ) TESTCASE( result.quot == -2 && result.rem == -1 ); result = ldiv( 5, -2 ); TESTCASE( result.quot == -2 && result.rem == 1 ); - TESTCASE( sizeof( result.quot ) == _PDCLIB_LONG_BYTES ); - TESTCASE( sizeof( result.rem ) == _PDCLIB_LONG_BYTES ); + TESTCASE( sizeof( result.quot ) == sizeof( long ) ); + TESTCASE( sizeof( result.rem ) == sizeof( long ) ); return TEST_RESULTS; } diff --git a/functions/stdlib/lldiv.c b/functions/stdlib/lldiv.c index 3028883..423d119 100644 --- a/functions/stdlib/lldiv.c +++ b/functions/stdlib/lldiv.c @@ -24,10 +24,6 @@ lldiv_t lldiv( long long int numer, long long int denom ) #ifdef TEST #include <_PDCLIB_test.h> -#ifndef _PDCLIB_CONFIG_H -#include <_PDCLIB_config.h> -#endif - int main( void ) { lldiv_t result; @@ -37,8 +33,8 @@ int main( void ) TESTCASE( result.quot == -2 && result.rem == -1 ); result = lldiv( 5ll, -2ll ); TESTCASE( result.quot == -2 && result.rem == 1 ); - TESTCASE( sizeof( result.quot ) == _PDCLIB_LLONG_BYTES ); - TESTCASE( sizeof( result.rem ) == _PDCLIB_LLONG_BYTES ); + TESTCASE( sizeof( result.quot ) == sizeof( long long ) ); + TESTCASE( sizeof( result.rem ) == sizeof( long long ) ); return TEST_RESULTS; } diff --git a/functions/stdlib/strtol.c b/functions/stdlib/strtol.c index ea54b98..05271e0 100644 --- a/functions/stdlib/strtol.c +++ b/functions/stdlib/strtol.c @@ -37,11 +37,6 @@ long int strtol( const char * s, char ** endptr, int base ) #ifdef TEST #include <_PDCLIB_test.h> -#ifndef _PDCLIB_INT_H -#define _PDCLIB_INT_H -#include <_PDCLIB_int.h> -#endif - #include int main( void ) @@ -93,7 +88,7 @@ int main( void ) /* one-complement and signed magnitude just as well. Anyone having a */ /* platform to test this on? */ errno = 0; -#if _PDCLIB_LONG_BYTES == 4 +#if LONG_MAX == 0x7fffffffL /* testing "even" overflow, i.e. base is power of two */ TESTCASE( strtol( "0x7FFFFFFF", NULL, 0 ) == 0x7fffffff ); TESTCASE( errno == 0 ); @@ -107,7 +102,7 @@ int main( void ) TESTCASE( strtol( "-0x80000001", NULL, 0 ) == LONG_MIN ); TESTCASE( errno == ERANGE ); /* TODO: test "odd" overflow, i.e. base is not power of two */ -#elif _PDCLIB_LONG_BYTES == 8 +#elif LONG_MAX == 0x7fffffffffffffffL /* testing "even" overflow, i.e. base is power of two */ TESTCASE( strtol( "0x7FFFFFFFFFFFFFFF", NULL, 0 ) == 0x7fffffffffffffff ); TESTCASE( errno == 0 ); diff --git a/functions/stdlib/strtoll.c b/functions/stdlib/strtoll.c index 5b13074..8222d34 100644 --- a/functions/stdlib/strtoll.c +++ b/functions/stdlib/strtoll.c @@ -38,11 +38,6 @@ long long int strtoll( const char * s, char ** endptr, int base ) #ifdef TEST #include <_PDCLIB_test.h> -#ifndef _PDCLIB_INT_H -#define _PDCLIB_INT_H -#include <_PDCLIB_int.h> -#endif - #include int main( void ) @@ -94,7 +89,7 @@ int main( void ) /* one-complement and signed magnitude just as well. Anyone having a */ /* platform to test this on? */ errno = 0; -#if _PDCLIB_LLONG_BYTES == 8 +#if LLONG_MAX == 0x7fffffffffffffffLL /* testing "even" overflow, i.e. base is power of two */ TESTCASE( strtoll( "0x7FFFFFFFFFFFFFFF", NULL, 0 ) == 0x7fffffffffffffff ); TESTCASE( errno == 0 ); @@ -108,7 +103,7 @@ int main( void ) TESTCASE( strtoll( "-0x8000000000000001", NULL, 0 ) == LLONG_MIN ); TESTCASE( errno == ERANGE ); /* TODO: test "odd" overflow, i.e. base is not power of two */ -#elif _PDCLIB_LONG_BYTES == 16 +#elif LLONG_MAX == 0x7fffffffffffffffffffffffffffffffLL /* testing "even" overflow, i.e. base is power of two */ TESTCASE( strtoll( "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", NULL, 0 ) == 0x7fffffffffffffffffffffffffffffff ); TESTCASE( errno == 0 ); diff --git a/platform/example_cygwin/Readme.txt b/platform/example_cygwin/Readme.txt new file mode 100644 index 0000000..5ec24bd --- /dev/null +++ b/platform/example_cygwin/Readme.txt @@ -0,0 +1,24 @@ +$Id$ + +"Example" Platform Overlay +========================== + +This is an example platform overlay, as described in the main Readme.txt of +this archive. For ease of development, it applies (and tests) correctly on the +machine of the author; no other guarantees can be given. +It should give you a good idea of what is REQUIRED to make a copy of PDCLib +work. There is a lot more you could do, and even some things you SHOULD do, in +order to experience anything but abysmal performance: + +- Read / write operations on binary streams, and even on text streams for + machines that do not do any text conversion, can be made much more efficient + by using some sort of page buffer instead of the linear buffer implemented + here. It requires some special and platform-dependent manipulations, though, + which is why it is not done by default. + +- Anything relating to floating point logic is written in generic C. While + this is (hopefully) highly portable and should get you started on your + platform of choice, it is also highly inefficient and should be replaced by + inline assembly. Just make sure that your assembly keeps all the promises + the C library makes. + diff --git a/platform/example_cygwin/functions/_PDCLIB/_Exit.c b/platform/example_cygwin/functions/_PDCLIB/_Exit.c new file mode 100644 index 0000000..5c95fca --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/_Exit.c @@ -0,0 +1,38 @@ +/* $Id$ */ + +/* _PDCLIB_exit( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_exit() fit for use with POSIX + kernels. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +extern void _exit( int status ) _PDCLIB_NORETURN; + +void _PDCLIB_Exit( int status ) +{ + _exit( status ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + int UNEXPECTED_RETURN = 0; + _PDCLIB_Exit( 0 ); + TESTCASE( UNEXPECTED_RETURN ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/functions/_PDCLIB/allocpages.c b/platform/example_cygwin/functions/_PDCLIB/allocpages.c new file mode 100644 index 0000000..5998c40 --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/allocpages.c @@ -0,0 +1,77 @@ +/* $Id$ */ + +/* _PDCLIB_allocpages( int const ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_allocpages() (declared in + _PDCLIB_config.h), fit for use with POSIX kernels. +*/ + +#include +#include + +void * sbrk( intptr_t ); + +#ifndef _PDCLIB_GLUE_H +#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H +#include <_PDCLIB_glue.h> +#endif + +static void * membreak = NULL; + +void * _PDCLIB_allocpages( int const n ) +{ + if ( membreak == NULL ) + { + /* first call, make sure end-of-heap is page-aligned */ + intptr_t unaligned = 0; + membreak = sbrk( 0 ); + unaligned = _PDCLIB_PAGESIZE - (intptr_t)membreak % _PDCLIB_PAGESIZE; + if ( unaligned < _PDCLIB_PAGESIZE ) + { + /* end-of-heap not page-aligned - adjust */ + if ( sbrk( unaligned ) != membreak ) + { + /* error */ + return NULL; + } + membreak = (char *)membreak + unaligned; + } + } + /* increasing or decreasing heap - standard operation */ + void * oldbreak = membreak; + membreak = (void *)( (char *)membreak + ( n * _PDCLIB_PAGESIZE ) ); + if ( sbrk( (char*)membreak - (char*)oldbreak ) == membreak ) + { + /* successful */ + return oldbreak; + } + else + { + /* out of memory */ + membreak = oldbreak; + return NULL; + } +} + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + char * startbreak = sbrk( 0 ); + TESTCASE( _PDCLIB_allocpages( 0 ) ); + TESTCASE( ( (char *)sbrk( 0 ) - startbreak ) <= _PDCLIB_PAGESIZE ); + startbreak = sbrk( 0 ); + TESTCASE( _PDCLIB_allocpages( 1 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 1 * _PDCLIB_PAGESIZE ) ); + TESTCASE( _PDCLIB_allocpages( 5 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 6 * _PDCLIB_PAGESIZE ) ); + TESTCASE( _PDCLIB_allocpages( -3 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 3 * _PDCLIB_PAGESIZE ) ); +} + +#endif diff --git a/platform/example_cygwin/functions/_PDCLIB/close.c b/platform/example_cygwin/functions/_PDCLIB/close.c new file mode 100644 index 0000000..c4b6173 --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/close.c @@ -0,0 +1,36 @@ +/* $Id$ */ + +/* _PDCLIB_close( _PDCLIB_fd_t fd ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_close() fit for use with POSIX + kernels. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +extern int close( int fd ); + +int _PDCLIB_close( int fd ) +{ + return close( fd ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* No testdriver; tested in driver for _PDCLIB_open(). */ + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c b/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c new file mode 100644 index 0000000..ecfb968 --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c @@ -0,0 +1,74 @@ +/* $Id$ */ + +/* _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_fillbuffer() fit for + use with POSIX kernels. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +#include + +typedef long ssize_t; +extern ssize_t read( int fd, void * buf, size_t count ); + +int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) +{ + /* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */ + ssize_t rc = read( stream->handle, stream->buffer, stream->bufsize ); + if ( rc > 0 ) + { + /* Reading successful. */ + if ( ! ( stream->status & _PDCLIB_FBIN ) ) + { + /* TODO: Text stream conversion here */ + } + stream->bufend = rc; + stream->bufidx = 0; + return 0; + } + if ( rc < 0 ) + { + /* Reading error */ + switch ( errno ) + { + case EBADF: + case EFAULT: + case EINTR: + case EINVAL: + case EIO: + _PDCLIB_errno = _PDCLIB_EIO; + break; + default: + _PDCLIB_errno = _PDCLIB_EUNKNOWN; + break; + } + stream->status |= _PDCLIB_ERRORFLAG; + return EOF; + } + /* End-of-File */ + stream->status |= _PDCLIB_EOFFLAG; + return EOF; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by ftell.c */ + return TEST_RESULTS; +} + +#endif + diff --git a/platform/example_cygwin/functions/_PDCLIB/flushbuffer.c b/platform/example_cygwin/functions/_PDCLIB/flushbuffer.c new file mode 100644 index 0000000..c2ac98d --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/flushbuffer.c @@ -0,0 +1,103 @@ +/* $Id$ */ + +/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_flushbuffer() fit for + use with POSIX kernels. +*/ + +#include +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +#include + +typedef long ssize_t; +extern ssize_t write( int fd, const void * buf, size_t count ); + +/* The number of attempts to complete an output buffer flushing before giving + * up. + * */ +#define _PDCLIB_IO_RETRIES 1 + +/* What the system should do after an I/O operation did not succeed, before */ +/* trying again. (Empty by default.) */ +#define _PDCLIB_IO_RETRY_OP( stream ) + +int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) +{ + if ( ! ( stream->status & _PDCLIB_FBIN ) ) + { + /* TODO: Text stream conversion here */ + } + /* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */ + _PDCLIB_size_t written = 0; + int rc; + /* Keep trying to write data until everything is written, an error + occurs, or the configured number of retries is exceeded. + */ + for ( unsigned int retries = _PDCLIB_IO_RETRIES; retries > 0; --retries ) + { + rc = (int)write( stream->handle, stream->buffer + written, stream->bufidx - written ); + if ( rc < 0 ) + { + /* Write error */ + switch ( errno ) + { + case EBADF: + case EFAULT: + case EFBIG: + case EINTR: + case EINVAL: + case EIO: + case ENOSPC: + case EPIPE: + _PDCLIB_errno = _PDCLIB_EIO; + break; + default: + _PDCLIB_errno = _PDCLIB_EUNKNOWN; + break; + } + stream->status |= _PDCLIB_ERRORFLAG; + /* Move unwritten remains to begin of buffer. */ + stream->bufidx -= written; + memmove( stream->buffer, stream->buffer + written, stream->bufidx ); + return EOF; + } + written += (_PDCLIB_size_t)rc; + stream->pos.offset += rc; + if ( written == stream->bufidx ) + { + /* Buffer written completely. */ + stream->bufidx = 0; + return 0; + } + } + _PDCLIB_errno = _PDCLIB_ERETRY; + stream->status |= _PDCLIB_ERRORFLAG; + /* Move unwritten remains to begin of buffer. */ + stream->bufidx -= written; + memmove( stream->buffer, stream->buffer + written, stream->bufidx ); + return EOF; +} + +#endif + + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by ftell.c */ + return TEST_RESULTS; +} + +#endif + diff --git a/platform/example_cygwin/functions/_PDCLIB/open.c b/platform/example_cygwin/functions/_PDCLIB/open.c new file mode 100644 index 0000000..7949726 --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/open.c @@ -0,0 +1,162 @@ +/* $Id$ */ + +/* _PDCLIB_open( char const * const, int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_open() fit for use with POSIX + kernels. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +#include +#include +#include +#include + +#include "/usr/include/errno.h" + +int _PDCLIB_open( char const * const filename, unsigned int mode ) +{ + /* This is an example implementation of _PDCLIB_open() fit for use with + POSIX kernels. + FIXME: The permissions of newly created files should not be hardcoded + here. + */ + int osmode; + switch ( mode & ~_PDCLIB_FBIN ) + { + case _PDCLIB_FREAD: /* "r" */ + osmode = O_RDONLY; + break; + case _PDCLIB_FWRITE: /* "w" */ + osmode = O_WRONLY | O_CREAT | O_TRUNC; + break; + case _PDCLIB_FAPPEND: /* "a" */ + osmode = O_WRONLY | O_APPEND | O_CREAT; + break; + case _PDCLIB_FREAD | _PDCLIB_FRW: /* "r+" */ + osmode = O_RDWR; + break; + case _PDCLIB_FWRITE | _PDCLIB_FRW: /* "w+" */ + osmode = O_RDWR | O_CREAT | O_TRUNC; + break; + case _PDCLIB_FAPPEND | _PDCLIB_FRW: /* "a+" */ + osmode = O_RDWR | O_APPEND | O_CREAT; + break; + default: /* Invalid mode */ + return -1; + } + int rc; + if ( osmode & O_CREAT ) + { + rc = open( filename, osmode, S_IRUSR | S_IWUSR ); + } + else + { + rc = open( filename, osmode ); + } + if ( rc == -1 ) + { + switch ( errno ) + { + case EACCES: + case EFAULT: + case EINTR: + case EISDIR: + case ELOOP: + case EMFILE: + case ENAMETOOLONG: + case ENFILE: + case ENODEV: + case ENOENT: + case ENOMEM: + case ENOSPC: + case ENOTDIR: + case EOVERFLOW: + case EROFS: + case ETXTBSY: + _PDCLIB_errno = _PDCLIB_EIO; + default: + _PDCLIB_errno = _PDCLIB_EUNKNOWN; + } + } + return rc; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +#include +#include + +int main( void ) +{ + /* This testdriver assumes POSIX, i.e. _PDCLIB_fd_t being int and being + incremented by one on each successful open. + */ + int fh; + char buffer[ 10 ]; + remove( "testfile" ); + /* Trying to read non-existent file. */ + TESTCASE( _PDCLIB_open( "testfile", _PDCLIB_FREAD ) == _PDCLIB_NOHANDLE ); + /* Writing to file, trying to read from it. */ + TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FWRITE ) ) != _PDCLIB_NOHANDLE ); + TESTCASE( write( fh, "test", 4 ) == 4 ); + TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 ); + TESTCASE( read( fh, buffer, 4 ) == -1 ); + TESTCASE( _PDCLIB_close( fh ) == 0 ); + /* Reading from file, trying to write to it. */ + TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FREAD ) ) != _PDCLIB_NOHANDLE ); + TESTCASE( write( fh, "test", 4 ) == -1 ); + TESTCASE( _PDCLIB_close( fh ) == 0 ); + /* Appending to file, trying to read from it. */ + TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FAPPEND ) ) != _PDCLIB_NOHANDLE ); + TESTCASE( write( fh, "app", 3 ) == 3 ); + TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 ); + TESTCASE( read( fh, buffer, 10 ) == -1 ); + TESTCASE( write( fh, "end", 3 ) == 3 ); + TESTCASE( _PDCLIB_close( fh ) == 0 ); + /* Reading and writing from file ("r+"). */ + TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FREAD | _PDCLIB_FRW ) ) != _PDCLIB_NOHANDLE ); + TESTCASE( read( fh, buffer, 10 ) == 10 ); + TESTCASE( memcmp( buffer, "testappend", 10 ) == 0 ); + TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 ); + TESTCASE( write( fh, "wedo", 4 ) == 4 ); + TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 ); + TESTCASE( read( fh, buffer, 10 ) == 10 ); + TESTCASE( memcmp( buffer, "wedoappend", 10 ) == 0 ); + TESTCASE( _PDCLIB_close( fh ) == 0 ); + /* Writing and reading from file ("w+"). */ + TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FWRITE | _PDCLIB_FRW ) ) != _PDCLIB_NOHANDLE ); + TESTCASE( write( fh, "test", 4 ) == 4 ); + TESTCASE( lseek( fh, 1, SEEK_SET ) == 1 ); + TESTCASE( read( fh, buffer, 2 ) == 2 ); + TESTCASE( memcmp( buffer, "es", 2 ) == 0 ); + TESTCASE( write( fh, "sie", 3 ) == 3 ); + TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 ); + TESTCASE( read( fh, buffer, 6 ) == 6 ); + TESTCASE( memcmp( buffer, "tessie", 6 ) == 0 ); + TESTCASE( _PDCLIB_close( fh ) == 0 ); + /* Appending and reading from file ("a+"). */ + TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) != _PDCLIB_NOHANDLE ); + TESTCASE( write( fh, "baby", 4 ) == 4 ); + TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 ); + TESTCASE( read( fh, buffer, 10 ) == 10 ); + TESTCASE( memcmp( buffer, "tessiebaby", 10 ) == 0 ); + TESTCASE( _PDCLIB_close( fh ) == 0 ); + /* Cleaning up. */ + TESTCASE( remove( "testfile" ) == 0 ); + return TEST_RESULTS; +} + +#endif + diff --git a/platform/example_cygwin/functions/_PDCLIB/rename.c b/platform/example_cygwin/functions/_PDCLIB/rename.c new file mode 100644 index 0000000..3f770c9 --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/rename.c @@ -0,0 +1,128 @@ +/* $Id$ */ + +/* _PDCLIB_rename( const char *, const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +#include + +extern int unlink( const char * pathname ); +extern int link( const char * old, const char * new ); + +int _PDCLIB_rename( const char * old, const char * new ) +{ + /* Note that the behaviour if new file exists is implementation-defined. + There is nothing wrong with either overwriting it or failing the + operation, but you might want to document whichever you chose. + This example fails if new file exists. + */ + if ( link( old, new ) == 0 ) + { + if ( unlink( old ) == EOF ) + { + switch ( errno ) + { + case EACCES: + case EFAULT: + case EIO: + case EISDIR: + case ELOOP: + case ENAMETOOLONG: + case ENOENT: + case ENOMEM: + case ENOTDIR: + case EPERM: + case EROFS: + _PDCLIB_errno = _PDCLIB_EIO; + break; + default: + _PDCLIB_errno = _PDCLIB_EUNKNOWN; + break; + } + return -1; + } + else + { + return 0; + } + } + else + { + switch ( errno ) + { + case EACCES: + case EEXIST: + case EFAULT: + case EIO: + case ELOOP: + case EMLINK: + case ENAMETOOLONG: + case ENOENT: + case ENOMEM: + case ENOSPC: + case ENOTDIR: + case EPERM: + case EROFS: + case EXDEV: + _PDCLIB_errno = _PDCLIB_EIO; + break; + default: + _PDCLIB_errno = _PDCLIB_EUNKNOWN; + break; + } + return EOF; + } +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +#include + +int main( void ) +{ + char filename1[] = "touch testfile1"; + char filename2[] = "testfile2"; + remove( filename1 + 6 ); + remove( filename2 ); + /* check that neither file exists */ + TESTCASE( fopen( filename1 + 6, "r" ) == NULL ); + TESTCASE( fopen( filename2, "r" ) == NULL ); + /* rename file 1 to file 2 - expected to fail */ + TESTCASE( _PDCLIB_rename( filename1 + 6, filename2 ) == -1 ); + /* create file 1 */ + system( filename1 ); + /* check that file 1 exists */ + TESTCASE( fopen( filename1 + 6, "r" ) != NULL ); + /* rename file 1 to file 2 */ + TESTCASE( _PDCLIB_rename( filename1 + 6, filename2 ) == 0 ); + /* check that file 2 exists, file 1 does not */ + TESTCASE( fopen( filename1 + 6, "r" ) == NULL ); + TESTCASE( fopen( filename2, "r" ) != NULL ); + /* create another file 1 */ + system( filename1 ); + /* check that file 1 exists */ + TESTCASE( fopen( filename1 + 6, "r" ) != NULL ); + /* rename file 1 to file 2 - expected to fail, see comment in + _PDCLIB_rename() itself. + */ + TESTCASE( _PDCLIB_rename( filename1 + 6, filename2 ) == -1 ); + /* remove both files */ + remove( filename1 + 6 ); + remove( filename2 ); + /* check that they're gone */ + TESTCASE( fopen( filename1 + 6, "r" ) == NULL ); + TESTCASE( fopen( filename2, "r" ) == NULL ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/functions/_PDCLIB/seek.c b/platform/example_cygwin/functions/_PDCLIB/seek.c new file mode 100644 index 0000000..ee21f56 --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/seek.c @@ -0,0 +1,66 @@ +/* $Id$ */ + +/* int64_t _PDCLIB_seek( FILE *, int64_t, int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef _PDCLIB_GLUE_H +#define _PDCLIB_GLUE_H +#include <_PDCLIB_glue.h> +#endif + +#include "/usr/include/errno.h" + +extern int lseek( int fd, int offset, int whence ); + +_PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t offset, int whence ) +{ + switch ( whence ) + { + case SEEK_SET: + case SEEK_CUR: + case SEEK_END: + /* EMPTY - OK */ + break; + default: + _PDCLIB_errno = _PDCLIB_EINVAL; + return EOF; + break; + } + _PDCLIB_int64_t rc = lseek( stream->handle, offset, whence ); + if ( rc != EOF ) + { + stream->ungetidx = 0; + stream->bufidx = 0; + stream->bufend = 0; + stream->pos.offset = rc; + return rc; + } + switch ( errno ) + { + case EBADF: + case EFAULT: + _PDCLIB_errno = _PDCLIB_EIO; + break; + default: + _PDCLIB_errno = _PDCLIB_EUNKNOWN; + break; + } + return EOF; +} + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main() +{ + /* Testing covered by ftell.c */ + return TEST_RESULTS; +} + +#endif + diff --git a/platform/example_cygwin/functions/_PDCLIB/stdinit.c b/platform/example_cygwin/functions/_PDCLIB/stdinit.c new file mode 100644 index 0000000..af37f06 --- /dev/null +++ b/platform/example_cygwin/functions/_PDCLIB/stdinit.c @@ -0,0 +1,55 @@ +/* $Id$ */ + +/* _PDCLIB_stdinit + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example initialization of stdin, stdout and stderr to the integer + file descriptors 0, 1, and 2, respectively. This applies for a great variety + of operating systems, including POSIX compliant ones. +*/ + +#include + +#ifndef REGTEST + +/* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file + descriptors 0, 1, and 2 respectively. +*/ +/* TODO: This is proof-of-concept, requires finetuning. */ +static char _PDCLIB_sin_buffer[BUFSIZ]; +static char _PDCLIB_sout_buffer[BUFSIZ]; +static char _PDCLIB_serr_buffer[BUFSIZ]; + +static unsigned char _PDCLIB_sin_ungetbuf[_PDCLIB_UNGETCBUFSIZE]; +static unsigned char _PDCLIB_sout_ungetbuf[_PDCLIB_UNGETCBUFSIZE]; +static unsigned char _PDCLIB_serr_ungetbuf[_PDCLIB_UNGETCBUFSIZE]; + +/* FIXME: serr should handle one character. Buffering on out / in? */ +static struct _PDCLIB_file_t _PDCLIB_serr = { 2, _PDCLIB_serr_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_serr_ungetbuf, _IONBF | _PDCLIB_FWRITE, NULL, NULL }; +static struct _PDCLIB_file_t _PDCLIB_sout = { 1, _PDCLIB_sout_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sout_ungetbuf, _IOLBF | _PDCLIB_FWRITE, NULL, &_PDCLIB_serr }; +static struct _PDCLIB_file_t _PDCLIB_sin = { 0, _PDCLIB_sin_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sin_ungetbuf, _IOLBF | _PDCLIB_FREAD, NULL, &_PDCLIB_sout }; + +struct _PDCLIB_file_t * stdin = &_PDCLIB_sin; +struct _PDCLIB_file_t * stdout = &_PDCLIB_sout; +struct _PDCLIB_file_t * stderr = &_PDCLIB_serr; + +/* FIXME: This approach is a possible attack vector. */ +struct _PDCLIB_file_t * _PDCLIB_filelist = &_PDCLIB_sin; + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by several other testdrivers using stdin / stdout / + stderr. + */ + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/functions/stdio/remove.c b/platform/example_cygwin/functions/stdio/remove.c new file mode 100644 index 0000000..0e66f4c --- /dev/null +++ b/platform/example_cygwin/functions/stdio/remove.c @@ -0,0 +1,64 @@ +/* $Id$ */ + +/* remove( const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of remove() fit for use with POSIX kernels. +*/ + +#include + +#ifndef REGTEST + +#include "/usr/include/errno.h" + +extern int unlink( const char * pathname ); + +int remove( const char * pathname ) +{ + int rc; + if ( ( rc = unlink( pathname ) ) == -1 ) + { + switch ( errno ) + { + /* These are the values possible on a Linux machine. Adapt the + values and their mapping to PDCLib errno values at will. (This + is an example implementation, so we keep it very simple.) + */ + case EACCES: + case EFAULT: + case EIO: + case EISDIR: + case ELOOP: + case ENAMETOOLONG: + case ENOENT: + case ENOMEM: + case ENOTDIR: + case EPERM: + case EROFS: + _PDCLIB_errno = _PDCLIB_EIO; + break; + default: + _PDCLIB_errno = _PDCLIB_EUNKNOWN; + break; + } + } + return rc; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by ftell.c (and several others) */ + return TEST_RESULTS; +} + +#endif + diff --git a/platform/example_cygwin/functions/stdio/tmpfile.c b/platform/example_cygwin/functions/stdio/tmpfile.c new file mode 100644 index 0000000..255a35e --- /dev/null +++ b/platform/example_cygwin/functions/stdio/tmpfile.c @@ -0,0 +1,30 @@ +/* $Id$ */ + +/* tmpfile( void ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +struct _PDCLIB_file_t * tmpfile( void ) +{ + /* TODO: Implement */ + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main() +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/functions/stdio/tmpnam.c b/platform/example_cygwin/functions/stdio/tmpnam.c new file mode 100644 index 0000000..c4a0a4d --- /dev/null +++ b/platform/example_cygwin/functions/stdio/tmpnam.c @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* tmpnam( char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include +#include + +#ifndef REGTEST + +char * tmpnam( char * s ) +{ + /* TODO: Implement. */ + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/functions/stdlib/getenv.c b/platform/example_cygwin/functions/stdlib/getenv.c new file mode 100644 index 0000000..4eb7010 --- /dev/null +++ b/platform/example_cygwin/functions/stdlib/getenv.c @@ -0,0 +1,46 @@ +/* $Id$ */ + +/* getenv( const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of getenv() fit for use with POSIX kernels. +*/ + +#include +#include + +#ifndef REGTEST + +extern char * * environ; + +char * getenv( const char * name ) +{ + size_t len = strlen( name ); + size_t index = 0; + while ( environ[ index ] != NULL ) + { + if ( strncmp( environ[ index ], name, len ) == 0 ) + { + return environ[ index ] + len + 1; + } + index++; + } + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( strcmp( getenv( "SHELL" ), "/bin/bash" ) == 0 ); + /* TESTCASE( strcmp( getenv( "SHELL" ), "/bin/sh" ) == 0 ); */ + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/functions/stdlib/system.c b/platform/example_cygwin/functions/stdlib/system.c new file mode 100644 index 0000000..2e0079a --- /dev/null +++ b/platform/example_cygwin/functions/stdlib/system.c @@ -0,0 +1,47 @@ +/* $Id$ */ + +/* system( const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +/* This is an example implementation of system() fit for use with POSIX kernels. +*/ + +extern int fork( void ); +extern int execve( const char * filename, char * const argv[], char * const envp[] ); +extern int wait( int * status ); + +int system( const char * string ) +{ + char const * const argv[] = { "sh", "-c", (char const * const)string, NULL }; + if ( string != NULL ) + { + int pid = fork(); + if ( pid == 0 ) + { + execve( "/bin/sh", (char * * const)argv, NULL ); + } + else if ( pid > 0 ) + { + while( wait( NULL ) != pid ); + } + } + return -1; +} + +#ifdef TEST +#include <_PDCLIB_test.h> + +#define SHELLCOMMAND "echo 'SUCCESS testing system()'" + +int main( void ) +{ + TESTCASE( system( SHELLCOMMAND ) ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example_cygwin/includes/float.h b/platform/example_cygwin/includes/float.h new file mode 100644 index 0000000..de47aeb --- /dev/null +++ b/platform/example_cygwin/includes/float.h @@ -0,0 +1,80 @@ +/* $Id$ */ + +/* 7.7 Characteristics of floating types + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#ifndef _PDCLIB_FLOAT_H +#define _PDCLIB_FLOAT_H _PDCLIB_FLOAT_H + +#ifndef _PDCLIB_CONFIG_H +#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H +#include <_PDCLIB_config.h> +#endif + +#define FLT_ROUNDS _PDCLIB_FLT_ROUNDS +#define FLT_EVAL_METHOD _PDCLIB_FLT_EVAL_METHOD +#define DECIMAL_DIG _PDCLIB_DECIMAL_DIG + + /* Radix of exponent representation */ +#define FLT_RADIX __FLT_RADIX__ + /* Number of base-FLT_RADIX digits in the significand of a float */ +#define FLT_MANT_DIG __FLT_MANT_DIG__ + /* Number of decimal digits of precision in a float */ +#define FLT_DIG __FLT_DIG__ + /* Difference between 1.0 and the minimum float greater than 1.0 */ +#define FLT_EPSILON __FLT_EPSILON__ + /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */ +#define FLT_MIN_EXP __FLT_MIN_EXP__ + /* Minimum normalised float */ +#define FLT_MIN __FLT_MIN__ + /* Minimum int x such that 10**x is a normalised float */ +#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ + /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */ +#define FLT_MAX_EXP __FLT_MAX_EXP__ + /* Maximum float */ +#define FLT_MAX __FLT_MAX__ + /* Maximum int x such that 10**x is a representable float */ +#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ + + /* Number of base-FLT_RADIX digits in the significand of a double */ +#define DBL_MANT_DIG __DBL_MANT_DIG__ + /* Number of decimal digits of precision in a double */ +#define DBL_DIG __DBL_DIG__ + /* Difference between 1.0 and the minimum double greater than 1.0 */ +#define DBL_EPSILON __DBL_EPSILON__ + /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */ +#define DBL_MIN_EXP __DBL_MIN_EXP__ + /* Minimum normalised double */ +#define DBL_MIN __DBL_MIN__ + /* Minimum int x such that 10**x is a normalised double */ +#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ + /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */ +#define DBL_MAX_EXP __DBL_MAX_EXP__ + /* Maximum double */ +#define DBL_MAX __DBL_MAX__ + /* Maximum int x such that 10**x is a representable double */ +#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ + + /* Number of base-FLT_RADIX digits in the significand of a long double */ +#define LDBL_MANT_DIG __LDBL_MANT_DIG__ + /* Number of decimal digits of precision in a long double */ +#define LDBL_DIG __LDBL_DIG__ + /* Difference between 1.0 and the minimum long double greater than 1.0 */ +#define LDBL_EPSILON __LDBL_EPSILON__ + /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */ +#define LDBL_MIN_EXP __LDBL_MIN_EXP__ + /* Minimum normalised long double */ +#define LDBL_MIN __LDBL_MIN__ + /* Minimum int x such that 10**x is a normalised long double */ +#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ + /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */ +#define LDBL_MAX_EXP __LDBL_MAX_EXP__ + /* Maximum long double */ +#define LDBL_MAX __LDBL_MAX__ + /* Maximum int x such that 10**x is a representable long double */ +#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ + +#endif diff --git a/platform/example_cygwin/internals/_PDCLIB_config.h b/platform/example_cygwin/internals/_PDCLIB_config.h new file mode 100644 index 0000000..ee3fed3 --- /dev/null +++ b/platform/example_cygwin/internals/_PDCLIB_config.h @@ -0,0 +1,272 @@ +/* $Id$ */ + +/* Internal PDCLib configuration <_PDCLIB_config.h> + (Generic Template) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* -------------------------------------------------------------------------- */ +/* Misc */ +/* -------------------------------------------------------------------------- */ + +/* The character (sequence) your platform uses as newline. */ +#define _PDCLIB_endl "\n" + +/* exit() can signal success to the host environment by the value of zero or */ +/* the constant EXIT_SUCCESS. Failure is signaled by EXIT_FAILURE. Note that */ +/* any other return value is "implementation-defined", i.e. your environment */ +/* is not required to handle it gracefully. Set your definitions here. */ +#define _PDCLIB_SUCCESS 0 +#define _PDCLIB_FAILURE -1 + +/* qsort() in requires a function that swaps two memory areas. */ +/* Below is a naive implementation that can be improved significantly for */ +/* specific platforms, e.g. by swapping int instead of char. */ +#define _PDCLIB_memswp( i, j, size ) char tmp; do { tmp = *i; *i++ = *j; *j++ = tmp; } while ( --size ); + +/* Define this to some compiler directive that can be written after the */ +/* parameter list of a function declaration to indicate the function does */ +/* never return. If your compiler does not support such a directive, define */ +/* to nothing. (This is to avoid warnings with the exit functions under GCC.) */ +#define _PDCLIB_NORETURN __attribute__(( noreturn )) + +/* -------------------------------------------------------------------------- */ +/* Integers */ +/* -------------------------------------------------------------------------- */ +/* Assuming 8-bit char, two's-complement architecture here. 'short' being */ +/* 16 bit, 'int' being either 16, 32 or 64 bit, 'long' being either 32 or 64 */ +/* bit (but 64 bit only if 'int' is 32 bit), and 'long long' being 64 bit if */ +/* 'long' is not, 64 or 128 bit otherwise. */ +/* Author is quite willing to support other systems but would like to hear of */ +/* interest in such support and details on the to-be-supported architecture */ +/* first, before going to lengths about it. */ +/* -------------------------------------------------------------------------- */ + +/* Comment out (or delete) the line below if your 'char' type is unsigned. */ +#define _PDCLIB_CHAR_SIGNED 1 + +/* Width of the integer types short, int, long, and long long, in bytes. */ +/* SHRT == 2, INT >= SHRT, LONG >= INT >= 4, LLONG >= LONG - check your */ +/* compiler manuals. */ +#define _PDCLIB_SHRT_BYTES 2 +#define _PDCLIB_INT_BYTES 4 +#define _PDCLIB_LONG_BYTES 4 +#define _PDCLIB_LLONG_BYTES 8 + +/* defines the div() function family that allows taking quotient */ +/* and remainder of an integer division in one operation. Many platforms */ +/* support this in hardware / opcode, and the standard permits ordering of */ +/* the return structure in any way to fit the hardware. That is why those */ +/* structs can be configured here. */ + +struct _PDCLIB_div_t +{ + int quot; + int rem; +}; + +struct _PDCLIB_ldiv_t +{ + long int quot; + long int rem; +}; + +struct _PDCLIB_lldiv_t +{ + long long int quot; + long long int rem; +}; + +/* -------------------------------------------------------------------------- */ +/* defines a set of integer types that are of a minimum width, and */ +/* "usually fastest" on the system. (If, for example, accessing a single char */ +/* requires the CPU to access a complete int and then mask out the char, the */ +/* "usually fastest" type of at least 8 bits would be int, not char.) */ +/* If you do not have information on the relative performance of the types, */ +/* the standard allows you to define any type that meets minimum width and */ +/* signedness requirements. */ +/* The defines below are just configuration for the real typedefs and limit */ +/* definitions done in <_PDCLIB_int.h>. The uppercase define shall be either */ +/* SHRT, INT, LONG, or LLONG (telling which values to use for the *_MIN and */ +/* *_MAX limits); the lowercase define either short, int, long, or long long */ +/* (telling the actual type to use). */ +/* If you require a non-standard datatype to define the "usually fastest" */ +/* types, PDCLib as-is doesn't support that. Please contact the author with */ +/* details on your platform in that case, so support can be added. */ +/* -------------------------------------------------------------------------- */ + +#define _PDCLIB_FAST8 INT +#define _PDCLIB_fast8 int + +#define _PDCLIB_FAST16 INT +#define _PDCLIB_fast16 int + +#define _PDCLIB_FAST32 INT +#define _PDCLIB_fast32 int + +#define _PDCLIB_FAST64 LLONG +#define _PDCLIB_fast64 long long + +/* -------------------------------------------------------------------------- */ +/* What follows are a couple of "special" typedefs and their limits. Again, */ +/* the actual definition of the limits is done in <_PDCLIB_int.h>, and the */ +/* defines here are merely "configuration". See above for details. */ +/* -------------------------------------------------------------------------- */ + +/* The result type of substracting two pointers */ +#define _PDCLIB_ptrdiff int +#define _PDCLIB_PTRDIFF INT + +/* An integer type that can be accessed as atomic entity (think asynchronous + interrupts). The type itself is not defined in a freestanding environment, + but its limits are. (Don't ask.) +*/ +#define _PDCLIB_sig_atomic int +#define _PDCLIB_SIG_ATOMIC INT + +/* Result type of the 'sizeof' operator (must be unsigned) */ +#define _PDCLIB_size unsigned int +#define _PDCLIB_SIZE UINT + +/* Large enough an integer to hold all character codes of the largest supported + locale. +*/ +#define _PDCLIB_wchar unsigned short +#define _PDCLIB_WCHAR USHRT + +#define _PDCLIB_intptr int +#define _PDCLIB_INTPTR INT + +/* Largest supported integer type. Implementation note: see _PDCLIB_atomax(). */ +#define _PDCLIB_intmax long long int +#define _PDCLIB_INTMAX LLINT +/* You are also required to state the literal suffix for the intmax type */ +#define _PDCLIB_INTMAX_LITERAL ll + +/* -------------------------------------------------------------------------- */ +/* Floating Point */ +/* -------------------------------------------------------------------------- */ + +/* Whether the implementation rounds toward zero (0), to nearest (1), toward + positive infinity (2), or toward negative infinity (3). (-1) signifies + indeterminable rounding, any other value implementation-specific rounding. +*/ +#define _PDCLIB_FLT_ROUNDS -1 + +/* Whether the implementation uses exact-width precision (0), promotes float + to double (1), or promotes float and double to long double (2). (-1) + signifies indeterminable behaviour, any other value implementation-specific + behaviour. +*/ +#define _PDCLIB_FLT_EVAL_METHOD -1 + +/* "Number of the decimal digits (n), such that any floating-point number in the + widest supported floating type with p(max) radix (b) digits can be rounded to + a floating-point number with (n) decimal digits and back again without change + to the value p(max) log(10)b if (b) is a power of 10, [1 + p(max) log(10)b] + otherwise." + 64bit IEC 60559 double format (53bit mantissa) is DECIMAL_DIG 17. + 80bit IEC 60559 double-extended format (64bit mantissa) is DECIMAL_DIG 21. +*/ +#define _PDCLIB_DECIMAL_DIG 17 + +/* -------------------------------------------------------------------------- */ +/* Platform-dependent macros defined by the standard headers. */ +/* -------------------------------------------------------------------------- */ + +/* The offsetof macro + Contract: Expand to an integer constant expression of type size_t, which + represents the offset in bytes to the structure member from the beginning + of the structure. If the specified member is a bitfield, behaviour is + undefined. + There is no standard-compliant way to do this. + This implementation casts an integer zero to 'pointer to type', and then + takes the address of member. This is undefined behaviour but should work on + most compilers. +*/ +#define _PDCLIB_offsetof( type, member ) ( (size_t) &( ( (type *) 0 )->member ) ) + +/* Variable Length Parameter List Handling () + The macros defined by are highly dependent on the calling + conventions used, and you probably have to replace them with builtins of + your compiler. The following generic implementation works only for pure + stack-based architectures, and only if arguments are aligned to pointer + type. Credits to Michael Moody, who contributed this to the Public Domain. +*/ + +/* Internal helper macro. va_round is not part of . */ +#define _PDCLIB_va_round( type ) ( (sizeof(type) + sizeof(void *) - 1) & ~(sizeof(void *) - 1) ) + +typedef char * _PDCLIB_va_list; +#define _PDCLIB_va_arg( ap, type ) ( (ap) += (_PDCLIB_va_round(type)), ( *(type*) ( (ap) - (_PDCLIB_va_round(type)) ) ) ) +#define _PDCLIB_va_copy( dest, src ) ( (dest) = (src), (void)0 ) +#define _PDCLIB_va_end( ap ) ( (ap) = (void *)0, (void)0 ) +#define _PDCLIB_va_start( ap, parmN ) ( (ap) = (char *) &parmN + ( _PDCLIB_va_round(parmN) ), (void)0 ) + +/* -------------------------------------------------------------------------- */ +/* OS "glue", part 1 */ +/* These are values and data type definitions that you would have to adapt to */ +/* the capabilities and requirements of your OS. */ +/* The actual *functions* of the OS interface are declared in _PDCLIB_glue.h. */ +/* -------------------------------------------------------------------------- */ + +/* Memory management -------------------------------------------------------- */ + +/* Set this to the page size of your OS. If your OS does not support paging, set + to an appropriate value. (Too small, and malloc() will call the kernel too + often. Too large, and you will waste memory.) +*/ +#define _PDCLIB_PAGESIZE 4096 + +/* Set this to the minimum memory node size. Any malloc() for a smaller size + will be satisfied by a malloc() of this size instead (to avoid excessive + fragmentation). +*/ +#define _PDCLIB_MINALLOC 8 + +/* I/O ---------------------------------------------------------------------- */ + +/* The type of the file descriptor returned by _PDCLIB_open(). */ +typedef int _PDCLIB_fd_t; + +/* The value (of type _PDCLIB_fd_t) returned by _PDCLIB_open() if the operation + failed. +*/ +#define _PDCLIB_NOHANDLE ( (_PDCLIB_fd_t) -1 ) + +/* The default size for file buffers. Must be at least 256. */ +#define _PDCLIB_BUFSIZ 1024 + +/* The minimum number of files the implementation can open simultaneously. Must + be at least 8. Depends largely on how the bookkeeping is done by fopen() / + freopen() / fclose(). The example implementation limits the number of open + files only by available memory. +*/ +#define _PDCLIB_FOPEN_MAX 8 + +/* Length of the longest filename the implementation guarantees to support. */ +#define _PDCLIB_FILENAME_MAX 128 + +/* Buffer size for tmpnam(). */ +#define _PDCLIB_L_tmpnam 100 + +/* Number of distinct file names that can be generated by tmpnam(). */ +#define _PDCLIB_TMP_MAX 50 + +/* The values of SEEK_SET, SEEK_CUR and SEEK_END, used by fseek(). + Since at least one platform (POSIX) uses the same symbols for its own "seek" + function, we use whatever the host defines (if it does define them). +*/ +#define _PDCLIB_SEEK_SET 0 +#define _PDCLIB_SEEK_CUR 1 +#define _PDCLIB_SEEK_END 2 + +/* The number of characters that can be buffered with ungetc(). The standard + guarantees only one (1); anything larger would make applications relying on + this capability dependent on implementation-defined behaviour (not good). +*/ +#define _PDCLIB_UNGETCBUFSIZE 1 + +typedef long wint_t; -- 2.40.0