Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / stdio / local.h
blob63c0618f1baf34ca0c61182e968a1f51a1e8d776
1 /*
2 * Copyright (c) 1990, 2007 The Regents of the University of California.
3 * All rights reserved.
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.
25 #include <_ansi.h>
26 #include <reent.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #ifdef __SCLE
32 # include <io.h>
33 #endif
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
43 #endif
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
61 #endif
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)
73 #include <pthread.h>
75 /* Start a stream oriented critical section: */
76 # define _newlib_flockfile_start(_fp) \
77 { \
78 int __oldfpcancel; \
79 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldfpcancel); \
80 if (!(_fp->_flags2 & __SNLK)) \
81 _flockfile (_fp)
83 /* Exit from a stream oriented critical section prematurely: */
84 # define _newlib_flockfile_exit(_fp) \
85 if (!(_fp->_flags2 & __SNLK)) \
86 _funlockfile (_fp); \
87 pthread_setcancelstate (__oldfpcancel, &__oldfpcancel);
89 /* End a stream oriented critical section: */
90 # define _newlib_flockfile_end(_fp) \
91 if (!(_fp->_flags2 & __SNLK)) \
92 _funlockfile (_fp); \
93 pthread_setcancelstate (__oldfpcancel, &__oldfpcancel); \
96 /* Start a stream list oriented critical section: */
97 # define _newlib_sfp_lock_start() \
98 { \
99 int __oldsfpcancel; \
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)) \
119 _flockfile (_fp)
121 # define _newlib_flockfile_exit(_fp) \
122 if (!(_fp->_flags2 & __SNLK)) \
123 _funlockfile(_fp); \
125 # define _newlib_flockfile_end(_fp) \
126 if (!(_fp->_flags2 & __SNLK)) \
127 _funlockfile(_fp); \
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 *,
155 va_list)
156 _ATTRIBUTE ((__format__ (__printf__, 3, 0)));
157 int _svfiprintf_r (struct _reent *, FILE *, const char *,
158 va_list)
159 _ATTRIBUTE ((__format__ (__printf__, 3, 0)));
160 int _svfwprintf_r (struct _reent *, FILE *, const wchar_t *,
161 va_list);
162 int _svfiwprintf_r (struct _reent *, FILE *, const wchar_t *,
163 va_list);
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 *);
169 #endif
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 *,
174 char *,
175 _READ_WRITE_BUFSIZE_TYPE);
176 extern _READ_WRITE_RETURN_TYPE __swrite (struct _reent *, void *,
177 const char *,
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 *,
190 const char *,
191 _READ_WRITE_BUFSIZE_TYPE);
192 #endif
194 /* Called by the main entry point fns to ensure stdio has been initialized. */
196 #define CHECK_INIT(ptr, fp) \
197 do \
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); \
204 while (0)
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; }
229 #ifdef _WIDE_ORIENT
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), \
242 (ori > 0) ? \
243 ((fp)->_flags2 |= __SWID) \
245 ((fp)->_flags2 &= ~__SWID) \
247 ), \
248 ((fp)->_flags2 & __SWID) ? 1 : -1 \
250 #else
251 #define ORIENT(fp,ori) (-1)
252 #endif
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 *);
257 #ifdef __GNUC__
258 _ELIDABLE_INLINE int __swputc_r(struct _reent *_ptr, int _c, FILE *_p) {
259 #ifdef __SCLE
260 if ((_p->_flags & __SCLE) && _c == '\n')
261 __swputc_r (_ptr, '\r', _p);
262 #endif
263 if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
264 return (*_p->_p++ = _c);
265 else
266 return (__swbufw_r(_ptr, _c, _p));
268 #else
269 #define __swputc_raw_r(__ptr, __c, __p) \
270 (--(__p)->_w < 0 ? \
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++))
277 #ifdef __SCLE
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)))
282 #else
283 #define __swputc_r(__ptr, __c, __p) __swputc_raw_r(__ptr, __c, __p)
284 #endif
285 #endif
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);
293 #ifdef __GNUC__
294 char *_llicvt (char *, long long, char);
295 #endif
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()
306 #else
307 void __sfp_lock_acquire (void);
308 void __sfp_lock_release (void);
309 #endif
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 {
315 ZERO, /* '0' */
316 DIGIT, /* '1-9' */
317 DOLLAR, /* '$' */
318 MODFR, /* spec modifier */
319 SPEC, /* format specifier */
320 DOT, /* '.' */
321 STAR, /* '*' */
322 FLAG, /* format flag */
323 OTHER, /* all other chars */
324 MAX_CH_CLASS /* place-holder */
325 } __CH_CLASS;
327 typedef enum __packed {
328 START, /* start */
329 SFLAG, /* seen a flag */
330 WDIG, /* seen digits in width area */
331 WIDTH, /* processed width */
332 SMOD, /* seen spec modifier */
333 SDOT, /* seen dot */
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 */
339 DONE, /* done */
340 MAX_STATE, /* place-holder */
341 } __STATE;
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 */
353 } __ACTION;
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];