From: solar Date: Mon, 26 Jun 2006 06:01:23 +0000 (+0000) Subject: Added some functions. X-Git-Tag: v0.5~157 X-Git-Url: https://pd.if.org/git/?p=pdclib;a=commitdiff_plain;h=13ee02fa27a739d9d602f801126eadcfbfeab8a8 Added some functions. --- diff --git a/functions/_PDCLIB/print.c b/functions/_PDCLIB/print.c index fdf3982..ddb6b99 100644 --- a/functions/_PDCLIB/print.c +++ b/functions/_PDCLIB/print.c @@ -40,7 +40,7 @@ n - pointer to maximum number of characters to be delivered in this call s - the buffer into which the character shall be delivered */ -#define DELIVER( x ) do { if ( status->i < status->n ) { if ( status->stream != NULL ) putc( x, status->stream ); else status->s[status->i] = x; } ++(status->i); } while ( 0 ) +#define DELIVER( x ) do { if ( status->i < status->n ) { if ( status->stream != NULL ) { status->stream->buffer[status->stream->bufidx++] = x; if ( ( status->stream->bufidx == status->stream->bufsize ) || ( ( status->stream->status & _IOLBF ) && ( x == '\n' ) ) || ( status->stream->status & _IONBF ) ) fflush( status->stream ); } else status->s[status->i] = x; } ++(status->i); } while ( 0 ) /* This function recursively converts a given integer value to a character stream. The conversion is done under the control of a given status struct @@ -116,6 +116,26 @@ static void int2base( intmax_t value, struct _PDCLIB_status_t * status ) for ( int i = 0; i < status->width - characters; ++i ) { DELIVER( ' ' ); + /* + do + { + if ( status->i < status->n ) + { + if ( status->stream != 0 ) + do + { + status->stream->buffer[status->stream->bufidx++] = (char)' ', + if ( ( status->stream->bufidx == status->stream->bufsize ) + || ( ( status->stream->status & 2 ) && (char)' ' == '\n' ) + || ( status->stream->status & 4 ) ) + fflush( status->stream ) + } while (0), + ' '; + else status->s[status->i] = ' '; + } + ++(status->i); + } while ( 0 ); + */ ++(status->this); } } diff --git a/functions/stdio/clearerr.c b/functions/stdio/clearerr.c new file mode 100644 index 0000000..6d80c8a --- /dev/null +++ b/functions/stdio/clearerr.c @@ -0,0 +1,29 @@ +/* $Id$ */ + +/* clearerr( FILE * ) + + 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 clearerr( struct _PDCLIB_file_t * stream ) +{ + stream->status &= ~( _PDCLIB_ERRORFLAG | _PDCLIB_EOFFLAG ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/feof.c b/functions/stdio/feof.c new file mode 100644 index 0000000..13c4b64 --- /dev/null +++ b/functions/stdio/feof.c @@ -0,0 +1,29 @@ +/* $Id$ */ + +/* feof( FILE * ) + + 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 feof( struct _PDCLIB_file_t * stream ) +{ + return stream->status & _PDCLIB_EOFFLAG; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/ferror.c b/functions/stdio/ferror.c new file mode 100644 index 0000000..b6f51ee --- /dev/null +++ b/functions/stdio/ferror.c @@ -0,0 +1,29 @@ +/* $Id$ */ + +/* ferror( FILE * ) + + 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 ferror( struct _PDCLIB_file_t * stream ) +{ + return stream->status & _PDCLIB_ERRORFLAG; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/fflush.c b/functions/stdio/fflush.c new file mode 100644 index 0000000..2ddb0ad --- /dev/null +++ b/functions/stdio/fflush.c @@ -0,0 +1,41 @@ +/* $Id$ */ + +/* fflush( FILE * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include +#include <_PDCLIB_glue.h> + +#ifndef REGTEST + +int fflush( struct _PDCLIB_file_t * stream ) +{ + /* FIXME: This is ad-hoc. */ + if ( fwrite( stream->buffer, stream->bufidx, 1, stream ) == stream->bufidx ) + { + stream->bufidx = 0; + return 0; + } + else + { + stream->status |= _PDCLIB_ERRORFLAG; + return EOF; + } +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif + diff --git a/functions/stdio/fopen.c b/functions/stdio/fopen.c index 4a74e17..96fdcc1 100644 --- a/functions/stdio/fopen.c +++ b/functions/stdio/fopen.c @@ -80,9 +80,10 @@ struct _PDCLIB_file_t * fopen( const char * _PDCLIB_restrict filename, const cha /* Adding to list of open files */ rc->next = _PDCLIB_filelist; _PDCLIB_filelist = rc; - /* Setting buffer, and mark as internal. TODO: Check for unbuffered? */ + /* Setting buffer, and mark as internal. TODO: Check for unbuffered */ if ( ( rc->buffer = malloc( BUFSIZ ) ) == NULL ) goto fail; rc->bufsize = BUFSIZ; + rc->bufidx = 0; rc->status |= ( _PDCLIB_LIBBUFFER | _PDCLIB_VIRGINSTR ); /* TODO: Setting mbstate */ return rc; diff --git a/functions/stdio/fputc.c b/functions/stdio/fputc.c new file mode 100644 index 0000000..8f97378 --- /dev/null +++ b/functions/stdio/fputc.c @@ -0,0 +1,45 @@ +/* $Id$ */ + +/* fputc( int, FILE * ) + + 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 + +/* Write the value c (cast to unsigned char) to the given stream. + Returns c if successful, EOF otherwise. + If a write error occurs, sets the error indicator of the stream is set. +*/ +int fputc( int c, struct _PDCLIB_file_t * stream ) +{ + /* FIXME: This is devoid of any error checking (file writeable? r/w + constraints honored?) (Text format translations?) + */ + stream->buffer[stream->bufidx++] = (char)c; + if ( ( stream->bufidx == stream->bufsize ) /* _IOFBF */ + || ( ( stream->status & _IOLBF ) && (char)c == '\n' ) /* _IOLBF */ + || ( stream->status & _IONBF ) /* _IONBF */ + ) + { + /* buffer filled, unbuffered stream, or end-of-line. */ + fflush( stream ); + } + return c; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/fputs.c b/functions/stdio/fputs.c new file mode 100644 index 0000000..716fef8 --- /dev/null +++ b/functions/stdio/fputs.c @@ -0,0 +1,48 @@ +/* $Id$ */ + +/* fputs( const char *, FILE * ) + + 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 fputs( const char * _PDCLIB_restrict s, struct _PDCLIB_file_t * _PDCLIB_restrict stream ) +{ + /* FIXME: This is devoid of any error checking (file writeable? r/w + constraints honored?) + */ + /* FIXME: Proper buffering handling. */ + while ( stream->bufidx < stream->bufsize ) + { + if ( ( stream->buffer[stream->bufidx++] = *(s++) ) == '\0' ) + { + break; + } + } + fflush( stream ); + if ( *(s-1) != '\0' ) + { + return fputs( s, stream ); + } + else + { + return 1; + } +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdlib/strtoll.c b/functions/stdlib/strtoll.c index 80a8d17..768da39 100644 --- a/functions/stdlib/strtoll.c +++ b/functions/stdlib/strtoll.c @@ -26,6 +26,7 @@ long long int strtoll( const char * s, char ** endptr, int base ) else { /* FIXME: This breaks on some machines that round negatives wrongly */ + /* FIXME: Sign error not caught by testdriver */ 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; diff --git a/includes/stdio.h b/includes/stdio.h index 02d711e..06f0f44 100644 --- a/includes/stdio.h +++ b/includes/stdio.h @@ -713,7 +713,7 @@ char * gets( char * s ); /* Equivalent to fputc( c, stdout ), but may be implemented as a macro that evaluates its parameter more than once. */ -int putchar( int c ); +#define putchar( c ) putc( c, stdout ) /* Write the string s (not including the terminating \0) to stdout, and append a newline to the output. Returns a value >= 0 when successful, EOF if a diff --git a/internals/_PDCLIB_glue.h b/internals/_PDCLIB_glue.h index f390dfa..505b919 100644 --- a/internals/_PDCLIB_glue.h +++ b/internals/_PDCLIB_glue.h @@ -36,7 +36,8 @@ void * _PDCLIB_allocpages( int n ); _PDCLIB_fd_t _PDCLIB_open( char const * const filename, unsigned int mode ); /* A system call that writes n characters to a file identified by given file - descriptor. Return the number of characters written. + descriptor. Return the number of characters actually written, or zero if + an error occured. */ _PDCLIB_size_t _PDCLIB_write( _PDCLIB_fd_t fd, char const * buffer, _PDCLIB_size_t n ); diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index 7c061c8..1c89ae0 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -267,13 +267,16 @@ typedef unsigned _PDCLIB_intmax _PDCLIB_uintmax_t; #define _PDCLIB_WROTELAST 256u #define _PDCLIB_LIBBUFFER 512u #define _PDCLIB_VIRGINSTR 1024u +#define _PDCLIB_ERRORFLAG 2048u +#define _PDCLIB_EOFFLAG 4096u struct _PDCLIB_file_t { _PDCLIB_fd_t handle; /* OS-specific file descriptor */ _PDCLIB_fpos_t position; /* file position indicator */ - void * buffer; /* file buffer */ + char * buffer; /* file buffer */ _PDCLIB_size_t bufsize; /* size of buffer */ + _PDCLIB_size_t bufidx; /* pointer into buffer */ unsigned int status; /* misc. status bits */ /*mbstate_t mbstate; multibyte parse state - TODO: Unmask. */ struct _PDCLIB_file_t * next; /* provisions for linked list handling */