1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2012 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
19da2e3ebdSchin *                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebdSchin *                                                                      *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #ifndef _SFHDR_H
23da2e3ebdSchin #define _SFHDR_H	1
24da2e3ebdSchin #if !defined(_BLD_sfio) && !defined(_BLD_stdio)
25da2e3ebdSchin #define _BLD_sfio	1
26da2e3ebdSchin #endif
27da2e3ebdSchin 
28da2e3ebdSchin /*	Internal definitions for sfio.
29da2e3ebdSchin **	Written by Kiem-Phong Vo
30da2e3ebdSchin */
31da2e3ebdSchin 
32da2e3ebdSchin #define _next		next
33da2e3ebdSchin #define _endw		endw
34da2e3ebdSchin #define _endr		endr
35da2e3ebdSchin #define _endb		endb
36da2e3ebdSchin #define _push		push
37da2e3ebdSchin #define _flags		flags
38da2e3ebdSchin #define _file		file
39da2e3ebdSchin #define _data		data
40da2e3ebdSchin #define _size		size
41da2e3ebdSchin #define _val		val
42da2e3ebdSchin 
43da2e3ebdSchin #include	"FEATURE/sfio"
44da2e3ebdSchin #include	"FEATURE/mmap"
45da2e3ebdSchin 
46da2e3ebdSchin /* define va_list, etc. before including sfio_t.h (sfio.h) */
47da2e3ebdSchin #if !_PACKAGE_ast
48da2e3ebdSchin 
49da2e3ebdSchin /* some systems don't know large files */
50da2e3ebdSchin #if defined(_NO_LARGEFILE64_SOURCE) || _mips == 2 /* || __hppa */
51da2e3ebdSchin #undef _NO_LARGEFILE64_SOURCE
52da2e3ebdSchin #define _NO_LARGEFILE64_SOURCE	1
53da2e3ebdSchin #undef	_LARGEFILE64_SOURCE
54da2e3ebdSchin #undef	_LARGEFILE_SOURCE
55da2e3ebdSchin #endif
56da2e3ebdSchin 
57da2e3ebdSchin #if !_NO_LARGEFILE64_SOURCE && _typ_off64_t && _lib_lseek64 && _lib_stat64
58da2e3ebdSchin #undef	_LARGEFILE64_SOURCE
59da2e3ebdSchin #undef	_LARGEFILE_SOURCE
60da2e3ebdSchin #undef	_FILE_OFFSET_BITS
61da2e3ebdSchin #define _LARGEFILE64_SOURCE	1	/* enabling the *64 stuff */
62da2e3ebdSchin #define _LARGEFILE_SOURCE	1
63da2e3ebdSchin #endif
64da2e3ebdSchin 
65da2e3ebdSchin #if _hdr_stdarg
66da2e3ebdSchin #include	<stdarg.h>
67da2e3ebdSchin #else
68da2e3ebdSchin #include	<varargs.h>
69da2e3ebdSchin #endif
70da2e3ebdSchin #include	"FEATURE/common"
71da2e3ebdSchin #if !__STD_C
72da2e3ebdSchin #define const
73da2e3ebdSchin #endif
74da2e3ebdSchin #endif /* !_PACKAGE_ast */
75da2e3ebdSchin 
76da2e3ebdSchin #include	"sfio_t.h"
77da2e3ebdSchin 
78da2e3ebdSchin /* note that the macro vt_threaded has effect on vthread.h */
79da2e3ebdSchin #include	<vthread.h>
80da2e3ebdSchin 
81da2e3ebdSchin /* file system info */
82da2e3ebdSchin #if _PACKAGE_ast
83da2e3ebdSchin 
84da2e3ebdSchin #include	<ast.h>
85da2e3ebdSchin #include	<ast_time.h>
86da2e3ebdSchin #include	<ast_tty.h>
87da2e3ebdSchin #include	<ls.h>
88da2e3ebdSchin 
89da2e3ebdSchin /* ast always provides multibyte handling */
90da2e3ebdSchin #undef _hdr_wchar
91da2e3ebdSchin #undef _lib_mbrtowc
92da2e3ebdSchin #undef _lib_wcrtomb
93da2e3ebdSchin #define _hdr_wchar	1
94da2e3ebdSchin #define _lib_mbrtowc	1
95da2e3ebdSchin #define _lib_wcrtomb	1
96da2e3ebdSchin 
97da2e3ebdSchin #if _mem_st_blksize_stat
98da2e3ebdSchin #define _stat_blksize	1
99da2e3ebdSchin #endif
100da2e3ebdSchin 
101da2e3ebdSchin #if _lib_localeconv && _hdr_locale
102da2e3ebdSchin #define _lib_locale	1
103da2e3ebdSchin #endif
104da2e3ebdSchin 
105da2e3ebdSchin #define sfoff_t		off_t
106da2e3ebdSchin #define sfstat_t	struct stat
107da2e3ebdSchin #define sysclosef	close
108da2e3ebdSchin #define syscreatf	creat
109da2e3ebdSchin #define sysdupf		dup
110da2e3ebdSchin #define sysfcntlf	fcntl
111da2e3ebdSchin #define sysfstatf	fstat
112da2e3ebdSchin #define sysftruncatef	ftruncate
113da2e3ebdSchin #define syslseekf	lseek
114da2e3ebdSchin #define sysmmapf	mmap
115da2e3ebdSchin #define sysmunmapf	munmap
116da2e3ebdSchin #define sysopenf	open
117da2e3ebdSchin #define syspipef	pipe
118da2e3ebdSchin #define sysreadf	read
119da2e3ebdSchin #define sysremovef	remove
120da2e3ebdSchin #define sysstatf	stat
121da2e3ebdSchin #define syswritef	write
122da2e3ebdSchin 
123da2e3ebdSchin #else /*!_PACKAGE_ast*/
124da2e3ebdSchin 
125da2e3ebdSchin /* when building the binary compatibility package, a number of header files
126da2e3ebdSchin    are not needed and they may get in the way so we remove them here.
127da2e3ebdSchin */
128da2e3ebdSchin #if _SFBINARY_H
129da2e3ebdSchin #undef  _hdr_time
130da2e3ebdSchin #undef  _sys_time
131da2e3ebdSchin #undef  _sys_stat
132da2e3ebdSchin #undef  _hdr_stat
133da2e3ebdSchin #undef  _hdr_filio
134da2e3ebdSchin #undef  _sys_filio
135da2e3ebdSchin #undef  _lib_poll
136da2e3ebdSchin #undef  _stream_peek
137da2e3ebdSchin #undef  _socket_peek
138da2e3ebdSchin #undef  _hdr_vfork
139da2e3ebdSchin #undef  _sys_vfork
140da2e3ebdSchin #undef  _lib_vfork
141da2e3ebdSchin #undef  _hdr_values
142da2e3ebdSchin #undef  _hdr_math
143da2e3ebdSchin #undef  _sys_mman
144da2e3ebdSchin #undef  _hdr_mman
145da2e3ebdSchin #undef  _sys_ioctl
146da2e3ebdSchin #endif
147da2e3ebdSchin 
148da2e3ebdSchin #if _hdr_stdlib
149da2e3ebdSchin #include	<stdlib.h>
150da2e3ebdSchin #endif
151da2e3ebdSchin 
152da2e3ebdSchin #if _hdr_string
153da2e3ebdSchin #include	<string.h>
154da2e3ebdSchin #endif
155da2e3ebdSchin 
156da2e3ebdSchin #if _hdr_time
157da2e3ebdSchin #include	<time.h>
158da2e3ebdSchin #endif
159da2e3ebdSchin #if _sys_time
160da2e3ebdSchin #include	<sys/time.h>
161da2e3ebdSchin #endif
162da2e3ebdSchin 
163da2e3ebdSchin #if _sys_stat
164da2e3ebdSchin #include	<sys/stat.h>
165da2e3ebdSchin #else
166da2e3ebdSchin #if _hdr_stat
167da2e3ebdSchin #include	<stat.h>
168da2e3ebdSchin #ifndef _sys_stat
169da2e3ebdSchin #define	_sys_stat	1
170da2e3ebdSchin #endif
171da2e3ebdSchin #endif
172da2e3ebdSchin #endif /*_sys_stat*/
173da2e3ebdSchin 
174da2e3ebdSchin #ifndef _sys_stat
175da2e3ebdSchin #define _sys_stat	0
176da2e3ebdSchin #endif
177da2e3ebdSchin 
178da2e3ebdSchin #include	<fcntl.h>
179da2e3ebdSchin 
180da2e3ebdSchin #ifndef F_SETFD
181da2e3ebdSchin #ifndef FIOCLEX
182da2e3ebdSchin #if _hdr_filio
183da2e3ebdSchin #include	<filio.h>
184da2e3ebdSchin #else
185da2e3ebdSchin #if _sys_filio
186da2e3ebdSchin #include	<sys/filio.h>
187da2e3ebdSchin #endif /*_sys_filio*/
188da2e3ebdSchin #endif /*_hdr_filio*/
189da2e3ebdSchin #endif /*_FIOCLEX*/
190da2e3ebdSchin #endif /*F_SETFD*/
191da2e3ebdSchin 
192da2e3ebdSchin #if _hdr_unistd
193da2e3ebdSchin #include	<unistd.h>
194da2e3ebdSchin #endif
195da2e3ebdSchin 
196da2e3ebdSchin #if !_LARGEFILE64_SOURCE	/* turn off the *64 stuff */
197da2e3ebdSchin #undef	_typ_off64_t
198da2e3ebdSchin #undef	_typ_struct_stat64
199da2e3ebdSchin #undef	_lib_creat64
200da2e3ebdSchin #undef	_lib_open64
201da2e3ebdSchin #undef	_lib_close64
202da2e3ebdSchin #undef	_lib_stat64
203da2e3ebdSchin #undef	_lib_fstat64
204da2e3ebdSchin #undef	_lib_ftruncate64
205da2e3ebdSchin #undef	_lib_lseek64
206da2e3ebdSchin #undef	_lib_mmap64
207da2e3ebdSchin #undef	_lib_munmap64
208da2e3ebdSchin #endif /*!_LARGEFILE64_SOURCE */
209da2e3ebdSchin 
210da2e3ebdSchin /* see if we can use memory mapping for io */
211da2e3ebdSchin #if _LARGEFILE64_SOURCE && !_lib_mmap64
212da2e3ebdSchin #undef _mmap_worthy
213da2e3ebdSchin #endif
214da2e3ebdSchin #if !_mmap_worthy
215da2e3ebdSchin #undef _hdr_mman
216da2e3ebdSchin #undef _sys_mman
217da2e3ebdSchin #endif
218da2e3ebdSchin #if _hdr_mman
219da2e3ebdSchin #include	<mman.h>
220da2e3ebdSchin #endif
221da2e3ebdSchin #if _sys_mman
222da2e3ebdSchin #include	<sys/mman.h>
223da2e3ebdSchin #endif
224da2e3ebdSchin 
225da2e3ebdSchin /* standardize system calls and types dealing with files */
226da2e3ebdSchin #if _typ_off64_t
227da2e3ebdSchin #define sfoff_t		off64_t
228da2e3ebdSchin #else
229da2e3ebdSchin #define sfoff_t		off_t
230da2e3ebdSchin #endif
231da2e3ebdSchin #if _typ_struct_stat64
232da2e3ebdSchin #define sfstat_t	struct stat64
233da2e3ebdSchin #else
234da2e3ebdSchin #define sfstat_t	struct stat
235da2e3ebdSchin #endif
236da2e3ebdSchin #if _lib_lseek64
237da2e3ebdSchin #define syslseekf	lseek64
238da2e3ebdSchin #else
239da2e3ebdSchin #define syslseekf	lseek
240da2e3ebdSchin #endif
241da2e3ebdSchin #if _lib_stat64
242da2e3ebdSchin #define sysstatf	stat64
243da2e3ebdSchin #else
244da2e3ebdSchin #define sysstatf	stat
245da2e3ebdSchin #endif
246da2e3ebdSchin #if _lib_fstat64
247da2e3ebdSchin #define sysfstatf	fstat64
248da2e3ebdSchin #else
249da2e3ebdSchin #define sysfstatf	fstat
250da2e3ebdSchin #endif
251da2e3ebdSchin #if _lib_mmap64
252da2e3ebdSchin #define sysmmapf	mmap64
253da2e3ebdSchin #else
254da2e3ebdSchin #define sysmmapf	mmap
255da2e3ebdSchin #endif
256da2e3ebdSchin #if _lib_munmap64
257da2e3ebdSchin #define sysmunmapf	munmap64
258da2e3ebdSchin #else
259da2e3ebdSchin #define sysmunmapf	munmap
260da2e3ebdSchin #endif
261da2e3ebdSchin #if _lib_open64
262da2e3ebdSchin #define sysopenf	open64
263da2e3ebdSchin #else
264da2e3ebdSchin #define sysopenf	open
265da2e3ebdSchin #endif
266da2e3ebdSchin #if _lib_creat64
267da2e3ebdSchin #define syscreatf	creat64
268da2e3ebdSchin #else
269da2e3ebdSchin #define syscreatf	creat
270da2e3ebdSchin #endif
271da2e3ebdSchin #if _lib_close64
272da2e3ebdSchin #define sysclosef	close64
273da2e3ebdSchin #else
274da2e3ebdSchin #define sysclosef	close
275da2e3ebdSchin #endif
276da2e3ebdSchin #if _lib_ftruncate64
277da2e3ebdSchin #undef _lib_ftruncate
278da2e3ebdSchin #define _lib_ftruncate	1
279da2e3ebdSchin #define sysftruncatef	ftruncate64
280da2e3ebdSchin #endif
281da2e3ebdSchin #if !_lib_ftruncate64 && _lib_ftruncate
282da2e3ebdSchin #define sysftruncatef	ftruncate
283da2e3ebdSchin #endif
284da2e3ebdSchin #if _lib_remove
285da2e3ebdSchin #define sysremovef	remove
286da2e3ebdSchin #else
287da2e3ebdSchin #define sysremovef	unlink
288da2e3ebdSchin #endif
289da2e3ebdSchin 
290da2e3ebdSchin #define sysreadf	read
291da2e3ebdSchin #define syswritef	write
292da2e3ebdSchin #define syspipef	pipe
293da2e3ebdSchin #define sysdupf		dup
294da2e3ebdSchin #define sysfcntlf	fcntl
295da2e3ebdSchin 
296da2e3ebdSchin #endif /*_PACKAGE_ast*/
297da2e3ebdSchin 
298da2e3ebdSchin #if !_mmap_worthy
299da2e3ebdSchin #undef MAP_TYPE
300da2e3ebdSchin #endif
301da2e3ebdSchin 
302da2e3ebdSchin #include	"FEATURE/float"
303da2e3ebdSchin 
304da2e3ebdSchin #include	<errno.h>
305da2e3ebdSchin #include	<ctype.h>
306da2e3ebdSchin 
307da2e3ebdSchin /* deal with multi-byte character and string conversions */
308da2e3ebdSchin #if _PACKAGE_ast
309da2e3ebdSchin 
310da2e3ebdSchin #include	<wchar.h>
311da2e3ebdSchin 
312da2e3ebdSchin #define _has_multibyte		1
313da2e3ebdSchin 
314da2e3ebdSchin #define SFMBMAX			mbmax()
315da2e3ebdSchin #define SFMBCPY(to,fr)		memcpy((to), (fr), sizeof(mbstate_t))
316da2e3ebdSchin #define SFMBCLR(mb)		memset((mb), 0,  sizeof(mbstate_t))
317da2e3ebdSchin #define SFMBSET(lhs,v)		(lhs = (v))
318da2e3ebdSchin #define SFMBLEN(s,mb)		mbsize(s)
319da2e3ebdSchin #define SFMBDCL(ms)		mbstate_t ms;
320da2e3ebdSchin 
321da2e3ebdSchin #else
322da2e3ebdSchin 
323da2e3ebdSchin #if _hdr_wchar && _typ_mbstate_t && _lib_wcrtomb && _lib_mbrtowc
324da2e3ebdSchin #define _has_multibyte		1	/* Xopen-compliant	*/
325*b30d1939SAndy Fiddaman #if _typ___va_list && !defined(__va_list)
326*b30d1939SAndy Fiddaman #define __va_list	va_list
327*b30d1939SAndy Fiddaman #endif
328da2e3ebdSchin #include	<wchar.h>
329da2e3ebdSchin #define SFMBCPY(to,fr)		memcpy((to), (fr), sizeof(mbstate_t))
330da2e3ebdSchin #define SFMBCLR(mb)		memset((mb), 0,  sizeof(mbstate_t))
331da2e3ebdSchin #define SFMBSET(lhs,v)		(lhs = (v))
332da2e3ebdSchin #define SFMBDCL(mb)		mbstate_t mb;
333da2e3ebdSchin #define SFMBLEN(s,mb)		mbrtowc(NIL(wchar_t*), (s), SFMBMAX, (mb) )
334da2e3ebdSchin #endif /*_hdr_wchar && _typ_mbstate_t && _lib_wcrtomb && _lib_mbrtowc*/
335da2e3ebdSchin 
336da2e3ebdSchin #if !_has_multibyte && _hdr_wchar && _lib_mbtowc && _lib_wctomb
337da2e3ebdSchin #define _has_multibyte		2	/* no shift states	*/
338da2e3ebdSchin #include	<wchar.h>
339da2e3ebdSchin #undef mbrtowc
340da2e3ebdSchin #define mbrtowc(wp,s,n,mb)	mbtowc(wp, s, n)
341da2e3ebdSchin #undef wcrtomb
342da2e3ebdSchin #define wcrtomb(s,wc,mb)	wctomb(s, wc)
343da2e3ebdSchin #define SFMBCPY(to,fr)
344da2e3ebdSchin #define SFMBCLR(mb)
345da2e3ebdSchin #define SFMBSET(lhs,v)
346da2e3ebdSchin #define SFMBDCL(mb)
347da2e3ebdSchin #define SFMBLEN(s,mb)		mbrtowc(NIL(wchar_t*), (s), SFMBMAX, (mb) )
348da2e3ebdSchin #endif /*!_has_multibyte && _hdr_wchar && _lib_mbtowc && _lib_wctomb*/
349da2e3ebdSchin 
350da2e3ebdSchin #ifdef MB_CUR_MAX
351da2e3ebdSchin #define SFMBMAX			MB_CUR_MAX
352da2e3ebdSchin #else
353da2e3ebdSchin #define SFMBMAX			sizeof(Sflong_t)
354da2e3ebdSchin #endif
355da2e3ebdSchin 
356da2e3ebdSchin #endif /* _PACKAGE_ast */
357da2e3ebdSchin 
358da2e3ebdSchin #if !_has_multibyte
359da2e3ebdSchin #define _has_multibyte		0	/* no multibyte support	*/
360da2e3ebdSchin #define SFMBCPY(to,fr)
361da2e3ebdSchin #define SFMBCLR(mb)
362da2e3ebdSchin #define SFMBSET(lhs,v)
363da2e3ebdSchin #define SFMBDCL(mb)
364*b30d1939SAndy Fiddaman #define SFMBLEN(s,mb)		(*(s) ? 1 : 0)
365da2e3ebdSchin #endif /* _has_multibyte */
366da2e3ebdSchin 
3677c2fbfb3SApril Chin /* dealing with streams that might be accessed concurrently */
368da2e3ebdSchin #if vt_threaded
369da2e3ebdSchin 
3707c2fbfb3SApril Chin #define SFMTXdecl(ff,_mf_)	Sfio_t* _mf_ = (ff)
3717c2fbfb3SApril Chin #define SFMTXbegin(ff,_mf_,rv) \
3727c2fbfb3SApril Chin 	{	if((ff)->_flags&SF_MTSAFE) \
3737c2fbfb3SApril Chin 		{	(_mf_) = (ff); \
3747c2fbfb3SApril Chin 			if(sfmutex((ff), SFMTX_LOCK) != 0) return(rv); \
3757c2fbfb3SApril Chin 			if(_Sfnotify) \
3767c2fbfb3SApril Chin 			{	(*_Sfnotify)((_mf_), SF_MTACCESS, (Void_t*)(&(ff)) ); \
3777c2fbfb3SApril Chin 				if(!(ff)) (ff) = (_mf_); \
3787c2fbfb3SApril Chin 			} \
3797c2fbfb3SApril Chin 		} \
3807c2fbfb3SApril Chin 	}
3817c2fbfb3SApril Chin #define SFMTXend(ff,_mf_) \
3827c2fbfb3SApril Chin 	{	if((ff)->_flags&SF_MTSAFE) \
3837c2fbfb3SApril Chin 		{	if(_Sfnotify) \
3847c2fbfb3SApril Chin 				(*_Sfnotify)((_mf_), SF_MTACCESS, NIL(Void_t*) ); \
3857c2fbfb3SApril Chin 			sfmutex((ff), SFMTX_UNLOCK); \
3867c2fbfb3SApril Chin 			(ff) = (_mf_); \
3877c2fbfb3SApril Chin 		} \
3887c2fbfb3SApril Chin 	}
3897c2fbfb3SApril Chin 
3907c2fbfb3SApril Chin #define SFONCE()		(_Sfdone ? 0 : vtonce(_Sfonce,_Sfoncef))
3917c2fbfb3SApril Chin 
3927c2fbfb3SApril Chin #define SFMTXLOCK(f)		(((f)->flags&SF_MTSAFE) ? sfmutex(f,SFMTX_LOCK) : 0)
3937c2fbfb3SApril Chin #define SFMTXUNLOCK(f)		(((f)->flags&SF_MTSAFE) ? sfmutex(f,SFMTX_UNLOCK) : 0)
394da2e3ebdSchin 
3957c2fbfb3SApril Chin #define SFMTXDECL(ff)		SFMTXdecl((ff), _mtxf1_)
3967c2fbfb3SApril Chin #define SFMTXBEGIN(ff,v) 	{ SFMTXbegin((ff), _mtxf1_, (v) ); }
3977c2fbfb3SApril Chin #define SFMTXEND(ff)		{ SFMTXend(ff, _mtxf1_); }
3987c2fbfb3SApril Chin #define SFMTXENTER(ff,v) 	{ if(!(ff)) return(v); SFMTXBEGIN((ff), (v)); }
3997c2fbfb3SApril Chin #define SFMTXRETURN(ff,v)	{ SFMTXEND(ff); return(v); }
4007c2fbfb3SApril Chin 
4017c2fbfb3SApril Chin #define SFMTXDECL2(ff)		SFMTXdecl((ff), _mtxf2_)
4027c2fbfb3SApril Chin #define SFMTXBEGIN2(ff,v) 	{ SFMTXbegin((ff), _mtxf2_, (v) ); }
4037c2fbfb3SApril Chin #define SFMTXEND2(ff)		{ SFMTXend((ff), _mtxf2_); }
404da2e3ebdSchin 
405da2e3ebdSchin #define POOLMTXLOCK(p)		( vtmtxlock(&(p)->mutex) )
406da2e3ebdSchin #define POOLMTXUNLOCK(p)	( vtmtxunlock(&(p)->mutex) )
4077c2fbfb3SApril Chin #define POOLMTXENTER(p)		{ POOLMTXLOCK(p); }
4087c2fbfb3SApril Chin #define POOLMTXRETURN(p,rv)	{ POOLMTXUNLOCK(p); return(rv); }
409da2e3ebdSchin 
410da2e3ebdSchin #else /*!vt_threaded*/
411da2e3ebdSchin 
412da2e3ebdSchin #undef SF_MTSAFE /* no need to worry about thread-safety */
413da2e3ebdSchin #define SF_MTSAFE		0
414da2e3ebdSchin 
415da2e3ebdSchin #define SFONCE()		/*(0)*/
416da2e3ebdSchin 
417da2e3ebdSchin #define SFMTXLOCK(f)		/*(0)*/
418da2e3ebdSchin #define SFMTXUNLOCK(f)		/*(0)*/
4197c2fbfb3SApril Chin 
4207c2fbfb3SApril Chin #define	SFMTXDECL(ff)		/*(0)*/
4217c2fbfb3SApril Chin #define SFMTXBEGIN(ff,v) 	/*(0)*/
4227c2fbfb3SApril Chin #define SFMTXEND(ff)		/*(0)*/
4237c2fbfb3SApril Chin #define SFMTXENTER(ff,v)	{ if(!(ff)) return(v); }
4247c2fbfb3SApril Chin #define SFMTXRETURN(ff,v)	{ return(v); }
4257c2fbfb3SApril Chin 
4267c2fbfb3SApril Chin #define SFMTXDECL2(ff)		/*(0)*/
4277c2fbfb3SApril Chin #define SFMTXBEGIN2(ff,v) 	/*(0)*/
4287c2fbfb3SApril Chin #define SFMTXEND2(ff)		/*(0)*/
429da2e3ebdSchin 
430da2e3ebdSchin #define POOLMTXLOCK(p)
431da2e3ebdSchin #define POOLMTXUNLOCK(p)
4327c2fbfb3SApril Chin #define POOLMTXENTER(p)
433da2e3ebdSchin #define POOLMTXRETURN(p,v)	{ return(v); }
434da2e3ebdSchin 
435da2e3ebdSchin #endif /*vt_threaded*/
436da2e3ebdSchin 
437da2e3ebdSchin 
438da2e3ebdSchin /* functions for polling readiness of streams */
439da2e3ebdSchin #if _lib_select
440da2e3ebdSchin #undef _lib_poll
441*b30d1939SAndy Fiddaman #if _sys_select
442*b30d1939SAndy Fiddaman #include	<sys/select.h>
443*b30d1939SAndy Fiddaman #endif
444da2e3ebdSchin #else
445da2e3ebdSchin #if _lib_poll_fd_1 || _lib_poll_fd_2
446da2e3ebdSchin #define _lib_poll	1
447da2e3ebdSchin #endif
448da2e3ebdSchin #endif /*_lib_select_*/
449da2e3ebdSchin 
450da2e3ebdSchin #if _lib_poll
451da2e3ebdSchin #include	<poll.h>
452da2e3ebdSchin 
453da2e3ebdSchin #if _lib_poll_fd_1
454da2e3ebdSchin #define SFPOLL(pfd,n,tm)	poll((pfd),(ulong)(n),(tm))
455da2e3ebdSchin #else
456da2e3ebdSchin #define SFPOLL(pfd,n,tm)	poll((ulong)(n),(pfd),(tm))
457da2e3ebdSchin #endif
458da2e3ebdSchin #endif /*_lib_poll*/
459da2e3ebdSchin 
460da2e3ebdSchin #if _stream_peek
461da2e3ebdSchin #include	<stropts.h>
462da2e3ebdSchin #endif
463da2e3ebdSchin 
464da2e3ebdSchin #if _socket_peek
465da2e3ebdSchin #include	<sys/socket.h>
466da2e3ebdSchin #endif
467da2e3ebdSchin 
468da2e3ebdSchin /* to test for executable access mode of a file */
469da2e3ebdSchin #ifndef X_OK
470da2e3ebdSchin #define X_OK	01
471da2e3ebdSchin #endif
472da2e3ebdSchin 
473da2e3ebdSchin /* alternative process forking */
474*b30d1939SAndy Fiddaman #if _lib_vfork && !defined(fork) && !defined(__sparc) && !defined(__sparc__)
475da2e3ebdSchin #if _hdr_vfork
476da2e3ebdSchin #include	<vfork.h>
477da2e3ebdSchin #endif
478da2e3ebdSchin #if _sys_vfork
479da2e3ebdSchin #include	<sys/vfork.h>
480da2e3ebdSchin #endif
481da2e3ebdSchin #define fork	vfork
482da2e3ebdSchin #endif
483da2e3ebdSchin 
484da2e3ebdSchin /* to get rid of pesky compiler warnings */
485da2e3ebdSchin #if __STD_C
486da2e3ebdSchin #define NOTUSED(x)	(void)(x)
487da2e3ebdSchin #else
488da2e3ebdSchin #define NOTUSED(x)	(&x,1)
489da2e3ebdSchin #endif
490da2e3ebdSchin 
491da2e3ebdSchin /* Private flags in the "bits" field */
492da2e3ebdSchin #define SF_MMAP		00000001	/* in memory mapping mode		*/
493da2e3ebdSchin #define SF_BOTH		00000002	/* both read/write			*/
494da2e3ebdSchin #define SF_HOLE		00000004	/* a hole of zero's was created		*/
495da2e3ebdSchin #define SF_NULL		00000010	/* stream is /dev/null			*/
496da2e3ebdSchin #define SF_SEQUENTIAL	00000020	/* sequential access			*/
497da2e3ebdSchin #define SF_JUSTSEEK	00000040	/* just did a sfseek			*/
498da2e3ebdSchin #define SF_PRIVATE	00000100	/* private stream to Sfio, no mutex	*/
499da2e3ebdSchin #define SF_ENDING	00000200	/* no re-io on interrupts at closing	*/
500da2e3ebdSchin #define SF_WIDE		00000400	/* in wide mode - stdio only		*/
501*b30d1939SAndy Fiddaman #define SF_PUTR		00001000	/* in sfputr()				*/
502da2e3ebdSchin 
503da2e3ebdSchin /* "bits" flags that must be cleared in sfclrlock */
504da2e3ebdSchin #define SF_TMPBITS	00170000
505da2e3ebdSchin #define SF_DCDOWN	00010000	/* recurse down the discipline stack	*/
506da2e3ebdSchin 
507da2e3ebdSchin #define SF_WCFORMAT	00020000	/* wchar_t formatting - stdio only	*/
508da2e3ebdSchin #if _has_multibyte
509da2e3ebdSchin #define SFWCSET(f)	((f)->bits |= SF_WCFORMAT)
510da2e3ebdSchin #define SFWCGET(f,v)	(((v) = (f)->bits & SF_WCFORMAT), ((f)->bits &= ~SF_WCFORMAT) )
511da2e3ebdSchin #else
512da2e3ebdSchin #define SFWCSET(f)
513da2e3ebdSchin #define SFWCGET(f,v)
514da2e3ebdSchin #endif
515da2e3ebdSchin 
516da2e3ebdSchin #define SF_MVSIZE	00040000	/* f->size was reset in sfmove()	*/
517da2e3ebdSchin #define SFMVSET(f)	(((f)->size *= SF_NMAP), ((f)->bits |= SF_MVSIZE) )
518da2e3ebdSchin #define SFMVUNSET(f)	(!((f)->bits&SF_MVSIZE) ? 0 : \
519da2e3ebdSchin 				(((f)->bits &= ~SF_MVSIZE), ((f)->size /= SF_NMAP)) )
520da2e3ebdSchin 
521da2e3ebdSchin #define SFCLRBITS(f)	(SFMVUNSET(f), ((f)->bits &= ~SF_TMPBITS) )
522da2e3ebdSchin 
523da2e3ebdSchin 
524da2e3ebdSchin /* bits for the mode field, SF_INIT defined in sfio_t.h */
525da2e3ebdSchin #define SF_RC		00000010	/* peeking for a record			*/
526da2e3ebdSchin #define SF_RV		00000020	/* reserve without read	or most write	*/
527da2e3ebdSchin #define SF_LOCK		00000040	/* stream is locked for io op		*/
528da2e3ebdSchin #define SF_PUSH		00000100	/* stream has been pushed		*/
529da2e3ebdSchin #define SF_POOL		00000200	/* stream is in a pool but not current	*/
530da2e3ebdSchin #define SF_PEEK		00000400	/* there is a pending peek		*/
531da2e3ebdSchin #define SF_PKRD		00001000	/* did a peek read			*/
532da2e3ebdSchin #define SF_GETR		00002000	/* did a getr on this stream		*/
533da2e3ebdSchin #define SF_SYNCED	00004000	/* stream was synced			*/
534da2e3ebdSchin #define SF_STDIO	00010000	/* given up the buffer to stdio		*/
535da2e3ebdSchin #define SF_AVAIL	00020000	/* was closed, available for reuse	*/
536da2e3ebdSchin #define SF_LOCAL	00100000	/* sentinel for a local call		*/
537da2e3ebdSchin 
538da2e3ebdSchin #ifdef DEBUG
539da2e3ebdSchin #define ASSERT(p)	((p) ? 0 : (abort(),0) )
540da2e3ebdSchin #else
541da2e3ebdSchin #define ASSERT(p)
542da2e3ebdSchin #endif
543da2e3ebdSchin 
544da2e3ebdSchin /* short-hands */
545da2e3ebdSchin #define NIL(t)		((t)0)
546da2e3ebdSchin #define reg		register
547da2e3ebdSchin #ifndef uchar
548da2e3ebdSchin #define uchar		unsigned char
549da2e3ebdSchin #endif
550da2e3ebdSchin #ifndef ulong
551da2e3ebdSchin #define ulong		unsigned long
552da2e3ebdSchin #endif
553da2e3ebdSchin #ifndef uint
554da2e3ebdSchin #define uint		unsigned int
555da2e3ebdSchin #endif
556da2e3ebdSchin #ifndef ushort
557da2e3ebdSchin #define ushort		unsigned short
558da2e3ebdSchin #endif
559da2e3ebdSchin 
560da2e3ebdSchin #define SECOND		1000	/* millisecond units */
561da2e3ebdSchin 
562da2e3ebdSchin /* macros do determine stream types from sfstat_t data */
563da2e3ebdSchin #ifndef S_IFDIR
564da2e3ebdSchin #define S_IFDIR	0
565da2e3ebdSchin #endif
566da2e3ebdSchin #ifndef S_IFREG
567da2e3ebdSchin #define S_IFREG	0
568da2e3ebdSchin #endif
569da2e3ebdSchin #ifndef S_IFCHR
570da2e3ebdSchin #define S_IFCHR	0
571da2e3ebdSchin #endif
572da2e3ebdSchin #ifndef S_IFIFO
573da2e3ebdSchin #define S_IFIFO	0
574da2e3ebdSchin #endif
575*b30d1939SAndy Fiddaman #ifndef S_ISOCK
576*b30d1939SAndy Fiddaman #define S_ISOCK	0
577*b30d1939SAndy Fiddaman #endif
578*b30d1939SAndy Fiddaman 
579*b30d1939SAndy Fiddaman #ifndef S_IFMT
580*b30d1939SAndy Fiddaman #define S_IFMT	(S_IFDIR|S_IFREG|S_IFCHR|S_IFIFO|S_ISOCK)
581*b30d1939SAndy Fiddaman #endif
582da2e3ebdSchin 
583da2e3ebdSchin #ifndef S_ISDIR
584da2e3ebdSchin #define S_ISDIR(m)	(((m)&S_IFMT) == S_IFDIR)
585da2e3ebdSchin #endif
586da2e3ebdSchin #ifndef S_ISREG
587da2e3ebdSchin #define S_ISREG(m)	(((m)&S_IFMT) == S_IFREG)
588da2e3ebdSchin #endif
589da2e3ebdSchin #ifndef S_ISCHR
590da2e3ebdSchin #define S_ISCHR(m)	(((m)&S_IFMT) == S_IFCHR)
591da2e3ebdSchin #endif
592da2e3ebdSchin 
593da2e3ebdSchin #ifndef S_ISFIFO
594*b30d1939SAndy Fiddaman #	if S_IFIFO
5957c2fbfb3SApril Chin #		define S_ISFIFO(m)	(((m)&S_IFMT) == S_IFIFO)
596da2e3ebdSchin #	else
597da2e3ebdSchin #		define S_ISFIFO(m)	(0)
598da2e3ebdSchin #	endif
599da2e3ebdSchin #endif
600da2e3ebdSchin 
601da2e3ebdSchin #ifdef S_IRUSR
602da2e3ebdSchin #define SF_CREATMODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
603da2e3ebdSchin #else
604da2e3ebdSchin #define SF_CREATMODE	0666
605da2e3ebdSchin #endif
606da2e3ebdSchin 
607da2e3ebdSchin /* set close-on-exec */
608da2e3ebdSchin #ifdef F_SETFD
609da2e3ebdSchin #	ifndef FD_CLOEXEC
610da2e3ebdSchin #		define FD_CLOEXEC	1
611da2e3ebdSchin #	endif /*FD_CLOEXEC*/
612da2e3ebdSchin #	define SETCLOEXEC(fd)		((void)fcntl((fd),F_SETFD,FD_CLOEXEC))
613da2e3ebdSchin #else
614da2e3ebdSchin #	ifdef FIOCLEX
615da2e3ebdSchin #		define SETCLOEXEC(fd)	((void)ioctl((fd),FIOCLEX,0))
616da2e3ebdSchin #	else
617da2e3ebdSchin #		define SETCLOEXEC(fd)
618da2e3ebdSchin #	endif /*FIOCLEX*/
619da2e3ebdSchin #endif /*F_SETFD*/
620da2e3ebdSchin 
621*b30d1939SAndy Fiddaman #define SF_FD_CLOEXEC			0x0001
622*b30d1939SAndy Fiddaman 
623da2e3ebdSchin /* a couple of error number that we use, default values are like Linux */
624da2e3ebdSchin #ifndef EINTR
625da2e3ebdSchin #define EINTR	4
626da2e3ebdSchin #endif
627da2e3ebdSchin #ifndef EBADF
628da2e3ebdSchin #define EBADF	9
629da2e3ebdSchin #endif
630da2e3ebdSchin #ifndef EAGAIN
631da2e3ebdSchin #define EAGAIN	11
632da2e3ebdSchin #endif
633da2e3ebdSchin #ifndef ENOMEM
634da2e3ebdSchin #define ENOMEM	12
635da2e3ebdSchin #endif
636da2e3ebdSchin #ifndef EINVAL
637da2e3ebdSchin #define EINVAL	22
638da2e3ebdSchin #endif
639da2e3ebdSchin #ifndef ESPIPE
640da2e3ebdSchin #define ESPIPE	29
641da2e3ebdSchin #endif
642da2e3ebdSchin 
643da2e3ebdSchin /* function to get the decimal point for local environment */
644da2e3ebdSchin #if !defined(SFSETLOCALE) && _PACKAGE_ast
645da2e3ebdSchin #include "lclib.h"
646da2e3ebdSchin #define SFSETLOCALE(dp,tp) \
647da2e3ebdSchin 	do if (*(dp) == 0) { \
648da2e3ebdSchin 		Lc_numeric_t*	lv = (Lc_numeric_t*)LCINFO(AST_LC_NUMERIC)->data; \
649da2e3ebdSchin 		*(dp) = lv->decimal; \
650*b30d1939SAndy Fiddaman 		*(tp) = lv->thousand; \
651da2e3ebdSchin 	} while (0)
652da2e3ebdSchin #endif /*!defined(SFSETLOCALE) && _PACKAGE_ast*/
653da2e3ebdSchin 
654da2e3ebdSchin #if !defined(SFSETLOCALE) && _lib_locale
655da2e3ebdSchin #include	<locale.h>
656da2e3ebdSchin #define SFSETLOCALE(decimal,thousand) \
657da2e3ebdSchin 	do { struct lconv*	lv; \
658da2e3ebdSchin 	  if(*(decimal) == 0) \
659da2e3ebdSchin 	  { *(decimal) = '.'; \
660*b30d1939SAndy Fiddaman 	    *(thousand) = -1; \
661da2e3ebdSchin 	    if((lv = localeconv())) \
662da2e3ebdSchin 	    { if(lv->decimal_point && *lv->decimal_point) \
663da2e3ebdSchin 	    	*(decimal) = *(unsigned char*)lv->decimal_point; \
664*b30d1939SAndy Fiddaman 	      if(lv->thousands_sep && *lv->thousands_sep) \
665da2e3ebdSchin 	    	*(thousand) = *(unsigned char*)lv->thousands_sep; \
666da2e3ebdSchin 	    } \
667da2e3ebdSchin 	  } \
668da2e3ebdSchin 	} while (0)
669da2e3ebdSchin #endif /*!defined(SFSETLOCALE) && _lib_locale*/
670da2e3ebdSchin 
671da2e3ebdSchin #if !defined(SFSETLOCALE)
672*b30d1939SAndy Fiddaman #define SFSETLOCALE(decimal,thousand)	(*(decimal)='.',*(thousand)=-1)
673da2e3ebdSchin #endif
674da2e3ebdSchin 
675da2e3ebdSchin /* stream pool structure. */
676da2e3ebdSchin typedef struct _sfpool_s	Sfpool_t;
677da2e3ebdSchin struct _sfpool_s
678da2e3ebdSchin {	Sfpool_t*	next;
679da2e3ebdSchin 	int		mode;		/* type of pool			*/
680da2e3ebdSchin 	int		s_sf;		/* size of pool array		*/
681da2e3ebdSchin 	int		n_sf;		/* number currently in pool	*/
682da2e3ebdSchin 	Sfio_t**	sf;		/* array of streams		*/
683da2e3ebdSchin 	Sfio_t*		array[3];	/* start with 3			*/
684da2e3ebdSchin 	Vtmutex_t	mutex;		/* mutex lock object		*/
685da2e3ebdSchin };
686da2e3ebdSchin 
687da2e3ebdSchin /* reserve buffer structure */
688da2e3ebdSchin typedef struct _sfrsrv_s	Sfrsrv_t;
689da2e3ebdSchin struct _sfrsrv_s
690da2e3ebdSchin {	ssize_t		slen;		/* last string length		*/
691da2e3ebdSchin 	ssize_t		size;		/* buffer size			*/
692da2e3ebdSchin 	uchar		data[1];	/* data buffer			*/
693da2e3ebdSchin };
694da2e3ebdSchin 
695da2e3ebdSchin /* co-process structure */
696da2e3ebdSchin typedef struct _sfproc_s	Sfproc_t;
697da2e3ebdSchin struct _sfproc_s
698da2e3ebdSchin {	int		pid;	/* process id			*/
699da2e3ebdSchin 	uchar*		rdata;	/* read data being cached	*/
700da2e3ebdSchin 	int		ndata;	/* size of cached data		*/
701da2e3ebdSchin 	int		size;	/* buffer size			*/
702da2e3ebdSchin 	int		file;	/* saved file descriptor	*/
703da2e3ebdSchin 	int		sigp;	/* sigpipe protection needed	*/
704da2e3ebdSchin };
705da2e3ebdSchin 
706da2e3ebdSchin /* extensions to sfvprintf/sfvscanf */
707da2e3ebdSchin #define FP_SET(fp,fn)	(fp < 0 ? (fn += 1) : (fn = fp) )
708da2e3ebdSchin #define FP_WIDTH	0
709da2e3ebdSchin #define FP_PRECIS	1
710da2e3ebdSchin #define FP_BASE		2
711da2e3ebdSchin #define FP_STR		3
712da2e3ebdSchin #define FP_SIZE		4
713da2e3ebdSchin #define FP_INDEX	5	/* index size	*/
714da2e3ebdSchin 
715da2e3ebdSchin typedef struct _fmt_s		Fmt_t;
716da2e3ebdSchin typedef struct _fmtpos_s	Fmtpos_t;
717da2e3ebdSchin typedef union
718da2e3ebdSchin {	int		i, *ip;
719da2e3ebdSchin 	long		l, *lp;
720da2e3ebdSchin 	short		h, *hp;
721da2e3ebdSchin 	uint		ui;
722da2e3ebdSchin 	ulong		ul;
723da2e3ebdSchin 	ushort		uh;
724da2e3ebdSchin 	Sflong_t	ll, *llp;
725da2e3ebdSchin 	Sfulong_t	lu;
726da2e3ebdSchin 	Sfdouble_t	ld;
727da2e3ebdSchin 	double		d;
728da2e3ebdSchin 	float		f;
729da2e3ebdSchin #if _has_multibyte
730da2e3ebdSchin 	wchar_t		wc;
731da2e3ebdSchin 	wchar_t		*ws, **wsp;
732da2e3ebdSchin #endif
733da2e3ebdSchin 	char		c, *s, **sp;
734da2e3ebdSchin 	uchar		uc, *us, **usp;
735da2e3ebdSchin 	Void_t		*vp;
736da2e3ebdSchin 	Sffmt_t		*ft;
737da2e3ebdSchin } Argv_t;
738da2e3ebdSchin 
739da2e3ebdSchin struct _fmt_s
740da2e3ebdSchin {	char*		form;		/* format string		*/
741da2e3ebdSchin 	va_list		args;		/* corresponding arglist	*/
742da2e3ebdSchin 	SFMBDCL(mbs)			/* multibyte parsing state	*/
743da2e3ebdSchin 
744da2e3ebdSchin 	char*		oform;		/* original format string	*/
745da2e3ebdSchin 	va_list		oargs;		/* original arg list		*/
746da2e3ebdSchin 	int		argn;		/* number of args already used	*/
747da2e3ebdSchin 	Fmtpos_t*	fp;		/* position list		*/
748da2e3ebdSchin 
749da2e3ebdSchin 	Sffmt_t*	ft;		/* formatting environment	*/
750da2e3ebdSchin 	Sffmtevent_f	eventf;		/* event function		*/
751da2e3ebdSchin 	Fmt_t*		next;		/* stack frame pointer		*/
752da2e3ebdSchin };
753da2e3ebdSchin 
754da2e3ebdSchin struct _fmtpos_s
755da2e3ebdSchin {	Sffmt_t	ft;			/* environment			*/
756da2e3ebdSchin 	Argv_t	argv;			/* argument value		*/
757da2e3ebdSchin 	int	fmt;			/* original format		*/
758da2e3ebdSchin 	int	need[FP_INDEX];		/* positions depending on	*/
759da2e3ebdSchin };
760da2e3ebdSchin 
761da2e3ebdSchin #define LEFTP		'('
762da2e3ebdSchin #define RIGHTP		')'
763da2e3ebdSchin #define QUOTE		'\''
764da2e3ebdSchin 
765da2e3ebdSchin #ifndef CHAR_BIT
766da2e3ebdSchin #define CHAR_BIT	8
767da2e3ebdSchin #endif
768da2e3ebdSchin 
769da2e3ebdSchin #define FMTSET(ft, frm,ags, fv, sz, flgs, wid,pr,bs, ts,ns) \
770da2e3ebdSchin 	((ft->form = (char*)frm), va_copy(ft->args,ags), \
771da2e3ebdSchin 	 (ft->fmt = fv), (ft->size = sz), \
772da2e3ebdSchin 	 (ft->flags = (flgs&SFFMT_SET)), \
773da2e3ebdSchin 	 (ft->width = wid), (ft->precis = pr), (ft->base = bs), \
774da2e3ebdSchin 	 (ft->t_str = ts), (ft->n_str = ns) )
775da2e3ebdSchin #define FMTGET(ft, frm,ags, fv, sz, flgs, wid,pr,bs) \
776da2e3ebdSchin 	((frm = ft->form), va_copy(ags,ft->args), \
777da2e3ebdSchin 	 (fv = ft->fmt), (sz = ft->size), \
778da2e3ebdSchin 	 (flgs = (flgs&~(SFFMT_SET))|(ft->flags&SFFMT_SET)), \
779da2e3ebdSchin 	 (wid = ft->width), (pr = ft->precis), (bs = ft->base) )
780da2e3ebdSchin 
781da2e3ebdSchin /* format flags&types, must coexist with those in sfio.h */
782da2e3ebdSchin #define SFFMT_FORBIDDEN 000077777777	/* for sfio.h only		*/
783da2e3ebdSchin #define SFFMT_EFORMAT	001000000000	/* sfcvt converting %e		*/
784da2e3ebdSchin #define SFFMT_MINUS	002000000000	/* minus sign			*/
785da2e3ebdSchin #define SFFMT_AFORMAT	004000000000	/* sfcvt converting %a		*/
786da2e3ebdSchin #define SFFMT_UPPER	010000000000	/* sfcvt converting upper	*/
787da2e3ebdSchin 
788da2e3ebdSchin #define SFFMT_TYPES	(SFFMT_SHORT|SFFMT_SSHORT | SFFMT_LONG|SFFMT_LLONG|\
789da2e3ebdSchin 			 SFFMT_LDOUBLE | SFFMT_IFLAG|SFFMT_JFLAG| \
790da2e3ebdSchin 			 SFFMT_TFLAG | SFFMT_ZFLAG )
791da2e3ebdSchin 
792da2e3ebdSchin /* type of elements to be converted */
793da2e3ebdSchin #define SFFMT_INT	001		/* %d,%i 		*/
794da2e3ebdSchin #define SFFMT_UINT	002		/* %u,o,x etc.		*/
795da2e3ebdSchin #define SFFMT_FLOAT	004		/* %f,e,g etc.		*/
796da2e3ebdSchin #define SFFMT_CHAR	010		/* %c,C			*/
797da2e3ebdSchin #define SFFMT_POINTER	020		/* %p,n,s,S		*/
798da2e3ebdSchin #define SFFMT_CLASS	040		/* %[			*/
799da2e3ebdSchin 
800da2e3ebdSchin /* local variables used across sf-functions */
801*b30d1939SAndy Fiddaman typedef void  (*Sfnotify_f)_ARG_((Sfio_t*, int, void*));
802da2e3ebdSchin #define _Sfpage		(_Sfextern.sf_page)
803da2e3ebdSchin #define _Sfpool		(_Sfextern.sf_pool)
804da2e3ebdSchin #define _Sfpmove	(_Sfextern.sf_pmove)
805da2e3ebdSchin #define _Sfstack	(_Sfextern.sf_stack)
806da2e3ebdSchin #define _Sfnotify	(_Sfextern.sf_notify)
807da2e3ebdSchin #define _Sfstdsync	(_Sfextern.sf_stdsync)
808da2e3ebdSchin #define _Sfudisc	(&(_Sfextern.sf_udisc))
809da2e3ebdSchin #define _Sfcleanup	(_Sfextern.sf_cleanup)
810da2e3ebdSchin #define _Sfexiting	(_Sfextern.sf_exiting)
811da2e3ebdSchin #define _Sfdone		(_Sfextern.sf_done)
812da2e3ebdSchin #define _Sfonce		(_Sfextern.sf_once)
813da2e3ebdSchin #define _Sfoncef	(_Sfextern.sf_oncef)
814da2e3ebdSchin #define _Sfmutex	(_Sfextern.sf_mutex)
815da2e3ebdSchin typedef struct _sfextern_s
816da2e3ebdSchin {	ssize_t			sf_page;
817da2e3ebdSchin 	struct _sfpool_s	sf_pool;
818da2e3ebdSchin 	int			(*sf_pmove)_ARG_((Sfio_t*, int));
819da2e3ebdSchin 	Sfio_t*			(*sf_stack)_ARG_((Sfio_t*, Sfio_t*));
8207c2fbfb3SApril Chin 	void			(*sf_notify)_ARG_((Sfio_t*, int, void*));
821da2e3ebdSchin 	int			(*sf_stdsync)_ARG_((Sfio_t*));
822da2e3ebdSchin 	struct _sfdisc_s	sf_udisc;
823da2e3ebdSchin 	void			(*sf_cleanup)_ARG_((void));
824da2e3ebdSchin 	int			sf_exiting;
825da2e3ebdSchin 	int			sf_done;
826da2e3ebdSchin 	Vtonce_t*		sf_once;
827da2e3ebdSchin 	void			(*sf_oncef)_ARG_((void));
828da2e3ebdSchin 	Vtmutex_t*		sf_mutex;
829da2e3ebdSchin } Sfextern_t;
830da2e3ebdSchin 
831da2e3ebdSchin /* get the real value of a byte in a coded long or ulong */
832da2e3ebdSchin #define SFUVALUE(v)	(((ulong)(v))&(SF_MORE-1))
833da2e3ebdSchin #define SFSVALUE(v)	((( long)(v))&(SF_SIGN-1))
834da2e3ebdSchin #define SFBVALUE(v)	(((ulong)(v))&(SF_BYTE-1))
835da2e3ebdSchin 
836da2e3ebdSchin /* pick this many bits in each iteration of double encoding */
837da2e3ebdSchin #define SF_PRECIS	7
838da2e3ebdSchin 
839da2e3ebdSchin /* grain size for buffer increment */
840da2e3ebdSchin #define SF_GRAIN	1024
841da2e3ebdSchin #define SF_PAGE		((ssize_t)(SF_GRAIN*sizeof(int)*2))
842da2e3ebdSchin 
843da2e3ebdSchin /* when the buffer is empty, certain io requests may be better done directly
844da2e3ebdSchin    on the given application buffers. The below condition determines when.
845da2e3ebdSchin */
846da2e3ebdSchin #define SFDIRECT(f,n)	(((ssize_t)(n) >= (f)->size) || \
847da2e3ebdSchin 			 ((n) >= SF_GRAIN && (ssize_t)(n) >= (f)->size/16 ) )
848da2e3ebdSchin 
849da2e3ebdSchin /* number of pages to memory map at a time */
850*b30d1939SAndy Fiddaman #if _ptr_bits >= 64
851*b30d1939SAndy Fiddaman #define SF_NMAP		1024
852*b30d1939SAndy Fiddaman #else
853*b30d1939SAndy Fiddaman #define SF_NMAP		32
854*b30d1939SAndy Fiddaman #endif
855da2e3ebdSchin 
856da2e3ebdSchin #ifndef MAP_VARIABLE
857da2e3ebdSchin #define MAP_VARIABLE	0
858da2e3ebdSchin #endif
859da2e3ebdSchin #ifndef _mmap_fixed
860da2e3ebdSchin #define _mmap_fixed	0
861da2e3ebdSchin #endif
862da2e3ebdSchin 
863da2e3ebdSchin /* set/unset sequential states for mmap */
864da2e3ebdSchin #if _lib_madvise && defined(MADV_SEQUENTIAL) && defined(MADV_NORMAL)
865da2e3ebdSchin #define SFMMSEQON(f,a,s) \
866da2e3ebdSchin 		do { int oerrno = errno; \
867da2e3ebdSchin 		     (void)madvise((caddr_t)(a),(size_t)(s),MADV_SEQUENTIAL); \
868da2e3ebdSchin 		     errno = oerrno; \
869da2e3ebdSchin 		} while(0)
870da2e3ebdSchin #define SFMMSEQOFF(f,a,s) \
871da2e3ebdSchin 		do { int oerrno = errno; \
872da2e3ebdSchin 		     (void)madvise((caddr_t)(a),(size_t)(s),MADV_NORMAL); \
873da2e3ebdSchin 		     errno = oerrno; \
874da2e3ebdSchin 		} while(0)
875da2e3ebdSchin #else
876da2e3ebdSchin #define SFMMSEQON(f,a,s)
877da2e3ebdSchin #define SFMMSEQOFF(f,a,s)
878da2e3ebdSchin #endif
879da2e3ebdSchin 
880da2e3ebdSchin #define SFMUNMAP(f,a,s)		(sysmunmapf((caddr_t)(a),(size_t)(s)), \
881da2e3ebdSchin 				 ((f)->endb = (f)->endr = (f)->endw = (f)->next = \
882da2e3ebdSchin 				  (f)->data = NIL(uchar*)) )
883da2e3ebdSchin 
884da2e3ebdSchin /* safe closing function */
885da2e3ebdSchin #define CLOSE(f)	{ while(sysclosef(f) < 0 && errno == EINTR) errno = 0; }
886da2e3ebdSchin 
887da2e3ebdSchin /* the bottomless bit bucket */
888da2e3ebdSchin #define DEVNULL		"/dev/null"
889da2e3ebdSchin #define SFSETNULL(f)	((f)->extent = (Sfoff_t)(-1), (f)->bits |= SF_NULL)
890da2e3ebdSchin #define SFISNULL(f)	((f)->extent < 0 && ((f)->bits&SF_NULL) )
891da2e3ebdSchin 
892da2e3ebdSchin #define SFKILL(f)	((f)->mode = (SF_AVAIL|SF_LOCK) )
893da2e3ebdSchin #define SFKILLED(f)	(((f)->mode&(SF_AVAIL|SF_LOCK)) == (SF_AVAIL|SF_LOCK) )
894da2e3ebdSchin 
895da2e3ebdSchin /* exception types */
896da2e3ebdSchin #define SF_EDONE	0	/* stop this operation and return	*/
897da2e3ebdSchin #define SF_EDISC	1	/* discipline says it's ok		*/
898da2e3ebdSchin #define SF_ESTACK	2	/* stack was popped			*/
899da2e3ebdSchin #define SF_ECONT	3	/* can continue normally		*/
900da2e3ebdSchin 
901da2e3ebdSchin #define SETLOCAL(f)	((f)->mode |= SF_LOCAL)
902da2e3ebdSchin #define GETLOCAL(f,v)	((v) = ((f)->mode&SF_LOCAL), (f)->mode &= ~SF_LOCAL, (v))
903da2e3ebdSchin #define SFWRALL(f)	((f)->mode |= SF_RV)
904da2e3ebdSchin #define SFISALL(f,v)	((((v) = (f)->mode&SF_RV) ? ((f)->mode &= ~SF_RV) : 0), \
90534f9b3eeSRoland Mainz 			 ((v) || ((f)->flags&(SF_SHARE|SF_APPENDWR|SF_WHOLE)) ) )
906da2e3ebdSchin #define SFSK(f,a,o,d)	(SETLOCAL(f),sfsk(f,(Sfoff_t)a,o,d))
907da2e3ebdSchin #define SFRD(f,b,n,d)	(SETLOCAL(f),sfrd(f,(Void_t*)b,n,d))
908da2e3ebdSchin #define SFWR(f,b,n,d)	(SETLOCAL(f),sfwr(f,(Void_t*)b,n,d))
909da2e3ebdSchin #define SFSYNC(f)	(SETLOCAL(f),sfsync(f))
910da2e3ebdSchin #define SFCLOSE(f)	(SETLOCAL(f),sfclose(f))
911da2e3ebdSchin #define SFFLSBUF(f,n)	(SETLOCAL(f),_sfflsbuf(f,n))
912da2e3ebdSchin #define SFFILBUF(f,n)	(SETLOCAL(f),_sffilbuf(f,n))
913da2e3ebdSchin #define SFSETBUF(f,s,n)	(SETLOCAL(f),sfsetbuf(f,s,n))
914da2e3ebdSchin #define SFWRITE(f,s,n)	(SETLOCAL(f),sfwrite(f,s,n))
915da2e3ebdSchin #define SFREAD(f,s,n)	(SETLOCAL(f),sfread(f,s,n))
916da2e3ebdSchin #define SFSEEK(f,p,t)	(SETLOCAL(f),sfseek(f,p,t))
917da2e3ebdSchin #define SFNPUTC(f,c,n)	(SETLOCAL(f),sfnputc(f,c,n))
918da2e3ebdSchin #define SFRAISE(f,e,d)	(SETLOCAL(f),sfraise(f,e,d))
919da2e3ebdSchin 
920da2e3ebdSchin /* lock/open a stream */
921da2e3ebdSchin #define SFMODE(f,l)	((f)->mode & ~(SF_RV|SF_RC|((l) ? SF_LOCK : 0)) )
922da2e3ebdSchin #define SFLOCK(f,l)	(void)((f)->mode |= SF_LOCK, (f)->endr = (f)->endw = (f)->data)
923da2e3ebdSchin #define _SFOPENRD(f)	((f)->endr = ((f)->flags&SF_MTSAFE) ? (f)->data : (f)->endb)
924da2e3ebdSchin #define _SFOPENWR(f)	((f)->endw = ((f)->flags&(SF_MTSAFE|SF_LINE)) ? (f)->data : (f)->endb)
925da2e3ebdSchin #define _SFOPEN(f)	((f)->mode == SF_READ  ? _SFOPENRD(f) : \
926da2e3ebdSchin 			 (f)->mode == SF_WRITE ? _SFOPENWR(f) : \
927da2e3ebdSchin 			 ((f)->endw = (f)->endr = (f)->data) )
928da2e3ebdSchin #define SFOPEN(f,l)	(void)((l) ? 0 : \
929da2e3ebdSchin 				((f)->mode &= ~(SF_LOCK|SF_RC|SF_RV), _SFOPEN(f), 0) )
930da2e3ebdSchin 
931da2e3ebdSchin /* check to see if the stream can be accessed */
932da2e3ebdSchin #define SFFROZEN(f)	(((f)->mode&(SF_PUSH|SF_LOCK|SF_PEEK)) ? 1 : \
933da2e3ebdSchin 			 !((f)->mode&SF_STDIO) ? 0 : \
934da2e3ebdSchin 			 _Sfstdsync ? (*_Sfstdsync)(f) : (((f)->mode &= ~SF_STDIO),0) )
935da2e3ebdSchin 
936da2e3ebdSchin 
937da2e3ebdSchin /* set discipline code */
938da2e3ebdSchin #define SFDISC(f,dc,iof) \
939da2e3ebdSchin 	{	Sfdisc_t* d; \
940da2e3ebdSchin 		if(!(dc)) \
941da2e3ebdSchin 			d = (dc) = (f)->disc; \
942da2e3ebdSchin 		else 	d = (f->bits&SF_DCDOWN) ? ((dc) = (dc)->disc) : (dc); \
943da2e3ebdSchin 		while(d && !(d->iof))	d = d->disc; \
944da2e3ebdSchin 		if(d)	(dc) = d; \
945da2e3ebdSchin 	}
946da2e3ebdSchin #define SFDCRD(f,buf,n,dc,rv) \
947da2e3ebdSchin 	{	int		dcdown = f->bits&SF_DCDOWN; f->bits |= SF_DCDOWN; \
948da2e3ebdSchin 		rv = (*dc->readf)(f,buf,n,dc); \
949da2e3ebdSchin 		if(!dcdown)	f->bits &= ~SF_DCDOWN; \
950da2e3ebdSchin 	}
951da2e3ebdSchin #define SFDCWR(f,buf,n,dc,rv) \
952da2e3ebdSchin 	{	int		dcdown = f->bits&SF_DCDOWN; f->bits |= SF_DCDOWN; \
953da2e3ebdSchin 		rv = (*dc->writef)(f,buf,n,dc); \
954da2e3ebdSchin 		if(!dcdown)	f->bits &= ~SF_DCDOWN; \
955da2e3ebdSchin 	}
956da2e3ebdSchin #define SFDCSK(f,addr,type,dc,rv) \
957da2e3ebdSchin 	{	int		dcdown = f->bits&SF_DCDOWN; f->bits |= SF_DCDOWN; \
958da2e3ebdSchin 		rv = (*dc->seekf)(f,addr,type,dc); \
959da2e3ebdSchin 		if(!dcdown)	f->bits &= ~SF_DCDOWN; \
960da2e3ebdSchin 	}
961da2e3ebdSchin 
962da2e3ebdSchin /* fast peek of a stream */
963da2e3ebdSchin #define _SFAVAIL(f,s,n)	((n) = (f)->endb - ((s) = (f)->next) )
964da2e3ebdSchin #define SFRPEEK(f,s,n)	(_SFAVAIL(f,s,n) > 0 ? (n) : \
965da2e3ebdSchin 				((n) = SFFILBUF(f,-1), (s) = (f)->next, (n)) )
966da2e3ebdSchin #define SFWPEEK(f,s,n)	(_SFAVAIL(f,s,n) > 0 ? (n) : \
967da2e3ebdSchin 				((n) = SFFLSBUF(f,-1), (s) = (f)->next, (n)) )
968da2e3ebdSchin 
969da2e3ebdSchin /* more than this for a line buffer, we might as well flush */
970da2e3ebdSchin #define HIFORLINE	128
971da2e3ebdSchin 
972da2e3ebdSchin /* string stream extent */
973da2e3ebdSchin #define SFSTRSIZE(f)	{ Sfoff_t s = (f)->next - (f)->data; \
974da2e3ebdSchin 			  if(s > (f)->here) \
975da2e3ebdSchin 			    { (f)->here = s; if(s > (f)->extent) (f)->extent = s; } \
976da2e3ebdSchin 			}
977da2e3ebdSchin 
978da2e3ebdSchin /* control flags for open() */
979da2e3ebdSchin #ifdef O_CREAT
980da2e3ebdSchin #define _has_oflags	1
981da2e3ebdSchin #else	/* for example, research UNIX */
982da2e3ebdSchin #define _has_oflags	0
983da2e3ebdSchin #define O_CREAT		004
984da2e3ebdSchin #define O_TRUNC		010
985da2e3ebdSchin #define O_APPEND	020
986da2e3ebdSchin #define O_EXCL		040
987da2e3ebdSchin 
988da2e3ebdSchin #ifndef O_RDONLY
989da2e3ebdSchin #define	O_RDONLY	000
990da2e3ebdSchin #endif
991da2e3ebdSchin #ifndef O_WRONLY
992da2e3ebdSchin #define O_WRONLY	001
993da2e3ebdSchin #endif
994da2e3ebdSchin #ifndef O_RDWR
995da2e3ebdSchin #define O_RDWR		002
996da2e3ebdSchin #endif
997da2e3ebdSchin #endif /*O_CREAT*/
998da2e3ebdSchin 
999da2e3ebdSchin #ifndef O_BINARY
1000da2e3ebdSchin #define O_BINARY	000
1001da2e3ebdSchin #endif
1002da2e3ebdSchin #ifndef O_TEXT
1003da2e3ebdSchin #define O_TEXT		000
1004da2e3ebdSchin #endif
1005da2e3ebdSchin #ifndef O_TEMPORARY
1006da2e3ebdSchin #define O_TEMPORARY	000
1007da2e3ebdSchin #endif
1008da2e3ebdSchin 
1009da2e3ebdSchin #define	SF_RADIX	64	/* maximum integer conversion base */
1010da2e3ebdSchin 
1011da2e3ebdSchin #if _PACKAGE_ast
1012da2e3ebdSchin #define SF_MAXINT	INT_MAX
1013da2e3ebdSchin #define SF_MAXLONG	LONG_MAX
1014da2e3ebdSchin #else
1015da2e3ebdSchin #define SF_MAXINT	((int)(((uint)~0) >> 1))
1016da2e3ebdSchin #define SF_MAXLONG	((long)(((ulong)~0L) >> 1))
1017da2e3ebdSchin #endif
1018da2e3ebdSchin 
1019da2e3ebdSchin #define SF_MAXCHAR	((uchar)(~0))
1020da2e3ebdSchin 
1021da2e3ebdSchin /* floating point to ascii conversion */
1022da2e3ebdSchin #define SF_MAXEXP10	6
1023da2e3ebdSchin #define SF_MAXPOW10	(1 << SF_MAXEXP10)
1024da2e3ebdSchin #if !_ast_fltmax_double
1025da2e3ebdSchin #define SF_FDIGITS	1024		/* max allowed fractional digits */
1026da2e3ebdSchin #define SF_IDIGITS	(8*1024)	/* max number of digits in int part */
1027da2e3ebdSchin #else
1028da2e3ebdSchin #define SF_FDIGITS	256		/* max allowed fractional digits */
1029da2e3ebdSchin #define SF_IDIGITS	1024		/* max number of digits in int part */
1030da2e3ebdSchin #endif
1031da2e3ebdSchin #define SF_MAXDIGITS	(((SF_FDIGITS+SF_IDIGITS)/sizeof(int) + 1)*sizeof(int))
1032da2e3ebdSchin 
1033da2e3ebdSchin /* tables for numerical translation */
1034da2e3ebdSchin #define _Sfpos10	(_Sftable.sf_pos10)
1035da2e3ebdSchin #define _Sfneg10	(_Sftable.sf_neg10)
1036da2e3ebdSchin #define _Sfdec		(_Sftable.sf_dec)
1037da2e3ebdSchin #define _Sfdigits	(_Sftable.sf_digits)
1038da2e3ebdSchin #define _Sfcvinitf	(_Sftable.sf_cvinitf)
1039da2e3ebdSchin #define _Sfcvinit	(_Sftable.sf_cvinit)
1040da2e3ebdSchin #define _Sffmtposf	(_Sftable.sf_fmtposf)
1041da2e3ebdSchin #define _Sffmtintf	(_Sftable.sf_fmtintf)
1042da2e3ebdSchin #define _Sfcv36		(_Sftable.sf_cv36)
1043da2e3ebdSchin #define _Sfcv64		(_Sftable.sf_cv64)
1044da2e3ebdSchin #define _Sftype		(_Sftable.sf_type)
1045da2e3ebdSchin #define _Sfieee		(&_Sftable.sf_ieee)
1046da2e3ebdSchin #define _Sffinf		(_Sftable.sf_ieee.fltinf)
1047da2e3ebdSchin #define _Sfdinf		(_Sftable.sf_ieee.dblinf)
1048da2e3ebdSchin #define _Sflinf		(_Sftable.sf_ieee.ldblinf)
1049da2e3ebdSchin #define _Sffnan		(_Sftable.sf_ieee.fltnan)
1050da2e3ebdSchin #define _Sfdnan		(_Sftable.sf_ieee.dblnan)
1051da2e3ebdSchin #define _Sflnan		(_Sftable.sf_ieee.ldblnan)
1052da2e3ebdSchin #define _Sffpow10	(_Sftable.sf_flt_pow10)
1053da2e3ebdSchin #define _Sfdpow10	(_Sftable.sf_dbl_pow10)
1054da2e3ebdSchin #define _Sflpow10	(_Sftable.sf_ldbl_pow10)
1055da2e3ebdSchin typedef struct _sfieee_s	Sfieee_t;
1056da2e3ebdSchin struct _sfieee_s
1057da2e3ebdSchin {	float		fltnan;		/* float NAN			*/
1058da2e3ebdSchin 	float		fltinf;		/* float INF			*/
1059da2e3ebdSchin 	double		dblnan;		/* double NAN			*/
1060da2e3ebdSchin 	double		dblinf;		/* double INF			*/
1061da2e3ebdSchin 	Sfdouble_t	ldblnan;	/* Sfdouble_t NAN		*/
1062da2e3ebdSchin 	Sfdouble_t	ldblinf;	/* Sfdouble_t INF		*/
1063da2e3ebdSchin };
1064da2e3ebdSchin typedef struct _sftab_
1065da2e3ebdSchin {	Sfdouble_t	sf_pos10[SF_MAXEXP10];	/* positive powers of 10	*/
1066da2e3ebdSchin 	Sfdouble_t	sf_neg10[SF_MAXEXP10];	/* negative powers of 10	*/
1067da2e3ebdSchin 	uchar		sf_dec[200];		/* ascii reps of values < 100	*/
1068da2e3ebdSchin 	char*		sf_digits;		/* digits for general bases	*/
1069da2e3ebdSchin 	int		(*sf_cvinitf)();	/* initialization function	*/
1070da2e3ebdSchin 	int		sf_cvinit;		/* initialization state		*/
1071da2e3ebdSchin 	Fmtpos_t*	(*sf_fmtposf)_ARG_((Sfio_t*,const char*,va_list,Sffmt_t*,int));
1072da2e3ebdSchin 	char*		(*sf_fmtintf)_ARG_((const char*,int*));
1073da2e3ebdSchin 	float*		sf_flt_pow10;		/* float powers of 10		*/
1074da2e3ebdSchin 	double*		sf_dbl_pow10;		/* double powers of 10		*/
1075da2e3ebdSchin 	Sfdouble_t*	sf_ldbl_pow10;		/* Sfdouble_t powers of 10	*/
1076da2e3ebdSchin 	uchar		sf_cv36[SF_MAXCHAR+1];	/* conversion for base [2-36]	*/
1077da2e3ebdSchin 	uchar		sf_cv64[SF_MAXCHAR+1];	/* conversion for base [37-64]	*/
1078da2e3ebdSchin 	uchar		sf_type[SF_MAXCHAR+1];	/* conversion formats&types	*/
1079da2e3ebdSchin 	Sfieee_t	sf_ieee;		/* IEEE floating point constants*/
1080da2e3ebdSchin } Sftab_t;
1081da2e3ebdSchin 
1082da2e3ebdSchin /* thread-safe macro/function to initialize _Sfcv* conversion tables */
1083da2e3ebdSchin #define SFCVINIT()      (_Sfcvinit ? 1 : (_Sfcvinit = (*_Sfcvinitf)()) )
1084da2e3ebdSchin 
1085da2e3ebdSchin /* sfucvt() converts decimal integers to ASCII */
1086da2e3ebdSchin #define SFDIGIT(v,scale,digit) \
1087da2e3ebdSchin 	{ if(v < 5*scale) \
1088da2e3ebdSchin 		if(v < 2*scale) \
1089da2e3ebdSchin 			if(v < 1*scale) \
1090da2e3ebdSchin 				{ digit = '0'; } \
1091da2e3ebdSchin 			else	{ digit = '1'; v -= 1*scale; } \
1092da2e3ebdSchin 		else	if(v < 3*scale) \
1093da2e3ebdSchin 				{ digit = '2'; v -= 2*scale; } \
1094da2e3ebdSchin 			else if(v < 4*scale) \
1095da2e3ebdSchin 				{ digit = '3'; v -= 3*scale; } \
1096da2e3ebdSchin 			else	{ digit = '4'; v -= 4*scale; } \
1097da2e3ebdSchin 	  else	if(v < 7*scale) \
1098da2e3ebdSchin 			if(v < 6*scale) \
1099da2e3ebdSchin 				{ digit = '5'; v -= 5*scale; } \
1100da2e3ebdSchin 			else	{ digit = '6'; v -= 6*scale; } \
1101da2e3ebdSchin 		else	if(v < 8*scale) \
1102da2e3ebdSchin 				{ digit = '7'; v -= 7*scale; } \
1103da2e3ebdSchin 			else if(v < 9*scale) \
1104da2e3ebdSchin 				{ digit = '8'; v -= 8*scale; } \
1105da2e3ebdSchin 			else	{ digit = '9'; v -= 9*scale; } \
1106da2e3ebdSchin 	}
1107da2e3ebdSchin #define sfucvt(v,s,n,list,type,utype) \
1108da2e3ebdSchin 	{ while((utype)v >= 10000) \
1109da2e3ebdSchin 	  {	n = v; v = (type)(((utype)v)/10000); \
1110da2e3ebdSchin 		n = (type)((utype)n - ((utype)v)*10000); \
1111da2e3ebdSchin 	  	s -= 4; SFDIGIT(n,1000,s[0]); SFDIGIT(n,100,s[1]); \
1112da2e3ebdSchin 			s[2] = *(list = (char*)_Sfdec + (n <<= 1)); s[3] = *(list+1); \
1113da2e3ebdSchin 	  } \
1114da2e3ebdSchin 	  if(v < 100) \
1115da2e3ebdSchin 	  { if(v < 10) \
1116da2e3ebdSchin 	    { 	s -= 1; s[0] = (char)('0'+v); \
1117da2e3ebdSchin 	    } else \
1118da2e3ebdSchin 	    { 	s -= 2; s[0] = *(list = (char*)_Sfdec + (v <<= 1)); s[1] = *(list+1); \
1119da2e3ebdSchin 	    } \
1120da2e3ebdSchin 	  } else \
1121da2e3ebdSchin 	  { if(v < 1000) \
1122da2e3ebdSchin 	    { 	s -= 3; SFDIGIT(v,100,s[0]); \
1123da2e3ebdSchin 			s[1] = *(list = (char*)_Sfdec + (v <<= 1)); s[2] = *(list+1); \
1124da2e3ebdSchin 	    } else \
1125da2e3ebdSchin 	    {	s -= 4; SFDIGIT(v,1000,s[0]); SFDIGIT(v,100,s[1]); \
1126da2e3ebdSchin 			s[2] = *(list = (char*)_Sfdec + (v <<= 1)); s[3] = *(list+1); \
1127da2e3ebdSchin 	    } \
1128da2e3ebdSchin 	  } \
1129da2e3ebdSchin 	}
1130da2e3ebdSchin 
1131da2e3ebdSchin /* handy functions */
1132da2e3ebdSchin #undef min
1133da2e3ebdSchin #undef max
1134da2e3ebdSchin #define min(x,y)	((x) < (y) ? (x) : (y))
1135da2e3ebdSchin #define max(x,y)	((x) > (y) ? (x) : (y))
1136da2e3ebdSchin 
1137da2e3ebdSchin /* fast functions for memory copy and memory clear */
1138da2e3ebdSchin #if _PACKAGE_ast
1139da2e3ebdSchin #define memclear(s,n)	memzero(s,n)
1140da2e3ebdSchin #else
1141da2e3ebdSchin #if _lib_bcopy && !_lib_memcpy
1142da2e3ebdSchin #define memcpy(to,fr,n)	bcopy((fr),(to),(n))
1143da2e3ebdSchin #endif
1144da2e3ebdSchin #if _lib_bzero && !_lib_memset
1145da2e3ebdSchin #define memclear(s,n)	bzero((s),(n))
1146da2e3ebdSchin #else
1147da2e3ebdSchin #define memclear(s,n)	memset((s),'\0',(n))
1148da2e3ebdSchin #endif
1149da2e3ebdSchin #endif /*_PACKAGE_ast*/
1150da2e3ebdSchin 
1151da2e3ebdSchin /* note that MEMCPY advances the associated pointers */
1152da2e3ebdSchin #define MEMCPY(to,fr,n) \
11535c16836eSToomas Soome 	{ memcpy((Void_t*)to,(Void_t*)fr,n); to += n; fr += n; }
1154da2e3ebdSchin #define MEMSET(s,c,n) \
11555c16836eSToomas Soome 	{ memset((Void_t*)s,(int)c,n); s += n; }
1156da2e3ebdSchin 
1157da2e3ebdSchin _BEGIN_EXTERNS_
1158da2e3ebdSchin 
1159da2e3ebdSchin extern Sftab_t		_Sftable;
1160da2e3ebdSchin 
1161da2e3ebdSchin extern int		_sfpopen _ARG_((Sfio_t*, int, int, int));
1162da2e3ebdSchin extern int		_sfpclose _ARG_((Sfio_t*));
1163da2e3ebdSchin extern int		_sfexcept _ARG_((Sfio_t*, int, ssize_t, Sfdisc_t*));
1164da2e3ebdSchin extern Sfrsrv_t*	_sfrsrv _ARG_((Sfio_t*, ssize_t));
1165da2e3ebdSchin extern int		_sfsetpool _ARG_((Sfio_t*));
11667c2fbfb3SApril Chin extern char*		_sfcvt _ARG_((Void_t*,char*,size_t,int,int*,int*,int*,int));
1167da2e3ebdSchin extern char**		_sfgetpath _ARG_((char*));
1168da2e3ebdSchin 
1169da2e3ebdSchin #if _BLD_sfio && defined(__EXPORT__)
1170da2e3ebdSchin #define extern		__EXPORT__
1171da2e3ebdSchin #endif
1172da2e3ebdSchin #if !_BLD_sfio && defined(__IMPORT__)
1173da2e3ebdSchin #define extern		extern __IMPORT__
1174da2e3ebdSchin #endif
1175da2e3ebdSchin 
1176da2e3ebdSchin extern Sfextern_t	_Sfextern;
1177da2e3ebdSchin 
1178da2e3ebdSchin extern int		_sfmode _ARG_((Sfio_t*, int, int));
1179*b30d1939SAndy Fiddaman extern int		_sftype _ARG_((const char*, int*, int*, int*));
1180da2e3ebdSchin 
1181da2e3ebdSchin #undef	extern
1182da2e3ebdSchin 
1183da2e3ebdSchin #ifndef errno
1184da2e3ebdSchin extern int		errno;
1185da2e3ebdSchin #endif
1186da2e3ebdSchin 
1187da2e3ebdSchin /* for portable encoding of double values */
1188da2e3ebdSchin #ifndef frexpl
1189da2e3ebdSchin #if _ast_fltmax_double
1190da2e3ebdSchin #define frexpl		frexp
1191da2e3ebdSchin #endif
1192*b30d1939SAndy Fiddaman #if !_lib_frexpl
1193da2e3ebdSchin extern Sfdouble_t	frexpl _ARG_((Sfdouble_t, int*));
1194da2e3ebdSchin #endif
1195da2e3ebdSchin #endif
1196da2e3ebdSchin #ifndef ldexpl
1197da2e3ebdSchin #if _ast_fltmax_double
1198da2e3ebdSchin #define ldexpl		ldexp
1199da2e3ebdSchin #endif
1200*b30d1939SAndy Fiddaman #if !_lib_ldexpl
1201da2e3ebdSchin extern Sfdouble_t	ldexpl _ARG_((Sfdouble_t, int));
1202da2e3ebdSchin #endif
1203da2e3ebdSchin #endif
1204da2e3ebdSchin 
1205da2e3ebdSchin #if !_PACKAGE_ast
1206da2e3ebdSchin 
1207da2e3ebdSchin #if !__STDC__ && !_hdr_stdlib
1208da2e3ebdSchin extern void	abort _ARG_((void));
1209da2e3ebdSchin extern int	atexit _ARG_((void(*)(void)));
1210da2e3ebdSchin extern char*	getenv _ARG_((const char*));
1211da2e3ebdSchin extern void*	malloc _ARG_((size_t));
1212da2e3ebdSchin extern void*	realloc _ARG_((void*, size_t));
1213da2e3ebdSchin extern void	free _ARG_((void*));
1214da2e3ebdSchin extern size_t	strlen _ARG_((const char*));
1215da2e3ebdSchin extern char*	strcpy _ARG_((char*, const char*));
1216da2e3ebdSchin 
1217da2e3ebdSchin extern Void_t*	memset _ARG_((void*, int, size_t));
1218da2e3ebdSchin extern Void_t*	memchr _ARG_((const void*, int, size_t));
1219da2e3ebdSchin extern Void_t*	memccpy _ARG_((void*, const void*, int, size_t));
1220da2e3ebdSchin #ifndef memcpy
1221da2e3ebdSchin extern Void_t*	memcpy _ARG_((void*, const void*, size_t));
1222da2e3ebdSchin #endif
1223da2e3ebdSchin #if !defined(strtod)
1224da2e3ebdSchin extern double	strtod _ARG_((const char*, char**));
1225da2e3ebdSchin #endif
1226da2e3ebdSchin #if !defined(remove)
1227da2e3ebdSchin extern int	sysremovef _ARG_((const char*));
1228da2e3ebdSchin #endif
1229da2e3ebdSchin #endif /* !__STDC__ && !_hdr_stdlib */
1230da2e3ebdSchin 
1231da2e3ebdSchin #if !_hdr_unistd
1232da2e3ebdSchin #if _proto_open && __cplusplus
1233da2e3ebdSchin extern int	sysopenf _ARG_((const char*, int, ...));
1234da2e3ebdSchin #endif
1235da2e3ebdSchin extern int	sysclosef _ARG_((int));
1236da2e3ebdSchin extern ssize_t	sysreadf _ARG_((int, void*, size_t));
1237da2e3ebdSchin extern ssize_t	syswritef _ARG_((int, const void*, size_t));
1238da2e3ebdSchin extern sfoff_t	syslseekf _ARG_((int, sfoff_t, int));
1239da2e3ebdSchin extern int	sysdupf _ARG_((int));
1240da2e3ebdSchin extern int	syspipef _ARG_((int*));
1241da2e3ebdSchin extern int	sysaccessf _ARG_((const char*, int));
1242da2e3ebdSchin extern int	sysremovef _ARG_((const char*));
1243da2e3ebdSchin extern int	sysfstatf _ARG_((int, sfstat_t*));
1244da2e3ebdSchin extern int	sysstatf _ARG_((const char*, sfstat_t*));
1245da2e3ebdSchin 
1246da2e3ebdSchin extern int	isatty _ARG_((int));
1247da2e3ebdSchin 
1248da2e3ebdSchin extern int	wait _ARG_((int*));
1249da2e3ebdSchin extern uint	sleep _ARG_((uint));
1250da2e3ebdSchin extern int	execl _ARG_((const char*, const char*,...));
1251da2e3ebdSchin extern int	execv _ARG_((const char*, char**));
1252da2e3ebdSchin #if !defined(fork)
1253da2e3ebdSchin extern int	fork _ARG_((void));
1254da2e3ebdSchin #endif
1255da2e3ebdSchin #if _lib_unlink
1256da2e3ebdSchin extern int	unlink _ARG_((const char*));
1257da2e3ebdSchin #endif
1258da2e3ebdSchin 
1259da2e3ebdSchin #endif /*_hdr_unistd*/
1260da2e3ebdSchin 
1261da2e3ebdSchin #if _lib_bcopy && !_proto_bcopy
1262da2e3ebdSchin extern void	bcopy _ARG_((const void*, void*, size_t));
1263da2e3ebdSchin #endif
1264da2e3ebdSchin #if _lib_bzero && !_proto_bzero
1265da2e3ebdSchin extern void	bzero _ARG_((void*, size_t));
1266da2e3ebdSchin #endif
1267da2e3ebdSchin 
1268da2e3ebdSchin extern time_t	time _ARG_((time_t*));
1269da2e3ebdSchin extern int	waitpid _ARG_((int,int*,int));
1270da2e3ebdSchin extern void	_exit _ARG_((int));
1271da2e3ebdSchin typedef int(*	Onexit_f)_ARG_((void));
1272da2e3ebdSchin extern Onexit_f	onexit _ARG_((Onexit_f));
1273da2e3ebdSchin 
1274da2e3ebdSchin #if _lib_vfork && !_hdr_vfork && !_sys_vfork
1275da2e3ebdSchin extern pid_t	vfork _ARG_((void));
1276da2e3ebdSchin #endif /*_lib_vfork*/
1277da2e3ebdSchin 
1278da2e3ebdSchin #if _lib_poll
1279da2e3ebdSchin #if _lib_poll_fd_1
1280da2e3ebdSchin extern int	poll _ARG_((struct pollfd*, ulong, int));
1281da2e3ebdSchin #else
1282da2e3ebdSchin extern int	poll _ARG_((ulong, struct pollfd*, int));
1283da2e3ebdSchin #endif
1284da2e3ebdSchin #endif /*_lib_poll*/
1285da2e3ebdSchin 
1286da2e3ebdSchin #endif /* _PACKAGE_ast */
1287da2e3ebdSchin 
1288da2e3ebdSchin _END_EXTERNS_
1289da2e3ebdSchin 
1290da2e3ebdSchin #endif /*_SFHDR_H*/
1291