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