From d02f38605b53cdff5460cc6b9e1b2a80c3a2ba4c Mon Sep 17 00:00:00 2001 From: solar Date: Mon, 6 Mar 2006 10:38:58 +0000 Subject: [PATCH] Porting current working set from CVS. --- Makefile | 16 +- Readme.txt | 4 +- functions/_PDCLIB/assert.c | 15 +- functions/_PDCLIB/atomax.c | 3 +- functions/_PDCLIB/digits.c | 6 +- functions/_PDCLIB/seed.c | 3 +- functions/_PDCLIB/stdarg.c | 11 +- functions/_PDCLIB/strtox_main.c | 14 +- functions/_PDCLIB/strtox_prelim.c | 9 +- functions/stdio/fopen.c | 87 ++++ functions/stdio/fprintf.c | 34 ++ functions/stdio/fscanf.c | 34 ++ functions/stdio/getc.c | 31 ++ functions/stdio/getchar.c | 31 ++ functions/stdio/printf.c | 34 ++ functions/stdio/putc.c | 31 ++ functions/stdio/putchar.c | 31 ++ functions/stdio/remove.c | 33 ++ functions/stdio/rename.c | 33 ++ functions/stdio/scanf.c | 34 ++ functions/stdio/setbuf.c | 39 ++ functions/stdio/setvbuf.c | 43 ++ functions/stdio/snprintf.c | 34 ++ functions/stdio/sprintf.c | 35 ++ functions/stdio/sscanf.c | 34 ++ functions/stdio/vfprintf.c | 33 ++ functions/stdio/vfscanf.c | 33 ++ functions/stdio/vprintf.c | 32 ++ functions/stdio/vscanf.c | 32 ++ functions/stdio/vsnprintf.c | 36 ++ functions/stdio/vsprintf.c | 33 ++ functions/stdio/vsscanf.c | 33 ++ functions/stdlib/_Exit.c | 11 +- functions/stdlib/abort.c | 5 +- functions/stdlib/abs.c | 3 +- functions/stdlib/atexit.c | 13 +- functions/stdlib/atoi.c | 3 +- functions/stdlib/atol.c | 3 +- functions/stdlib/atoll.c | 3 +- functions/stdlib/bsearch.c | 5 +- functions/stdlib/calloc.c | 3 +- functions/stdlib/div.c | 21 +- functions/stdlib/exit.c | 3 +- functions/stdlib/free.c | 3 +- functions/stdlib/labs.c | 3 +- functions/stdlib/ldiv.c | 21 +- functions/stdlib/llabs.c | 5 +- functions/stdlib/lldiv.c | 21 +- functions/stdlib/malloc.c | 49 ++- functions/stdlib/qsort.c | 5 +- functions/stdlib/rand.c | 3 +- functions/stdlib/realloc.c | 3 +- functions/stdlib/srand.c | 3 +- functions/stdlib/strtol.c | 10 +- functions/stdlib/strtoll.c | 10 +- functions/stdlib/strtoul.c | 8 +- functions/stdlib/strtoull.c | 8 +- functions/string/memchr.c | 3 +- functions/string/memcmp.c | 3 +- functions/string/memcpy.c | 3 +- functions/string/memmove.c | 3 +- functions/string/memset.c | 3 +- functions/string/strcat.c | 3 +- functions/string/strchr.c | 3 +- functions/string/strcmp.c | 3 +- functions/string/strcoll.c | 3 +- functions/string/strcpy.c | 3 +- functions/string/strcspn.c | 3 +- functions/string/strlen.c | 3 +- functions/string/strncat.c | 3 +- functions/string/strncmp.c | 3 +- functions/string/strncpy.c | 3 +- functions/string/strpbrk.c | 3 +- functions/string/strrchr.c | 3 +- functions/string/strspn.c | 3 +- functions/string/strstr.c | 3 +- functions/string/strtok.c | 3 +- functions/string/strxfrm.c | 3 +- includes/stddef.h | 3 + includes/stdio.h | 146 ++++++- includes/stdlib.h | 120 +++++- includes/string.h | 383 +++++++++--------- internals/_PDCLIB_glue.h | 62 +++ internals/_PDCLIB_int.h | 14 +- internals/_PDCLIB_test.h | 51 +-- platform/example/functions/_PDCLIB/_Exit.c | 37 ++ .../example/functions/_PDCLIB/allocpages.c | 21 +- platform/example/functions/_PDCLIB/open.c | 47 +++ platform/example/functions/_PDCLIB/remove.c | 46 +++ platform/example/functions/_PDCLIB/rename.c | 43 ++ platform/example/functions/stdlib/getenv.c | 3 +- platform/example/functions/stdlib/system.c | 10 +- platform/example/internals/_PDCLIB_config.h | 44 +- 93 files changed, 1779 insertions(+), 450 deletions(-) create mode 100644 functions/stdio/fopen.c create mode 100644 functions/stdio/fprintf.c create mode 100644 functions/stdio/fscanf.c create mode 100644 functions/stdio/getc.c create mode 100644 functions/stdio/getchar.c create mode 100644 functions/stdio/printf.c create mode 100644 functions/stdio/putc.c create mode 100644 functions/stdio/putchar.c create mode 100644 functions/stdio/remove.c create mode 100644 functions/stdio/rename.c create mode 100644 functions/stdio/scanf.c create mode 100644 functions/stdio/setbuf.c create mode 100644 functions/stdio/setvbuf.c create mode 100644 functions/stdio/snprintf.c create mode 100644 functions/stdio/sprintf.c create mode 100644 functions/stdio/sscanf.c create mode 100644 functions/stdio/vfprintf.c create mode 100644 functions/stdio/vfscanf.c create mode 100644 functions/stdio/vprintf.c create mode 100644 functions/stdio/vscanf.c create mode 100644 functions/stdio/vsnprintf.c create mode 100644 functions/stdio/vsprintf.c create mode 100644 functions/stdio/vsscanf.c create mode 100644 internals/_PDCLIB_glue.h create mode 100644 platform/example/functions/_PDCLIB/_Exit.c create mode 100644 platform/example/functions/_PDCLIB/open.c create mode 100644 platform/example/functions/_PDCLIB/remove.c create mode 100644 platform/example/functions/_PDCLIB/rename.c diff --git a/Makefile b/Makefile index 7bfb401..e883e60 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,15 @@ AUXFILES := Makefile Readme.txt PROJDIRS := functions includes internals SRCFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.c") HDRFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.h") -INTFILES := atomax digits seed strtox_main strtox_prelim +INTFILES := atomax digits seed strtox_main strtox_prelim rename remove _Exit OBJFILES := $(patsubst %.c,%.o,$(SRCFILES)) TSTFILES := $(patsubst %.c,%.t,$(SRCFILES)) REGFILES := $(filter-out $(patsubst %,functions/_PDCLIB/%.r,$(INTFILES)),$(patsubst %.c,%.r,$(SRCFILES))) DEPFILES := $(patsubst %.c,%.d,$(SRCFILES)) ALLFILES := $(SRCFILES) $(HDRFILES) $(AUXFILES) +CFLAGS := -Wall -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wconversion -Wstrict-prototypes + .PHONY: clean dist test testdrivers regtest all: pdclib.a @@ -19,19 +21,19 @@ pdclib.a: $(OBJFILES) @ar r pdclib.a $? test: testdrivers - -@rc=0; for file in $(TSTFILES); do ./$$file; rc=`expr $$rc + $$?`; done; echo; echo "Tests failed: $$rc" + -@rc=0; count=0; for file in $(TSTFILES); do ./$$file; rc=`expr $$rc + $$?`; count=`expr $$count + 1`; done; echo; echo "Tests executed (linking PDCLib): $$count Tests failed: $$rc" testdrivers: $(TSTFILES) regtest: regtestdrivers - -@rc=0; for file in $(REGFILES); do ./$$file; rc=`expr $$rc + $$?`; done; echo; echo "Regression tests failed: $$rc" + -@rc=0; count=0; for file in $(REGFILES); do ./$$file; rc=`expr $$rc + $$?`; count=`expr $$count + 1`; done; echo; echo "Tests executed (linking system libc): $$count Tests failed: $$rc" regtestdrivers: $(REGFILES) -include $(DEPFILES) clean: - -@for file in $(OBJFILES) $(DEPFILES) $(TSTFILES) $(REGFILES) pdclib.a pdclib.tgz; do if [ -f $$file ]; then rm $$file; fi; done + @for file in $(OBJFILES) $(DEPFILES) $(TSTFILES) $(REGFILES) pdclib.a pdclib.tgz; do if [ -f $$file ]; then rm $$file; fi; done dist: @tar czf pdclib.tgz $(ALLFILES) @@ -40,10 +42,10 @@ todolist: -@for file in $(ALLFILES); do grep -H TODO $$file; done; true %.o: %.c Makefile - @$(CC) -Wall -DNDEBUG -MMD -MP -MT "$*.d $*.t" -g -std=c99 -I./includes -I./internals -c $< -o $@ + @$(CC) $(CFLAGS) -Wall -DNDEBUG -MMD -MP -MT "$*.d $*.t" -g -std=c99 -I./includes -I./internals -c $< -o $@ %.t: %.c Makefile pdclib.a - @$(CC) -Wall -DTEST -std=c99 -I./includes -I./internals $< pdclib.a -o $@ + @$(CC) $(CFLAGS) -DTEST -std=c99 -I./includes -I./internals $< pdclib.a -o $@ %.r: %.c Makefile - @$(CC) -Wall -DTEST -DREGTEST -std=c99 -I./internals $< -o $@ + @$(CC) $(CFLAGS) -DTEST -DREGTEST -std=c99 -I./internals $< -o $@ diff --git a/Readme.txt b/Readme.txt index 8e62b7e..0977094 100644 --- a/Readme.txt +++ b/Readme.txt @@ -154,5 +154,7 @@ point conversions, and the wide-/multibyte-character functions. v0.5 - unreleased Implementations for parts of . Bug fixes. Still no locale / -wide-char support. +wide-char support. Enabled all GCC compiler warnings I could find, and +fixed everything that threw a warning. Fixed all open bugs in the v0.4 +release. diff --git a/functions/_PDCLIB/assert.c b/functions/_PDCLIB/assert.c index 5c4b310..e3d1a0a 100644 --- a/functions/_PDCLIB/assert.c +++ b/functions/_PDCLIB/assert.c @@ -10,6 +10,9 @@ #include #include +#include + +#ifndef REGTEST #ifndef _PDCLIB_AUX_H #define _PDCLIB_AUX_H _PDCLIB_AUX_H @@ -32,25 +35,25 @@ void _PDCLIB_assert( char const * const message ) } #endif +#endif #ifdef TEST #include <_PDCLIB_test.h> #include -static int rc = 0; static int EXPECTED_ABORT = 0; static int UNEXPECTED_ABORT = 1; -void aborthandler( int signal ) +static void aborthandler( int sig ) { TESTCASE( ! EXPECTED_ABORT ); - exit( rc ); + exit( (signed int)rc ); } #define NDEBUG #include -int disabled_test() +static int disabled_test( void ) { int i = 0; assert( i == 0 ); /* NDEBUG set, condition met */ @@ -61,10 +64,10 @@ int disabled_test() #undef NDEBUG #include -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( signal( SIGABRT, &aborthandler ) != SIG_ERR ); + TESTCASE( disabled_test() == 0 ); assert( UNEXPECTED_ABORT ); /* NDEBUG not set, condition met */ assert( EXPECTED_ABORT ); /* NDEBUG not set, condition fails - should abort */ return TEST_RESULTS; diff --git a/functions/_PDCLIB/atomax.c b/functions/_PDCLIB/atomax.c index e2403f4..6835b14 100644 --- a/functions/_PDCLIB/atomax.c +++ b/functions/_PDCLIB/atomax.c @@ -32,9 +32,8 @@ _PDCLIB_intmax_t _PDCLIB_atomax( const char * s ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* basic functionality */ TESTCASE( _PDCLIB_atomax( "123" ) == 123 ); /* testing skipping of leading whitespace and trailing garbage */ diff --git a/functions/_PDCLIB/digits.c b/functions/_PDCLIB/digits.c index b58886b..21a2b46 100644 --- a/functions/_PDCLIB/digits.c +++ b/functions/_PDCLIB/digits.c @@ -11,13 +11,11 @@ char _PDCLIB_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; #ifdef TEST -#include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* no tests for raw data */ - return TEST_RESULTS; + return 0; } #endif diff --git a/functions/_PDCLIB/seed.c b/functions/_PDCLIB/seed.c index df0c55d..eba8025 100644 --- a/functions/_PDCLIB/seed.c +++ b/functions/_PDCLIB/seed.c @@ -13,9 +13,8 @@ unsigned long int _PDCLIB_seed = 1; #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* no tests for raw data */ return TEST_RESULTS; } diff --git a/functions/_PDCLIB/stdarg.c b/functions/_PDCLIB/stdarg.c index defd5fe..4900cc5 100644 --- a/functions/_PDCLIB/stdarg.c +++ b/functions/_PDCLIB/stdarg.c @@ -8,14 +8,11 @@ Permission is granted to use, modify, and / or redistribute at will. */ -#ifdef TEST - -#include <_PDCLIB_test.h> #include #include #include -unsigned int rc = 0; +#include <_PDCLIB_test.h> typedef int (*intfunc_t)( void ); @@ -98,12 +95,12 @@ static int test( enum tag_t s, ... ) } } -int dummy() +static int dummy( void ) { return INT_MAX; } -int main() +int main( void ) { int x = INT_MAX; long double d = LDBL_MAX; @@ -114,5 +111,3 @@ int main() test( TAG_INTPTR, &x, TAG_LDBLPTR, &d, TAG_FUNCPTR, dummy, TAG_END ); return TEST_RESULTS; } - -#endif diff --git a/functions/_PDCLIB/strtox_main.c b/functions/_PDCLIB/strtox_main.c index 25aff70..59534d8 100644 --- a/functions/_PDCLIB/strtox_main.c +++ b/functions/_PDCLIB/strtox_main.c @@ -13,8 +13,9 @@ #include #include #include +#include -_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, _PDCLIB_uintmax_t limdigit, char * sign ) +_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, uintmax_t error, uintmax_t limval, uintmax_t limdigit, char * sign ) { _PDCLIB_uintmax_t rc = 0; int digit = -1; @@ -49,27 +50,26 @@ _PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, int base, _PDCLIB_uintma #include <_PDCLIB_test.h> #include -int main() +int main( void ) { const char * p; char test[] = "123_"; char fail[] = "xxx"; char sign = '-'; - BEGIN_TESTS; /* basic functionality */ p = test; errno = 0; - TESTCASE( _PDCLIB_strtox_main( &p, 10, 999, 12, 3, &sign ) == 123 ); + TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)12, (uintmax_t)3, &sign ) == 123 ); TESTCASE( errno == 0 ); TESTCASE( p == &test[3] ); /* proper functioning to smaller base */ p = test; - TESTCASE( _PDCLIB_strtox_main( &p, 8, 999, 12, 3, &sign ) == 0123 ); + TESTCASE( _PDCLIB_strtox_main( &p, 8u, (uintmax_t)999, (uintmax_t)12, (uintmax_t)3, &sign ) == 0123 ); TESTCASE( errno == 0 ); TESTCASE( p == &test[3] ); /* overflowing subject sequence must still return proper endptr */ p = test; - TESTCASE( _PDCLIB_strtox_main( &p, 4, 999, 1, 2, &sign ) == 999 ); + TESTCASE( _PDCLIB_strtox_main( &p, 4u, (uintmax_t)999, (uintmax_t)1, (uintmax_t)2, &sign ) == 999 ); TESTCASE( errno == ERANGE ); TESTCASE( p == &test[3] ); TESTCASE( sign == '+' ); @@ -77,7 +77,7 @@ int main() errno = 0; p = fail; sign = '-'; - TESTCASE( _PDCLIB_strtox_main( &p, 10, 999, 99, 8, &sign ) == 0 ); + TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)99, (uintmax_t)8, &sign ) == 0 ); TESTCASE( p == NULL ); return TEST_RESULTS; } diff --git a/functions/_PDCLIB/strtox_prelim.c b/functions/_PDCLIB/strtox_prelim.c index 8b0f442..6925527 100644 --- a/functions/_PDCLIB/strtox_prelim.c +++ b/functions/_PDCLIB/strtox_prelim.c @@ -39,20 +39,19 @@ const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base ) { *base = 10; } - return p; + return ( ( *base >= 2 ) && ( *base <= 36 ) ) ? p : NULL; } #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { int base = 0; char sign = '\0'; char test1[] = " 123"; char test2[] = "\t+0123"; char test3[] = "\v-0x123"; - BEGIN_TESTS; TESTCASE( _PDCLIB_strtox_prelim( test1, &sign, &base ) == &test1[2] ); TESTCASE( sign == '+' ); TESTCASE( base == 10 ); @@ -71,6 +70,10 @@ int main() TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[2] ); TESTCASE( sign == '-' ); TESTCASE( base == 10 ); + base = 1; + TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL ); + base = 37; + TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL ); return TEST_RESULTS; } diff --git a/functions/stdio/fopen.c b/functions/stdio/fopen.c new file mode 100644 index 0000000..4d249ef --- /dev/null +++ b/functions/stdio/fopen.c @@ -0,0 +1,87 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* fopen( 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 +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +static const FILE * _PDCLIB_filelist = NULL; + +static int filemode( char const * const mode ) +{ + int rc = 0; + switch ( mode[0] ) + { + case 'r': + rc |= _PDCLIB_FREAD; + break; + case 'w': + rc |= _PDCLIB_FWRITE; + break; + case 'a': + rc |= _PDCLIB_FAPPEND; + break; + default: + return -1; + } + for ( size_t i = 1; i < 4; ++i ) + { + switch ( mode[1] ) + { + case '+': + if ( rc & _PDCLIB_FRW ) return -1; + rc |= _PDCLIB_FRW; + break; + case 'b': + if ( rc & _PDCLIB_FBIN ) return -1; + rc |= _PDCLIB_FBIN; + break; + case '\0': + return rc; + default: + return -1; + } + } + return -1; +} + +FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode ) +{ + FILE * rc; + if ( mode == NULL || filename == NULL || filename[0] == '\0' ) + { + return NULL; + } + if ( ( rc = calloc( 1, sizeof( FILE ) ) ) == NULL ) return rc; /* no space for another FILE */ + if ( ( rc->status = filemode( mode ) ) == -1 ) goto fail; /* invalid mode given */ + if ( ( rc->handle = _PDCLIB_open( filename, rc->status ) ) == -1 ) goto fail; /* OS "open" failed */ + rc->next = _PDCLIB_filelist; + _PDCLIB_filelist = rc; + /* TODO: Continue here: Set up PDCLib FILE contents */ + return rc; +fail: + free( rc ); + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/fprintf.c b/functions/stdio/fprintf.c new file mode 100644 index 0000000..5dfec4d --- /dev/null +++ b/functions/stdio/fprintf.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* fprintf( FILE *, 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 +#include + +#ifndef REGTEST + +int fprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) +{ + va_list ap; + va_start( ap, format ); + return vfprintf( stream, format, ap ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/fscanf.c b/functions/stdio/fscanf.c new file mode 100644 index 0000000..3996257 --- /dev/null +++ b/functions/stdio/fscanf.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* fscanf( FILE *, 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 +#include + +#ifndef REGTEST + +int fscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) +{ + va_list ap; + va_start( ap, format ); + return vfscanf( stream, format, ap ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/getc.c b/functions/stdio/getc.c new file mode 100644 index 0000000..b4229f2 --- /dev/null +++ b/functions/stdio/getc.c @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* getc( 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 + +int getc( FILE * stream ) +{ + return fgetc( stream ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/getchar.c b/functions/stdio/getchar.c new file mode 100644 index 0000000..bce6855 --- /dev/null +++ b/functions/stdio/getchar.c @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* getchar( 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 + +int getchar( void ) +{ + return fgetc( stdin ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/printf.c b/functions/stdio/printf.c new file mode 100644 index 0000000..4933422 --- /dev/null +++ b/functions/stdio/printf.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* printf( 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 +#include + +#ifndef REGTEST + +int printf( const char * _PDCLIB_restrict format, ... ) +{ + va_list ap; + va_start( ap, format ); + return vfprintf( stdout, format, ap ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/putc.c b/functions/stdio/putc.c new file mode 100644 index 0000000..b416332 --- /dev/null +++ b/functions/stdio/putc.c @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* putc( 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 REGTEST + +int putc( int c, FILE * stream ) +{ + return fputc( c, stream ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/putchar.c b/functions/stdio/putchar.c new file mode 100644 index 0000000..7ef2014 --- /dev/null +++ b/functions/stdio/putchar.c @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* putchar( 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 REGTEST + +int putchar( int c ) +{ + return fputc( c, stdout ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/remove.c b/functions/stdio/remove.c new file mode 100644 index 0000000..ec7941b --- /dev/null +++ b/functions/stdio/remove.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* 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. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +int remove( const char * filename ) +{ + /* TODO: Check open file list, flush and close file if open */ + return _PDCLIB_remove( filename ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/rename.c b/functions/stdio/rename.c new file mode 100644 index 0000000..4a1cc85 --- /dev/null +++ b/functions/stdio/rename.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* 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> + +int rename( const char * old, const char * new ) +{ + /* TODO: Search open file list, flush and close file */ + return _PDCLIB_rename( old, new ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/scanf.c b/functions/stdio/scanf.c new file mode 100644 index 0000000..dfb219b --- /dev/null +++ b/functions/stdio/scanf.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* scanf( 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 +#include + +#ifndef REGTEST + +int scanf( const char * _PDCLIB_restrict format, ... ) +{ + va_list ap; + va_start( ap, format ); + return vfscanf( stdin, format, ap ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/setbuf.c b/functions/stdio/setbuf.c new file mode 100644 index 0000000..d9b722b --- /dev/null +++ b/functions/stdio/setbuf.c @@ -0,0 +1,39 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* setbuf( FILE *, 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 + +void setbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf ) +{ + /* TODO: Only allowed on a "virgin" stream; add check. */ + if ( buf == NULL ) + { + setvbuf( stream, buf, _IONBF, BUFSIZ ); + } + else + { + setvbuf( stream, buf, _IOFBF, BUFSIZ ); + } +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/setvbuf.c b/functions/stdio/setvbuf.c new file mode 100644 index 0000000..c8d751c --- /dev/null +++ b/functions/stdio/setvbuf.c @@ -0,0 +1,43 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* setvbuf( FILE *, char *, int, size_t ) + + 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 + +int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size ) +{ + /* TODO: Only allowed on a "virgin" stream; add check. */ + if ( ( stream->status & ( _IOFBF | _IOLBF | _IONBF ) ) /* Only allowed on "virgin" stream */ + || ( ( mode != _IOFBF ) && ( mode != _IOLBF ) && ( mode != _IONBF ) ) /* invalid mode */ + || ( ( buf == NULL ) && ( ( buf = malloc( size ) ) == NULL ) ) /* no memory available */ + ) + { + return -1; + } + stream->status |= mode; + stream->buffer = buf; + stream->bufsize = size; + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/snprintf.c b/functions/stdio/snprintf.c new file mode 100644 index 0000000..efe1ba9 --- /dev/null +++ b/functions/stdio/snprintf.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* snprintf( char *, size_t, 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 +#include + +#ifndef REGTEST + +int snprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, ...) +{ + va_list ap; + va_start( ap, format ); + return vsnprintf( s, n, format, ap ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/sprintf.c b/functions/stdio/sprintf.c new file mode 100644 index 0000000..d85b205 --- /dev/null +++ b/functions/stdio/sprintf.c @@ -0,0 +1,35 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* sprintf( 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 +#include +#include + +#ifndef REGTEST + +int sprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ...) +{ + va_list ap; + va_start( ap, format ); + return vsnprintf( s, SIZE_MAX, format, ap ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/sscanf.c b/functions/stdio/sscanf.c new file mode 100644 index 0000000..f379dca --- /dev/null +++ b/functions/stdio/sscanf.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* sscanf( 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 +#include + +#ifndef REGTEST + +int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ) +{ + va_list ap; + va_start( ap, format ); + return vsscanf( s, format, ap ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vfprintf.c b/functions/stdio/vfprintf.c new file mode 100644 index 0000000..2315b9a --- /dev/null +++ b/functions/stdio/vfprintf.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* vfprintf( FILE *, const char *, va_list ) + + 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 + +int vfprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, va_list arg ) +{ + /* TODO: Implement using vsnprintf() writing to file buffer */ + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vfscanf.c b/functions/stdio/vfscanf.c new file mode 100644 index 0000000..1cfea64 --- /dev/null +++ b/functions/stdio/vfscanf.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* vfscanf( FILE *, const char *, va_list ) + + 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 + +int vfscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, va_list arg ) +{ + /* TODO: Implement using vsscanf() reading from file buffer */ + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vprintf.c b/functions/stdio/vprintf.c new file mode 100644 index 0000000..85db470 --- /dev/null +++ b/functions/stdio/vprintf.c @@ -0,0 +1,32 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* vprintf( const char *, va_list arg ) + + 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 + +int vprintf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) +{ + return vfprintf( stdout, format, arg ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vscanf.c b/functions/stdio/vscanf.c new file mode 100644 index 0000000..3adde22 --- /dev/null +++ b/functions/stdio/vscanf.c @@ -0,0 +1,32 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* vscanf( const char *, va_list arg ) + + 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 + +int vscanf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) +{ + return vfscanf( stdin, format, arg ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vsnprintf.c b/functions/stdio/vsnprintf.c new file mode 100644 index 0000000..30086ab --- /dev/null +++ b/functions/stdio/vsnprintf.c @@ -0,0 +1,36 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* vsnprintf( char *, size_t, const char *, va_list ap ) + + 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 + +typedef char wchar_t; + +int vsnprintf( char * str, size_t size, const char * format, _PDCLIB_va_list arg ) +{ + /* TODO: This function should interpret format as multibyte characters. */ + /* TODO: Implement */ + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vsprintf.c b/functions/stdio/vsprintf.c new file mode 100644 index 0000000..fc06a20 --- /dev/null +++ b/functions/stdio/vsprintf.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* vsprintf( char *, const char *, va_list ap ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include +#include +#include + +#ifndef REGTEST + +int vsprintf( char * str, const char * format, _PDCLIB_va_list arg ) +{ + return vsnprintf( str, SIZE_MAX, format, arg ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vsscanf.c b/functions/stdio/vsscanf.c new file mode 100644 index 0000000..8e2c967 --- /dev/null +++ b/functions/stdio/vsscanf.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* vsscanf( const char *, const char *, va_list arg ) + + 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 + +int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, va_list arg ) +{ + /* TODO: Implement. */ + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdlib/_Exit.c b/functions/stdlib/_Exit.c index e46af39..da60c87 100644 --- a/functions/stdlib/_Exit.c +++ b/functions/stdlib/_Exit.c @@ -8,8 +8,8 @@ Permission is granted to use, modify, and / or redistribute at will. */ -#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H -#include <_PDCLIB_config.h> +#include +#include <_PDCLIB_glue.h> #ifndef REGTEST @@ -24,10 +24,11 @@ void _Exit( int status ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; - /* TODO: Add testdrivers after flush / close / tmpfile is implemented. */ + int UNEXPECTED_RETURN = 0; + _Exit( 0 ); + TESTCASE( UNEXPECTED_RETURN ); return TEST_RESULTS; } diff --git a/functions/stdlib/abort.c b/functions/stdlib/abort.c index 6a6743f..c5adfbd 100644 --- a/functions/stdlib/abort.c +++ b/functions/stdlib/abort.c @@ -26,15 +26,14 @@ void abort( void ) #include -static void aborthandler( int signal ) +static void aborthandler( int sig ) { exit( 0 ); } -int main() +int main( void ) { int UNEXPECTED_RETURN_FROM_ABORT = 0; - BEGIN_TESTS; TESTCASE( signal( SIGABRT, &aborthandler ) != SIG_ERR ); abort(); TESTCASE( UNEXPECTED_RETURN_FROM_ABORT ); diff --git a/functions/stdlib/abs.c b/functions/stdlib/abs.c index 1bd965d..c5fd00c 100644 --- a/functions/stdlib/abs.c +++ b/functions/stdlib/abs.c @@ -23,9 +23,8 @@ int abs( int j ) #include <_PDCLIB_test.h> #include -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( abs( 0 ) == 0 ); TESTCASE( abs( INT_MAX ) == INT_MAX ); TESTCASE( abs( INT_MIN + 1 ) == -( INT_MIN + 1 ) ); diff --git a/functions/stdlib/atexit.c b/functions/stdlib/atexit.c index 0d61e32..8a5f4d7 100644 --- a/functions/stdlib/atexit.c +++ b/functions/stdlib/atexit.c @@ -36,14 +36,14 @@ int atexit( void (*func)( void ) ) static int flags[ 32 ]; -static void counthandler() +static void counthandler( void ) { - static int rc = 0; - flags[ rc ] = rc; - ++rc; + static int count = 0; + flags[ count ] = count; + ++count; } -static void checkhandler() +static void checkhandler( void ) { for ( int i = 0; i < 31; ++i ) { @@ -51,9 +51,8 @@ static void checkhandler() } } -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( atexit( &checkhandler ) == 0 ); for ( int i = 0; i < 31; ++i ) { diff --git a/functions/stdlib/atoi.c b/functions/stdlib/atoi.c index 5d0a27b..08a873f 100644 --- a/functions/stdlib/atoi.c +++ b/functions/stdlib/atoi.c @@ -22,9 +22,8 @@ int atoi( const char * s ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* no tests for a simple wrapper */ return TEST_RESULTS; } diff --git a/functions/stdlib/atol.c b/functions/stdlib/atol.c index 475adef..a1403fe 100644 --- a/functions/stdlib/atol.c +++ b/functions/stdlib/atol.c @@ -22,9 +22,8 @@ long int atol( const char * s ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* no tests for a simple wrapper */ return TEST_RESULTS; } diff --git a/functions/stdlib/atoll.c b/functions/stdlib/atoll.c index 0f0fe18..00c1dd3 100644 --- a/functions/stdlib/atoll.c +++ b/functions/stdlib/atoll.c @@ -22,9 +22,8 @@ long long int atoll( const char * s ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* no tests for a simple wrapper */ return TEST_RESULTS; } diff --git a/functions/stdlib/bsearch.c b/functions/stdlib/bsearch.c index 881c99a..b9a33c6 100644 --- a/functions/stdlib/bsearch.c +++ b/functions/stdlib/bsearch.c @@ -42,14 +42,13 @@ void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, #ifdef TEST #include <_PDCLIB_test.h> -int compare( const void * left, const void * right ) +static int compare( const void * left, const void * right ) { return *( (unsigned char *)left ) - *( (unsigned char *)right ); } -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( bsearch( "e", abcde, 4, 1, compare ) == NULL ); TESTCASE( bsearch( "e", abcde, 5, 1, compare ) == &abcde[4] ); TESTCASE( bsearch( "a", abcde + 1, 4, 1, compare ) == NULL ); diff --git a/functions/stdlib/calloc.c b/functions/stdlib/calloc.c index 5450b97..fc1c80e 100644 --- a/functions/stdlib/calloc.c +++ b/functions/stdlib/calloc.c @@ -30,10 +30,9 @@ void * calloc( size_t nmemb, size_t size ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char * s; - BEGIN_TESTS; TESTCASE( ( s = calloc( 3, 2 ) ) != NULL ); TESTCASE( s[0] == '\0' ); TESTCASE( s[5] == '\0' ); diff --git a/functions/stdlib/div.c b/functions/stdlib/div.c index bf82bed..3e32638 100644 --- a/functions/stdlib/div.c +++ b/functions/stdlib/div.c @@ -30,18 +30,17 @@ div_t div( int numer, int denom ) #include <_PDCLIB_config.h> #endif -int main() +int main( void ) { - div_t idiv; - BEGIN_TESTS; - idiv = div( 5, 2 ); - TESTCASE( idiv.quot == 2 && idiv.rem == 1 ); - idiv = div( -5, 2 ); - TESTCASE( idiv.quot == -2 && idiv.rem == -1 ); - idiv = div( 5, -2 ); - TESTCASE( idiv.quot == -2 && idiv.rem == 1 ); - TESTCASE( sizeof( idiv.quot ) == _PDCLIB_INT_BYTES ); - TESTCASE( sizeof( idiv.rem ) == _PDCLIB_INT_BYTES ); + div_t result; + result = div( 5, 2 ); + TESTCASE( result.quot == 2 && result.rem == 1 ); + result = div( -5, 2 ); + 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 ); return TEST_RESULTS; } diff --git a/functions/stdlib/exit.c b/functions/stdlib/exit.c index 0d816a3..8862f41 100644 --- a/functions/stdlib/exit.c +++ b/functions/stdlib/exit.c @@ -38,9 +38,8 @@ void exit( int status ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* Unwinding of regstack tested in atexit(). */ return TEST_RESULTS; } diff --git a/functions/stdlib/free.c b/functions/stdlib/free.c index 632f670..6b63741 100644 --- a/functions/stdlib/free.c +++ b/functions/stdlib/free.c @@ -42,9 +42,8 @@ void free( void * ptr ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* tests covered in malloc test driver */ return TEST_RESULTS; } diff --git a/functions/stdlib/labs.c b/functions/stdlib/labs.c index 09d15a6..d2a6885 100644 --- a/functions/stdlib/labs.c +++ b/functions/stdlib/labs.c @@ -23,9 +23,8 @@ long int labs( long int j ) #include <_PDCLIB_test.h> #include -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( labs( 0 ) == 0 ); TESTCASE( labs( LONG_MAX ) == LONG_MAX ); TESTCASE( labs( LONG_MIN + 1 ) == -( LONG_MIN + 1 ) ); diff --git a/functions/stdlib/ldiv.c b/functions/stdlib/ldiv.c index 11940de..a6974d5 100644 --- a/functions/stdlib/ldiv.c +++ b/functions/stdlib/ldiv.c @@ -30,18 +30,17 @@ ldiv_t ldiv( long int numer, long int denom ) #include <_PDCLIB_config.h> #endif -int main() +int main( void ) { - ldiv_t div; - BEGIN_TESTS; - div = ldiv( 5, 2 ); - TESTCASE( div.quot == 2 && div.rem == 1 ); - div = ldiv( -5, 2 ); - TESTCASE( div.quot == -2 && div.rem == -1 ); - div = ldiv( 5, -2 ); - TESTCASE( div.quot == -2 && div.rem == 1 ); - TESTCASE( sizeof( div.quot ) == _PDCLIB_LONG_BYTES ); - TESTCASE( sizeof( div.rem ) == _PDCLIB_LONG_BYTES ); + ldiv_t result; + result = ldiv( 5, 2 ); + TESTCASE( result.quot == 2 && result.rem == 1 ); + result = ldiv( -5, 2 ); + 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 ); return TEST_RESULTS; } diff --git a/functions/stdlib/llabs.c b/functions/stdlib/llabs.c index ab9aca1..876afa8 100644 --- a/functions/stdlib/llabs.c +++ b/functions/stdlib/llabs.c @@ -23,10 +23,9 @@ long long int llabs( long long int j ) #include <_PDCLIB_test.h> #include -int main() +int main( void ) { - BEGIN_TESTS; - TESTCASE( llabs( 0 ) == 0 ); + TESTCASE( llabs( 0ll ) == 0 ); TESTCASE( llabs( LLONG_MAX ) == LLONG_MAX ); TESTCASE( llabs( LLONG_MIN + 1 ) == -( LLONG_MIN + 1 ) ); return TEST_RESULTS; diff --git a/functions/stdlib/lldiv.c b/functions/stdlib/lldiv.c index 358b288..731a316 100644 --- a/functions/stdlib/lldiv.c +++ b/functions/stdlib/lldiv.c @@ -30,18 +30,17 @@ lldiv_t lldiv( long long int numer, long long int denom ) #include <_PDCLIB_config.h> #endif -int main() +int main( void ) { - lldiv_t div; - BEGIN_TESTS; - div = lldiv( 5, 2 ); - TESTCASE( div.quot == 2 && div.rem == 1 ); - div = lldiv( -5, 2 ); - TESTCASE( div.quot == -2 && div.rem == -1 ); - div = lldiv( 5, -2 ); - TESTCASE( div.quot == -2 && div.rem == 1 ); - TESTCASE( sizeof( div.quot ) == _PDCLIB_LLONG_BYTES ); - TESTCASE( sizeof( div.rem ) == _PDCLIB_LLONG_BYTES ); + lldiv_t result; + result = lldiv( 5ll, 2ll ); + TESTCASE( result.quot == 2 && result.rem == 1 ); + result = lldiv( -5ll, 2ll ); + 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 ); return TEST_RESULTS; } diff --git a/functions/stdlib/malloc.c b/functions/stdlib/malloc.c index a97730f..650d67f 100644 --- a/functions/stdlib/malloc.c +++ b/functions/stdlib/malloc.c @@ -9,18 +9,16 @@ */ #include +#include #ifndef REGTEST -#include - -#ifndef _PDCLIB_INT_H -#define _PDCLIB_INT_H _PDLIB_INT_H -#include <_PDCLIB_int.h> +#ifndef _PDCLIB_GLUE_H +#define _PDCLIB_GLUE_H _PDLIB_GLUE_H +#include <_PDCLIB_glue.h> #endif /* TODO: Primitive placeholder. Much room for improvement. */ -/* TODO: Leaves nodes with size < _PDCLIB_MINALLOC, which are never assigned */ /* Keeping pointers to the first and the last element of the free list. */ struct _PDCLIB_headnode_t _PDCLIB_memlist = { NULL, NULL }; @@ -108,14 +106,14 @@ void * malloc( size_t size ) } { /* No fit possible; how many additional pages do we need? */ - uintmax_t pages = ( ( size + sizeof( struct _PDCLIB_memnode_t ) - 1 ) / _PDCLIB_PAGESIZE ) + 1; + int pages = ( ( size + sizeof( struct _PDCLIB_memnode_t ) - 1 ) / _PDCLIB_PAGESIZE ) + 1; /* Allocate more pages */ struct _PDCLIB_memnode_t * newnode = (struct _PDCLIB_memnode_t *)_PDCLIB_allocpages( pages ); if ( newnode != NULL ) { newnode->next = NULL; newnode->size = pages * _PDCLIB_PAGESIZE - sizeof( struct _PDCLIB_memnode_t ); - if ( ( newnode->size - size ) > _PDCLIB_MINALLOC ) + if ( ( newnode->size - size ) > ( _PDCLIB_MINALLOC + sizeof( struct _PDCLIB_memnode_t ) ) ) { /* Oversized - split into two nodes */ struct _PDCLIB_memnode_t * splitnode = (struct _PDCLIB_memnode_t *)( (char *)newnode + sizeof( struct _PDCLIB_memnode_t ) + size ); @@ -150,6 +148,13 @@ void * malloc( size_t size ) #define PAGETEST( x ) ( pages_start + x * _PDCLIB_PAGESIZE ) == sbrk( 0 ) #define EFFECTIVE _PDCLIB_PAGESIZE - sizeof( struct _PDCLIB_memnode_t ) +/* This can be enabled to give a dump of available nodes */ +#if 0 +#define NODETRACE( x ) do { struct _PDCLIB_memnode_t * tracer = _PDCLIB_memlist.first; printf( "Node trace #%d, %d allocated pages\n", x, ( (intptr_t)sbrk( 0 ) - (intptr_t)pages_start ) / _PDCLIB_PAGESIZE ); while ( tracer != NULL ) { printf( "- node %p, size %#x\n", (void *)tracer, tracer->size ); tracer = tracer->next; } } while ( 0 ) +#else +#define NODETRACE( x ) ( (void) 0 ) +#endif + /* Note that this test driver heavily tests *internals* of the implementation above (and of free() and realloc(), too). That means that changes in the implementation must be accompanied with appropriate changes of the test @@ -157,69 +162,89 @@ void * malloc( size_t size ) I am afraid, and thus there is no REGTEST equivalent. */ -#include +void * sbrk( intptr_t ); -int main( int argc, char * argv[] ) +int main( void ) { - BEGIN_TESTS; #ifndef REGTEST + printf( "Start of malloc() testing...\n" ); { void * ptr1, * ptr2, * ptr3, * ptr4, * ptr5, * ptr6, * ptr7, * ptr8, * ptr9; char * pages_start = _PDCLIB_allocpages( 0 ); /* allocating 10 byte; expected: 1 page allocation, node split */ TESTCASE( MEMTEST( ptr1, 10 ) ); TESTCASE( PAGETEST( 1 ) ); + NODETRACE( 1 ); /* allocating EFFECTIVE - 10 byte; expected: no page allocation, receiving split node */ TESTCASE( MEMTEST( ptr2, EFFECTIVE - 10 - sizeof( struct _PDCLIB_memnode_t ) ) ); TESTCASE( PAGETEST( 1 ) ); + NODETRACE( 2 ); /* allocating EFFECTIVE; expected: 1 page allocation, no node split */ TESTCASE( MEMTEST( ptr3, EFFECTIVE ) ); TESTCASE( PAGETEST( 2 ) ); + NODETRACE( 3 ); /* allocating EFFECTIVE - 4; expected: 1 page allocation, no node split */ TESTCASE( MEMTEST( ptr4, EFFECTIVE - 4 ) ); TESTCASE( PAGETEST( 3 ) ); + NODETRACE( 4 ); /* freeing and re-allocating EFFECTIVE - 4; expected: no page allocation, no node split */ free( ptr4 ); TESTCASE( MEMTEST( ptr5, EFFECTIVE - 4 ) ); TESTCASE( ptr4 == ptr5 ); TESTCASE( PAGETEST( 3 ) ); + NODETRACE( 5 ); /* releasing EFFECTIVE; expected: no page release */ free( ptr3 ); TESTCASE( PAGETEST( 3 ) ); + NODETRACE( 6 ); /* allocating EFFECTIVE + _PDCLIB_PAGESIZE; expected: 2 page allocation, no node split */ TESTCASE( MEMTEST( ptr3, EFFECTIVE + _PDCLIB_PAGESIZE ) ); TESTCASE( PAGETEST( 5 ) ); + NODETRACE( 7 ); /* reallocating to 10 byte; expected: no page allocation, no node split */ TESTCASE( realloc( ptr3, 10 ) == ptr3 ); TESTCASE( PAGETEST( 5 ) ); + NODETRACE( 8 ); /* reallocating to EFFECTIVE + _PDCLIB_PAGESIZE; expected: no page allocation, no node split */ TESTCASE( realloc( ptr3, EFFECTIVE + _PDCLIB_PAGESIZE ) == ptr3 ); TESTCASE( PAGETEST( 5 ) ); + NODETRACE( 9 ); /* reallocating to EFFECTIVE + _PDCLIB_PAGESIZE * 2; expected: 3 page allocations, no node split */ TESTCASE( realloc( ptr3, EFFECTIVE + _PDCLIB_PAGESIZE * 2 ) != ptr3 ); TESTCASE( PAGETEST( 8 ) ); + NODETRACE( 10 ); /* allocating EFFECTIVE + _PDCLIB_PAGESIZE; expected: no page allocation, no node split */ TESTCASE( MEMTEST( ptr4, EFFECTIVE + _PDCLIB_PAGESIZE ) ); TESTCASE( PAGETEST( 8 ) ); + NODETRACE( 11 ); /* allocating zero size; expected: no page allocation, no node split */ TESTCASE( ! MEMTEST( ptr6, 0 ) ); TESTCASE( PAGETEST( 8 ) ); + NODETRACE( 12 ); /* allocating 4 byte; expected: no page allocation, upsizing of size, node split */ TESTCASE( MEMTEST( ptr7, 4 ) ); TESTCASE( PAGETEST( 8 ) ); + NODETRACE( 13 ); /* allocating rest of page; expected: no page allocation, no node split */ TESTCASE( MEMTEST( ptr8, EFFECTIVE - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ) ) ); TESTCASE( PAGETEST( 8 ) ); - /* freeing, and allocating one byte more; expected: 1 page allocation, node split */ + NODETRACE( 14 ); + /* freeing, and allocating one byte more; expected: 1 page allocation, no node split */ free( ptr8 ); + NODETRACE( 15 ); TESTCASE( MEMTEST( ptr8, EFFECTIVE + 1 - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ) ) ); TESTCASE( PAGETEST( 9 ) ); + NODETRACE( 16 ); /* realloc with NULL pointer; expected: no page allocation, no node split */ ptr9 = realloc( NULL, 4072 ); TESTCASE( ptr9 != NULL ); TESTCASE( memset( ptr9, 0, 4072 ) == ptr9 ); TESTCASE( PAGETEST( 9 ) ); + NODETRACE( 17 ); + printf( "End of malloc() testing.\n" ); } +#else + printf( "No testing of malloc() - test driver does not know internals of system malloc().\n" ); #endif return TEST_RESULTS; } diff --git a/functions/stdlib/qsort.c b/functions/stdlib/qsort.c index fedda0f..7fd7c41 100644 --- a/functions/stdlib/qsort.c +++ b/functions/stdlib/qsort.c @@ -133,18 +133,17 @@ void qsort( void * base, size_t nmemb, size_t size, int (*compar)( const void *, #include #include -int compare( const void * left, const void * right ) +static int compare( const void * left, const void * right ) { return *( (unsigned char *)left ) - *( (unsigned char *)right ); } -int main() +int main( void ) { char presort[] = { "shreicnyjqpvozxmbt" }; char sorted1[] = { "bcehijmnopqrstvxyz" }; char sorted2[] = { "bticjqnyozpvreshxm" }; char s[19]; - BEGIN_TESTS; strcpy( s, presort ); qsort( s, 18, 1, compare ); TESTCASE( strcmp( s, sorted1 ) == 0 ); diff --git a/functions/stdlib/rand.c b/functions/stdlib/rand.c index b8163a3..b326be0 100644 --- a/functions/stdlib/rand.c +++ b/functions/stdlib/rand.c @@ -23,10 +23,9 @@ int rand( void ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { int rnd1, rnd2; - BEGIN_TESTS; TESTCASE( ( rnd1 = rand() ) < RAND_MAX ); TESTCASE( ( rnd2 = rand() ) < RAND_MAX ); srand( 1 ); diff --git a/functions/stdlib/realloc.c b/functions/stdlib/realloc.c index 90214e0..67133b4 100644 --- a/functions/stdlib/realloc.c +++ b/functions/stdlib/realloc.c @@ -44,9 +44,8 @@ void * realloc( void * ptr, size_t size ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* tests covered in malloc test driver */ return TEST_RESULTS; } diff --git a/functions/stdlib/srand.c b/functions/stdlib/srand.c index f207de8..21d48a5 100644 --- a/functions/stdlib/srand.c +++ b/functions/stdlib/srand.c @@ -22,9 +22,8 @@ void srand( unsigned int seed ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; /* tested in rand.c */ return TEST_RESULTS; } diff --git a/functions/stdlib/strtol.c b/functions/stdlib/strtol.c index 7252923..7ff35b3 100644 --- a/functions/stdlib/strtol.c +++ b/functions/stdlib/strtol.c @@ -13,19 +13,22 @@ #ifndef REGTEST +#include + long int strtol( const char * s, char ** endptr, int base ) { long int rc; char sign = '+'; const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); + if ( base < 2 || base > 36 ) return 0; if ( sign == '+' ) { - rc = _PDCLIB_strtox_main( &p, base, LONG_MAX, LONG_MAX / base, LONG_MAX % base, &sign ); + rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LONG_MAX, (uintmax_t)( LONG_MAX / base ), (uintmax_t)( LONG_MAX % base ), &sign ); } else { /* FIXME: This breaks on some machines that round negatives wrongly */ - rc = _PDCLIB_strtox_main( &p, base, LONG_MIN, LONG_MIN / -base, -( LONG_MIN % base ), &sign ); + rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LONG_MIN, (uintmax_t)( LONG_MIN / -base ), (uintmax_t)( -( LONG_MIN % base ) ), &sign ); } if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; return ( sign == '+' ) ? rc : -rc; @@ -43,12 +46,11 @@ long int strtol( const char * s, char ** endptr, int base ) #include -int main() +int main( void ) { char * endptr; /* this, to base 36, overflows even a 256 bit integer */ char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - BEGIN_TESTS; errno = 0; /* basic functionality */ TESTCASE( strtol( "123", NULL, 10 ) == 123 ); diff --git a/functions/stdlib/strtoll.c b/functions/stdlib/strtoll.c index fbe837d..b9b6627 100644 --- a/functions/stdlib/strtoll.c +++ b/functions/stdlib/strtoll.c @@ -13,19 +13,22 @@ #ifndef REGTEST +#include + long long int strtoll( const char * s, char ** endptr, int base ) { long long int rc; char sign = '+'; const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); + if ( base < 2 || base > 36 ) return 0; if ( sign == '+' ) { - rc = _PDCLIB_strtox_main( &p, base, LLONG_MAX, LLONG_MAX / base, LLONG_MAX % base, &sign ); + rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LLONG_MAX, (uintmax_t)( LLONG_MAX / base ), (uintmax_t)( LLONG_MAX % base ), &sign ); } else { /* FIXME: This breaks on some machines that round negatives wrongly */ - rc = _PDCLIB_strtox_main( &p, base, LLONG_MIN, LLONG_MIN / -base, -( LLONG_MIN % base ), &sign ); + rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LLONG_MIN, (uintmax_t)( LLONG_MIN / -base ), (uintmax_t)( -( LLONG_MIN % base ) ), &sign ); } if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; return ( sign == '+' ) ? rc : -rc; @@ -43,12 +46,11 @@ long long int strtoll( const char * s, char ** endptr, int base ) #include -int main() +int main( void ) { char * endptr; /* this, to base 36, overflows even a 256 bit integer */ char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - BEGIN_TESTS; errno = 0; /* basic functionality */ TESTCASE( strtoll( "123", NULL, 10 ) == 123 ); diff --git a/functions/stdlib/strtoul.c b/functions/stdlib/strtoul.c index 98f5446..d283efb 100644 --- a/functions/stdlib/strtoul.c +++ b/functions/stdlib/strtoul.c @@ -13,12 +13,15 @@ #ifndef REGTEST +#include + unsigned long int strtoul( const char * s, char ** endptr, int base ) { unsigned long int rc; char sign = '+'; const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); - rc = _PDCLIB_strtox_main( &p, base, ULONG_MAX, ULONG_MAX / base, ULONG_MAX % base, &sign ); + if ( base < 2 || base > 36 ) return 0; + rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)ULONG_MAX, (uintmax_t)( ULONG_MAX / base ), (uintmax_t)( ULONG_MAX % base ), &sign ); if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; return ( sign == '+' ) ? rc : -rc; } @@ -29,12 +32,11 @@ unsigned long int strtoul( const char * s, char ** endptr, int base ) #include <_PDCLIB_test.h> #include -int main() +int main( void ) { char * endptr; /* this, to base 36, overflows even a 256 bit integer */ char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - BEGIN_TESTS; errno = 0; /* basic functionality */ TESTCASE( strtoul( "123", NULL, 10 ) == 123 ); diff --git a/functions/stdlib/strtoull.c b/functions/stdlib/strtoull.c index a996c76..929a96c 100644 --- a/functions/stdlib/strtoull.c +++ b/functions/stdlib/strtoull.c @@ -13,12 +13,15 @@ #ifndef REGTEST +#include + unsigned long long int strtoull( const char * s, char ** endptr, int base ) { unsigned long long int rc; char sign = '+'; const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); - rc = _PDCLIB_strtox_main( &p, base, ULLONG_MAX, ULLONG_MAX / base, ULLONG_MAX % base, &sign ); + if ( base < 2 || base > 36 ) return 0; + rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)ULLONG_MAX, (uintmax_t)( ULLONG_MAX / base ), (uintmax_t)( ULLONG_MAX % base ), &sign ); if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; return ( sign == '+' ) ? rc : -rc; } @@ -29,12 +32,11 @@ unsigned long long int strtoull( const char * s, char ** endptr, int base ) #include <_PDCLIB_test.h> #include -int main() +int main( void ) { char * endptr; /* this, to base 36, overflows even a 256 bit integer */ char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - BEGIN_TESTS; errno = 0; /* basic functionality */ TESTCASE( strtoull( "123", NULL, 10 ) == 123 ); diff --git a/functions/string/memchr.c b/functions/string/memchr.c index 972e7ff..6402dc2 100644 --- a/functions/string/memchr.c +++ b/functions/string/memchr.c @@ -31,9 +31,8 @@ void * memchr( const void * s, int c, size_t n ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( memchr( abcde, 'c', 5 ) == &abcde[2] ); TESTCASE( memchr( abcde, 'a', 1 ) == &abcde[0] ); TESTCASE( memchr( abcde, 'a', 0 ) == NULL ); diff --git a/functions/string/memcmp.c b/functions/string/memcmp.c index 167355f..2997694 100644 --- a/functions/string/memcmp.c +++ b/functions/string/memcmp.c @@ -33,10 +33,9 @@ int memcmp( const void * s1, const void * s2, size_t n ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char const xxxxx[] = "xxxxx"; - BEGIN_TESTS; TESTCASE( memcmp( abcde, abcdx, 5 ) < 0 ); TESTCASE( memcmp( abcde, abcdx, 4 ) == 0 ); TESTCASE( memcmp( abcde, xxxxx, 0 ) == 0 ); diff --git a/functions/string/memcpy.c b/functions/string/memcpy.c index 5893e4d..636b21b 100644 --- a/functions/string/memcpy.c +++ b/functions/string/memcpy.c @@ -28,10 +28,9 @@ void * memcpy( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, siz #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xxxxxxxxxxx"; - BEGIN_TESTS; TESTCASE( memcpy( s, abcde, 6 ) == s ); TESTCASE( s[4] == 'e' ); TESTCASE( s[5] == '\0' ); diff --git a/functions/string/memmove.c b/functions/string/memmove.c index 7a01996..3bb8895 100644 --- a/functions/string/memmove.c +++ b/functions/string/memmove.c @@ -40,10 +40,9 @@ void * memmove( void * s1, const void * s2, size_t n ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xxxxabcde"; - BEGIN_TESTS; TESTCASE( memmove( s, s + 4, 5 ) == s ); TESTCASE( s[0] == 'a' ); TESTCASE( s[4] == 'e' ); diff --git a/functions/string/memset.c b/functions/string/memset.c index 4abb466..9c9760f 100644 --- a/functions/string/memset.c +++ b/functions/string/memset.c @@ -27,10 +27,9 @@ void * memset( void * s, int c, size_t n ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xxxxxxxxx"; - BEGIN_TESTS; TESTCASE( memset( s, 'o', 10 ) == s ); TESTCASE( s[9] == 'o' ); TESTCASE( memset( s, '_', 0 ) == s ); diff --git a/functions/string/strcat.c b/functions/string/strcat.c index e76b7db..7d1f662 100644 --- a/functions/string/strcat.c +++ b/functions/string/strcat.c @@ -28,10 +28,9 @@ char * strcat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xx\0xxxxxx"; - BEGIN_TESTS; TESTCASE( strcat( s, abcde ) == s ); TESTCASE( s[2] == 'a' ); TESTCASE( s[6] == 'e' ); diff --git a/functions/string/strchr.c b/functions/string/strchr.c index 15155a4..19a29a8 100644 --- a/functions/string/strchr.c +++ b/functions/string/strchr.c @@ -29,10 +29,9 @@ char * strchr( const char * s, int c ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char abccd[] = "abccd"; - BEGIN_TESTS; TESTCASE( strchr( abccd, 'x' ) == NULL ); TESTCASE( strchr( abccd, 'a' ) == &abccd[0] ); TESTCASE( strchr( abccd, 'd' ) == &abccd[4] ); diff --git a/functions/string/strcmp.c b/functions/string/strcmp.c index 6519b01..8c51e93 100644 --- a/functions/string/strcmp.c +++ b/functions/string/strcmp.c @@ -27,11 +27,10 @@ int strcmp( const char * s1, const char * s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char cmpabcde[] = "abcde"; char empty[] = ""; - BEGIN_TESTS; TESTCASE( strcmp( abcde, cmpabcde ) == 0 ); TESTCASE( strcmp( abcde, abcdx ) < 0 ); TESTCASE( strcmp( abcdx, abcde ) > 0 ); diff --git a/functions/string/strcoll.c b/functions/string/strcoll.c index 4b7af32..c5ac543 100644 --- a/functions/string/strcoll.c +++ b/functions/string/strcoll.c @@ -23,11 +23,10 @@ int strcoll( const char * s1, const char * s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char cmpabcde[] = "abcde"; char empty[] = ""; - BEGIN_TESTS; TESTCASE( strcmp( abcde, cmpabcde ) == 0 ); TESTCASE( strcmp( abcde, abcdx ) < 0 ); TESTCASE( strcmp( abcdx, abcde ) > 0 ); diff --git a/functions/string/strcpy.c b/functions/string/strcpy.c index c0ca9f0..8276dd7 100644 --- a/functions/string/strcpy.c +++ b/functions/string/strcpy.c @@ -24,10 +24,9 @@ char * strcpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xxxxx"; - BEGIN_TESTS; TESTCASE( strcpy( s, "" ) == s ); TESTCASE( s[0] == '\0' ); TESTCASE( s[1] == 'x' ); diff --git a/functions/string/strcspn.c b/functions/string/strcspn.c index 68dd8b4..2709e92 100644 --- a/functions/string/strcspn.c +++ b/functions/string/strcspn.c @@ -36,9 +36,8 @@ size_t strcspn( const char * s1, const char * s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( strcspn( abcde, "x" ) == 5 ); TESTCASE( strcspn( abcde, "xyz" ) == 5 ); TESTCASE( strcspn( abcde, "zyx" ) == 5 ); diff --git a/functions/string/strlen.c b/functions/string/strlen.c index 17ab3cf..14686bb 100644 --- a/functions/string/strlen.c +++ b/functions/string/strlen.c @@ -27,9 +27,8 @@ size_t strlen( const char * s ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( strlen( abcde ) == 5 ); TESTCASE( strlen( "" ) == 0 ); return TEST_RESULTS; diff --git a/functions/string/strncat.c b/functions/string/strncat.c index f05a9ec..eb059b2 100644 --- a/functions/string/strncat.c +++ b/functions/string/strncat.c @@ -35,10 +35,9 @@ char * strncat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, si #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xx\0xxxxxx"; - BEGIN_TESTS; TESTCASE( strncat( s, abcde, 10 ) == s ); TESTCASE( s[2] == 'a' ); TESTCASE( s[6] == 'e' ); diff --git a/functions/string/strncmp.c b/functions/string/strncmp.c index 286d41e..0ba2bee 100644 --- a/functions/string/strncmp.c +++ b/functions/string/strncmp.c @@ -35,12 +35,11 @@ int strncmp( const char * s1, const char * s2, size_t n ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char cmpabcde[] = "abcde"; char empty[] = ""; char x[] = "x"; - BEGIN_TESTS; TESTCASE( strncmp( abcde, cmpabcde, 5 ) == 0 ); TESTCASE( strncmp( abcde, abcdx, 5 ) < 0 ); TESTCASE( strncmp( abcdx, abcde, 5 ) > 0 ); diff --git a/functions/string/strncpy.c b/functions/string/strncpy.c index e1f34a7..a5671b6 100644 --- a/functions/string/strncpy.c +++ b/functions/string/strncpy.c @@ -34,10 +34,9 @@ char * strncpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, si #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xxxxxxx"; - BEGIN_TESTS; TESTCASE( strncpy( s, "", 1 ) == s ); TESTCASE( s[0] == '\0' ); TESTCASE( s[1] == 'x' ); diff --git a/functions/string/strpbrk.c b/functions/string/strpbrk.c index 2bec285..a6dffeb 100644 --- a/functions/string/strpbrk.c +++ b/functions/string/strpbrk.c @@ -36,9 +36,8 @@ char * strpbrk( const char * s1, const char * s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( strpbrk( abcde, "x" ) == NULL ); TESTCASE( strpbrk( abcde, "xyz" ) == NULL ); TESTCASE( strpbrk( abcdx, "x" ) == &abcdx[4] ); diff --git a/functions/string/strrchr.c b/functions/string/strrchr.c index 69321b2..89c4ebf 100644 --- a/functions/string/strrchr.c +++ b/functions/string/strrchr.c @@ -31,10 +31,9 @@ char * strrchr( const char * s, int c ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char abccd[] = "abccd"; - BEGIN_TESTS; TESTCASE( strrchr( abcde, '\0' ) == &abcde[5] ); TESTCASE( strrchr( abcde, 'e' ) == &abcde[4] ); TESTCASE( strrchr( abcde, 'a' ) == &abcde[0] ); diff --git a/functions/string/strspn.c b/functions/string/strspn.c index ed9b8b1..78ee1aa 100644 --- a/functions/string/strspn.c +++ b/functions/string/strspn.c @@ -41,9 +41,8 @@ size_t strspn( const char * s1, const char * s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( strspn( abcde, "abc" ) == 3 ); TESTCASE( strspn( abcde, "b" ) == 0 ); TESTCASE( strspn( abcde, abcde ) == 5 ); diff --git a/functions/string/strstr.c b/functions/string/strstr.c index 0856030..793d38a 100644 --- a/functions/string/strstr.c +++ b/functions/string/strstr.c @@ -39,10 +39,9 @@ char * strstr( const char * s1, const char * s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "abcabcabcdabcde"; - BEGIN_TESTS; TESTCASE( strstr( s, "x" ) == NULL ); TESTCASE( strstr( s, "xyz" ) == NULL ); TESTCASE( strstr( s, "a" ) == &s[0] ); diff --git a/functions/string/strtok.c b/functions/string/strtok.c index a7fc461..c4b72f9 100644 --- a/functions/string/strtok.c +++ b/functions/string/strtok.c @@ -78,10 +78,9 @@ char * strtok( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "_a_bc__d_"; - BEGIN_TESTS; TESTCASE( strtok( s, "_" ) == &s[1] ); TESTCASE( s[1] == 'a' ); TESTCASE( s[2] == '\0' ); diff --git a/functions/string/strxfrm.c b/functions/string/strxfrm.c index c80839e..57a106f 100644 --- a/functions/string/strxfrm.c +++ b/functions/string/strxfrm.c @@ -31,10 +31,9 @@ size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, si #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { char s[] = "xxxxxxxxxxx"; - BEGIN_TESTS; TESTCASE( strxfrm( NULL, "123456789012", 0 ) == 12 ); TESTCASE( strxfrm( s, "123456789012", 12 ) == 12 ); /* diff --git a/includes/stddef.h b/includes/stddef.h index f64a9a1..e335dd0 100644 --- a/includes/stddef.h +++ b/includes/stddef.h @@ -30,7 +30,10 @@ typedef _PDCLIB_size_t size_t; 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 ) diff --git a/includes/stdio.h b/includes/stdio.h index df9bfe4..274966e 100644 --- a/includes/stdio.h +++ b/includes/stdio.h @@ -8,23 +8,151 @@ Permission is granted to use, modify, and / or redistribute at will. */ -/* TODO: This is a dummy header to avoid errors when mixing PDCLIB */ -/* with glibc . */ - #ifndef _PDCLIB_STDIO_H #define _PDCLIB_STDIO_H _PDCLIB_STDIO_H -#ifndef _PDCLIB_AUX_H -#define _PDCLIB_AUX_H _PDCLIB_AUX_H -#include <_PDCLIB_aux.h> +#ifndef _PDCLIB_INT_H +#define _PDCLIB_INT_H _PDCLIB_INT_H +#include <_PDCLIB_int.h> +#endif + +#ifndef _PDCLIB_SIZE_T_DEFINED +#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED +typedef _PDCLIB_size_t size_t; #endif -typedef void * FILE; +#ifndef _PDCLIB_NULL_DEFINED +#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED +#define NULL _PDCLIB_NULL +#endif + +/* See setvbuf(), third argument */ +/* Fully buffered - transmit block-wise */ +#define _IOFBF 1 +/* Line buffered - transmit line-wise */ +#define _IOLBF 2 +/* Not buffered - transmit immediately */ +#define _IONBF 4 + +/* See setbuf(). Minimum 256. */ +#define BUFSIZ 1024 + +/* Internal-only flags for representing mode */ +#define _PDCLIB_FREAD 1 +#define _PDCLIB_FWRITE 2 +#define _PDCLIB_FAPPEND 4 +#define _PDCLIB_FRW 8 +#define _PDCLIB_FBIN 16 + +typedef struct _PDCLIB_file_t FILE; +typedef _PDCLIB_fpos_t fpos_t; + +/* Must be integer and of negative value */ +#define EOF -1 + +/* Maximum number of files this implementation can open simultaneously. Minimum 8. */ +#define FOPEN_MAX 1 + +/* Maximum file name length (plus terminating \0) this implementation does + guarantee can be opened. If there is no limit on the length of filenames, + this should be a recommended size for filename buffers. +*/ +#define FILENAME_MAX 1024 -extern void * stderr; +/* Buffer size for tmpnam() */ +#define L_tmpnam 1024 +/* Number of distinct file names that can be generated by tmpnam(). */ +#define TMP_MAX 50 + +/* See fseek(), third argument */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_SET 4 + +typedef struct +{ + _PDCLIB_fd_t handle; /* OS-specific file descriptor */ + _PDCLIB_fpos_t position; /* file position indicator */ + void * buffer; /* file buffer */ + size_t bufsize; /* size of buffer */ + int status; /* misc. status bits */ + /*mbstate_t mbstate;*//* multibyte parse state */ /* TODO: Unmask. */ + FILE * next; /* provisions for linked list handling */ +} FILE; + +/* Text-mode I/O is at liberty to skip non-printing characters and trailing spaces. + Binary I/O is at liberty to add trailing zero bytes. + First operation decides "orientation" of the stream (wide / byte). + freopen() removes orientation; see also fwide(). + Binary wide-oriented streams have the file-positioning restrictions ascribed to both text and binary streams. + For wide-oriented streams, after a successful call to a file-positioning function that leaves the file position indicator prior to the end-of-file, a wide character output function can overwrite a partial multibyte character; any file contents beyond the byte(s) written are henceforth indeterminate. + Whether a file of zero length (unwritten-to) actually exists is implementation-defined. + Wide text input from file: fgetwc() / mbrtowc() + Wide text output to file: wcrtomb() / fputwc() + Multibyte encoding in file may contain embedded null bytes + Multibyte encoding in file need not begin / end in initial shift state. + Conversion may trigger EILSEQ. +*/ + +/* Operations on files */ +int remove( const char * filename ); +int rename( const char * old, const char * new ); +FILE * tmpfile( void ); /* TODO: Implement. */ +char * tmpnam( char * s ); /* TODO: Implement. */ + +/* File access functions */ +int fclose( FILE * stream ); +int fflush( FILE * stream ); +FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode ); +FILE * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, FILE * _PDCLIB_restrict stream ); +void setbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf ); +int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size ); + +/* Formatted input/output functions */ +int fprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ); +int fscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ); int printf( const char * _PDCLIB_restrict format, ... ); +int scanf( const char * _PDCLIB_restrict format, ... ); +int snprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, ... ); +int sprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ); +int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ); +int vfprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); +int vfscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); +int vprintf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); +int vscanf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); +int vsnprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); +int vsprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); +int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); + +/* Character input/output functions */ +int fgetc( FILE * stream ); +char * fgets( char * _PDCLIB_restrict s, int n, FILE * _PDCLIB_restrict stream ); +int fputc( int c, FILE * stream ); int fputs( const char * _PDCLIB_restrict s, FILE * _PDCLIB_restrict stream ); -int puts( const char * _PDCLIB_restrict s ); +int getc( FILE * stream ); +int getchar( void ); +char * gets( char * s ); +int putc( int c, FILE * stream ); +int putchar( int c ); +int puts( const char * s ); +int ungetc( int c, FILE * stream ); + +/* Direct input/output functions */ +size_t fread( void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream ); +size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream ); + +/* File positioning functions */ +int fgetpos( FILE * _PDCLIB_restrict stream, fpos_t * _PDCLIB_restrict pos ); +int fseek( FILE * stream, long int offset, int whence ); +int fsetpos( FILE * stream, const fpos_t * pos ); +long int ftell( FILE * stream ); +void rewind( FILE * stream ); + +/* Error-handling functions */ +void clearerr( FILE * stream ); +int feof( FILE * stream ); +int ferror( FILE * stream ); +void perror( const char * s ); #endif diff --git a/includes/stdlib.h b/includes/stdlib.h index 4d6fc53..1bf1fc2 100644 --- a/includes/stdlib.h +++ b/includes/stdlib.h @@ -21,9 +21,10 @@ typedef _PDCLIB_size_t size_t; #endif -#define NULL _PDCLIB_NULL -#define EXIT_SUCCESS _PDCLIB_SUCCESS -#define EXIT_FAILURE _PDCLIB_FAILURE +#ifndef _PDCLIB_NULL_DEFINED +#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED +#define NULL _PDCLIB_NULL +#endif /* Numeric conversion functions */ @@ -81,7 +82,7 @@ extern unsigned long int _PDCLIB_seed; (PDCLib uses the implementation suggested by the standard document, which is next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;) */ -int rand(); +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. @@ -90,42 +91,147 @@ 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 ); -void * realloc( void * ptr, 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 -void abort(); +/* 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(), _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 ); -/* Multibyte / wide character conversion functions */ +/* TODO: Multibyte / wide character conversion functions */ /* TODO: Macro MB_CUR_MAX */ diff --git a/includes/string.h b/includes/string.h index c8ac5c6..ad2e668 100644 --- a/includes/string.h +++ b/includes/string.h @@ -1,190 +1,193 @@ -/* $Id$ */ - -/* Release $Name$ */ - -/* String handling - - 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 - -#ifndef _PDCLIB_INT_H -#define _PDCLIB_INT_H _PDCLIB_INT_H -#include <_PDCLIB_int.h> -#endif - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#define NULL _PDCLIB_NULL - -/* 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. - TODO: strerror() not yet implemented. -char * strerror( int errnum ); -*/ - -/* Returns the length of the string s (excluding terminating '\0'). -*/ -size_t strlen( const char * s ); - -#endif +/* $Id$ */ + +/* Release $Name$ */ + +/* String handling + + 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 + +#ifndef _PDCLIB_INT_H +#define _PDCLIB_INT_H _PDCLIB_INT_H +#include <_PDCLIB_int.h> +#endif + +#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. + TODO: strerror() not yet implemented. +char * strerror( int errnum ); +*/ + +/* Returns the length of the string s (excluding terminating '\0'). +*/ +size_t strlen( const char * s ); + +#endif diff --git a/internals/_PDCLIB_glue.h b/internals/_PDCLIB_glue.h new file mode 100644 index 0000000..f19e250 --- /dev/null +++ b/internals/_PDCLIB_glue.h @@ -0,0 +1,62 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* 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_INT_H +#define _PDCLIB_INT_H _PDCLIB_INT_H +#include <_PDCLIB_int.h> +#endif + +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +/* 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 ); + +/* A system call that opens a file identified by name in a given mode, and + returns a file descriptor uniquely identifying that file. +*/ +_PDCLIB_fd_t _PDCLIB_open( char const * const filename, int mode ); + +/* A system call that writes n characters to a file identified by given file + descriptor. Return the number of characters written. +*/ +_PDCLIB_size_t _PDCLIB_write( _PDCLIB_fd_t fd, char const * buffer, _PDCLIB_size_t n ); + +/* A system call that reads n characters into a buffer, from a file identified + by given file descriptor. Return the number of characters read. +*/ +_PDCLIB_size_t _PDCLIB_read( _PDCLIB_fd_t fd, char * buffer, _PDCLIB_size_t n ); + +/* A system call that closes a file identified by given file descriptor. */ +void _PDCLIB_close( _PDCLIB_fd_t fd ); + +/* A system call that removes a file identified by name. Return zero on success, + non-zero otherwise. +*/ +int _PDCLIB_remove( const char * filename ); + +/* 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. +*/ +int _PDCLIB_rename( const char * old, const char * new ); diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index 84781d2..42f5e8f 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -261,7 +261,7 @@ _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, int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, _PDCLIB_uintmax_t limdigit, char * sign ); +_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, _PDCLIB_uintmax_t limdigit, char * sign ); /* Digits array used by various integer conversion functions in */ extern char _PDCLIB_digits[]; @@ -289,3 +289,15 @@ struct _PDCLIB_memnode_t _PDCLIB_size_t size; struct _PDCLIB_memnode_t * next; }; + +#if 0 + +/* fpos_t, an object type (not an array!) capable of storing any position + information of a file. +*/ +typedef unsigned long long int _PDCLIB_fpos_t; + +/* file descriptor - a type used by the OS to identify a stream */ +typedef int _PDCLIB_fd_t; + +#endif diff --git a/internals/_PDCLIB_test.h b/internals/_PDCLIB_test.h index 66ffb06..90c47bd 100644 --- a/internals/_PDCLIB_test.h +++ b/internals/_PDCLIB_test.h @@ -1,25 +1,26 @@ -/* $Id$ */ - -/* Release $Name$ */ - -/* PDCLib testing suite <_PDCLIB_test.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -/* -------------------------------------------------------------------------- */ -/* Helper macros for test drivers */ -/* -------------------------------------------------------------------------- */ - -#include - -char const abcde[] = "abcde"; -char const abcdx[] = "abcdx"; - -int NO_TESTDRIVER = 0; - -#define BEGIN_TESTS unsigned int rc = 0 -#define TESTCASE( x ) if ( x ) {} \ - else { rc += 1; printf( "Testcase failed: " __FILE__ ", line %d - " #x "\n", __LINE__ ); } -#define TEST_RESULTS rc +/* $Id$ */ + +/* Release $Name$ */ + +/* PDCLib testing suite <_PDCLIB_test.h> + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* -------------------------------------------------------------------------- */ +/* Helper macros for test drivers */ +/* -------------------------------------------------------------------------- */ + +#include + +char const abcde[] = "abcde"; +char const abcdx[] = "abcdx"; + +int NO_TESTDRIVER = 0; + +//#define BEGIN_TESTS unsigned int rc = 0 +static unsigned int rc = 0; +#define TESTCASE( x ) if ( x ) {} \ + else { rc += 1; printf( "Testcase failed: " __FILE__ ", line %d - " #x "\n", __LINE__ ); } +#define TEST_RESULTS rc diff --git a/platform/example/functions/_PDCLIB/_Exit.c b/platform/example/functions/_PDCLIB/_Exit.c new file mode 100644 index 0000000..e096e70 --- /dev/null +++ b/platform/example/functions/_PDCLIB/_Exit.c @@ -0,0 +1,37 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* _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> +#include + +void _PDCLIB_Exit( int status ) +{ + _exit( status ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example/functions/_PDCLIB/allocpages.c b/platform/example/functions/_PDCLIB/allocpages.c index 48b8dc9..55dd9d8 100644 --- a/platform/example/functions/_PDCLIB/allocpages.c +++ b/platform/example/functions/_PDCLIB/allocpages.c @@ -13,12 +13,14 @@ */ #include +#include -#include +int brk( void * ); +void * sbrk( intptr_t ); -#ifndef _PDCLIB_CONFIG_H -#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H -#include <_PDCLIB_config.h> +#ifndef _PDCLIB_GLUE_H +#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H +#include <_PDCLIB_glue.h> #endif static void * membreak = NULL; @@ -39,7 +41,7 @@ void * _PDCLIB_allocpages( int const n ) /* error */ return NULL; } - membreak += unaligned; + membreak = (char *)membreak + unaligned; } } /* increasing or decreasing heap - standard operation */ @@ -61,16 +63,13 @@ void * _PDCLIB_allocpages( int const n ) #ifdef TEST #include <_PDCLIB_test.h> -int puts( const char * ); - -int main() +int main( void ) { - BEGIN_TESTS; #ifndef REGTEST { - void * startbreak = sbrk( 0 ); + char * startbreak = sbrk( 0 ); TESTCASE( _PDCLIB_allocpages( 0 ) ); - TESTCASE( ( sbrk( 0 ) - startbreak ) <= _PDCLIB_PAGESIZE ); + TESTCASE( ( (char *)sbrk( 0 ) - startbreak ) <= _PDCLIB_PAGESIZE ); startbreak = sbrk( 0 ); TESTCASE( _PDCLIB_allocpages( 1 ) ); TESTCASE( sbrk( 0 ) == startbreak + ( 1 * _PDCLIB_PAGESIZE ) ); diff --git a/platform/example/functions/_PDCLIB/open.c b/platform/example/functions/_PDCLIB/open.c new file mode 100644 index 0000000..d3aafb2 --- /dev/null +++ b/platform/example/functions/_PDCLIB/open.c @@ -0,0 +1,47 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* _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 + +_PDCLIB_fd_t _PDCLIB_open( char const * const filename, int mode ) +{ + int osmode = 0; + if ( mode & _PDCLIB_FRW ) osmode |= O_RDWR; + if ( mode & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND ) ) osmode |= O_CREAT; + if ( mode & _PDCLIB_FWRITE ) osmode |= O_TRUNC; + if ( mode & _PDCLIB_FAPPEND ) osmode |= O_APPEND; + if ( ( mode & _PDCLIB_FREAD ) && ! ( mode & _PDCLIB_FRW ) ) osmode |= O_RDONLY; + return open( filename, osmode ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example/functions/_PDCLIB/remove.c b/platform/example/functions/_PDCLIB/remove.c new file mode 100644 index 0000000..403fcda --- /dev/null +++ b/platform/example/functions/_PDCLIB/remove.c @@ -0,0 +1,46 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* _PDCLIB_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 _PDCLIB_remove() (declared in + _PDCLIB_glue.h), fit for use in POSIX kernels. + NOTE: Linux is *not* POSIX-compliant in this, as it sets EISDIR instead of + EPERM if you try to unlink a directory. Check the manpage for unlink(2). +*/ + +#ifndef REGTEST +#include <_PDCLIB_glue.h> +#include +#include + +int _PDCLIB_remove( const char * filename ) +{ + int prev_errno = errno; + int rc; + errno = 0; + if ( ( ( rc = unlink( filename ) ) != 0 ) && ( errno == EPERM ) ) + { + rc = rmdir( filename ); + } + errno = prev_errno; + return rc; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example/functions/_PDCLIB/rename.c b/platform/example/functions/_PDCLIB/rename.c new file mode 100644 index 0000000..9996e7c --- /dev/null +++ b/platform/example/functions/_PDCLIB/rename.c @@ -0,0 +1,43 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* _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. +*/ + +#ifndef REGTEST +#include +#include <_PDCLIB_glue.h> + +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 ) + { + return unlink( old ); + } + else + { + return -1; + } +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/example/functions/stdlib/getenv.c b/platform/example/functions/stdlib/getenv.c index aa2817a..3bad450 100644 --- a/platform/example/functions/stdlib/getenv.c +++ b/platform/example/functions/stdlib/getenv.c @@ -38,9 +38,8 @@ char * getenv( const char * name ) #ifdef TEST #include <_PDCLIB_test.h> -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( strcmp( getenv( "SHELL" ), "/bin/sh" ) == 0 ); return TEST_RESULTS; } diff --git a/platform/example/functions/stdlib/system.c b/platform/example/functions/stdlib/system.c index 41c3671..306226d 100644 --- a/platform/example/functions/stdlib/system.c +++ b/platform/example/functions/stdlib/system.c @@ -8,6 +8,8 @@ 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. */ @@ -16,13 +18,13 @@ int system( const char * string ) { - char * const argv[] = { "sh", "-c", (char * const)string, NULL }; + char const * const argv[] = { "sh", "-c", (char const * const)string, NULL }; if ( string != NULL ) { int pid = fork(); if ( pid == 0 ) { - execve( "/bin/sh", argv, NULL ); + execve( "/bin/sh", (char * * const)argv, NULL ); } else if ( pid > 0 ) { @@ -34,13 +36,11 @@ int system( const char * string ) #ifdef TEST #include <_PDCLIB_test.h> -#include <_PDCLIB_config.h> #define SHELLCOMMAND "echo 'SUCCESS testing system()'" -int main() +int main( void ) { - BEGIN_TESTS; TESTCASE( system( SHELLCOMMAND ) ); return TEST_RESULTS; } diff --git a/platform/example/internals/_PDCLIB_config.h b/platform/example/internals/_PDCLIB_config.h index 41fe02c..150161f 100644 --- a/platform/example/internals/_PDCLIB_config.h +++ b/platform/example/internals/_PDCLIB_config.h @@ -28,6 +28,12 @@ /* 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 */ /* -------------------------------------------------------------------------- */ @@ -201,15 +207,12 @@ typedef char * _PDCLIB_va_list; #define _PDCLIB_va_start( ap, parmN ) ( (ap) = (char *) &parmN + ( _PDCLIB_va_round(parmN) ), (void)0 ) /* -------------------------------------------------------------------------- */ -/* OS "glue" */ -/* This is where PDCLib interfaces with the operating system. The examples */ -/* below are POSIX calls; provide your OS' equivalents. */ +/* 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. */ /* -------------------------------------------------------------------------- */ -/* A system call that terminates the calling process */ -void _exit( int status ) __attribute__(( noreturn )); -#define _PDCLIB_Exit( x ) _exit( x ) - /* Memory management */ /* Set this to the page size of your OS. If your OS does not support paging, set @@ -223,9 +226,24 @@ void _exit( int status ) __attribute__(( noreturn )); */ #define _PDCLIB_MINALLOC 8 -/* Request another x pages (of size _PDCLIB_PAGESIZE) of memory from the kernel, - or release them back to the kernel if n is negative. - Return a (void *) pointing to the former end-of-heap if successful, NULL - otherwise. -*/ -void * _PDCLIB_allocpages( int n ); +/* I/O */ + +/* The unique file descriptor returned by _PDCLIB_open(). */ +typedef int _PDCLIB_fd_t; + +/* A type in which to store file offsets. See fgetpos() / fsetpos(). */ +typedef struct +{ + int position; + int parse_state; +} _PDCLIB_fpos_t; + +/* The mode flags used in calls to _PDCLIB_open(). */ +enum _PDCLIB_iomode_e +{ + _PDCLIB_io_read = 1, + _PDCLIB_io_write = 2, + _PDCLIB_io_append = 4, + _PDCLIB_io_create = 8, + _PDCLIB_io_truncate = 16, +}; -- 2.40.0