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