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
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);
}
}
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+#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
+
/* 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;
--- /dev/null
+/* $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 <stdio.h>
+
+#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
--- /dev/null
+/* $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 <stdio.h>
+
+#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
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;
/* 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
_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 );
#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 */