1 /* Copyright (c) 2002, 2005, 2007 Joerg Wunsch
2    All rights reserved.
3 
4    Portions of documentation Copyright (c) 1990, 1991, 1993
5    The Regents of the University of California.
6 
7    All rights reserved.
8 
9    Redistribution and use in source and binary forms, with or without
10    modification, are permitted provided that the following conditions are met:
11 
12    * Redistributions of source code must retain the above copyright
13      notice, this list of conditions and the following disclaimer.
14 
15    * Redistributions in binary form must reproduce the above copyright
16      notice, this list of conditions and the following disclaimer in
17      the documentation and/or other materials provided with the
18      distribution.
19 
20    * Neither the name of the copyright holders nor the names of
21      contributors may be used to endorse or promote products derived
22      from this software without specific prior written permission.
23 
24   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34   POSSIBILITY OF SUCH DAMAGE.
35 
36   $Id: stdio.h 2527 2016-10-27 20:41:22Z joerg_wunsch $
37 */
38 
39 #ifndef _STDIO_H_
40 #define	_STDIO_H_ 1
41 
42 #include "_ansi.h"
43 
44 #define __need_NULL
45 #define __need_size_t
46 #define __need_ssize_t
47 #include <sys/cdefs.h>
48 #include <stddef.h>
49 
50 #include <inttypes.h>
51 #include <stdarg.h>
52 #include <sys/types.h>
53 
54 /*
55  * This is an internal structure of the library that is subject to be
56  * changed without warnings at any time.  Please do *never* reference
57  * elements of it beyond by using the official interfaces provided.
58  */
59 
60 #ifdef ATOMIC_UNGETC
61 #if defined(__riscv) || defined(__MICROBLAZE__)
62 /*
63  * Use 32-bit ungetc storage when doing atomic ungetc on RISC-V and
64  * MicroBlaze, which have 4-byte swap intrinsics but not 2-byte swap
65  * intrinsics. This increases the size of the __file struct by four
66  * bytes.
67  */
68 #define __PICOLIBC_UNGETC_SIZE	4
69 #endif
70 #endif
71 
72 #ifndef __PICOLIBC_UNGETC_SIZE
73 #define __PICOLIBC_UNGETC_SIZE	2
74 #endif
75 
76 #if __PICOLIBC_UNGETC_SIZE == 4
77 typedef uint32_t __ungetc_t;
78 #endif
79 
80 #if __PICOLIBC_UNGETC_SIZE == 2
81 typedef uint16_t __ungetc_t;
82 #endif
83 
84 struct __file {
85 	__ungetc_t unget;	/* ungetc() buffer */
86 	uint8_t	flags;		/* flags, see below */
87 #define __SRD	0x0001		/* OK to read */
88 #define __SWR	0x0002		/* OK to write */
89 #define __SERR	0x0004		/* found error */
90 #define __SEOF	0x0008		/* found EOF */
91 #define __SCLOSE 0x0010		/* struct is __file_close */
92 #define __SEXT  0x0020          /* struct is __file_ext */
93 #define __SBUF  0x0040          /* struct is __file_bufio */
94 #define __SWIDE 0x0080          /* wchar output mode */
95 	int	(*put)(char, struct __file *);	/* function to write one char to device */
96 	int	(*get)(struct __file *);	/* function to read one char from device */
97 	int	(*flush)(struct __file *);	/* function to flush output to device */
98 };
99 
100 /*
101  * This variant includes a 'close' function which is
102  * invoked from fclose when the __SCLOSE bit is set
103  */
104 struct __file_close {
105 	struct __file file;			/* main file struct */
106 	int	(*close)(struct __file *);	/* function to close file */
107 };
108 
109 #define FDEV_SETUP_CLOSE(put, get, flush, _close, rwflag) \
110         {                                                               \
111                 .file = FDEV_SETUP_STREAM(put, get, flush, (rwflag) | __SCLOSE),   \
112                 .close = (_close),                                      \
113         }
114 
115 struct __file_ext {
116         struct __file_close cfile;              /* close file struct */
117         __off_t (*seek)(struct __file *, __off_t offset, int whence);
118         int     (*setvbuf)(struct __file *, char *buf, int mode, size_t size);
119 };
120 
121 #define FDEV_SETUP_EXT(put, get, flush, close, _seek, _setvbuf, rwflag) \
122         {                                                               \
123                 .cfile = FDEV_SETUP_CLOSE(put, get, flush, close, (rwflag) | __SEXT), \
124                 .seek = (_seek),                                        \
125                 .setvbuf = (_setvbuf),                                  \
126         }
127 
128 /*@{*/
129 /**
130    \c FILE is the opaque structure that is passed around between the
131    various standard IO functions.
132 */
133 typedef struct __file __FILE;
134 #if !defined(__FILE_defined)
135 typedef __FILE FILE;
136 # define __FILE_defined
137 #endif
138 
139 /**
140    This symbol is defined when stdin/stdout/stderr are global
141    variables. When undefined, the old __iob array is used which
142    contains the pointers instead
143 */
144 #define PICOLIBC_STDIO_GLOBALS
145 
146 extern FILE *const stdin;
147 extern FILE *const stdout;
148 extern FILE *const stderr;
149 
150 /* The stdin, stdout, and stderr symbols are described as macros in the C
151  * standard. */
152 #define stdin stdin
153 #define stdout stdout
154 #define stderr stderr
155 
156 #define EOF	(-1)
157 
158 #define	_IOFBF	0		/* setvbuf should set fully buffered */
159 #define	_IOLBF	1		/* setvbuf should set line buffered */
160 #define	_IONBF	2		/* setvbuf should set unbuffered */
161 
162 #define fdev_setup_stream(stream, p, g, fl, f)	\
163 	do { \
164 		(stream)->flags = f; \
165 		(stream)->put = p; \
166 		(stream)->get = g; \
167 		(stream)->flush = fl; \
168 	} while(0)
169 
170 #define _FDEV_SETUP_READ  __SRD	/**< fdev_setup_stream() with read intent */
171 #define _FDEV_SETUP_WRITE __SWR	/**< fdev_setup_stream() with write intent */
172 #define _FDEV_SETUP_RW    (__SRD|__SWR)	/**< fdev_setup_stream() with read/write intent */
173 
174 /**
175  * Return code for an error condition during device read.
176  *
177  * To be used in the get function of fdevopen().
178  */
179 #define _FDEV_ERR (-1)
180 
181 /**
182  * Return code for an end-of-file condition during device read.
183  *
184  * To be used in the get function of fdevopen().
185  */
186 #define _FDEV_EOF (-2)
187 
188 #define FDEV_SETUP_STREAM(p, g, fl, f)		\
189 	{ \
190                 .flags = (f),                   \
191                 .put = (p),                     \
192                 .get = (g),                     \
193                 .flush = (fl),                  \
194 	}
195 
196 #ifdef __cplusplus
197 extern "C" {
198 #endif
199 
200 FILE *fdevopen(int (*__put)(char, FILE*), int (*__get)(FILE*), int(*__flush)(FILE *));
201 int	fclose(FILE *__stream);
202 int	fflush(FILE *stream);
203 
204 # define fdev_close(f) (fflush(f))
205 
206 #ifdef _HAVE_FORMAT_ATTRIBUTE
207 #ifdef PICOLIBC_FLOAT_PRINTF_SCANF
208 #pragma GCC diagnostic ignored "-Wformat"
209 #define __FORMAT_ATTRIBUTE__(__a, __s, __f) __attribute__((__format__ (__a, __s, 0)))
210 #else
211 #define __FORMAT_ATTRIBUTE__(__a, __s, __f) __attribute__((__format__ (__a, __s, __f)))
212 #endif
213 #else
214 #define __FORMAT_ATTRIBUTE__(__a, __s, __f)
215 #endif
216 
217 #define __PRINTF_ATTRIBUTE__(__s, __f) __FORMAT_ATTRIBUTE__(printf, __s, __f)
218 #define __SCANF_ATTRIBUTE__(__s, _f) __FORMAT_ATTRIBUTE__(scanf, __s, __f)
219 
220 int	fputc(int __c, FILE *__stream);
221 int	putc(int __c, FILE *__stream);
222 int	putchar(int __c);
223 #define putc(__c, __stream) fputc(__c, __stream)
224 #define putchar(__c) fputc(__c, stdout)
225 
226 int	printf(const char *__fmt, ...) __PRINTF_ATTRIBUTE__(1, 2);
227 int	fprintf(FILE *__stream, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(2, 3);
228 int	vprintf(const char *__fmt, va_list __ap) __PRINTF_ATTRIBUTE__(1, 0);
229 int	vfprintf(FILE *__stream, const char *__fmt, va_list __ap) __PRINTF_ATTRIBUTE__(2, 0);
230 int	sprintf(char *__s, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(2, 3);
231 int	snprintf(char *__s, size_t __n, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(3, 4);
232 int	vsprintf(char *__s, const char *__fmt, va_list ap) __PRINTF_ATTRIBUTE__(2, 0);
233 int	vsnprintf(char *__s, size_t __n, const char *__fmt, va_list ap) __PRINTF_ATTRIBUTE__(3, 0);
234 int     asprintf(char **strp, const char *fmt, ...) __PRINTF_ATTRIBUTE__(2,3);
235 int     vasprintf(char **strp, const char *fmt, va_list ap) __PRINTF_ATTRIBUTE__(2,0);
236 
237 int	fputs(const char *__str, FILE *__stream);
238 int	puts(const char *__str);
239 size_t	fwrite(const void *__ptr, size_t __size, size_t __nmemb,
240 		       FILE *__stream);
241 
242 int	fgetc(FILE *__stream);
243 int	getc(FILE *__stream);
244 int	getchar(void);
245 #define getc(__stream) fgetc(__stream)
246 #define getchar() fgetc(stdin)
247 int	ungetc(int __c, FILE *__stream);
248 
249 int	scanf(const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 1, 2);
250 int	fscanf(FILE *__stream, const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 2, 3);
251 int	vscanf(const char *__fmt, va_list __ap) __FORMAT_ATTRIBUTE__(scanf, 1, 0);
252 int	vfscanf(FILE *__stream, const char *__fmt, va_list __ap) __FORMAT_ATTRIBUTE__(scanf, 2, 0);
253 int	sscanf(const char *__buf, const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 2, 3);
254 int	vsscanf(const char *__buf, const char *__fmt, va_list ap) __FORMAT_ATTRIBUTE__(scanf, 2, 0);
255 
256 char	*fgets(char *__str, int __size, FILE *__stream);
257 char	*gets(char *__str);
258 size_t	fread(void *__ptr, size_t __size, size_t __nmemb,
259 		      FILE *__stream);
260 
261 void	clearerr(FILE *__stream);
262 
263 /* fast inlined version of clearerr() */
264 #define clearerr(s) ((s)->flags &= ~(__SERR | __SEOF))
265 
266 int	feof(FILE *__stream);
267 
268 /* fast inlined version of feof() */
269 #define feof(s) ((s)->flags & __SEOF)
270 
271 int	ferror(FILE *__stream);
272 
273 /* fast inlined version of ferror() */
274 #define ferror(s) ((s)->flags & __SERR)
275 
276 #ifndef SEEK_SET
277 #define	SEEK_SET	0	/* set file offset to offset */
278 #endif
279 #ifndef SEEK_CUR
280 #define	SEEK_CUR	1	/* set file offset to current plus offset */
281 #endif
282 #ifndef SEEK_END
283 #define	SEEK_END	2	/* set file offset to EOF plus offset */
284 #endif
285 
286 /* only mentioned for libstdc++ support, not implemented in library */
287 #ifndef BUFSIZ
288 #define BUFSIZ 512
289 #endif
290 
291 /*
292  * We don't have any way of knowing any underlying POSIX limits,
293  * so just use a reasonably small values here
294  */
295 #ifndef FOPEN_MAX
296 #define FOPEN_MAX 32
297 #endif
298 #ifndef FILENAME_MAX
299 #define FILENAME_MAX 1024
300 #endif
301 
302 __extension__ typedef _fpos_t fpos_t;
303 int fgetpos(FILE *stream, fpos_t *pos);
304 FILE *fopen(const char *path, const char *mode) __malloc_like_with_free(fclose, 1);
305 FILE *freopen(const char *path, const char *mode, FILE *stream);
306 FILE *fdopen(int, const char *) __malloc_like_with_free(fclose, 1);
307 FILE *fmemopen(void *buf, size_t size, const char *mode) __malloc_like_with_free(fclose, 1);
308 int fseek(FILE *stream, long offset, int whence);
309 int fseeko(FILE *stream, __off_t offset, int whence);
310 int fsetpos(FILE *stream, fpos_t *pos);
311 long ftell(FILE *stream);
312 __off_t ftello(FILE *stream);
313 int fileno(FILE *);
314 void perror(const char *s);
315 int remove(const char *pathname);
316 int rename(const char *oldpath, const char *newpath);
317 void rewind(FILE *stream);
318 void setbuf(FILE *stream, char *buf);
319 void setbuffer(FILE *stream, char *buf, size_t size);
320 void setlinebuf(FILE *stream);
321 int setvbuf(FILE *stream, char *buf, int mode, size_t size);
322 FILE *tmpfile(void);
323 char *tmpnam (char *s);
324 ssize_t getline(char **__restrict lineptr, size_t *__restrict n, FILE *__restrict stream);
325 ssize_t getdelim(char **__restrict lineptr, size_t *__restrict  n, int delim, FILE *__restrict stream);
326 
327 /*
328  * The format of tmpnam names is TXXXXXX, which works with mktemp
329  */
330 #define L_tmpnam        8
331 
332 /*
333  * tmpnam files are created in the current directory
334  */
335 #define P_tmpdir        ""
336 
337 /*
338  * We don't have any way of knowing any underlying POSIX limits,
339  * so just use a reasonably small value here
340  */
341 #define TMP_MAX         32
342 
343 #ifdef __cplusplus
344 }
345 #endif
346 
347 /*@}*/
348 
349 static __inline uint32_t
__printf_float(float f)350 __printf_float(float f)
351 {
352 	union {
353 		float		f;
354 		uint32_t	u;
355 	} u = { .f = f };
356 	return u.u;
357 }
358 
359 #if !defined(PICOLIBC_DOUBLE_PRINTF_SCANF) && \
360     !defined(PICOLIBC_FLOAT_PRINTF_SCANF) && \
361     !defined(PICOLIBC_LONG_LONG_PRINTF_SCANF) && \
362     !defined(PICOLIBC_INTEGER_PRINTF_SCANF) && \
363     !defined(PICOLIBC_MINIMAL_PRINTF_SCANF)
364 #if defined(_FORMAT_DEFAULT_FLOAT)
365 #define PICOLIBC_FLOAT_PRINTF_SCANF
366 #elif defined(_FORMAT_DEFAULT_LONG_LONG)
367 #define PICOLIBC_LONG_LONG_PRINTF_SCANF
368 #elif defined(_FORMAT_DEFAULT_INTEGER)
369 #define PICOLIBC_INTEGER_PRINTF_SCANF
370 #elif defined(_FORMAT_DEFAULT_MINIMAL)
371 #define PICOLIBC_MINIMAL_PRINTF_SCANF
372 #else
373 #define PICOLIBC_DOUBLE_PRINTF_SCANF
374 #endif
375 #endif
376 
377 #if defined(PICOLIBC_MINIMAL_PRINTF_SCANF)
378 # define printf_float(x) ((double) (x))
379 # if defined(_WANT_MINIMAL_IO_LONG_LONG) || __SIZEOF_LONG_LONG__ == __SIZEOF_LONG__
380 #  define _HAS_IO_LONG_LONG
381 # endif
382 # ifdef _WANT_IO_C99_FORMATS
383 #  define _HAS_IO_C99_FORMATS
384 # endif
385 #elif defined(PICOLIBC_INTEGER_PRINTF_SCANF)
386 # define printf_float(x) ((double) (x))
387 # if defined(_WANT_IO_LONG_LONG) || __SIZEOF_LONG_LONG__ == __SIZEOF_LONG__
388 #  define _HAS_IO_LONG_LONG
389 # endif
390 # ifdef _WANT_IO_POS_ARGS
391 #  define _HAS_IO_POS_ARGS
392 # endif
393 # ifdef _WANT_IO_C99_FORMATS
394 #  define _HAS_IO_C99_FORMATS
395 # endif
396 # ifdef _WANT_IO_PERCENT_B
397 #  define _HAS_IO_PERCENT_B
398 # endif
399 #elif defined(PICOLIBC_LONG_LONG_PRINTF_SCANF)
400 # define printf_float(x) ((double) (x))
401 # define _HAS_IO_LONG_LONG
402 # ifdef _WANT_IO_POS_ARGS
403 #  define _HAS_IO_POS_ARGS
404 # endif
405 # ifdef _WANT_IO_C99_FORMATS
406 #  define _HAS_IO_C99_FORMATS
407 # endif
408 # ifdef _WANT_IO_PERCENT_B
409 #  define _HAS_IO_PERCENT_B
410 # endif
411 #elif defined(PICOLIBC_FLOAT_PRINTF_SCANF)
412 # define printf_float(x) __printf_float(x)
413 # define _HAS_IO_LONG_LONG
414 # define _HAS_IO_POS_ARGS
415 # define _HAS_IO_C99_FORMATS
416 # ifdef _WANT_IO_PERCENT_B
417 #  define _HAS_IO_PERCENT_B
418 # endif
419 # define _HAS_IO_FLOAT
420 #else
421 # define printf_float(x) ((double) (x))
422 # define _HAS_IO_LONG_LONG
423 # define _HAS_IO_POS_ARGS
424 # define _HAS_IO_C99_FORMATS
425 # define _HAS_IO_DOUBLE
426 # ifdef _WANT_IO_PERCENT_B
427 #  define _HAS_IO_PERCENT_B
428 # endif
429 # ifdef _WANT_IO_LONG_DOUBLE
430 #  define _HAS_IO_LONG_DOUBLE
431 # endif
432 #endif
433 
434 #if __SSP_FORTIFY_LEVEL > 0
435 #include <ssp/stdio.h>
436 #endif
437 
438 #endif /* _STDIO_H_ */
439