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