X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=includes%2Fstdio.h;h=24fe0f4eeb96a6cdd748b6a2733534382894a312;hb=c97120968d26f69517f2da7db2278a1ba30e27a6;hp=c3122c4afaf21d0a748384316a3f344463b9b035;hpb=b08f4b52b1cd1f7a9553c0f357a7c90859fa3e73;p=pdclib diff --git a/includes/stdio.h b/includes/stdio.h index c3122c4..24fe0f4 100644 --- a/includes/stdio.h +++ b/includes/stdio.h @@ -25,86 +25,158 @@ typedef _PDCLIB_size_t size_t; #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 +#define _IOFBF 2 +#define _IOLBF 1 +#define _IONBF 0 -typedef struct _PDCLIB_file_t FILE; +/* The following are platform-dependant, and defined in _PDCLIB_config.h. */ typedef _PDCLIB_fpos_t fpos_t; - -/* Must be integer and of negative value */ +typedef struct _PDCLIB_file_t FILE; #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 - -/* Buffer size for tmpnam() */ -#define L_tmpnam 1024 - -/* Number of distinct file names that can be generated by tmpnam(). */ -#define TMP_MAX 50 +#define BUFSIZ _PDCLIB_BUFSIZ +#define FOPEN_MAX _PDCLIB_FOPEN_MAX +#define FILENAME_MAX _PDCLIB_FILENAME_MAX +#define L_tmpnam _PDCLIB_L_tmpnam +#define TMP_MAX _PDCLIB_TMP_MAX /* 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 */ + +/* Remove the given file. + Returns zero if successful, non-zero otherwise. + This implementation does detect if the filename corresponds to an open file, + and closes it before attempting the rename. +*/ int remove( const char * filename ); + +/* Rename the given old file to the given new name. + Returns zero if successful, non-zero otherwise. + This implementation does detect if the old filename corresponds to an open + file, and closes it before attempting the rename. + If the already is a file with the new filename, behaviour is defined by the + OS. +*/ int rename( const char * old, const char * new ); -FILE * tmpfile( void ); /* TODO: Implement. */ -char * tmpnam( char * s ); /* TODO: Implement. */ + +/* Open a temporary file with mode "wb+", i.e. binary-update. Remove the file + automatically if it is closed or the program exits normally (by returning + from main() or calling exit()). + Returns a pointer to a FILE handle for this file. + This implementation does not remove temporary files if the process aborts + abnormally (e.g. abort()). +*/ +FILE * tmpfile( void ); + +/* Generate a file name that is not equal to any existing filename AT THE TIME + OF GENERATION. Generate a different name each time it is called. + Returns a pointer to an internal static buffer containing the filename if s + is a NULL pointer. (This is not thread-safe!) + Returns s if it is not a NULL pointer (s is then assumed to point to an array + of at least L_tmpnam characters). + Returns NULL if unable to generate a suitable name (because all possible + names already exist, or the function has been called TMP_MAX times already). + Note that this implementation cannot guarantee a file of the name generated + is not generated between the call to this function and a subsequent fopen(). +*/ +char * tmpnam( char * s ); /* File access functions */ + +/* Close the file associated with the given stream (after flushing its buffers). + Returns zero if successful, EOF if any errors occur. +*/ int fclose( FILE * stream ); + +/* Flush the buffers of the given output stream. If the stream is an input + stream, or an update stream with the last operation being an input operation, + behaviour is undefined. + If stream is a NULL pointer, perform the buffer flushing for all applicable + streams. + Returns zero if successful, EOF if a write error occurs. + Sets the error indicator of the stream if a write error occurs. +*/ int fflush( FILE * stream ); + +/* Open the file with the given filename in the given mode, and return a stream + handle for it in which error and end-of-file indicator are cleared. Defined + values for mode are: + + READ MODES + text files binary files + without update "r" "rb" + with update "r+" "rb+" or "r+b" + + Opening in read mode fails if no file with the given filename exists, or if + cannot be read. + + WRITE MODES + text files binary files + without update "w" "wb" + with update "w+" "wb+" or "w+b" + + With write modes, if a file with the given filename already exists, it is + truncated to zero length. + + APPEND MODES + text files binary files + without update "a" "ab" + with update "a+" "ab+" or "a+b" + + With update modes, if a file with the given filename already exists, it is + not truncated to zero length, but all writes are forced to end-of-file (this + regardless to fseek() calls). Note that binary files opened in append mode + might have their end-of-file padded with '\0' characters. + + Update modes mean that both input and output functions can be performed on + the stream, but output must be terminated with a call to either fflush(), + fseek(), fsetpos(), or rewind() before input is performed, and input must + be terminated with a call to either fseek(), fsetpos(), or rewind() before + output is performed, unless input encountered end-of-file. + + If a text file is opened with update mode, the implementation is at liberty + to open a binary stream instead. This implementation honors the exact mode + given. + + The stream is fully buffered if and only if it can be determined not to + refer to an interactive device. As the generic code of this implementation + cannot determine this, _IOLBF (line buffering) is used for all streams. + + If the mode string begins with but is longer than one of the above sequences + the implementation is at liberty to ignore the additional characters, or do + implementation-defined things. This implementation only accepts the exact + modes above. + + Returns a pointer to the stream handle if successfull, NULL otherwise. +*/ FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode ); + +/* Close any file currently associated with the given stream. Open the file + identified by the given filename with the given mode (equivalent to fopen()), + and associate it with the given stream. If filename is a NULL pointer, + attempt to change the mode of the given stream. + This implementation allows the following mode changes: TODO + (Primary use of this function is to redirect stdin, stdout, and stderr.) +*/ FILE * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, FILE * _PDCLIB_restrict stream ); + +/* If buf is a NULL pointer, call setvbuf( stream, NULL, _IONBF, BUFSIZ ). + If buf is not a NULL pointer, call setvbuf( stream, buf, _IOFBF, BUFSIZ ). +*/ void setbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf ); + +/* Set the given stream to the given buffering mode. If buf is not a NULL + pointer, use buf as file buffer (of given size). If buf is a NULL pointer, + use a buffer of given size allocated internally. _IONBF causes unbuffered + behaviour, _IOLBF causes line-buffered behaviour, _IOFBF causes fully + buffered behaviour. Calling this function is only valid right after a file is + opened, and before any other operation (except for any unsuccessful calls to + setvbuf()) has been performed. + Returns zero if successful, nonzero otherwise. +*/ int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size ); /* Formatted input/output functions */ @@ -124,33 +196,176 @@ int vsprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _ int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ); /* Character input/output functions */ + +/* Retrieve the next character from given stream. + Returns the character, EOF otherwise. + If end-of-file is reached, the EOF indicator of the stream is set. + If a read error occurs, the error indicator of the stream is set. +*/ int fgetc( FILE * stream ); + +/* Read at most n-1 characters from given stream into the array s, stopping at + \n or EOF. Terminate the read string with \n. If EOF is encountered before + any characters are read, leave the contents of s unchanged. + Returns s if successful, NULL otherwise. + If a read error occurs, the error indicator of the stream is set. In this + case, the contents of s are indeterminate. +*/ char * fgets( char * _PDCLIB_restrict s, int n, FILE * _PDCLIB_restrict stream ); + +/* 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, FILE * stream ); + +/* Write the string s (not including the terminating \0) to the given stream. + Returns a value >=0 if successful, EOF otherwise. + This implementation does set the error indicator of the stream if a write + error occurs. +*/ int fputs( const char * _PDCLIB_restrict s, FILE * _PDCLIB_restrict stream ); -int getc( FILE * stream ); -int getchar( void ); + +/* Equivalent to fgetc( stream ), but may be implemented as a macro that + evaluates its parameter more than once. +*/ +#define getc( stream ) fgetc( stream ) + +/* Equivalent to fgetc( stdin ), but may be implemented as a macro. */ +#define getchar() fgetc( stdin ) + +/* Read characters from given stream into the array s, stopping at \n or EOF. + The string read is terminated with \0. Returns s if successful. If EOF is + encountered before any characters are read, the contents of s are unchanged, + and NULL is returned. If a read error occurs, the contents of s are indeter- + minate, and NULL is returned. +*/ char * gets( char * s ); -int putc( int c, FILE * stream ); + +/* Equivalent to fputc( c, stream ), but may be implemented as a macro that + evaluates its parameter more than once. +*/ +#define putc( c, stream ) fputc( c, stream ) + +/* Equivalent to fputc( c, stdout ), but may be implemented as a macro that + evaluates its parameter more than once. +*/ int putchar( int c ); + +/* 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 + write error occurred. +*/ int puts( const char * s ); + +/* Push the value c (cast to unsigned char) back onto the given (input) stream. + A character pushed back in this way will be delivered by subsequent read + operations (and skipped by subsequent file positioning operations) as if it + has not been read. The external representation of the stream is unaffected + by this pushback (it is a buffer operation). One character of pushback is + guaranteed, further pushbacks may fail. EOF as value for c does not change + the input stream and results in failure of the function. + For text files, the file position indicator is indeterminate until all + pushed-back characters are read. For binary files, the file position + indicator is decremented by each successful call of ungetc(). If the file + position indicator for a binary file was zero before the call of ungetc(), + behaviour is undefined. (Older versions of the library allowed such a call.) + Returns the pushed-back character if successful, EOF if it fails. +*/ int ungetc( int c, FILE * stream ); /* Direct input/output functions */ + +/* Read up to nmemb elements of given size from given stream into the buffer + pointed to by ptr. Returns the number of elements successfully read, which + may be less than nmemb if a read error or EOF is encountered. If a read + error is encountered, the value of the file position indicator is + indeterminate. If a partial element is read, its value is indeterminate. + If size or nmemb are zero, the function does nothing and returns zero. +*/ size_t fread( void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream ); + +/* Write up to nmemb elements of given size from buffer pointed to by ptr to + the given stream. Returns the number of elements successfully written, which + will be less than nmemb only if a write error is encountered. If a write + error is encountered, the value of the file position indicator is + indeterminate. If size or nmemb are zero, the function does nothing and + returns zero. +*/ size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream ); /* File positioning functions */ + +/* Store the current position indicator (and, where appropriate, the current + mbstate_t status object) for the given stream into the given pos object. The + actual contents of the object are unspecified, but it can be used as second + parameter to fsetpos() to reposition the stream to the exact position and + parse state at the time fgetpos() was called. + Returns zero if successful, nonzero otherwise. + TODO: Implementation-defined errno setting for fgetpos(). +*/ int fgetpos( FILE * _PDCLIB_restrict stream, fpos_t * _PDCLIB_restrict pos ); + +/* Set the position indicator for the given stream to the given offset from: + - the beginning of the file if whence is SEEK_SET, + - the current value of the position indicator if whence is SEEK_CUR, + - end-of-file if whence is SEEK_END. + On text streams, non-zero offsets are only allowed with SEEK_SET, and must + have been returned by ftell() for the same file. + Any characters buffered by ungetc() are dropped, the end-of-file indicator + for the stream is cleared. If the given stream is an update stream, the next + operation after a successful fseek() may be either input or output. + Returns zero if successful, nonzero otherwise. If a read/write error occurs, + the error indicator for the given stream is set. +*/ int fseek( FILE * stream, long int offset, int whence ); + +/* Set the position indicator (and, where appropriate the mbstate_t status + object) for the given stream to the given pos object (created by an earlier + call to fgetpos() on the same file). + Any characters buffered by ungetc() are dropped, the end-of-file indicator + for the stream is cleared. If the given stream is an update stream, the next + operation after a successful fsetpos() may be either input or output. + Returns zero if successful, nonzero otherwise. If a read/write error occurs, + the error indicator for the given stream is set. + TODO: Implementation-defined errno setting for fsetpos(). +*/ int fsetpos( FILE * stream, const fpos_t * pos ); + +/* Return the current offset of the given stream from the beginning of the + associated file. For text streams, the exact value returned is unspecified + (and may not be equal to the number of characters), but may be used in + subsequent calls to fseek(). + Returns -1L if unsuccessful. + TODO: Implementation-defined errno setting for ftell(). +*/ long int ftell( FILE * stream ); + +/* Equivalent to (void)fseek( stream, 0L, SEEK_SET ), except that the error + indicator for the stream is also cleared. +*/ void rewind( FILE * stream ); /* Error-handling functions */ + +/* Clear the end-of-file and error indicators for the given stream. */ void clearerr( FILE * stream ); + +/* Return zero if the end-of-file indicator for the given stream is not set, + nonzero otherwise. +*/ int feof( FILE * stream ); + +/* Return zero if the error indicator for the given stream is not set, nonzero + otherwise. +*/ int ferror( FILE * stream ); + +/* If s is neither a NULL pointer nor an empty string, print the string to + stderr (with appended colon (':') and a space) first. In any case, print an + error message depending on the current value of errno (being the same as if + strerror( errno ) had been called). +*/ void perror( const char * s ); #endif