Subversion Repositories Kolibri OS

Rev

Rev 4874 | Rev 6099 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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 
27
#include 
28
#include 
29
#include 
30
#include 
31
#ifdef __SCLE
32
# include 
33
#endif
34
 
4921 Serge 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
#ifndef __rtems__
42
#define _STDIO_CLOSE_PER_REENT_STD_STREAMS
43
#endif
4349 Serge 44
 
4921 Serge 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
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
64
#include 
65
 
66
/* Start a stream oriented critical section: */
67
# define _newlib_flockfile_start(_fp) \
68
	{ \
69
	  int __oldfpcancel; \
70
	  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldfpcancel); \
71
	  _flockfile (_fp)
72
 
73
/* Exit from a stream oriented critical section prematurely: */
74
# define _newlib_flockfile_exit(_fp) \
75
	  _funlockfile (_fp); \
76
	  pthread_setcancelstate (__oldfpcancel, &__oldfpcancel);
77
 
78
/* End a stream oriented critical section: */
79
# define _newlib_flockfile_end(_fp) \
80
	  _funlockfile (_fp); \
81
	  pthread_setcancelstate (__oldfpcancel, &__oldfpcancel); \
82
	}
83
 
84
/* Start a stream list oriented critical section: */
85
# define _newlib_sfp_lock_start() \
86
	{ \
87
	  int __oldsfpcancel; \
88
	  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldsfpcancel); \
89
	  __sfp_lock_acquire ()
90
 
91
/* Exit from a stream list oriented critical section prematurely: */
92
# define _newlib_sfp_lock_exit() \
93
	  __sfp_lock_release (); \
94
	  pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel);
95
 
96
/* End a stream list oriented critical section: */
97
# define _newlib_sfp_lock_end() \
98
	  __sfp_lock_release (); \
99
	  pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel); \
100
	}
101
 
102
#else /* !_STDIO_WITH_THREAD_CANCELLATION_SUPPORT */
103
 
104
# define _newlib_flockfile_start(_fp) \
105
	{ \
106
		_flockfile(_fp)
107
 
108
# define _newlib_flockfile_exit(_fp) \
109
		_funlockfile(_fp); \
110
 
111
# define _newlib_flockfile_end(_fp) \
112
		_funlockfile(_fp); \
113
	}
114
 
115
# define _newlib_sfp_lock_start() \
116
	{ \
117
		__sfp_lock_acquire ()
118
 
119
# define _newlib_sfp_lock_exit() \
120
		__sfp_lock_release ();
121
 
122
# define _newlib_sfp_lock_end() \
123
		__sfp_lock_release (); \
124
	}
125
 
126
#endif /* _STDIO_WITH_THREAD_CANCELLATION_SUPPORT */
127
 
4349 Serge 128
extern u_char *_EXFUN(__sccl, (char *, u_char *fmt));
129
extern int    _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list));
130
extern int    _EXFUN(__ssvfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list));
131
extern int    _EXFUN(__svfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list));
132
extern int    _EXFUN(__ssvfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list));
133
extern int    _EXFUN(__svfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list));
134
extern int    _EXFUN(__ssvfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list));
135
extern int    _EXFUN(__svfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list));
136
extern int    _EXFUN(__ssvfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list));
4921 Serge 137
int	      _EXFUN(_svfprintf_r,(struct _reent *, FILE *, const char *,
4349 Serge 138
				  va_list)
139
               			_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
4921 Serge 140
int	      _EXFUN(_svfiprintf_r,(struct _reent *, FILE *, const char *,
4349 Serge 141
				  va_list)
142
               			_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
4921 Serge 143
int	      _EXFUN(_svfwprintf_r,(struct _reent *, FILE *, const wchar_t *,
4349 Serge 144
				  va_list));
4921 Serge 145
int	      _EXFUN(_svfiwprintf_r,(struct _reent *, FILE *, const wchar_t *,
4349 Serge 146
				  va_list));
147
extern FILE  *_EXFUN(__sfp,(struct _reent *));
148
extern int    _EXFUN(__sflags,(struct _reent *,_CONST char*, int*));
149
extern int    _EXFUN(__sflush_r,(struct _reent *,FILE *));
150
extern int    _EXFUN(__srefill_r,(struct _reent *,FILE *));
151
extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *,
4921 Serge 152
					       _READ_WRITE_BUFSIZE_TYPE));
