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 #define EOF	(-1)
151 
152 #define	_IOFBF	0		/* setvbuf should set fully buffered */
153 #define	_IOLBF	1		/* setvbuf should set line buffered */
154 #define	_IONBF	2		/* setvbuf should set unbuffered */
155 
156 #define fdev_setup_stream(stream, p, g, fl, f)	\
157 	do { \
158 		(stream)->flags = f; \
159 		(stream)->put = p; \
160 		(stream)->get = g; \
161 		(stream)->flush = fl; \
162 	} while(0)
163 
164 #define _FDEV_SETUP_READ  __SRD	/**< fdev_setup_stream() with read intent */
165 #define _FDEV_SETUP_WRITE __SWR	/**< fdev_setup_stream() with write intent */
166 #define _FDEV_SETUP_RW    (__SRD|__SWR)	/**< fdev_setup_stream() with read/write intent */
167 
168 /**
169  * Return code for an error condition during device read.
170  *
171  * To be used in the get function of fdevopen().
172  */
173 #define _FDEV_ERR (-1)
174 
175 /**
176  * Return code for an end-of-file condition during device read.
177  *
178  * To be used in the get function of fdevopen().
179  */
180 #define _FDEV_EOF (-2)
181 
182 #define FDEV_SETUP_STREAM(p, g, fl, f)		\
183 	{ \
184                 .flags = (f),                   \
185                 .put = (p),                     \
186                 .get = (g),                     \
187                 .flush = (fl),                  \
188 	}
189 
190 #ifdef __cplusplus
191 extern "C" {
192 #endif
193 
194 FILE *fdevopen(int (*__put)(char, FILE*), int (*__get)(FILE*), int(*__flush)(FILE *));
195 int	fclose(FILE *__stream);
196 int	fflush(FILE *stream);
197 
198 # define fdev_close(f) (fflush(f))
199 
200 #ifdef _HAVE_FORMAT_ATTRIBUTE
201 #ifdef PICOLIBC_FLOAT_PRINTF_SCANF
202 #pragma GCC diagnostic ignored "-Wformat"
203 #define __FORMAT_ATTRIBUTE__(__a, __s, __f) __attribute__((__format__ (__a, __s, 0)))
204 #else
205 #define __FORMAT_ATTRIBUTE__(__a, __s, __f) __attribute__((__format__ (__a, __s, __f)))
206 #endif
207 #else
208 #define __FORMAT_ATTRIBUTE__(__a, __s, __f)
209 #endif
210 
211 #define __PRINTF_ATTRIBUTE__(__s, __f) __FORMAT_ATTRIBUTE__(printf, __s, __f)
212 #define __SCANF_ATTRIBUTE__(__s, _f) __FORMAT_ATTRIBUTE__(scanf, __s, __f)
213 
214 int	fputc(int __c, FILE *__stream);
215 int	putc(int __c, FILE *__stream);
216 int	putchar(int __c);
217 #define putc(__c, __stream) fputc(__c, __stream)
218 #define putchar(__c) fputc(__c, stdout)
219 
220 int	printf(const char *__fmt, ...) __PRINTF_ATTRIBUTE__(1, 2);
221 int	fprintf(FILE *__stream, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(2, 3);
222 int	vprintf(const char *__fmt, va_list __ap) __PRINTF_ATTRIBUTE__(1, 0);
223 int	vfprintf(FILE *__stream, const char *__fmt, va_list __ap) __PRINTF_ATTRIBUTE__(2, 0);
224 int	sprintf(char *__s, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(2, 3);
225 int	snprintf(char *__s, size_t __n, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(3, 4);
226 int	vsprintf(char *__s, const char *__fmt, va_list ap) __PRINTF_ATTRIBUTE__(2, 0);
227 int	vsnprintf(char *__s, size_t __n, const char *__fmt, va_list ap) __PRINTF_ATTRIBUTE__(3, 0);
228 int     asprintf(char **strp, const char *fmt, ...) __PRINTF_ATTRIBUTE__(2,3);
229 int     vasprintf(char **strp, const char *fmt, va_list ap) __PRINTF_ATTRIBUTE__(2,0);
230 
231 int	fputs(const char *__str, FILE *__stream);
232 int	puts(const char *__str);
233 size_t	fwrite(const void *__ptr, size_t __size, size_t __nmemb,
234 		       FILE *__stream);
235 
236 int	fgetc(FILE *__stream);
237 int	getc(FILE *__stream);
238 int	getchar(void);
239 #define getc(__stream) fgetc(__stream)
240 #define getchar() fgetc(stdin)
241 int	ungetc(int __c, FILE *__stream);
242 
243 int	scanf(const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 1, 2);
244 int	fscanf(FILE *__stream, const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 2, 3);
245 int	vscanf(const char *__fmt, va_list __ap) __FORMAT_ATTRIBUTE__(scanf, 1, 0);
246 int	vfscanf(FILE *__stream, const char *__fmt, va_list __ap) __FORMAT_ATTRIBUTE__(scanf, 2, 0);
247 int	sscanf(const char *__buf, const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 2, 3);
248 int	vsscanf(const char *__buf, const char *__fmt, va_list ap) __FORMAT_ATTRIBUTE__(scanf, 2, 0);
249 
250 char	*fgets(char *__str, int __size, FILE *__stream);
251 char	*gets(char *__str);
252 size_t	fread(void *__ptr, size_t __size, size_t __nmemb,
253 		      FILE *__stream);
254 
255 void	clearerr(FILE *__stream);
256 
257 /* fast inlined version of clearerr() */
258 #define clearerr(s) ((s)->flags &= ~(__SERR | __SEOF))
259 
260 int	feof(FILE *__stream);
261 
262 /* fast inlined version of feof() */
263 #define feof(s) ((s)->flags & __SEOF)
264 
265 int	ferror(FILE *__stream);
266 
267 /* fast inlined version of ferror() */
268 #define ferror(s) ((s)->flags & __SERR)
269 
270 #ifndef SEEK_SET
271 #define	SEEK_SET	0	/* set file offset to offset */
272 #endif
273 #ifndef SEEK_CUR
274 #define	SEEK_CUR	1	/* set file offset to current plus offset */
275 #endif
276 #ifndef SEEK_END
277 #define	SEEK_END	2	/* set file offset to EOF plus offset */
278 #endif
279 
280 /* only mentioned for libstdc++ support, not implemented in library */
281 #ifndef BUFSIZ
282 #define BUFSIZ 512
283 #endif
284 
285 __extension__ typedef _fpos_t fpos_t;
286 int fgetpos(FILE *stream, fpos_t *pos);
287 FILE *fopen(const char *path, const char *mode) __malloc_like_with_free(fclose, 1);
288 FILE *freopen(const char *path, const char *mode, FILE *stream);
289 FILE *fdopen(int, const char *) __malloc_like_with_free(fclose, 1);
290 FILE *fmemopen(void *buf, size_t size, const char *mode) __malloc_like_with_free(fclose, 1);
291 int fseek(FILE *stream, long offset, int whence);
292 int fseeko(FILE *stream, __off_t offset, int whence);
293 int fsetpos(FILE *stream, fpos_t *pos);
294 long ftell(FILE *stream);
295 __off_t ftello(FILE *stream);
296 int fileno(FILE *);
297 void perror(const char *s);
298 int remove(const char *pathname);
299 int rename(const char *oldpath, const char *newpath);
300 void rewind(FILE *stream);
301 void setbuf(FILE *stream, char *buf);
302 void setbuffer(FILE *stream, char *buf, size_t size);
303 void setlinebuf(FILE *stream);
304 int setvbuf(FILE *stream, char *buf, int mode, size_t size);
305 FILE *tmpfile(void);
306 char *tmpnam (char *s);
307 ssize_t getline(char **__restrict lineptr, size_t *__restrict n, FILE *__restrict stream);
308 ssize_t getdelim(char **__restrict lineptr, size_t *__restrict  n, int delim, FILE *__restrict stream);
309 
310 /*
311  * The format of tmpnam names is TXXXXXX, which works with mktemp
312  */
313 #define L_tmpnam        8
314 
315 /*
316  * tmpnam files are created in the current directory
317  */
318 #define P_tmpdir        ""
319 
320 /*
321  * We don't have any way of knowing any underlying POSIX limits,
322  * so just use a reasonably small value here
323  */
324 #define TMP_MAX         32
325 
326 #ifdef __cplusplus
327 }
328 #endif
329 
330 /*@}*/
331 
332 static __inline uint32_t
__printf_float(float f)333 __printf_float(float f)
334 {
335 	union {
336 		float		f;
337 		uint32_t	u;
338 	} u = { .f = f };
339 	return u.u;
340 }
341 
342 #ifdef PICOLIBC_FLOAT_PRINTF_SCANF
343 #define printf_float(x) __printf_float(x)
344 #else
345 #define printf_float(x) ((double) (x))
346 #endif
347 
348 #endif /* _STDIO_H_ */
349