From cd6cfe0f578c4f744ddc9a342243aff6b42f8027 Mon Sep 17 00:00:00 2001 From: Owen Shepherd Date: Thu, 9 Oct 2014 20:51:02 +0100 Subject: [PATCH] Add newline translationwq --- functions/stdio/_PDCLIB_flushbuffer.c | 70 ++++++++++++++++++------ internals/_PDCLIB_io.h | 34 ++++++++++-- platform/gandr/includes/_PDCLIB_config.h | 3 + 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/functions/stdio/_PDCLIB_flushbuffer.c b/functions/stdio/_PDCLIB_flushbuffer.c index 7ee0d93..44066d8 100644 --- a/functions/stdio/_PDCLIB_flushbuffer.c +++ b/functions/stdio/_PDCLIB_flushbuffer.c @@ -11,34 +11,72 @@ #include <_PDCLIB_glue.h> #include <_PDCLIB_io.h> -int _PDCLIB_flushbuffer( FILE * stream ) +static int flushsubbuffer( FILE * stream, size_t length ) { - if ( ! ( stream->status & _PDCLIB_FBIN ) ) - { - /* TODO: Text stream conversion here */ - } - size_t written = 0; + int rv = 0; - - while(written != stream->bufidx) { + while( written != length ) + { size_t justWrote; - size_t toWrite = stream->bufidx - written; - bool res = stream->ops->write( stream->handle, stream->buffer + written, + size_t toWrite = length - written; + bool res = stream->ops->write( stream->handle, stream->buffer + written, toWrite, &justWrote); written += justWrote; stream->pos.offset += justWrote; - if(!res) { + if (!res) + { stream->status |=_PDCLIB_ERRORFLAG; - stream->bufidx -= written; - memmove( stream->buffer, stream->buffer + written, stream->bufidx ); - return EOF; + rv = EOF; + break; + } + } + + stream->bufidx -= written; + memmove( stream->buffer, stream->buffer + written, stream->bufidx ); + + return rv; +} + +#if defined(_PDCLIB_NEED_EOL_TRANSLATION) +#undef _PDCLIB_NEED_EOL_TRANSLATION +#define _PDCLIB_NEED_EOL_TRANSLATION 1 +#else +#define _PDCLIB_NEED_EOL_TRANSLATION 0 +#endif + +int _PDCLIB_flushbuffer( FILE * stream ) +{ + // if a text stream, and this platform needs EOL translation, well... + if ( ! ( stream->status & _PDCLIB_FBIN ) && _PDCLIB_NEED_EOL_TRANSLATION ) + { + size_t pos; + for ( pos = 0; pos < stream->bufidx; pos++ ) + { + if (stream->buffer[pos] == '\n' ) { + if ( stream->bufidx == stream->bufend ) { + // buffer is full. Need to print out everything up till now + if( flushsubbuffer( stream, pos ) ) + { + return EOF; + } + + pos = 0; + } + + // we have spare space in buffer. Shift everything 1char and + // insert \r + memmove( &stream->buffer[pos+1], &stream->buffer[pos], stream->bufidx - pos ); + stream->buffer[pos] = '\r'; + + pos += 2; + stream->bufidx++; + } } } - stream->bufidx = 0; - return 0; + return flushsubbuffer( stream, stream->bufidx ); } #endif diff --git a/internals/_PDCLIB_io.h b/internals/_PDCLIB_io.h index 78e747c..2df3ff5 100644 --- a/internals/_PDCLIB_io.h +++ b/internals/_PDCLIB_io.h @@ -14,7 +14,7 @@ */ #define _PDCLIB_FREAD 8u #define _PDCLIB_FWRITE 16u -#define _PDCLIB_FAPPEND 32u +#define _PDCLIB_FAPPEND 32u #define _PDCLIB_FRW 64u #define _PDCLIB_FBIN 128u @@ -41,7 +41,7 @@ union _PDCLIB_fd #endif void * pointer; _PDCLIB_uintptr_t uval; - _PDCLIB_intptr_t sval; + _PDCLIB_intptr_t sval; }; /******************************************************************************/ @@ -206,21 +206,43 @@ static inline _PDCLIB_size_t _PDCLIB_getchars( char * out, _PDCLIB_size_t n, { while ( stream->bufidx != stream->bufend && i != n) { - c = (unsigned char) - ( out[ i++ ] = stream->buffer[ stream->bufidx++ ] ); + c = (unsigned char) stream->buffer[ stream->bufidx++ ]; +#ifdef _PDCLIB_NEED_EOL_TRANSLATION + if ( !( stream->status & _PDCLIB_FBIN ) && c == '\r' ) + { + if ( stream->bufidx == stream->bufend ) + break; + + if ( stream->buffer[ stream->bufidx ] == '\n' ) + { + c = '\n'; + stream->bufidx++; + } + } +#endif + out[ i++ ] = c; + if( c == stopchar ) return i; } - if ( stream->bufidx == stream->bufend ) + if ( i != n ) { if( _PDCLIB_fillbuffer( stream ) == -1 ) { - return i; + break; } } } +#ifdef _PDCLIB_NEED_EOL_TRANSLATION + if ( i != n && stream->bufidx != stream->bufend ) + { + // we must have EOF'd immediately after a \r + out[ i++ ] = stream->buffer[ stream->bufidx++ ]; + } +#endif + return i; } diff --git a/platform/gandr/includes/_PDCLIB_config.h b/platform/gandr/includes/_PDCLIB_config.h index c899cfd..98727c8 100644 --- a/platform/gandr/includes/_PDCLIB_config.h +++ b/platform/gandr/includes/_PDCLIB_config.h @@ -184,6 +184,9 @@ typedef __builtin_va_list _PDCLIB_va_list; /* The default size for file buffers. Must be at least 256. */ #define _PDCLIB_BUFSIZ 1024 +/* We need \n -> \r\n translation for text files */ +#define _PDCLIB_NEED_EOL_TRANSLATION 1 + /* Minimum number of files we can open simultaneously. C says this must be >= 8, * so we say that. May actually be a lie in some cases... */ -- 2.40.0