4349 Serge 153
extern _READ_WRITE_RETURN_TYPE _EXFUN(__seofread,(struct _reent *, void *,
4921 Serge 154
						  char *,
155
						  _READ_WRITE_BUFSIZE_TYPE));
4349 Serge 156
extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, void *,
4921 Serge 157
						const char *,
158
						_READ_WRITE_BUFSIZE_TYPE));
4349 Serge 159
extern _fpos_t _EXFUN(__sseek,(struct _reent *, void *, _fpos_t, int));
160
extern int    _EXFUN(__sclose,(struct _reent *, void *));
161
extern int    _EXFUN(__stextmode,(int));
162
extern _VOID   _EXFUN(__sinit,(struct _reent *));
163
extern _VOID   _EXFUN(_cleanup_r,(struct _reent *));
164
extern _VOID   _EXFUN(__smakebuf_r,(struct _reent *, FILE *));
165
extern int    _EXFUN(_fwalk,(struct _reent *, int (*)(FILE *)));
166
extern int    _EXFUN(_fwalk_reent,(struct _reent *, int (*)(struct _reent *, FILE *)));
167
struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n));
168
extern int _EXFUN(__submore, (struct _reent *, FILE *));
169
 
170
#ifdef __LARGE64_FILES
171
extern _fpos64_t _EXFUN(__sseek64,(struct _reent *, void *, _fpos64_t, int));
172
extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
4921 Serge 173
						  const char *,
174
						  _READ_WRITE_BUFSIZE_TYPE));
4349 Serge 175
#endif
176
 
177
/* Called by the main entry point fns to ensure stdio has been initialized.  */
178
 
179
#ifdef _REENT_SMALL
180
#define CHECK_INIT(ptr, fp) \
181
  do						\
182
    {						\
4921 Serge 183
      struct _reent *_check_init_ptr = (ptr);			\
184
      if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit)	\
185
	__sinit (_check_init_ptr);				\
4349 Serge 186
      if ((fp) == (FILE *)&__sf_fake_stdin)	\
4921 Serge 187
	(fp) = _stdin_r(_check_init_ptr);			\
4349 Serge 188
      else if ((fp) == (FILE *)&__sf_fake_stdout) \
4921 Serge 189
	(fp) = _stdout_r(_check_init_ptr);			\
4349 Serge 190
      else if ((fp) == (FILE *)&__sf_fake_stderr) \
4921 Serge 191
	(fp) = _stderr_r(_check_init_ptr);			\
4349 Serge 192
    }						\
193
  while (0)
194
#else /* !_REENT_SMALL   */
195
#define CHECK_INIT(ptr, fp) \
196
  do						\
197
    {						\
4921 Serge 198
      struct _reent *_check_init_ptr = (ptr);			\
199
      if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit)	\
200
	__sinit (_check_init_ptr);				\
4349 Serge 201
    }						\
202
  while (0)
203
#endif /* !_REENT_SMALL  */
204
 
205
#define CHECK_STD_INIT(ptr) \
206
  do						\
207
    {						\
4921 Serge 208
      struct _reent *_check_init_ptr = (ptr);			\
209
      if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit)	\
210
	__sinit (_check_init_ptr);				\
4349 Serge 211
    }						\
212
  while (0)
213
 
214
/* Return true and set errno and stream error flag iff the given FILE
215
   cannot be written now.  */
216
 
217
#define	cantwrite(ptr, fp)                                     \
218
  ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
219
   __swsetup_r(ptr, fp))
220
 
221
/* Test whether the given stdio file has an active ungetc buffer;
222
   release such a buffer, without restoring ordinary unread data.  */
223
 
224
#define	HASUB(fp) ((fp)->_ub._base != NULL)
225
#define	FREEUB(ptr, fp) {                    \
226
	if ((fp)->_ub._base != (fp)->_ubuf) \
227
		_free_r(ptr, (char *)(fp)->_ub._base); \
228
	(fp)->_ub._base = NULL; \
229
}
230
 
231
/* Test for an fgetline() buffer.  */
232
 
233
#define	HASLB(fp) ((fp)->_lb._base != NULL)
234
#define	FREELB(ptr, fp) { _free_r(ptr,(char *)(fp)->_lb._base); \
235
      (fp)->_lb._base = NULL; }
