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