source: trunk/libs/newlib/src/newlib/libc/stdio/local.h @ 577

Last change on this file since 577 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 12.0 KB
Line 
1/*
2 * Copyright (c) 1990, 2007 The Regents of the University of California.
3 * All rights reserved.
4 *
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 * advertising materials, and 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.
16 *
17 *      %W% (UofMD/Berkeley) %G%
18 */
19
20/*
21 * Information local to this implementation of stdio,
22 * in particular, macros and private variables.
23 */
24
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
34
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
44
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.
50
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. */
57
58#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS) \
59    && !defined (__rtems__)
60#define _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
61#endif
62
63#if defined(__SINGLE_THREAD__) || defined(__IMPL_UNLOCKED__)
64
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()
71
72#elif defined(_STDIO_WITH_THREAD_CANCELLATION_SUPPORT)
73#include <pthread.h>
74
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)
82
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);
88
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); \
94        }
95
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 ()
102
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);
107
108/* End a stream list oriented critical section: */
109# define _newlib_sfp_lock_end() \
110          __sfp_lock_release (); \
111          pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel); \
112        }
113
114#else /* !__SINGLE_THREAD__ && !__IMPL_UNLOCKED__ && !_STDIO_WITH_THREAD_CANCELLATION_SUPPORT */
115
116# define _newlib_flockfile_start(_fp) \
117        { \
118                if (!(_fp->_flags2 & __SNLK)) \
119                  _flockfile (_fp)
120
121# define _newlib_flockfile_exit(_fp) \
122                if (!(_fp->_flags2 & __SNLK)) \
123                  _funlockfile(_fp); \
124
125# define _newlib_flockfile_end(_fp) \
126                if (!(_fp->_flags2 & __SNLK)) \
127                  _funlockfile(_fp); \
128        }
129
130# define _newlib_sfp_lock_start() \
131        { \
132                __sfp_lock_acquire ()
133
134# define _newlib_sfp_lock_exit() \
135                __sfp_lock_release ();
136
137# define _newlib_sfp_lock_end() \
138                __sfp_lock_release (); \
139        }
140
141#endif /* __SINGLE_THREAD__ || __IMPL_UNLOCKED__ */
142
143extern wint_t __fgetwc (struct _reent *, FILE *);
144extern wint_t __fputwc (struct _reent *, wchar_t, FILE *);
145extern u_char *__sccl (char *, u_char *fmt);
146extern int    __svfscanf_r (struct _reent *,FILE *, const char *,va_list);
147extern int    __ssvfscanf_r (struct _reent *,FILE *, const char *,va_list);
148extern int    __svfiscanf_r (struct _reent *,FILE *, const char *,va_list);
149extern int    __ssvfiscanf_r (struct _reent *,FILE *, const char *,va_list);
150extern int    __svfwscanf_r (struct _reent *,FILE *, const wchar_t *,va_list);
151extern int    __ssvfwscanf_r (struct _reent *,FILE *, const wchar_t *,va_list);
152extern int    __svfiwscanf_r (struct _reent *,FILE *, const wchar_t *,va_list);
153extern int    __ssvfiwscanf_r (struct _reent *,FILE *, const wchar_t *,va_list);
154int           _svfprintf_r (struct _reent *, FILE *, const char *, 
155                                  va_list)
156                                _ATTRIBUTE ((__format__ (__printf__, 3, 0)));
157int           _svfiprintf_r (struct _reent *, FILE *, const char *, 
158                                  va_list)
159                                _ATTRIBUTE ((__format__ (__printf__, 3, 0)));
160int           _svfwprintf_r (struct _reent *, FILE *, const wchar_t *, 
161                                  va_list);
162int           _svfiwprintf_r (struct _reent *, FILE *, const wchar_t *, 
163                                  va_list);
164extern FILE  *__sfp (struct _reent *);
165extern int    __sflags (struct _reent *,const char*, int*);
166extern int    __sflush_r (struct _reent *,FILE *);
167#ifdef _STDIO_BSD_SEMANTICS
168extern int    __sflushw_r (struct _reent *,FILE *);
169#endif
170extern int    __srefill_r (struct _reent *,FILE *);
171extern _READ_WRITE_RETURN_TYPE __sread (struct _reent *, void *, char *,
172                                               _READ_WRITE_BUFSIZE_TYPE);
173extern _READ_WRITE_RETURN_TYPE __seofread (struct _reent *, void *,
174                                                  char *,
175                                                  _READ_WRITE_BUFSIZE_TYPE);
176extern _READ_WRITE_RETURN_TYPE __swrite (struct _reent *, void *,
177                                                const char *,
178                                                _READ_WRITE_BUFSIZE_TYPE);
179extern _fpos_t __sseek (struct _reent *, void *, _fpos_t, int);
180extern int    __sclose (struct _reent *, void *);
181extern int    __stextmode (int);
182extern void   __sinit (struct _reent *);
183extern void   _cleanup_r (struct _reent *);
184extern void   __smakebuf_r (struct _reent *, FILE *);
185extern int    __swhatbuf_r (struct _reent *, FILE *, size_t *, int *);
186extern int    _fwalk (struct _reent *, int (*)(FILE *));
187extern int    _fwalk_reent (struct _reent *, int (*)(struct _reent *, FILE *));
188struct _glue * __sfmoreglue (struct _reent *,int n);
189extern int __submore (struct _reent *, FILE *);
190
191#ifdef __LARGE64_FILES
192extern _fpos64_t __sseek64 (struct _reent *, void *, _fpos64_t, int);
193extern _READ_WRITE_RETURN_TYPE __swrite64 (struct _reent *, void *,
194                                                  const char *,
195                                                  _READ_WRITE_BUFSIZE_TYPE);
196#endif
197
198/* Called by the main entry point fns to ensure stdio has been initialized.  */
199
200#ifdef _REENT_SMALL
201#define CHECK_INIT(ptr, fp) \
202  do                                                            \
203    {                                                           \
204      struct _reent *_check_init_ptr = (ptr);                   \
205      if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit)  \
206        __sinit (_check_init_ptr);                              \
207      if ((fp) == (FILE *)&__sf_fake_stdin)                     \
208        (fp) = _stdin_r(_check_init_ptr);                       \
209      else if ((fp) == (FILE *)&__sf_fake_stdout)               \
210        (fp) = _stdout_r(_check_init_ptr);                      \
211      else if ((fp) == (FILE *)&__sf_fake_stderr)               \
212        (fp) = _stderr_r(_check_init_ptr);                      \
213    }                                                           \
214  while (0)
215#else /* !_REENT_SMALL   */
216#define CHECK_INIT(ptr, fp) \
217  do                                                            \
218    {                                                           \
219      struct _reent *_check_init_ptr = (ptr);                   \
220      if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit)  \
221        __sinit (_check_init_ptr);                              \
222    }                                                           \
223  while (0)
224#endif /* !_REENT_SMALL  */
225
226#define CHECK_STD_INIT(ptr) \
227  do                                                            \
228    {                                                           \
229      struct _reent *_check_init_ptr = (ptr);                   \
230      if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit)  \
231        __sinit (_check_init_ptr);                              \
232    }                                                           \
233  while (0)
234
235/* Return true and set errno and stream error flag iff the given FILE
236   cannot be written now.  */
237
238#define cantwrite(ptr, fp)                                     \
239  ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
240   __swsetup_r(ptr, fp))
241
242/* Test whether the given stdio file has an active ungetc buffer;
243   release such a buffer, without restoring ordinary unread data.  */
244
245#define HASUB(fp) ((fp)->_ub._base != NULL)
246#define FREEUB(ptr, fp) {                    \
247        if ((fp)->_ub._base != (fp)->_ubuf) \
248                _free_r(ptr, (char *)(fp)->_ub._base); \
249        (fp)->_ub._base = NULL; \
250}
251
252/* Test for an fgetline() buffer.  */
253
254#define HASLB(fp) ((fp)->_lb._base != NULL)
255#define FREELB(ptr, fp) { _free_r(ptr,(char *)(fp)->_lb._base); \
256      (fp)->_lb._base = NULL; }
257
258#ifdef _WIDE_ORIENT
259/*
260 * Set the orientation for a stream. If o > 0, the stream has wide-
261 * orientation. If o < 0, the stream has byte-orientation.
262 */
263#define ORIENT(fp,ori)                                  \
264  do                                                            \
265    {                                                           \
266      if (!((fp)->_flags & __SORD))     \
267        {                                                       \
268          (fp)->_flags |= __SORD;                               \
269          if (ori > 0)                                          \
270            (fp)->_flags2 |= __SWID;                            \
271          else                                                  \
272            (fp)->_flags2 &= ~__SWID;                           \
273        }                                                       \
274    }                                                           \
275  while (0)
276#else
277#define ORIENT(fp,ori)
278#endif
279
280/* WARNING: _dcvt is defined in the stdlib directory, not here!  */
281
282char *_dcvt (struct _reent *, char *, double, int, int, char, int);
283char *_sicvt (char *, short, char);
284char *_icvt (char *, int, char);
285char *_licvt (char *, long, char);
286#ifdef __GNUC__
287char *_llicvt (char *, long long, char);
288#endif
289
290#define CVT_BUF_SIZE 128
291
292#define NDYNAMIC 4      /* add four more whenever necessary */
293
294#ifdef __SINGLE_THREAD__
295#define __sfp_lock_acquire()
296#define __sfp_lock_release()
297#define __sinit_lock_acquire()
298#define __sinit_lock_release()
299#else
300void __sfp_lock_acquire (void);
301void __sfp_lock_release (void);
302void __sinit_lock_acquire (void);
303void __sinit_lock_release (void);
304#endif
305
306/* Types used in positional argument support in vfprinf/vfwprintf.
307   The implementation is char/wchar_t dependent but the class and state
308   tables are only defined once in vfprintf.c. */
309typedef enum __packed {
310  ZERO,   /* '0' */
311  DIGIT,  /* '1-9' */
312  DOLLAR, /* '$' */
313  MODFR,  /* spec modifier */
314  SPEC,   /* format specifier */
315  DOT,    /* '.' */
316  STAR,   /* '*' */
317  FLAG,   /* format flag */
318  OTHER,  /* all other chars */
319  MAX_CH_CLASS /* place-holder */
320} __CH_CLASS;
321
322typedef enum __packed {
323  START,  /* start */
324  SFLAG,  /* seen a flag */
325  WDIG,   /* seen digits in width area */
326  WIDTH,  /* processed width */
327  SMOD,   /* seen spec modifier */
328  SDOT,   /* seen dot */
329  VARW,   /* have variable width specifier */
330  VARP,   /* have variable precision specifier */
331  PREC,   /* processed precision */
332  VWDIG,  /* have digits in variable width specification */
333  VPDIG,  /* have digits in variable precision specification */
334  DONE,   /* done */
335  MAX_STATE, /* place-holder */
336} __STATE;
337
338typedef enum __packed {
339  NOOP,  /* do nothing */
340  NUMBER, /* build a number from digits */
341  SKIPNUM, /* skip over digits */
342  GETMOD,  /* get and process format modifier */
343  GETARG,  /* get and process argument */
344  GETPW,   /* get variable precision or width */
345  GETPWB,  /* get variable precision or width and pushback fmt char */
346  GETPOS,  /* get positional parameter value */
347  PWPOS,   /* get positional parameter value for variable width or precision */
348} __ACTION;
349
350extern const __CH_CLASS __chclass[256];
351extern const __STATE __state_table[MAX_STATE][MAX_CH_CLASS];
352extern const __ACTION __action_table[MAX_STATE][MAX_CH_CLASS];
Note: See TracBrowser for help on using the repository browser.