1da2e3ebchin/***********************************************************************
2da2e3ebchin*                                                                      *
3da2e3ebchin*               This software is part of the ast package               *
43e14f97Roger A. Faulkner*          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5da2e3ebchin*                      and is licensed under the                       *
6da2e3ebchin*                  Common Public License, Version 1.0                  *
77c2fbfbApril Chin*                    by AT&T Intellectual Property                     *
8da2e3ebchin*                                                                      *
9da2e3ebchin*                A copy of the License is available at                 *
10da2e3ebchin*            http://www.opensource.org/licenses/cpl1.0.txt             *
11da2e3ebchin*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12da2e3ebchin*                                                                      *
13da2e3ebchin*              Information and Software Systems Research               *
14da2e3ebchin*                            AT&T Research                             *
15da2e3ebchin*                           Florham Park NJ                            *
16da2e3ebchin*                                                                      *
17da2e3ebchin*                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebchin*                  David Korn <dgk@research.att.com>                   *
19da2e3ebchin*                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebchin*                                                                      *
21da2e3ebchin***********************************************************************/
22da2e3ebchin#ifndef _SFIO_H
23da2e3ebchin#define _SFIO_H	1
24da2e3ebchin
257c2fbfbApril Chin#define SFIO_VERSION	20080717L
26da2e3ebchin
27da2e3ebchin/*	Public header file for the sfio library
28da2e3ebchin**
29da2e3ebchin**	Written by Kiem-Phong Vo
30da2e3ebchin*/
31da2e3ebchin
32da2e3ebchintypedef struct _sfio_s		Sfio_t;
33da2e3ebchintypedef struct _sfdisc_s	Sfdisc_t;
34da2e3ebchin
35da2e3ebchin#if defined(_AST_STD_H) || defined(_PACKAGE_ast) && defined(_SFIO_PRIVATE)
36da2e3ebchin#include	<ast_std.h>
37da2e3ebchin#else
38da2e3ebchin#include	<ast_common.h>
39da2e3ebchin#endif /* _PACKAGE_ast */
40da2e3ebchin
41da2e3ebchin/* Sfoff_t should be large enough for largest file address */
42da2e3ebchin#define Sfoff_t		intmax_t
43da2e3ebchin#define Sflong_t	intmax_t
44da2e3ebchin#define Sfulong_t	uintmax_t
45da2e3ebchin#define Sfdouble_t	_ast_fltmax_t
46da2e3ebchin
47da2e3ebchintypedef ssize_t		(*Sfread_f)_ARG_((Sfio_t*, Void_t*, size_t, Sfdisc_t*));
48da2e3ebchintypedef ssize_t		(*Sfwrite_f)_ARG_((Sfio_t*, const Void_t*, size_t, Sfdisc_t*));
49da2e3ebchintypedef Sfoff_t		(*Sfseek_f)_ARG_((Sfio_t*, Sfoff_t, int, Sfdisc_t*));
50da2e3ebchintypedef int		(*Sfexcept_f)_ARG_((Sfio_t*, int, Void_t*, Sfdisc_t*));
5134f9b3eRoland Mainztypedef int		(*Sfwalk_f)_ARG_((Sfio_t*, Void_t*));
52da2e3ebchin
53da2e3ebchin/* discipline structure */
54da2e3ebchinstruct _sfdisc_s
55da2e3ebchin{	Sfread_f	readf;		/* read function		*/
56da2e3ebchin	Sfwrite_f	writef;		/* write function		*/
57da2e3ebchin	Sfseek_f	seekf;		/* seek function		*/
58da2e3ebchin	Sfexcept_f	exceptf;	/* to handle exceptions		*/
59da2e3ebchin	Sfdisc_t*	disc;		/* the continuing discipline	*/
60da2e3ebchin};
61da2e3ebchin
62da2e3ebchin#include <sfio_s.h>
63da2e3ebchin
64da2e3ebchin/* formatting environment */
65da2e3ebchintypedef struct _sffmt_s	Sffmt_t;
66da2e3ebchintypedef int		(*Sffmtext_f)_ARG_((Sfio_t*, Void_t*, Sffmt_t*));
67da2e3ebchintypedef int		(*Sffmtevent_f)_ARG_((Sfio_t*, int, Void_t*, Sffmt_t*));
68da2e3ebchinstruct _sffmt_s
69da2e3ebchin{	long		version;/* version of this structure		*/
70da2e3ebchin	Sffmtext_f	extf;	/* function to process arguments	*/
71da2e3ebchin	Sffmtevent_f	eventf;	/* process events			*/
72da2e3ebchin
73da2e3ebchin	char*		form;	/* format string to stack		*/
74da2e3ebchin	va_list	args;	/* corresponding arg list		*/
75da2e3ebchin
76da2e3ebchin	int		fmt;	/* format character			*/
77da2e3ebchin	ssize_t		size;	/* object size				*/
78da2e3ebchin	int		flags;	/* formatting flags			*/
79da2e3ebchin	int		width;	/* width of field			*/
80da2e3ebchin	int		precis;	/* precision required			*/
81da2e3ebchin	int		base;	/* conversion base			*/
82da2e3ebchin
83da2e3ebchin	char*		t_str;	/* type string 				*/
84da2e3ebchin	ssize_t		n_str;	/* length of t_str 			*/
85da2e3ebchin
86da2e3ebchin	Void_t*		mbs;	/* multibyte state for format string	*/
87da2e3ebchin
88da2e3ebchin	Void_t*		none;	/* unused for now			*/
89da2e3ebchin};
90da2e3ebchin#define sffmtversion(fe,type) \
91da2e3ebchin		((type) ? ((fe)->version = SFIO_VERSION) : (fe)->version)
92da2e3ebchin
93da2e3ebchin#define SFFMT_SSHORT	000000010 /* 'hh' flag, char			*/
94da2e3ebchin#define SFFMT_TFLAG	000000020 /* 't' flag, ptrdiff_t			*/
95da2e3ebchin#define SFFMT_ZFLAG	000000040 /* 'z' flag, size_t			*/
96da2e3ebchin
97da2e3ebchin#define SFFMT_LEFT	000000100 /* left-justification			*/
98da2e3ebchin#define SFFMT_SIGN	000000200 /* must have a sign			*/
99da2e3ebchin#define SFFMT_BLANK	000000400 /* if not signed, prepend a blank	*/
100da2e3ebchin#define SFFMT_ZERO	000001000 /* zero-padding on the left		*/
101da2e3ebchin#define SFFMT_ALTER	000002000 /* alternate formatting		*/
102da2e3ebchin#define SFFMT_THOUSAND	000004000 /* thousand grouping			*/
103da2e3ebchin#define SFFMT_SKIP	000010000 /* skip assignment in scanf()		*/
104da2e3ebchin#define SFFMT_SHORT	000020000 /* 'h' flag				*/
105da2e3ebchin#define SFFMT_LONG	000040000 /* 'l' flag				*/
106da2e3ebchin#define SFFMT_LLONG	000100000 /* 'll' flag				*/
107da2e3ebchin#define SFFMT_LDOUBLE	000200000 /* 'L' flag				*/
108da2e3ebchin#define SFFMT_VALUE	000400000 /* value is returned			*/
109da2e3ebchin#define SFFMT_ARGPOS	001000000 /* getting arg for $ patterns		*/
110da2e3ebchin#define SFFMT_IFLAG	002000000 /* 'I' flag				*/
111da2e3ebchin#define SFFMT_JFLAG	004000000 /* 'j' flag, intmax_t			*/
112da2e3ebchin#define SFFMT_CENTER	010000000 /* '=' flag, center justification	*/
113da2e3ebchin#define SFFMT_SET	017777770 /* flags settable on calling extf	*/
114da2e3ebchin
115da2e3ebchin/* for sfmutex() call */
116da2e3ebchin#define SFMTX_LOCK	0	/* up mutex count			*/
117da2e3ebchin#define SFMTX_TRYLOCK	1	/* try to up mutex count		*/
118da2e3ebchin#define SFMTX_UNLOCK	2	/* down mutex count			*/
119da2e3ebchin#define SFMTX_CLRLOCK	3	/* clear mutex count			*/
120da2e3ebchin
121da2e3ebchin/* various constants */
122da2e3ebchin#ifndef NULL
123da2e3ebchin#define NULL		0
124da2e3ebchin#endif
125da2e3ebchin#ifndef EOF
126da2e3ebchin#define EOF		(-1)
127da2e3ebchin#endif
128da2e3ebchin#ifndef SEEK_SET
129da2e3ebchin#define SEEK_SET	0
130da2e3ebchin#define SEEK_CUR	1
131da2e3ebchin#define SEEK_END	2
132da2e3ebchin#endif
133da2e3ebchin
134da2e3ebchin/* bits for various types of files */
135da2e3ebchin#define	SF_READ		0000001	/* open for reading			*/
136da2e3ebchin#define SF_WRITE	0000002	/* open for writing			*/
137da2e3ebchin#define SF_STRING	0000004	/* a string stream			*/
138da2e3ebchin#define SF_APPENDWR	0000010	/* file is in append mode only		*/
139da2e3ebchin#define SF_MALLOC	0000020	/* buffer is malloc-ed			*/
140da2e3ebchin#define SF_LINE		0000040	/* line buffering			*/
141da2e3ebchin#define SF_SHARE	0000100	/* stream with shared file descriptor 	*/
142da2e3ebchin#define SF_EOF		0000200	/* eof was detected			*/
143da2e3ebchin#define SF_ERROR	0000400	/* an error happened			*/
144da2e3ebchin#define SF_STATIC	0001000	/* a stream that cannot be freed	*/
145da2e3ebchin#define SF_IOCHECK	0002000	/* call exceptf before doing IO		*/
146da2e3ebchin#define SF_PUBLIC	0004000	/* SF_SHARE and follow physical seek	*/
147da2e3ebchin#define SF_MTSAFE	0010000	/* need thread safety			*/
148da2e3ebchin#define SF_WHOLE	0020000	/* preserve wholeness of sfwrite/sfputr */
149da2e3ebchin#define SF_IOINTR	0040000	/* return on interrupts			*/
150da2e3ebchin#define SF_WCWIDTH	0100000	/* wcwidth display stream		*/
151da2e3ebchin
152da2e3ebchin#define SF_FLAGS	0177177	/* PUBLIC FLAGS PASSABLE TO SFNEW()	*/
153da2e3ebchin#define SF_SETS		0177163	/* flags passable to sfset()		*/
154da2e3ebchin
155da2e3ebchin#ifndef _SF_NO_OBSOLETE
156da2e3ebchin#define SF_BUFCONST	0400000 /* unused flag - for compatibility only	*/
157da2e3ebchin#endif
158da2e3ebchin
159da2e3ebchin/* for sfgetr/sfreserve to hold a record */
160da2e3ebchin#define SF_LOCKR	0000010	/* lock record, stop access to stream	*/
161da2e3ebchin#define SF_LASTR	0000020	/* get the last incomplete record	*/
162da2e3ebchin
163da2e3ebchin/* exception events: SF_NEW(0), SF_READ(1), SF_WRITE(2) and the below 	*/
164da2e3ebchin#define SF_SEEK		3	/* seek error				*/
165da2e3ebchin#define SF_CLOSING	4	/* when stream is about to be closed	*/
166da2e3ebchin#define SF_DPUSH	5	/* when discipline is being pushed	*/
167da2e3ebchin#define SF_DPOP		6	/* when discipline is being popped	*/
168da2e3ebchin#define SF_DPOLL	7	/* see if stream is ready for I/O	*/
169da2e3ebchin#define SF_DBUFFER	8	/* buffer not empty during push or pop	*/
170da2e3ebchin#define SF_SYNC		9	/* announcing start/end synchronization */
171da2e3ebchin#define SF_PURGE	10	/* a sfpurge() call was issued		*/
172da2e3ebchin#define SF_FINAL	11	/* closing is done except stream free	*/
173da2e3ebchin#define SF_READY	12	/* a polled stream is ready		*/
174da2e3ebchin#define SF_LOCKED	13	/* stream is in a locked state		*/
175da2e3ebchin#define SF_ATEXIT	14	/* process is exiting			*/
176da2e3ebchin#define SF_EVENT	100	/* start of user-defined events		*/
177da2e3ebchin
178da2e3ebchin/* for stack and disciplines */
179da2e3ebchin#define SF_POPSTACK	((Sfio_t*)0)	/* pop the stream stack		*/
180da2e3ebchin#define SF_POPDISC	((Sfdisc_t*)0)	/* pop the discipline stack	*/
181da2e3ebchin
182da2e3ebchin/* for the notify function and discipline exception */
183da2e3ebchin#define SF_NEW		0	/* new stream				*/
184da2e3ebchin#define SF_SETFD	(-1)	/* about to set the file descriptor 	*/
1857c2fbfbApril Chin#define SF_MTACCESS	(-2)	/* starting a multi-threaded stream	*/
186da2e3ebchin
187da2e3ebchin#define SF_BUFSIZE	8192	/* default buffer size			*/
188da2e3ebchin#define SF_UNBOUND	(-1)	/* unbounded buffer size		*/
189da2e3ebchin
190da2e3ebchin/* namespace incursion workarounds -- migrate to the new names */
191da2e3ebchin#if !_mac_SF_APPEND
192da2e3ebchin#define SF_APPEND	SF_APPENDWR	/* BSDI sys/stat.h		*/
193da2e3ebchin#endif
194da2e3ebchin#if !_mac_SF_CLOSE
195da2e3ebchin#define SF_CLOSE	SF_CLOSING	/* AIX sys/socket.h		*/
196da2e3ebchin#endif
197da2e3ebchin
198da2e3ebchin_BEGIN_EXTERNS_
199da2e3ebchin
200da2e3ebchin/* standard in/out/err streams */
201da2e3ebchin
202da2e3ebchin#if _BLD_sfio && defined(__EXPORT__)
203da2e3ebchin#define extern		extern __EXPORT__
204da2e3ebchin#endif
205da2e3ebchin#if !_BLD_sfio && defined(__IMPORT__)
206da2e3ebchin#define extern		extern __IMPORT__
207da2e3ebchin#endif
208da2e3ebchin
209da2e3ebchinextern ssize_t		_Sfi;
210da2e3ebchinextern ssize_t		_Sfmaxr;
211da2e3ebchin
212da2e3ebchinextern Sfio_t*		sfstdin;
213da2e3ebchinextern Sfio_t*		sfstdout;
214da2e3ebchinextern Sfio_t*		sfstderr;
215da2e3ebchin
216da2e3ebchin#if _UWIN
217da2e3ebchin#undef	extern
218da2e3ebchin#endif
219da2e3ebchin
220da2e3ebchinextern Sfio_t		_Sfstdin;
221da2e3ebchinextern Sfio_t		_Sfstdout;
222da2e3ebchinextern Sfio_t		_Sfstderr;
223da2e3ebchin
224da2e3ebchin#undef	extern
225da2e3ebchin
226da2e3ebchin#if _BLD_sfio && defined(__EXPORT__)
227da2e3ebchin#define extern	__EXPORT__
228da2e3ebchin#endif
229da2e3ebchin
230da2e3ebchinextern Sfio_t*		sfnew _ARG_((Sfio_t*, Void_t*, size_t, int, int));
231da2e3ebchinextern Sfio_t*		sfopen _ARG_((Sfio_t*, const char*, const char*));
232da2e3ebchinextern Sfio_t*		sfpopen _ARG_((Sfio_t*, const char*, const char*));
233da2e3ebchinextern Sfio_t*		sfstack _ARG_((Sfio_t*, Sfio_t*));
234da2e3ebchinextern Sfio_t*		sfswap _ARG_((Sfio_t*, Sfio_t*));
235da2e3ebchinextern Sfio_t*		sftmp _ARG_((size_t));
23634f9b3eRoland Mainzextern int		sfwalk _ARG_((Sfwalk_f, Void_t*, int));
237da2e3ebchinextern int		sfpurge _ARG_((Sfio_t*));
238da2e3ebchinextern int		sfpoll _ARG_((Sfio_t**, int, int));
239da2e3ebchinextern Void_t*		sfreserve _ARG_((Sfio_t*, ssize_t, int));
240da2e3ebchinextern int		sfresize _ARG_((Sfio_t*, Sfoff_t));
241da2e3ebchinextern int		sfsync _ARG_((Sfio_t*));
242da2e3ebchinextern int		sfclrlock _ARG_((Sfio_t*));
243da2e3ebchinextern Void_t*		sfsetbuf _ARG_((Sfio_t*, Void_t*, size_t));
244da2e3ebchinextern Sfdisc_t*	sfdisc _ARG_((Sfio_t*,Sfdisc_t*));
245da2e3ebchinextern int		sfraise _ARG_((Sfio_t*, int, Void_t*));
2467c2fbfbApril Chinextern int		sfnotify _ARG_((void(*)(Sfio_t*, int, void*)));
247da2e3ebchinextern int		sfset _ARG_((Sfio_t*, int, int));
248da2e3ebchinextern int		sfsetfd _ARG_((Sfio_t*, int));
249da2e3ebchinextern Sfio_t*		sfpool _ARG_((Sfio_t*, Sfio_t*, int));
250da2e3ebchinextern ssize_t		sfread _ARG_((Sfio_t*, Void_t*, size_t));
251da2e3ebchinextern ssize_t		sfwrite _ARG_((Sfio_t*, const Void_t*, size_t));
252da2e3ebchinextern Sfoff_t		sfmove _ARG_((Sfio_t*, Sfio_t*, Sfoff_t, int));
253da2e3ebchinextern int		sfclose _ARG_((Sfio_t*));
254da2e3ebchinextern Sfoff_t		sftell _ARG_((Sfio_t*));
255da2e3ebchinextern Sfoff_t		sfseek _ARG_((Sfio_t*, Sfoff_t, int));
256da2e3ebchinextern ssize_t		sfputr _ARG_((Sfio_t*, const char*, int));
257da2e3ebchinextern char*		sfgetr _ARG_((Sfio_t*, int, int));
258da2e3ebchinextern ssize_t		sfnputc _ARG_((Sfio_t*, int, size_t));
259da2e3ebchinextern int		sfungetc _ARG_((Sfio_t*, int));
260da2e3ebchinextern int		sfprintf _ARG_((Sfio_t*, const char*, ...));
261da2e3ebchinextern char*		sfprints _ARG_((const char*, ...));
262da2e3ebchinextern ssize_t		sfsprintf _ARG_((char*, size_t, const char*, ...));
263da2e3ebchinextern ssize_t		sfvsprintf _ARG_((char*, size_t, const char*, va_list));
264da2e3ebchinextern int		sfvprintf _ARG_((Sfio_t*, const char*, va_list));
265da2e3ebchinextern int		sfscanf _ARG_((Sfio_t*, const char*, ...));
266da2e3ebchinextern int		sfsscanf _ARG_((const char*, const char*, ...));
267da2e3ebchinextern int		sfvsscanf _ARG_((const char*, const char*, va_list));
268da2e3ebchinextern int		sfvscanf _ARG_((Sfio_t*, const char*, va_list));
269da2e3ebchin
270da2e3ebchin/* mutex locking for thread-safety */
271da2e3ebchinextern int		sfmutex _ARG_((Sfio_t*, int));
272da2e3ebchin
273da2e3ebchin/* io functions with discipline continuation */
274da2e3ebchinextern ssize_t		sfrd _ARG_((Sfio_t*, Void_t*, size_t, Sfdisc_t*));
275da2e3ebchinextern ssize_t		sfwr _ARG_((Sfio_t*, const Void_t*, size_t, Sfdisc_t*));
276da2e3ebchinextern Sfoff_t		sfsk _ARG_((Sfio_t*, Sfoff_t, int, Sfdisc_t*));
277da2e3ebchinextern ssize_t		sfpkrd _ARG_((int, Void_t*, size_t, int, long, int));
278da2e3ebchin
279da2e3ebchin/* portable handling of primitive types */
280da2e3ebchinextern int		sfdlen _ARG_((Sfdouble_t));
281da2e3ebchinextern int		sfllen _ARG_((Sflong_t));
282da2e3ebchinextern int		sfulen _ARG_((Sfulong_t));
283da2e3ebchin
284da2e3ebchinextern int		sfputd _ARG_((Sfio_t*, Sfdouble_t));
285da2e3ebchinextern int		sfputl _ARG_((Sfio_t*, Sflong_t));
286da2e3ebchinextern int		sfputu _ARG_((Sfio_t*, Sfulong_t));
287da2e3ebchinextern int		sfputm _ARG_((Sfio_t*, Sfulong_t, Sfulong_t));
288da2e3ebchinextern int		sfputc _ARG_((Sfio_t*, int));
289da2e3ebchin
290da2e3ebchinextern Sfdouble_t	sfgetd _ARG_((Sfio_t*));
291da2e3ebchinextern Sflong_t		sfgetl _ARG_((Sfio_t*));
292da2e3ebchinextern Sfulong_t	sfgetu _ARG_((Sfio_t*));
293da2e3ebchinextern Sfulong_t	sfgetm _ARG_((Sfio_t*, Sfulong_t));
294da2e3ebchinextern int		sfgetc _ARG_((Sfio_t*));
295da2e3ebchin
296da2e3ebchinextern int		_sfputd _ARG_((Sfio_t*, Sfdouble_t));
297da2e3ebchinextern int		_sfputl _ARG_((Sfio_t*, Sflong_t));
298da2e3ebchinextern int		_sfputu _ARG_((Sfio_t*, Sfulong_t));
299da2e3ebchinextern int		_sfputm _ARG_((Sfio_t*, Sfulong_t, Sfulong_t));
300da2e3ebchinextern int		_sfflsbuf _ARG_((Sfio_t*, int));
301da2e3ebchin
302da2e3ebchinextern int		_sffilbuf _ARG_((Sfio_t*, int));
303da2e3ebchin
304da2e3ebchinextern int		_sfdlen _ARG_((Sfdouble_t));
305da2e3ebchinextern int		_sfllen _ARG_((Sflong_t));
306da2e3ebchinextern int		_sfulen _ARG_((Sfulong_t));
307da2e3ebchin
308da2e3ebchin/* miscellaneous function analogues of fast in-line functions */
309da2e3ebchinextern Sfoff_t		sfsize _ARG_((Sfio_t*));
310da2e3ebchinextern int		sfclrerr _ARG_((Sfio_t*));
311da2e3ebchinextern int		sfeof _ARG_((Sfio_t*));
312da2e3ebchinextern int		sferror _ARG_((Sfio_t*));
313da2e3ebchinextern int		sffileno _ARG_((Sfio_t*));
314da2e3ebchinextern int		sfstacked _ARG_((Sfio_t*));
315da2e3ebchinextern ssize_t		sfvalue _ARG_((Sfio_t*));
316da2e3ebchinextern ssize_t		sfslen _ARG_((void));
317da2e3ebchinextern ssize_t		sfmaxr _ARG_((ssize_t, int));
318da2e3ebchin
319da2e3ebchin#undef extern
320da2e3ebchin_END_EXTERNS_
321da2e3ebchin
322da2e3ebchin/* coding long integers in a portable and compact fashion */
323da2e3ebchin#define SF_SBITS	6
324da2e3ebchin#define SF_UBITS	7
325da2e3ebchin#define SF_BBITS	8
326da2e3ebchin#define SF_SIGN		(1 << SF_SBITS)
327da2e3ebchin#define SF_MORE		(1 << SF_UBITS)
328da2e3ebchin#define SF_BYTE		(1 << SF_BBITS)
329da2e3ebchin#define SF_U1		SF_MORE
330da2e3ebchin#define SF_U2		(SF_U1*SF_U1)
331da2e3ebchin#define SF_U3		(SF_U2*SF_U1)
332da2e3ebchin#define SF_U4		(SF_U3*SF_U1)
333da2e3ebchin
334da2e3ebchin#if __cplusplus
335da2e3ebchin#define _SF_(f)		(f)
336da2e3ebchin#else
337da2e3ebchin#define _SF_(f)		((Sfio_t*)(f))
338da2e3ebchin#endif
339da2e3ebchin
340da2e3ebchin#define __sf_putd(f,v)		(_sfputd(_SF_(f),(Sfdouble_t)(v)))
341da2e3ebchin#define __sf_putl(f,v)		(_sfputl(_SF_(f),(Sflong_t)(v)))
342da2e3ebchin#define __sf_putu(f,v)		(_sfputu(_SF_(f),(Sfulong_t)(v)))
343da2e3ebchin#define __sf_putm(f,v,m)	(_sfputm(_SF_(f),(Sfulong_t)(v),(Sfulong_t)(m)))
344da2e3ebchin
345da2e3ebchin#define __sf_putc(f,c)	(_SF_(f)->_next >= _SF_(f)->_endw ? \
346da2e3ebchin			 _sfflsbuf(_SF_(f),(int)((unsigned char)(c))) : \
347da2e3ebchin			 (int)(*_SF_(f)->_next++ = (unsigned char)(c)) )
348da2e3ebchin#define __sf_getc(f)	(_SF_(f)->_next >= _SF_(f)->_endr ? _sffilbuf(_SF_(f),0) : \
349da2e3ebchin			 (int)(*_SF_(f)->_next++) )
350da2e3ebchin
351da2e3ebchin#define __sf_dlen(v)	(_sfdlen((Sfdouble_t)(v)) )
352da2e3ebchin#define __sf_llen(v)	(_sfllen((Sflong_t)(v)) )
353da2e3ebchin#define __sf_ulen(v)	((Sfulong_t)(v) < SF_U1 ? 1 : (Sfulong_t)(v) < SF_U2 ? 2 : \
354da2e3ebchin			 (Sfulong_t)(v) < SF_U3 ? 3 : (Sfulong_t)(v) < SF_U4 ? 4 : 5)
355da2e3ebchin
356da2e3ebchin#define __sf_fileno(f)	(_SF_(f)->_file)
357da2e3ebchin#define __sf_eof(f)	(_SF_(f)->_flags&SF_EOF)
358da2e3ebchin#define __sf_error(f)	(_SF_(f)->_flags&SF_ERROR)
359da2e3ebchin#define __sf_clrerr(f)	(_SF_(f)->_flags &= ~(SF_ERROR|SF_EOF))
360da2e3ebchin#define __sf_stacked(f)	(_SF_(f)->_push != (Sfio_t*)0)
361da2e3ebchin#define __sf_value(f)	(_SF_(f)->_val)
362da2e3ebchin#define __sf_slen()	(_Sfi)
363da2e3ebchin#define __sf_maxr(n,s)	((s)?((_Sfi=_Sfmaxr),(_Sfmaxr=(n)),_Sfi):_Sfmaxr)
364da2e3ebchin
365da2e3ebchin#if defined(__INLINE__) && !_BLD_sfio
366da2e3ebchin
367da2e3ebchin__INLINE__ int sfputd(Sfio_t* f, Sfdouble_t v)	{ return __sf_putd(f,v); }
368da2e3ebchin__INLINE__ int sfputl(Sfio_t* f, Sflong_t v)	{ return __sf_putl(f,v); }
369da2e3ebchin__INLINE__ int sfputu(Sfio_t* f, Sfulong_t v)	{ return __sf_putu(f,v); }
370da2e3ebchin__INLINE__ int sfputm(Sfio_t* f, Sfulong_t v, Sfulong_t m)
371da2e3ebchin						{ return __sf_putm(f,v,m); }
372da2e3ebchin
373da2e3ebchin__INLINE__ int sfputc(Sfio_t* f, int c)		{ return __sf_putc(f,c); }
374da2e3ebchin__INLINE__ int sfgetc(Sfio_t* f)		{ return __sf_getc(f); }
375da2e3ebchin
376da2e3ebchin__INLINE__ int sfdlen(Sfdouble_t v)		{ return __sf_dlen(v); }
377da2e3ebchin__INLINE__ int sfllen(Sflong_t v)		{ return __sf_llen(v); }
378da2e3ebchin__INLINE__ int sfulen(Sfulong_t v)		{ return __sf_ulen(v); }
379da2e3ebchin
380da2e3ebchin__INLINE__ int sffileno(Sfio_t* f)		{ return __sf_fileno(f); }
381da2e3ebchin__INLINE__ int sfeof(Sfio_t* f)			{ return __sf_eof(f); }
382da2e3ebchin__INLINE__ int sferror(Sfio_t* f)		{ return __sf_error(f); }
383da2e3ebchin__INLINE__ int sfclrerr(Sfio_t* f)		{ return __sf_clrerr(f); }
384da2e3ebchin__INLINE__ int sfstacked(Sfio_t* f)		{ return __sf_stacked(f); }
385da2e3ebchin__INLINE__ ssize_t sfvalue(Sfio_t* f)		{ return __sf_value(f); }
386da2e3ebchin__INLINE__ ssize_t sfslen()			{ return __sf_slen(); }
387da2e3ebchin__INLINE__ ssize_t sfmaxr(ssize_t n, int s)	{ return __sf_maxr(n,s); }
388da2e3ebchin
389da2e3ebchin#else
390da2e3ebchin
391da2e3ebchin#define sfputd(f,v)				( __sf_putd((f),(v)) )
392da2e3ebchin#define sfputl(f,v)				( __sf_putl((f),(v)) )
393da2e3ebchin#define sfputu(f,v)				( __sf_putu((f),(v)) )
394da2e3ebchin#define sfputm(f,v,m)				( __sf_putm((f),(v),(m)) )
395da2e3ebchin
396da2e3ebchin#define sfputc(f,c)				( __sf_putc((f),(c)) )
397da2e3ebchin#define sfgetc(f)				( __sf_getc(f) )
398da2e3ebchin
399da2e3ebchin#define sfdlen(v)				( __sf_dlen(v) )
400da2e3ebchin#define sfllen(v)				( __sf_llen(v) )
401da2e3ebchin#define sfulen(v)				( __sf_ulen(v) )
402da2e3ebchin
403da2e3ebchin#define sffileno(f)				( __sf_fileno(f) )
404da2e3ebchin#define sfeof(f)				( __sf_eof(f) )
405da2e3ebchin#define sferror(f)				( __sf_error(f) )
406da2e3ebchin#define sfclrerr(f)				( __sf_clrerr(f) )
407da2e3ebchin#define sfstacked(f)				( __sf_stacked(f) )
408da2e3ebchin#define sfvalue(f)				( __sf_value(f) )
409da2e3ebchin#define sfslen()				( __sf_slen() )
410da2e3ebchin#define sfmaxr(n,s)				( __sf_maxr(n,s) )
411da2e3ebchin
412da2e3ebchin#endif /*__INLINE__*/
413da2e3ebchin
414da2e3ebchin#ifndef _SFSTR_H /* GSF's string manipulation stuff */
415da2e3ebchin#define _SFSTR_H		1
416da2e3ebchin
417da2e3ebchin#define sfstropen()		sfnew(0, 0, -1, -1, SF_READ|SF_WRITE|SF_STRING)
418da2e3ebchin#define sfstrclose(f)		sfclose(f)
419da2e3ebchin
420da2e3ebchin#define sfstrseek(f,p,m) \
421da2e3ebchin	( (m) == SEEK_SET ? \
422da2e3ebchin	 	(((p) < 0 || (p) > (f)->_size) ? (char*)0 : \
423da2e3ebchin		 (char*)((f)->_next = (f)->_data+(p)) ) \
424da2e3ebchin	: (m) == SEEK_CUR ? \
425da2e3ebchin		((f)->_next += (p), \
426da2e3ebchin		 (((f)->_next < (f)->_data || (f)->_next > (f)->_data+(f)->_size) ? \
427da2e3ebchin			((f)->_next -= (p), (char*)0) : (char*)(f)->_next ) ) \
428da2e3ebchin	: (m) == SEEK_END ? \
429da2e3ebchin		( ((p) > 0 || (f)->_size+(p) < 0) ? (char*)0 : \
430da2e3ebchin			(char*)((f)->_next = (f)->_data+(f)->_size+(p)) ) \
431da2e3ebchin	: (char*)0 \
432da2e3ebchin	)
433da2e3ebchin
434da2e3ebchin#define sfstrsize(f)		((f)->_size)
435da2e3ebchin#define sfstrtell(f)		((f)->_next - (f)->_data)
436da2e3ebchin#define sfstrpend(f)		((f)->_size - sfstrtell())
437da2e3ebchin#define sfstrbase(f)		((char*)(f)->_data)
438da2e3ebchin
439da2e3ebchin#define sfstruse(f) \
440da2e3ebchin	(sfputc((f),0) < 0 ? (char*)0 : (char*)((f)->_next = (f)->_data) \
441da2e3ebchin	)
442da2e3ebchin
443da2e3ebchin#define sfstrrsrv(f,n) \
444da2e3ebchin	(sfreserve((f),(n),SF_WRITE|SF_LOCKR), sfwrite((f),(f)->_next,0), \
445da2e3ebchin	 ((f)->_next+(n) <= (f)->_data+(f)->_size ? (char*)(f)->_next : (char*)0) \
446da2e3ebchin	)
447da2e3ebchin
448da2e3ebchin#define sfstrbuf(f,b,n,m) \
449da2e3ebchin	(sfsetbuf((f),(b),(n)), ((f)->_flags |= (m) ? SF_MALLOC : 0), \
450da2e3ebchin	 ((f)->_data == (unsigned char*)(b) ? 0 : -1) \
451da2e3ebchin	)
452da2e3ebchin
453da2e3ebchin#endif /* _SFSTR_H */
454da2e3ebchin
455da2e3ebchin#endif /* _SFIO_H */
456