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
@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)
-@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 $@
v0.5 - unreleased
Implementations for parts of <stdio.h>. 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.
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
+
+#ifndef REGTEST
#ifndef _PDCLIB_AUX_H
#define _PDCLIB_AUX_H _PDCLIB_AUX_H
}
#endif
+#endif
#ifdef TEST
#include <_PDCLIB_test.h>
#include <signal.h>
-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 <assert.h>
-int disabled_test()
+static int disabled_test( void )
{
int i = 0;
assert( i == 0 ); /* NDEBUG set, condition met */
#undef NDEBUG
#include <assert.h>
-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;
#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 */
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
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* no tests for raw data */
return TEST_RESULTS;
}
Permission is granted to use, modify, and / or redistribute at will.
*/
-#ifdef TEST
-
-#include <_PDCLIB_test.h>
#include <stdarg.h>
#include <limits.h>
#include <float.h>
-unsigned int rc = 0;
+#include <_PDCLIB_test.h>
typedef int (*intfunc_t)( void );
}
}
-int dummy()
+static int dummy( void )
{
return INT_MAX;
}
-int main()
+int main( void )
{
int x = INT_MAX;
long double d = LDBL_MAX;
test( TAG_INTPTR, &x, TAG_LDBLPTR, &d, TAG_FUNCPTR, dummy, TAG_END );
return TEST_RESULTS;
}
-
-#endif
#include <ctype.h>
#include <errno.h>
#include <string.h>
+#include <stdint.h>
-_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;
#include <_PDCLIB_test.h>
#include <errno.h>
-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 == '+' );
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;
}
{
*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 );
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;
}
--- /dev/null
+/* $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 <stdio.h>
+#include <stdlib.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdlib.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#include <stdarg.h>
+
+#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
Permission is granted to use, modify, and / or redistribute at will.
*/
-#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
-#include <_PDCLIB_config.h>
+#include <stdlib.h>
+#include <_PDCLIB_glue.h>
#ifndef REGTEST
#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;
}
#include <stdio.h>
-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 );
#include <_PDCLIB_test.h>
#include <limits.h>
-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 ) );
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 )
{
}
}
-int main()
+int main( void )
{
- BEGIN_TESTS;
TESTCASE( atexit( &checkhandler ) == 0 );
for ( int i = 0; i < 31; ++i )
{
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* no tests for a simple wrapper */
return TEST_RESULTS;
}
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* no tests for a simple wrapper */
return TEST_RESULTS;
}
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* no tests for a simple wrapper */
return TEST_RESULTS;
}
#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 );
#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' );
#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;
}
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* Unwinding of regstack tested in atexit(). */
return TEST_RESULTS;
}
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* tests covered in malloc test driver */
return TEST_RESULTS;
}
#include <_PDCLIB_test.h>
#include <limits.h>
-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 ) );
#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;
}
#include <_PDCLIB_test.h>
#include <limits.h>
-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;
#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;
}
*/
#include <stdlib.h>
+#include <stdint.h>
#ifndef REGTEST
-#include <stdint.h>
-
-#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 };
}
{
/* 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 );
#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
I am afraid, and thus there is no REGTEST equivalent.
*/
-#include <unistd.h>
+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;
}
#include <string.h>
#include <limits.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 )
{
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 );
#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 );
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* tests covered in malloc test driver */
return TEST_RESULTS;
}
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
/* tested in rand.c */
return TEST_RESULTS;
}
#ifndef REGTEST
+#include <stdint.h>
+
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;
#include <errno.h>
-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 );
#ifndef REGTEST
+#include <stdint.h>
+
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;
#include <errno.h>
-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 );
#ifndef REGTEST
+#include <stdint.h>
+
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;
}
#include <_PDCLIB_test.h>
#include <errno.h>
-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 );
#ifndef REGTEST
+#include <stdint.h>
+
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;
}
#include <_PDCLIB_test.h>
#include <errno.h>
-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 );
#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 );
#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 );
#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' );
#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' );
#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 );
#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' );
#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] );
#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 );
#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 );
#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' );
#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 );
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
TESTCASE( strlen( abcde ) == 5 );
TESTCASE( strlen( "" ) == 0 );
return TEST_RESULTS;
#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' );
#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 );
#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' );
#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] );
#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] );
#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 );
#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] );
#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' );
#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 );
/*
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 )
Permission is granted to use, modify, and / or redistribute at will.
*/
-/* TODO: This is a dummy header to avoid errors when mixing PDCLIB <stdarg.h> */
-/* with glibc <stdio.h>. */
-
#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
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 */
(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.
/* 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 */
-/* $Id$ */
-
-/* Release $Name$ */
-
-/* String handling <string.h>
-
- This file is part of the Public Domain C Library (PDCLib).
- Permission is granted to use, modify, and / or redistribute at will.
-*/
-
-#ifndef _PDCLIB_STRING_H
-#define _PDCLIB_STRING_H _PDCLIB_STRING_H
-
-#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$ */\r
+\r
+/* Release $Name$ */\r
+\r
+/* String handling <string.h>\r
+\r
+ This file is part of the Public Domain C Library (PDCLib).\r
+ Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+#ifndef _PDCLIB_STRING_H\r
+#define _PDCLIB_STRING_H _PDCLIB_STRING_H\r
+\r
+#ifndef _PDCLIB_INT_H\r
+#define _PDCLIB_INT_H _PDCLIB_INT_H\r
+#include <_PDCLIB_int.h>\r
+#endif\r
+\r
+#ifndef _PDCLIB_SIZE_T_DEFINED\r
+#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED\r
+typedef _PDCLIB_size_t size_t;\r
+#endif\r
+\r
+#ifndef _PDCLIB_NULL_DEFINED\r
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED\r
+#define NULL _PDCLIB_NULL\r
+#endif\r
+\r
+/* String function conventions */\r
+\r
+/*\r
+ In any of the following functions taking a size_t n to specify the length of\r
+ an array or size of a memory region, n may be 0, but the pointer arguments to\r
+ the call shall still be valid unless otherwise stated.\r
+*/\r
+\r
+/* Copying functions */\r
+\r
+/* Copy a number of n characters from the memory area pointed to by s2 to the\r
+ area pointed to by s1. If the two areas overlap, behaviour is undefined.\r
+ Returns the value of s1.\r
+*/\r
+void * memcpy( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );\r
+\r
+/* Copy a number of n characters from the memory area pointed to by s2 to the\r
+ area pointed to by s1. The two areas may overlap.\r
+ Returns the value of s1.\r
+*/\r
+void * memmove( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );\r
+\r
+/* Copy the character array s2 (including terminating '\0' byte) into the\r
+ character array s1.\r
+ Returns the value of s1.\r
+*/\r
+char * strcpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );\r
+\r
+/* Copy a maximum of n characters from the character array s2 into the character\r
+ array s1. If s2 is shorter than n characters, '\0' bytes will be appended to\r
+ the copy in s1 until n characters have been written. If s2 is longer than n\r
+ characters, NO terminating '\0' will be written to s1. If the arrays overlap,\r
+ behaviour is undefined.\r
+ Returns the value of s1.\r
+*/\r
+char * strncpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );\r
+\r
+/* Concatenation functions */\r
+\r
+/* Append the contents of the character array s2 (including terminating '\0') to\r
+ the character array s1 (first character of s2 overwriting the '\0' of s1). If\r
+ the arrays overlap, behaviour is undefined.\r
+ Returns the value of s1.\r
+*/\r
+char * strcat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );\r
+\r
+/* Append a maximum of n characters from the character array s1 to the character\r
+ array s1 (first character of s2 overwriting the '\0' of s1). A terminating\r
+ '\0' is ALWAYS appended, even if the full n characters have already been\r
+ written. If the arrays overlap, behaviour is undefined.\r
+ Returns the value of s1.\r
+*/\r
+char * strncat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );\r
+\r
+/* Comparison functions */\r
+\r
+/* Compare the first n characters of the memory areas pointed to by s1 and s2.\r
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if\r
+ s1 > s2.\r
+*/\r
+int memcmp( const void * s1, const void * s2, size_t n );\r
+\r
+/* Compare the character arrays s1 and s2.\r
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if\r
+ s1 > s2.\r
+*/\r
+int strcmp( const char * s1, const char * s2 );\r
+\r
+/* Compare the character arrays s1 and s2, interpreted as specified by the\r
+ LC_COLLATE category of the current locale.\r
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if\r
+ s1 > s2.\r
+ TODO: Currently a dummy wrapper for strcmp() as PDCLib does not yet support\r
+ locales.\r
+*/\r
+int strcoll( const char * s1, const char * s2 );\r
+\r
+/* Compare no more than the first n characters of the character arrays s1 and\r
+ s2.\r
+ Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if\r
+ s1 > s2.\r
+*/\r
+int strncmp( const char * s1, const char * s2, size_t n );\r
+\r
+/* Transform the character array s2 as appropriate for the LC_COLLATE setting of\r
+ the current locale. If length of resulting string is less than n, store it in\r
+ the character array pointed to by s1. Return the length of the resulting\r
+ string.\r
+*/\r
+size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );\r
+\r
+/* Search functions */\r
+\r
+/* Search the first n characters in the memory area pointed to by s for the\r
+ character c (interpreted as unsigned char).\r
+ Returns a pointer to the first instance found, or NULL.\r
+*/\r
+void * memchr( const void * s, int c, size_t n );\r
+\r
+/* Search the character array s (including terminating '\0') for the character c\r
+ (interpreted as char).\r
+ Returns a pointer to the first instance found, or NULL.\r
+*/\r
+char * strchr( const char * s, int c );\r
+\r
+/* Determine the length of the initial substring of character array s1 which\r
+ consists only of characters not from the character array s2.\r
+ Returns the length of that substring.\r
+*/\r
+size_t strcspn( const char * s1, const char * s2 );\r
+\r
+/* Search the character array s1 for any character from the character array s2.\r
+ Returns a pointer to the first occurrence, or NULL.\r
+*/\r
+char * strpbrk( const char * s1, const char * s2 );\r
+\r
+/* Search the character array s (including terminating '\0') for the character c\r
+ (interpreted as char).\r
+ Returns a pointer to the last instance found, or NULL.\r
+*/\r
+char * strrchr( const char * s, int c );\r
+\r
+/* Determine the length of the initial substring of character array s1 which\r
+ consists only of characters from the character array s2.\r
+ Returns the length of that substring.\r
+*/\r
+size_t strspn( const char * s1, const char * s2 );\r
+\r
+/* Search the character array s1 for the substring in character array s2.\r
+ Returns a pointer to that sbstring, or NULL. If s2 is of length zero,\r
+ returns s1.\r
+*/\r
+char * strstr( const char * s1, const char * s2 );\r
+\r
+/* In a series of subsequent calls, parse a C string into tokens.\r
+ On the first call to strtok(), the first argument is a pointer to the to-be-\r
+ parsed C string. On subsequent calls, the first argument is NULL unless you\r
+ want to start parsing a new string. s2 holds an array of seperator characters\r
+ which can differ from call to call. Leading seperators are skipped, the first\r
+ trailing seperator overwritten with '\0'.\r
+ Returns a pointer to the next token.\r
+ WARNING: This function uses static storage, and as such is not reentrant.\r
+*/\r
+char * strtok( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );\r
+\r
+/* Miscellaneous functions */\r
+\r
+/* Write the character c (interpreted as unsigned char) to the first n\r
+ characters of the memory area pointed to by s.\r
+ Returns s.\r
+*/\r
+void * memset( void * s, int c, size_t n );\r
+\r
+/* Map an error number to a (locale-specific) error message string. Error\r
+ numbers are typically errno values, but any number is mapped to a message.\r
+ TODO: PDCLib does not yet support locales.\r
+ TODO: strerror() not yet implemented.\r
+char * strerror( int errnum );\r
+*/\r
+\r
+/* Returns the length of the string s (excluding terminating '\0').\r
+*/\r
+size_t strlen( const char * s );\r
+\r
+#endif\r
--- /dev/null
+/* $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 );
/* 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 <stdlib.h> */
extern char _PDCLIB_digits[];
_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
-/* $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 <stdio.h>
-
-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$ */\r
+\r
+/* Release $Name$ */\r
+\r
+/* PDCLib testing suite <_PDCLIB_test.h>\r
+\r
+ This file is part of the Public Domain C Library (PDCLib).\r
+ Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+/* -------------------------------------------------------------------------- */\r
+/* Helper macros for test drivers */\r
+/* -------------------------------------------------------------------------- */\r
+\r
+#include <stdio.h>\r
+\r
+char const abcde[] = "abcde";\r
+char const abcdx[] = "abcdx";\r
+\r
+int NO_TESTDRIVER = 0;\r
+\r
+//#define BEGIN_TESTS unsigned int rc = 0\r
+static unsigned int rc = 0;\r
+#define TESTCASE( x ) if ( x ) {} \\r
+ else { rc += 1; printf( "Testcase failed: " __FILE__ ", line %d - " #x "\n", __LINE__ ); }\r
+#define TEST_RESULTS rc\r
--- /dev/null
+/* $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 <stdlib.h>
+
+#ifndef REGTEST
+#include <_PDCLIB_glue.h>
+#include <unistd.h>
+
+void _PDCLIB_Exit( int status )
+{
+ _exit( status );
+}
+
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+ TESTCASE( NO_TESTDRIVER );
+ return TEST_RESULTS;
+}
+
+#endif
*/
#include <stdint.h>
+#include <stddef.h>
-#include <unistd.h>
+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;
/* error */
return NULL;
}
- membreak += unaligned;
+ membreak = (char *)membreak + unaligned;
}
}
/* increasing or decreasing heap - standard operation */
#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 ) );
--- /dev/null
+/* $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 <stdio.h>
+
+#ifndef REGTEST
+#include <_PDCLIB_glue.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+_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
--- /dev/null
+/* $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 <errno.h>
+#include <unistd.h>
+
+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
--- /dev/null
+/* $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 <unistd.h>
+#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
#ifdef TEST
#include <_PDCLIB_test.h>
-int main()
+int main( void )
{
- BEGIN_TESTS;
TESTCASE( strcmp( getenv( "SHELL" ), "/bin/sh" ) == 0 );
return TEST_RESULTS;
}
Permission is granted to use, modify, and / or redistribute at will.
*/
+#include <stdlib.h>
+
/* This is an example implementation of system() fit for use with POSIX kernels.
*/
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 )
{
#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;
}
/* 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 */
/* -------------------------------------------------------------------------- */
#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
*/
#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,
+};