2021-05-09 23:00:11 +02:00
|
|
|
#ifndef __STDIO_H__
|
|
|
|
# define __STDIO_H__
|
2020-09-17 19:27:01 +02:00
|
|
|
|
2021-06-28 15:49:05 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2020-09-17 19:27:01 +02:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdarg.h>
|
2022-01-13 21:28:19 +01:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <sys/types.h>
|
2021-06-13 17:26:32 +02:00
|
|
|
|
2022-01-13 21:28:19 +01:00
|
|
|
#define __FILE_BUF_READ 0
|
|
|
|
#define __FILE_BUF_WRITE 1
|
|
|
|
|
|
|
|
/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the
|
|
|
|
work is maintaining that buffer to provide the basic fgetc()/fputc()
|
|
|
|
functions, then everything else is built on top of the abstracted stream.
|
|
|
|
|
|
|
|
The buffer of a FILE can either be in reading or writing mode. When in
|
|
|
|
reading mode, the buffer contains pre-fetched data from a previous read that
|
|
|
|
hasn't yet been requested by the user. When in writing mode, the buffer
|
|
|
|
contains data written by the user which hasn't yet been sent to the kernel.
|
|
|
|
|
|
|
|
The buffer has the following structure:
|
|
|
|
|
|
|
|
0 bufpos bufread bufsize
|
|
|
|
+--------+---------+---------+
|
|
|
|
|xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading)
|
|
|
|
+--------+---------+---------+
|
|
|
|
|wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing)
|
|
|
|
+--------+-------------------+
|
|
|
|
|
|
|
|
x: Data read from file descriptor and returned to user
|
|
|
|
r: Data read from file descriptor not yet returned to user
|
|
|
|
w: Data written by user not yet sent to file descriptor
|
|
|
|
u: Undefined
|
|
|
|
|
|
|
|
In reading mode, the region [0..bufread) contains data obtained from the
|
|
|
|
file. bufpos marks how much has been read, in the sense that [0..bufpos) has
|
|
|
|
already been returned to the user while [bufpos..bufread) has not. The offset
|
|
|
|
on the underlying file descriptor sits at bufread, so the position reported
|
|
|
|
by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined.
|
|
|
|
|
|
|
|
In writing mode, the region [0..bufpos) contains data received through API
|
|
|
|
but not yet written to the file descriptor. ftell() reports fdpos + bufpos.
|
|
|
|
The rest of the buffer is undefined.
|
|
|
|
|
|
|
|
The ungetc() function pushes back characters into the buffer; if the FILE is
|
|
|
|
unbuffered, then it's made buffered temporarily to hold the characters and
|
|
|
|
cleared at the next fflush() or read. The buffer is put in reading mode. For
|
|
|
|
this reason, reading functions should test [fp->buf] to check whether there
|
|
|
|
is a buffer instead of [fp->bufmode != _IONBF].
|
|
|
|
|
|
|
|
Many fields in the FILE structure are abstracted away by API calls in layers:
|
|
|
|
|
|
|
|
1. [fd], [fdpos] and [error] are updated by the primitive functions of
|
|
|
|
fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously).
|
|
|
|
2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(),
|
|
|
|
setvbuf() and fclose().
|
|
|
|
3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions
|
|
|
|
like fgets() or fwrite(), and cleared by fflush().
|
|
|
|
4. [readable], [writable], [append] and [text] are set by fopen() and
|
|
|
|
freopen(), and used as read-only by the primitive functions of 3. */
|
|
|
|
typedef struct {
|
|
|
|
/* File descriptor */
|
|
|
|
int fd;
|
|
|
|
/* Current position in file, as tracked by the file descriptor (ie. not
|
|
|
|
accounting for buffer operations) */
|
|
|
|
size_t fdpos;
|
|
|
|
|
|
|
|
/* Pointer to buffer (NULL if _IONBF) */
|
|
|
|
char *buf;
|
|
|
|
/* Current position in buffer, water mark of read data in buffer, and
|
|
|
|
buffer size; see header comment for details */
|
|
|
|
size_t bufpos;
|
|
|
|
size_t bufread;
|
|
|
|
size_t bufsize;
|
|
|
|
/* Number of ungetc()'d characters at the start of buffer data */
|
|
|
|
int bufungetc;
|
|
|
|
/* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */
|
|
|
|
uint8_t bufmode :2;
|
|
|
|
/* We own the buffer and it needs to be freed */
|
|
|
|
uint8_t bufowned :1;
|
|
|
|
/* __FILE_BUF_READ if the buffer is in reading mode
|
|
|
|
__FILE_BUF_WRITE if it's in writing mode
|
|
|
|
This mode can only be changed immediately after fflush(). */
|
|
|
|
uint8_t bufdir :1;
|
|
|
|
|
|
|
|
/* Opening flags */
|
|
|
|
uint8_t readable :1;
|
|
|
|
uint8_t writable :1;
|
|
|
|
uint8_t append :1;
|
|
|
|
/* Non-zero if text mode, zero if binary mode */
|
|
|
|
uint8_t text :1;
|
|
|
|
/* EOF indicator */
|
|
|
|
uint8_t eof :1;
|
|
|
|
/* Error indicator */
|
|
|
|
uint8_t error :1;
|
|
|
|
} FILE;
|
2021-05-16 18:02:46 +02:00
|
|
|
|
2022-01-02 22:09:06 +01:00
|
|
|
/* Type of positions within files. We don't have wide-oriented streams. */
|
2021-06-13 17:26:32 +02:00
|
|
|
typedef size_t fpos_t;
|
|
|
|
|
|
|
|
/* Buffering modes. */
|
|
|
|
#define _IOFBF 0
|
|
|
|
#define _IOLBF 1
|
|
|
|
#define _IONBF 2
|
|
|
|
|
|
|
|
/* Some buffer size for file buffering. */
|
2022-01-01 17:11:04 +01:00
|
|
|
#define BUFSIZ 512
|
2021-06-13 17:26:32 +02:00
|
|
|
|
|
|
|
/* End-of-file marker. */
|
|
|
|
#define EOF ((int)(-1))
|
|
|
|
|
|
|
|
/* Number of files guaranteed can be opened simultaneously. */
|
|
|
|
/* TODO: FOPEN_MAX is BFile-specific, Vhex might have much larger limits. */
|
|
|
|
#define FOPEN_MAX 4
|
|
|
|
|
|
|
|
/* Recommended length of a filename. */
|
|
|
|
/* TODO: FILENAME_MAX = 128 is quite BFile-centric, Vhex might be different. */
|
|
|
|
#define FILENAME_MAX 128
|
|
|
|
|
|
|
|
/* Length a filename for tmpnam. */
|
|
|
|
#define L_tmpnam FILENAME_MAX
|
|
|
|
|
|
|
|
/* Seeking positions. */
|
2022-08-13 00:01:30 +02:00
|
|
|
#define SEEK_CUR 1
|
|
|
|
#define SEEK_END 2
|
|
|
|
#define SEEK_SET 3
|
2021-06-13 17:26:32 +02:00
|
|
|
|
|
|
|
/* Maximum number of unique filenames that tmpnam can generate. */
|
|
|
|
/* TODO: Set a useful value in TMP_MAX other than 16*16*16 */
|
|
|
|
#define TMP_MAX (16*16*16)
|
|
|
|
|
2021-06-07 18:57:11 +02:00
|
|
|
/* Standard input, output and error streams. */
|
2021-05-16 18:02:46 +02:00
|
|
|
extern FILE *stdin;
|
|
|
|
extern FILE *stdout;
|
|
|
|
extern FILE *stderr;
|
|
|
|
/* Make them macros (7.19.1§3) */
|
|
|
|
#define stdin stdin
|
|
|
|
#define stdout stdout
|
|
|
|
#define stderr stderr
|
2020-09-17 19:27:01 +02:00
|
|
|
|
2022-01-01 17:11:04 +01:00
|
|
|
/*
|
|
|
|
** Operations on files.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Remove a file from the filesystem.
|
|
|
|
In gint, the file must not be open (open files' names are not tracked). */
|
|
|
|
extern int remove(char const *__filename);
|
|
|
|
|
2022-08-13 00:01:00 +02:00
|
|
|
extern int rename(char const *__old, char const *__new);
|
|
|
|
|
|
|
|
extern FILE *tmpfile(void);
|
|
|
|
|
|
|
|
extern char *tmpnam(char *__s);
|
|
|
|
|
2022-01-01 17:11:04 +01:00
|
|
|
/*
|
|
|
|
** File access functions.
|
|
|
|
*/
|
|
|
|
|
2022-01-02 18:51:16 +01:00
|
|
|
/* Flush the stream and disassociate it from the underlying file. */
|
|
|
|
extern int fclose(FILE *__fp);
|
|
|
|
|
2022-01-01 17:11:04 +01:00
|
|
|
/* Flush any written data in the FILE's internal buffer. */
|
|
|
|
extern int fflush(FILE *__fp);
|
|
|
|
|
2022-01-02 18:51:16 +01:00
|
|
|
/* Open a file and associate a stream with it. */
|
|
|
|
extern FILE *fopen(
|
|
|
|
char const * __restrict__ __filename,
|
|
|
|
char const * __restrict__ __mode);
|
|
|
|
|
|
|
|
/* Open a file descriptor and associate a stream with it. */
|
|
|
|
extern FILE *fdopen(int __fd, char const *__mode);
|
|
|
|
|
|
|
|
/* Reopen a stream with another file, or change its mode. */
|
|
|
|
extern FILE *freopen(
|
|
|
|
char const * __restrict__ __filename,
|
|
|
|
char const * __restrict__ __mode,
|
|
|
|
FILE * __restrict__ __fp);
|
|
|
|
|
2022-01-01 17:11:04 +01:00
|
|
|
/* Use __buf as a buffer (of size BUFSIZ) for access to __fp. */
|
|
|
|
extern void setbuf(FILE * __restrict__ __fp, char * __restrict__ __buf);
|
|
|
|
|
|
|
|
/* Changer the buffering mode and buffer address for __fp. */
|
|
|
|
extern int setvbuf(FILE * __restrict__ __fp, char * __restrict__ __buf,
|
|
|
|
int __mode, size_t __size);
|
|
|
|
|
2022-09-07 21:02:01 +02:00
|
|
|
/* Return the file descriptor associated with __fp. */
|
2022-08-13 00:01:00 +02:00
|
|
|
extern int fileno(FILE *__fp);
|
|
|
|
|
2021-06-07 18:57:11 +02:00
|
|
|
/*
|
|
|
|
** Formatted input/output functions.
|
|
|
|
**
|
|
|
|
** These functions implement most of printf(3)'s features, including:
|
|
|
|
** - Signed and unsigned integer formats (%d, %i, %o, %u, %x, %X)
|
|
|
|
** - Character, string and pointer formats (%c, %s, %p)
|
|
|
|
** - Character count and strerror() shorthand formats (%n, %m)
|
|
|
|
** - Format options (0, #, -, (space), length, precision)
|
2021-06-08 10:32:08 +02:00
|
|
|
** - Parameter length (hh, h, l, ll, L, z, j, t) (L: if long double is 64-bit)
|
2021-06-07 18:57:11 +02:00
|
|
|
** - Limiting the size of the output and still returning the whole length
|
|
|
|
** - If __printf_enable_fp() from <fxlibc/printf.h> is called: floating-point
|
|
|
|
** formats (%e, %E, %f, %F, %g, %G) (disabled by default to save space)
|
|
|
|
**
|
2021-06-08 10:32:08 +02:00
|
|
|
** They do not (yet?) support:
|
2021-06-07 18:57:11 +02:00
|
|
|
** - Hexadecimal floating-point (%a, %A)
|
2021-06-08 10:32:08 +02:00
|
|
|
** - Printing long double values when long double is more than 64-bit
|
2021-06-07 18:57:11 +02:00
|
|
|
** - Dynamic length field (*)
|
2021-06-08 10:32:08 +02:00
|
|
|
** - Parameter reordering ($m)
|
2021-06-07 18:57:11 +02:00
|
|
|
** - Thousands separators (') and locale-aware digits (I)
|
2021-06-08 10:32:08 +02:00
|
|
|
** - Nonstandard/old synonyms %C (%lc), %S (%ls), q (ll), and Z (z)
|
2021-06-07 18:57:11 +02:00
|
|
|
**
|
|
|
|
** There are extensions, namely to allow for custom conversions to be added.
|
|
|
|
** One custom conversion can be enabled with __printf_enable_fixed() from
|
2021-06-08 10:32:08 +02:00
|
|
|
** <fxlibc/printf.h>: a decimal fixed-point format %D which is like %d but
|
2021-06-07 18:57:11 +02:00
|
|
|
** with a decimal point. See <fxlibc/printf.h> for details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Formatted print to file. */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int fprintf(FILE * __restrict__ __fp,
|
|
|
|
char const * __restrict__ __format, ...);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to stdout. */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int printf(
|
|
|
|
char const * __restrict__ __format, ...);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to string (with limited size). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int snprintf(char * __restrict__ __str, size_t __size,
|
|
|
|
char const * __restrict__ __format, ...);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to string (with unlimited size!). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int sprintf(char * __restrict__ __str,
|
|
|
|
char const * __restrict__ __format, ...);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to file (variable argument list). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int vfprintf(FILE * __restrict__ __fp,
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to stdout (variable argument list). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int vprintf(
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to string (limited size, variable argument list). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int vsnprintf(char * __restrict__ __str, size_t __size,
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to string (unlimited size!, variable argument list). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int vsprintf(char * __restrict__ __str,
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
2020-09-17 19:27:01 +02:00
|
|
|
|
|
|
|
/* putx() - display char / string */
|
|
|
|
extern int putchar(int c);
|
|
|
|
extern int puts(const char *s);
|
|
|
|
|
2021-06-07 18:57:11 +02:00
|
|
|
/* Extensions. */
|
|
|
|
|
|
|
|
/* Formatted print to file descriptor. */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int dprintf(int __fd,
|
|
|
|
char const * __restrict__ __format, ...);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
|
|
|
/* Formatted print to file descriptor (variable argument list). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int vdprintf(int __fd,
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
2021-06-07 18:57:11 +02:00
|
|
|
|
2021-06-07 19:09:55 +02:00
|
|
|
/* Allocating sprintf(). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int asprintf(char ** __restrict__ __str,
|
|
|
|
char const * __restrict__ __format, ...);
|
2021-06-07 19:09:55 +02:00
|
|
|
|
|
|
|
/* Allocating vsprintf(). */
|
2021-06-13 16:51:47 +02:00
|
|
|
extern int vasprintf(char ** __restrict__ __str,
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
2021-06-07 19:09:55 +02:00
|
|
|
|
2022-08-13 00:01:00 +02:00
|
|
|
/* Formatted scan from file. */
|
|
|
|
extern int fscanf(FILE * __restrict__ __fp,
|
|
|
|
char const * __restrict__ __format, ...);
|
|
|
|
|
|
|
|
/* Formatted scan from stdin. */
|
|
|
|
extern int scanf(
|
|
|
|
char const * __restrict__ __format, ...);
|
|
|
|
|
|
|
|
/* Formatted scan from string. */
|
|
|
|
extern int sscanf(const char * __restrict__ __s,
|
|
|
|
char const * __restrict__ __format, ...);
|
|
|
|
|
|
|
|
/* Formatted scan from file (variable argument list). */
|
|
|
|
extern int vfscanf(FILE * __restrict__ __fp,
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
|
|
|
|
|
|
|
/* Formatted scan from stdin (variable argument list). */
|
|
|
|
extern int vscanf(
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
|
|
|
|
|
|
|
/* Formatted scan from string (variable argument list). */
|
|
|
|
extern int vsscanf(char const * __restrict__ __s,
|
|
|
|
char const * __restrict__ __format, va_list __args);
|
|
|
|
|
2022-01-02 22:09:06 +01:00
|
|
|
/*
|
2022-01-05 21:25:41 +01:00
|
|
|
** Character input/output functions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Read a character from a stream. */
|
|
|
|
extern int fgetc(FILE *__fp);
|
|
|
|
|
|
|
|
/* Read at most n characters from a stream, stopping after a newline. */
|
|
|
|
extern char *fgets(char * __restrict__ __s, int __n,
|
|
|
|
FILE * __restrict__ __fp);
|
|
|
|
|
|
|
|
/* Write a character to a stream. */
|
|
|
|
extern int fputc(int __c, FILE *__fp);
|
|
|
|
|
|
|
|
/* Write a string to a stream (excluding the NUL nyte). */
|
2022-03-31 11:12:01 +02:00
|
|
|
extern int fputs(char const * __restrict__ __s, FILE * __restrict__ __fp);
|
2022-01-05 21:25:41 +01:00
|
|
|
|
|
|
|
extern int getc(FILE *__fp);
|
|
|
|
#define getc fgetc
|
|
|
|
|
|
|
|
/* Get a character from stdin */
|
|
|
|
extern int getchar(void);
|
|
|
|
#define getchar() fgetc(stdin)
|
|
|
|
|
|
|
|
/* (DEPRECATED; use fgets() instead) Read a string from stdin. */
|
|
|
|
extern char *gets(char *__s);
|
|
|
|
|
2022-03-31 11:12:01 +02:00
|
|
|
/* Get a line from stream, with dynamic allocation */
|
|
|
|
extern ssize_t getline(char ** __restrict__ __lineptr,
|
|
|
|
size_t * __restrict__ __n, FILE * __restrict__ __fp);
|
2022-03-29 23:47:22 +02:00
|
|
|
|
2022-03-31 11:12:01 +02:00
|
|
|
/* Like getline but with [delim] instead of '\n' */
|
|
|
|
extern ssize_t getdelim(char ** __restrict__ __lineptr,
|
|
|
|
size_t * __restrict__ __n, int __delim, FILE * __restrict__ __fp);
|
2022-03-29 23:47:22 +02:00
|
|
|
|
2022-01-05 21:25:41 +01:00
|
|
|
extern int putc(int __c, FILE *__fp);
|
|
|
|
#define putc fputc
|
|
|
|
|
|
|
|
/* Write a character to stdout */
|
|
|
|
extern int putchar(int __c);
|
|
|
|
#define putchar(__c) fputc(__c, stdout)
|
|
|
|
|
|
|
|
/* Write a string to stdout, followed by a newline */
|
|
|
|
extern int puts(char const *__s);
|
|
|
|
|
|
|
|
/* Un-read a character back to the stream; only one ungetc() is guaranteed, and
|
|
|
|
the character is lost after reading, writing or flushing. */
|
|
|
|
extern int ungetc(int __c, FILE *__fp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Direct input/output functions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Read an array of items from a stream. */
|
|
|
|
extern size_t fread(void * __restrict__ __ptr, size_t __size, size_t __nmemb,
|
|
|
|
FILE * __restrict__ __fp);
|
|
|
|
|
|
|
|
/* Write an array of items to a stream. */
|
|
|
|
extern size_t fwrite(void const * __restrict__ __ptr, size_t __size,
|
|
|
|
size_t __nmemb, FILE * __restrict__ __fp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
** File positioning functions.
|
2022-01-02 22:09:06 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Get current position (same as ftell() unless wide-oriented). */
|
|
|
|
extern int fgetpos(FILE * __restrict__ __fp, fpos_t * __restrict__ __pos);
|
|
|
|
|
|
|
|
/* Set the current position. */
|
|
|
|
extern int fseek(FILE *__fp, long __offset, int __whence);
|
|
|
|
|
|
|
|
/* Restore the position to a value returned by fgetpos(). */
|
|
|
|
extern int fsetpos(FILE *__fp, fpos_t const *__pos);
|
|
|
|
|
|
|
|
/* Get the current position. */
|
|
|
|
extern long ftell(FILE *__fp);
|
|
|
|
|
|
|
|
/* Sets the file position to the start of the stream. */
|
|
|
|
extern void rewind(FILE *__fp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Error-handling functions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Clear EOF and error flags in the stream. */
|
|
|
|
extern void clearerr(FILE *__fp);
|
|
|
|
|
|
|
|
/* Test the EOF flag. */
|
|
|
|
extern int feof(FILE *__fp);
|
|
|
|
|
|
|
|
/* Test the error flag. */
|
|
|
|
extern int ferror(FILE *__fp);
|
|
|
|
|
2022-01-12 10:20:12 +01:00
|
|
|
/* Print a message followed by strerror(errno) to stdout. */
|
|
|
|
extern void perror(char const *__s);
|
|
|
|
|
2021-06-28 15:49:05 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-05-09 23:00:11 +02:00
|
|
|
#endif /*__STDIO_H__*/
|