236
 
4921 Serge 237
#ifdef _WIDE_ORIENT
4349 Serge 238
/*
239
 * Set the orientation for a stream. If o > 0, the stream has wide-
240
 * orientation. If o < 0, the stream has byte-orientation.
241
 */
242
#define ORIENT(fp,ori)					\
243
  do								\
244
    {								\
245
      if (!((fp)->_flags & __SORD))	\
246
	{							\
247
	  (fp)->_flags |= __SORD;				\
248
	  if (ori > 0)						\
249
	    (fp)->_flags2 |= __SWID;				\
250
	  else							\
251
	    (fp)->_flags2 &= ~__SWID;				\
252
	}							\
253
    }								\
254
  while (0)
4921 Serge 255
#else
256
#define ORIENT(fp,ori)
257
#endif
4349 Serge 258
 
259
/* WARNING: _dcvt is defined in the stdlib directory, not here!  */
260
 
261
char *_EXFUN(_dcvt,(struct _reent *, char *, double, int, int, char, int));
262
char *_EXFUN(_sicvt,(char *, short, char));
263
char *_EXFUN(_icvt,(char *, int, char));
264
char *_EXFUN(_licvt,(char *, long, char));
265
#ifdef __GNUC__
266
char *_EXFUN(_llicvt,(char *, long long, char));
267
#endif
268
 
269
#define CVT_BUF_SIZE 128
270
 
271
#define	NDYNAMIC 4	/* add four more whenever necessary */
272
 
273
#ifdef __SINGLE_THREAD__
274
#define __sfp_lock_acquire()
275
#define __sfp_lock_release()
276
#define __sinit_lock_acquire()
277
#define __sinit_lock_release()
278
#else
279
_VOID _EXFUN(__sfp_lock_acquire,(_VOID));
280
_VOID _EXFUN(__sfp_lock_release,(_VOID));
281
_VOID _EXFUN(__sinit_lock_acquire,(_VOID));
282
_VOID _EXFUN(__sinit_lock_release,(_VOID));
283
#endif
284
 
285
/* Types used in positional argument support in vfprinf/vfwprintf.
286
   The implementation is char/wchar_t dependent but the class and state
287
   tables are only defined once in vfprintf.c. */
288
typedef enum {
289
  ZERO,   /* '0' */
290
  DIGIT,  /* '1-9' */
291
  DOLLAR, /* '$' */
292
  MODFR,  /* spec modifier */
293
  SPEC,   /* format specifier */
294
  DOT,    /* '.' */
295
  STAR,   /* '*' */
296
  FLAG,   /* format flag */
297
  OTHER,  /* all other chars */
298
  MAX_CH_CLASS /* place-holder */
299
} __CH_CLASS;
300
 
301
typedef enum {
302
  START,  /* start */
303
  SFLAG,  /* seen a flag */
304
  WDIG,   /* seen digits in width area */
305
  WIDTH,  /* processed width */
306
  SMOD,   /* seen spec modifier */
307
  SDOT,   /* seen dot */
308
  VARW,   /* have variable width specifier */
309
  VARP,   /* have variable precision specifier */
310
  PREC,   /* processed precision */
311
  VWDIG,  /* have digits in variable width specification */
312
  VPDIG,  /* have digits in variable precision specification */
313
  DONE,   /* done */
314
  MAX_STATE, /* place-holder */
315
} __STATE;
316
 
317
typedef enum {
318
  NOOP,  /* do nothing */
319
  NUMBER, /* build a number from digits */
320
  SKIPNUM, /* skip over digits */
321
  GETMOD,  /* get and process format modifier */
322
  GETARG,  /* get and process argument */
323
  GETPW,   /* get variable precision or width */
324
  GETPWB,  /* get variable precision or width and pushback fmt char */
325
  GETPOS,  /* get positional parameter value */
326
  PWPOS,   /* get positional parameter value for variable width or precision */
327
} __ACTION;
328
 
329
extern _CONST __CH_CLASS __chclass[256];
330
extern _CONST __STATE __state_table[MAX_STATE][MAX_CH_CLASS];
331
extern _CONST __ACTION __action_table[MAX_STATE][MAX_CH_CLASS];