*/\r
#define _PDCLIB_FREAD 8u\r
#define _PDCLIB_FWRITE 16u\r
-#define _PDCLIB_FAPPEND 32u \r
+#define _PDCLIB_FAPPEND 32u\r
#define _PDCLIB_FRW 64u\r
#define _PDCLIB_FBIN 128u\r
\r
#endif\r
void * pointer;\r
_PDCLIB_uintptr_t uval;\r
- _PDCLIB_intptr_t sval; \r
+ _PDCLIB_intptr_t sval;\r
};\r
\r
/******************************************************************************/\r
be that of the current printf() function, of which the members n, s, stream\r
and arg will be preserved; i will be updated; and all others will be trashed\r
by the function.\r
- Returns a pointer to the first character not parsed as conversion specifier.\r
+ Returns the number of characters parsed as a conversion specifier (0 if none\r
+ parsed); returns -1 if the underlying I/O callback returns failure.\r
*/\r
-const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );\r
+int _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );\r
\r
/* The worker for all scanf() type of functions. The pointer spec should point\r
to the introducing '%' of a conversion specifier. The status structure is to\r
/* Parsing any fopen() style filemode string into a number of flags. */\r
unsigned int _PDCLIB_filemode( const char * mode );\r
\r
-/* Sanity checking and preparing of read buffer, should be called first thing \r
+/* Sanity checking and preparing of read buffer, should be called first thing\r
by any stdio read-data function.\r
Returns 0 on success, EOF on error.\r
On error, EOF / error flags and errno are set appropriately.\r
/* Repositions within a file. Returns new offset on success,\r
-1 / errno on error.\r
*/\r
-_PDCLIB_int_fast64_t _PDCLIB_seek( _PDCLIB_file_t * stream, \r
+_PDCLIB_int_fast64_t _PDCLIB_seek( _PDCLIB_file_t * stream,\r
_PDCLIB_int_fast64_t offset, int whence );\r
\r
/* File backend I/O operations\r
* On error, returns false and sets errno appropriately. *numBytesRead is\r
* ignored in this situation.\r
*/\r
- _PDCLIB_bool (*read)( _PDCLIB_fd_t self, \r
- void * buf, \r
- _PDCLIB_size_t length, \r
+ _PDCLIB_bool (*read)( _PDCLIB_fd_t self,\r
+ void * buf,\r
+ _PDCLIB_size_t length,\r
_PDCLIB_size_t * numBytesRead );\r
\r
/*! Write length bytes to the file from buf; returning the number of bytes\r
* actually written in *numBytesWritten\r
*\r
* Returns true if bytes were written successfully. On error, returns false\r
- * and setss errno appropriately (as with read, *numBytesWritten is \r
+ * and setss errno appropriately (as with read, *numBytesWritten is\r
* ignored)\r
*/\r
- _PDCLIB_bool (*write)( _PDCLIB_fd_t self, const void * buf, \r
+ _PDCLIB_bool (*write)( _PDCLIB_fd_t self, const void * buf,\r
_PDCLIB_size_t length, _PDCLIB_size_t * numBytesWritten );\r
\r
/* Seek to the file offset specified by offset, from location whence, which\r
* may be one of the standard constants SEEK_SET/SEEK_CUR/SEEK_END\r
*/\r
- _PDCLIB_bool (*seek)( _PDCLIB_fd_t self, _PDCLIB_int_fast64_t offset, \r
+ _PDCLIB_bool (*seek)( _PDCLIB_fd_t self, _PDCLIB_int_fast64_t offset,\r
int whence, _PDCLIB_int_fast64_t *newPos );\r
\r
void (*close)( _PDCLIB_fd_t self );\r
\r
- /*! Behaves as read does, except for wide characters. Both length and \r
+ /*! Behaves as read does, except for wide characters. Both length and\r
* *numCharsRead represent counts of characters, not bytes.\r
*\r
* This function is optional; if missing, PDCLib will buffer the character\r
* data as bytes and perform translation directly into the user's buffers.\r
- * It is useful if your backend can directly take wide characters (for \r
+ * It is useful if your backend can directly take wide characters (for\r
* example, the Windows console)\r
*/\r
- _PDCLIB_bool (*wread)( _PDCLIB_fd_t self, _PDCLIB_wchar_t * buf, \r
+ _PDCLIB_bool (*wread)( _PDCLIB_fd_t self, _PDCLIB_wchar_t * buf,\r
_PDCLIB_size_t length, _PDCLIB_size_t * numCharsRead );\r
\r
/* Behaves as write does, except for wide characters. As with wread, both\r
* length and *numCharsWritten are character counts.\r
*\r
- * This function is also optional; if missing, PDCLib will buffer the \r
- * character data as bytes and do translation directly from the user's \r
- * buffers. You only need to implement this if your backend can directly \r
+ * This function is also optional; if missing, PDCLib will buffer the\r
+ * character data as bytes and do translation directly from the user's\r
+ * buffers. You only need to implement this if your backend can directly\r
* take wide characters (for example, the Windows console)\r
*/\r
- _PDCLIB_bool (*wwrite)( _PDCLIB_fd_t self, const _PDCLIB_wchar_t * buf, \r
+ _PDCLIB_bool (*wwrite)( _PDCLIB_fd_t self, const _PDCLIB_wchar_t * buf,\r
_PDCLIB_size_t length, _PDCLIB_size_t * numCharsWritten );\r
};\r
\r
-/* FILE structure */\r
+/* struct _PDCLIB_file structure */\r
struct _PDCLIB_file\r
{\r
const _PDCLIB_fileops_t * ops;\r
int c;\r
while ( stream->ungetidx > 0 && i != n )\r
{\r
- c = (unsigned char) \r
+ c = (unsigned char)\r
( out[ i++ ] = stream->ungetbuf[ --(stream->ungetidx) ] );\r
if( c == stopchar )\r
return i;\r
\r
while ( i != n )\r
{\r
- while ( stream->bufidx != stream->bufend && i != n) \r
+ while ( stream->bufidx != stream->bufend && i != n)\r
{\r
- c = (unsigned char) \r
- ( out[ i++ ] = stream->buffer[ stream->bufidx++ ] );\r
+ c = (unsigned char) stream->buffer[ stream->bufidx++ ];\r
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
+ if ( !( stream->status & _PDCLIB_FBIN ) && c == '\r' )\r
+ {\r
+ if ( stream->bufidx == stream->bufend )\r
+ break;\r
+\r
+ if ( stream->buffer[ stream->bufidx ] == '\n' )\r
+ {\r
+ c = '\n';\r
+ stream->bufidx++;\r
+ }\r
+ }\r
+#endif\r
+ out[ i++ ] = c;\r
+\r
if( c == stopchar )\r
return i;\r
}\r
\r
- if ( stream->bufidx == stream->bufend )\r
+ if ( i != n )\r
{\r
if( _PDCLIB_fillbuffer( stream ) == -1 )\r
{\r
- return i;\r
+ break;\r
}\r
}\r
}\r
\r
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
+ if ( i != n && stream->bufidx != stream->bufend )\r
+ {\r
+ // we must have EOF'd immediately after a \r\r
+ out[ i++ ] = stream->buffer[ stream->bufidx++ ];\r
+ }\r
+#endif\r
+\r
return i;\r
}\r
\r
+/* Unlocked functions - internal names\r
+ *\r
+ * We can't use the functions using their "normal" names internally because that\r
+ * would cause namespace leakage. Therefore, we use them by prefixed internal\r
+ * names\r
+ */\r
+void _PDCLIB_flockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;\r
+int _PDCLIB_ftrylockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;\r
+void _PDCLIB_funlockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;\r
+\r
+int _PDCLIB_getc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_getchar_unlocked(void) _PDCLIB_nothrow;\r
+int _PDCLIB_putc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_putchar_unlocked(int c) _PDCLIB_nothrow;\r
+void _PDCLIB_clearerr_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_feof_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_ferror_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_fflush_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_fgetc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_fputc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+_PDCLIB_size_t _PDCLIB_fread_unlocked(void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+_PDCLIB_size_t _PDCLIB_fwrite_unlocked(const void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+char *_PDCLIB_fgets_unlocked(char *s, int n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_fputs_unlocked(const char *s, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
+int _PDCLIB_fgetpos_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, _PDCLIB_fpos_t * _PDCLIB_restrict pos ) _PDCLIB_nothrow;\r
+int _PDCLIB_fsetpos_unlocked( struct _PDCLIB_file * stream, const _PDCLIB_fpos_t * pos ) _PDCLIB_nothrow;\r
+long int _PDCLIB_ftell_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow;\r
+int _PDCLIB_fseek_unlocked( struct _PDCLIB_file * stream, long int offset, int whence ) _PDCLIB_nothrow;\r
+void _PDCLIB_rewind_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow;\r
+\r
+int _PDCLIB_puts_unlocked( const char * s ) _PDCLIB_nothrow;\r
+int _PDCLIB_ungetc_unlocked( int c, struct _PDCLIB_file * stream ) _PDCLIB_nothrow;\r
+\r
+\r
+int _PDCLIB_printf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
+int _PDCLIB_vprintf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
+int _PDCLIB_fprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
+int _PDCLIB_vfprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
+int _PDCLIB_scanf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
+int _PDCLIB_vscanf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
+int _PDCLIB_fscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
+int _PDCLIB_vfscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
+\r
#endif\r