2 * Copyright (c) 1990, 2007 The Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * and/or other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 * %W% (UofMD/Berkeley) %G%
21 * Information local to this implementation of stdio,
22 * in particular, macros and private variables.
35 /* The following define determines if the per-reent stdin, stdout and stderr
36 streams are closed during _reclaim_reent(). The stdin, stdout and stderr
37 streams are initialized to use file descriptors 0, 1 and 2 respectively. In
38 case _STDIO_CLOSE_PER_REENT_STD_STREAMS is defined these file descriptors
39 will be closed via close() provided the owner of the reent structure
40 triggerd the on demand reent initilization, see CHECK_INIT(). */
41 #if !defined(__tirtos__)
42 #define _STDIO_CLOSE_PER_REENT_STD_STREAMS
45 /* The following macros are supposed to replace calls to _flockfile/_funlockfile
46 and __sfp_lock_acquire/__sfp_lock_release. In case of multi-threaded
47 environments using pthreads, it's not sufficient to lock the stdio functions
48 against concurrent threads accessing the same data, the locking must also be
49 secured against thread cancellation.
51 The below macros have to be used in pairs. The _newlib_XXX_start macro
52 starts with a opening curly brace, the _newlib_XXX_end macro ends with a
53 closing curly brace, so the start macro and the end macro mark the code
54 start and end of a critical section. In case the code leaves the critical
55 section before reaching the end of the critical section's code end, use
56 the appropriate _newlib_XXX_exit macro. */
58 #if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS) \
59 && !defined (__rtems__)
60 #define _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
63 #if defined(__SINGLE_THREAD__) || defined(__IMPL_UNLOCKED__)
65 # define _newlib_flockfile_start(_fp)
66 # define _newlib_flockfile_exit(_fp)
67 # define _newlib_flockfile_end(_fp)
68 # define _newlib_sfp_lock_start()
69 # define _newlib_sfp_lock_exit()
70 # define _newlib_sfp_lock_end()
72 #elif defined(_STDIO_WITH_THREAD_CANCELLATION_SUPPORT)
75 /* Start a stream oriented critical section: */
76 # define _newlib_flockfile_start(_fp) \
79 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldfpcancel); \
80 if (!(_fp->_flags2 & __SNLK)) \
83 /* Exit from a stream oriented critical section prematurely: */
84 # define _newlib_flockfile_exit(_fp) \
85 if (!(_fp->_flags2 & __SNLK)) \
87 pthread_setcancelstate (__oldfpcancel, &__oldfpcancel);
89 /* End a stream oriented critical section: */
90 # define _newlib_flockfile_end(_fp) \
91 if (!(_fp->_flags2 & __SNLK)) \
93 pthread_setcancelstate (__oldfpcancel, &__oldfpcancel); \
96 /* Start a stream list oriented critical section: */
97 # define _newlib_sfp_lock_start() \
100 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldsfpcancel); \
101 __sfp_lock_acquire ()
103 /* Exit from a stream list oriented critical section prematurely: */
104 # define _newlib_sfp_lock_exit() \
105 __sfp_lock_release (); \
106 pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel);
108 /* End a stream list oriented critical section: */
109 # define _newlib_sfp_lock_end() \
110 __sfp_lock_release (); \
111 pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel); \
114 #else /* !__SINGLE_THREAD__ && !__IMPL_UNLOCKED__ && !_STDIO_WITH_THREAD_CANCELLATION_SUPPORT */
116 # define _newlib_flockfile_start(_fp) \
118 if (!(_fp->_flags2 & __SNLK)) \
121 # define _newlib_flockfile_exit(_fp) \
122 if (!(_fp->_flags2 & __SNLK)) \
125 # define _newlib_flockfile_end(_fp) \
126 if (!(_fp->_flags2 & __SNLK)) \
130 # define _newlib_sfp_lock_start() \
132 __sfp_lock_acquire ()
134 # define _newlib_sfp_lock_exit() \
135 __sfp_lock_release ();
137 # define _newlib_sfp_lock_end() \
138 __sfp_lock_release (); \
141 #endif /* __SINGLE_THREAD__ || __IMPL_UNLOCKED__ */
143 extern wint_t __fgetwc (struct _reent
*, FILE *);
144 extern wint_t __fputwc (struct _reent
*, wchar_t, FILE *);
145 extern u_char
*__sccl (char *, u_char
*fmt
);
146 extern int __svfscanf_r (struct _reent
*,FILE *, const char *,va_list);
147 extern int __ssvfscanf_r (struct _reent
*,FILE *, const char *,va_list);
148 extern int __svfiscanf_r (struct _reent
*,FILE *, const char *,va_list);
149 extern int __ssvfiscanf_r (struct _reent
*,FILE *, const char *,va_list);
150 extern int __svfwscanf_r (struct _reent
*,FILE *, const wchar_t *,va_list);
151 extern int __ssvfwscanf_r (struct _reent
*,FILE *, const wchar_t *,va_list);
152 extern int __svfiwscanf_r (struct _reent
*,FILE *, const wchar_t *,va_list);
153 extern int __ssvfiwscanf_r (struct _reent
*,FILE *, const wchar_t *,va_list);
154 int _svfprintf_r (struct _reent
*, FILE *, const char *,
156 _ATTRIBUTE ((__format__ (__printf__
, 3, 0)));
157 int _svfiprintf_r (struct _reent
*, FILE *, const char *,
159 _ATTRIBUTE ((__format__ (__printf__
, 3, 0)));
160 int _svfwprintf_r (struct _reent
*, FILE *, const wchar_t *,
162 int _svfiwprintf_r (struct _reent
*, FILE *, const wchar_t *,
164 extern FILE *__sfp (struct _reent
*);
165 extern int __sflags (struct _reent
*,const char*, int*);
166 extern int __sflush_r (struct _reent
*,FILE *);
167 #ifdef _STDIO_BSD_SEMANTICS
168 extern int __sflushw_r (struct _reent
*,FILE *);
170 extern int __srefill_r (struct _reent
*,FILE *);
171 extern _READ_WRITE_RETURN_TYPE
__sread (struct _reent
*, void *, char *,
172 _READ_WRITE_BUFSIZE_TYPE
);
173 extern _READ_WRITE_RETURN_TYPE
__seofread (struct _reent
*, void *,
175 _READ_WRITE_BUFSIZE_TYPE
);
176 extern _READ_WRITE_RETURN_TYPE
__swrite (struct _reent
*, void *,
178 _READ_WRITE_BUFSIZE_TYPE
);
179 extern _fpos_t
__sseek (struct _reent
*, void *, _fpos_t
, int);
180 extern int __sclose (struct _reent
*, void *);
181 extern int __stextmode (int);
182 extern void __sinit (struct _reent
*);
183 extern void __smakebuf_r (struct _reent
*, FILE *);
184 extern int __swhatbuf_r (struct _reent
*, FILE *, size_t *, int *);
185 extern int __submore (struct _reent
*, FILE *);
187 #ifdef __LARGE64_FILES
188 extern _fpos64_t
__sseek64 (struct _reent
*, void *, _fpos64_t
, int);
189 extern _READ_WRITE_RETURN_TYPE
__swrite64 (struct _reent
*, void *,
191 _READ_WRITE_BUFSIZE_TYPE
);
194 /* Called by the main entry point fns to ensure stdio has been initialized. */
196 #define CHECK_INIT(ptr, fp) \
199 struct _reent *_check_init_ptr = (ptr); \
200 if (!_REENT_IS_NULL(_check_init_ptr) && \
201 !_REENT_CLEANUP(_check_init_ptr)) \
202 __sinit (_check_init_ptr); \
206 /* Return true and set errno and stream error flag iff the given FILE
207 cannot be written now. */
209 #define cantwrite(ptr, fp) \
210 ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
211 __swsetup_r(ptr, fp))
213 /* Test whether the given stdio file has an active ungetc buffer;
214 release such a buffer, without restoring ordinary unread data. */
216 #define HASUB(fp) ((fp)->_ub._base != NULL)
217 #define FREEUB(ptr, fp) { \
218 if ((fp)->_ub._base != (fp)->_ubuf) \
219 _free_r(ptr, (char *)(fp)->_ub._base); \
220 (fp)->_ub._base = NULL; \
223 /* Test for an fgetline() buffer. */
225 #define HASLB(fp) ((fp)->_lb._base != NULL)
226 #define FREELB(ptr, fp) { _free_r(ptr,(char *)(fp)->_lb._base); \
227 (fp)->_lb._base = NULL; }
231 * Set the orientation for a stream. If o > 0, the stream has wide-
232 * orientation. If o < 0, the stream has byte-orientation.
234 #define ORIENT(fp,ori) \
237 ((fp)->_flags & __SORD) ? \
241 ((fp)->_flags |= __SORD), \
243 ((fp)->_flags2 |= __SWID) \
245 ((fp)->_flags2 &= ~__SWID) \
248 ((fp)->_flags2 & __SWID) ? 1 : -1 \
251 #define ORIENT(fp,ori) (-1)
254 /* Same thing as the functions in stdio.h, but these are to be called
255 from inside the wide-char functions. */
256 int __swbufw_r (struct _reent
*, int, FILE *);
258 _ELIDABLE_INLINE
int __swputc_r(struct _reent
*_ptr
, int _c
, FILE *_p
) {
260 if ((_p
->_flags
& __SCLE
) && _c
== '\n')
261 __swputc_r (_ptr
, '\r', _p
);
263 if (--_p
->_w
>= 0 || (_p
->_w
>= _p
->_lbfsize
&& (char)_c
!= '\n'))
264 return (*_p
->_p
++ = _c
);
266 return (__swbufw_r(_ptr
, _c
, _p
));
269 #define __swputc_raw_r(__ptr, __c, __p) \
271 (__p)->_w >= (__p)->_lbfsize ? \
272 (*(__p)->_p = (__c)), *(__p)->_p != '\n' ? \
273 (int)*(__p)->_p++ : \
274 __swbufw_r(__ptr, '\n', __p) : \
275 __swbufw_r(__ptr, (int)(__c), __p) : \
276 (*(__p)->_p = (__c), (int)*(__p)->_p++))
278 #define __swputc_r(__ptr, __c, __p) \
279 ((((__p)->_flags & __SCLE) && ((__c) == '\n')) \
280 ? __swputc_raw_r(__ptr, '\r', (__p)) : 0 , \
281 __swputc_raw_r((__ptr), (__c), (__p)))
283 #define __swputc_r(__ptr, __c, __p) __swputc_raw_r(__ptr, __c, __p)
287 /* WARNING: _dcvt is defined in the stdlib directory, not here! */
289 char *_dcvt (struct _reent
*, char *, double, int, int, char, int);
290 char *_sicvt (char *, short, char);
291 char *_icvt (char *, int, char);
292 char *_licvt (char *, long, char);
294 char *_llicvt (char *, long long, char);
297 #define CVT_BUF_SIZE 128
299 #define NDYNAMIC 4 /* add four more whenever necessary */
301 #ifdef __SINGLE_THREAD__
302 #define __sfp_lock_acquire()
303 #define __sfp_lock_release()
304 #define __sinit_lock_acquire()
305 #define __sinit_lock_release()
307 void __sfp_lock_acquire (void);
308 void __sfp_lock_release (void);
311 /* Types used in positional argument support in vfprinf/vfwprintf.
312 The implementation is char/wchar_t dependent but the class and state
313 tables are only defined once in vfprintf.c. */
314 typedef enum __packed
{
318 MODFR
, /* spec modifier */
319 SPEC
, /* format specifier */
322 FLAG
, /* format flag */
323 OTHER
, /* all other chars */
324 MAX_CH_CLASS
/* place-holder */
327 typedef enum __packed
{
329 SFLAG
, /* seen a flag */
330 WDIG
, /* seen digits in width area */
331 WIDTH
, /* processed width */
332 SMOD
, /* seen spec modifier */
334 VARW
, /* have variable width specifier */
335 VARP
, /* have variable precision specifier */
336 PREC
, /* processed precision */
337 VWDIG
, /* have digits in variable width specification */
338 VPDIG
, /* have digits in variable precision specification */
340 MAX_STATE
, /* place-holder */
343 typedef enum __packed
{
344 NOOP
, /* do nothing */
345 NUMBER
, /* build a number from digits */
346 SKIPNUM
, /* skip over digits */
347 GETMOD
, /* get and process format modifier */
348 GETARG
, /* get and process argument */
349 GETPW
, /* get variable precision or width */
350 GETPWB
, /* get variable precision or width and pushback fmt char */
351 GETPOS
, /* get positional parameter value */
352 PWPOS
, /* get positional parameter value for variable width or precision */
355 extern const __CH_CLASS __chclass
[256];
356 extern const __STATE __state_table
[MAX_STATE
][MAX_CH_CLASS
];
357 extern const __ACTION __action_table
[MAX_STATE
][MAX_CH_CLASS
];