1 /* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2011-2017, University of Amsterdam 7 VU University Amsterdam 8 All rights reserved. 9 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions 12 are met: 13 14 1. Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright 18 notice, this list of conditions and the following disclaimer in 19 the documentation and/or other materials provided with the 20 distribution. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #ifndef _PL_STREAM_H 37 #define _PL_STREAM_H 38 39 /* This appears to make the wide-character support compile and work 40 on HPUX 11.23. There really should be a cleaner way ... 41 */ 42 #if defined(__hpux) 43 #include <sys/_mbstate_t.h> 44 #endif 45 46 #ifndef __WINDOWS__ 47 #if defined(_MSC_VER) || defined(__MINGW32__) 48 #define __WINDOWS__ 1 49 #endif 50 #endif 51 52 #ifdef __MINGW32__ 53 #include <winsock2.h> 54 #include <windows.h> 55 #endif 56 57 #include <stdarg.h> 58 #include <wchar.h> 59 #include <stddef.h> 60 #ifdef _MSC_VER 61 typedef __int64 int64_t; 62 #if (_MSC_VER < 1300) 63 typedef long intptr_t; 64 typedef unsigned long uintptr_t; 65 #endif 66 typedef intptr_t ssize_t; /* signed version of size_t */ 67 #else 68 #include <unistd.h> 69 #include <inttypes.h> /* more portable than stdint.h */ 70 #endif 71 72 #ifdef __cplusplus 73 extern "C" { 74 #endif 75 76 /******************************* 77 * EXPORT * 78 *******************************/ 79 80 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 81 See SWI-Prolog.h, containing the same code for an explanation on this 82 stuff. 83 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 84 85 #ifndef _PL_EXPORT_DONE 86 #define _PL_EXPORT_DONE 87 88 #if defined(_MSC_VER) || defined(__MINGW32__) 89 #define HAVE_DECLSPEC 90 #endif 91 92 #ifdef HAVE_DECLSPEC 93 # ifdef PL_KERNEL 94 #define PL_EXPORT(type) __declspec(dllexport) type 95 #define PL_EXPORT_DATA(type) __declspec(dllexport) type 96 #define install_t void 97 # else 98 # ifdef __BORLANDC__ 99 #define PL_EXPORT(type) type _stdcall 100 #define PL_EXPORT_DATA(type) extern type 101 # else 102 # ifdef __MINGW32__ 103 #define PL_EXPORT(type) extern type 104 #define PL_EXPORT_DATA(type) extern type 105 # else 106 #define PL_EXPORT(type) extern type 107 #define PL_EXPORT_DATA(type) __declspec(dllimport) type 108 # endif 109 # endif 110 #define install_t __declspec(dllexport) void 111 # endif 112 #else /*HAVE_DECLSPEC*/ 113 #define PL_EXPORT(type) extern type 114 #define PL_EXPORT_DATA(type) extern type 115 #define install_t void 116 #endif /*HAVE_DECLSPEC*/ 117 #endif /*_PL_EXPORT_DONE*/ 118 119 /******************************* 120 * CONSTANTS * 121 *******************************/ 122 123 #ifndef EOF 124 #define EOF (-1) 125 #endif 126 127 #ifndef NULL 128 #define NULL ((void *)0) 129 #endif 130 131 #if defined(__WINDOWS__) && !defined(EWOULDBLOCK) 132 #define EWOULDBLOCK 140 /* Needed for socket handling */ 133 /* 140 is compatible to VS2010 */ 134 #endif 135 #define EPLEXCEPTION 1001 /* errno: pending Prolog exception */ 136 137 #define SIO_BUFSIZE (4096) /* buffering buffer-size */ 138 #define SIO_LINESIZE (1024) /* Sgets() default buffer size */ 139 #define SIO_OMAGIC (7212676) /* old magic number */ 140 #define SIO_MAGIC (7212677) /* magic number */ 141 #define SIO_CMAGIC (42) /* we are close (and thus illegal!) */ 142 143 typedef ssize_t (*Sread_function)(void *handle, char *buf, size_t bufsize); 144 typedef ssize_t (*Swrite_function)(void *handle, char*buf, size_t bufsize); 145 typedef long (*Sseek_function)(void *handle, long pos, int whence); 146 typedef int64_t (*Sseek64_function)(void *handle, int64_t pos, int whence); 147 typedef int (*Sclose_function)(void *handle); 148 typedef int (*Scontrol_function)(void *handle, int action, void *arg); 149 150 #if defined(O_PLMT) && defined(PL_KERNEL) 151 #include "pl-mutex.h" 152 #define IOLOCK recursiveMutex 153 #else 154 typedef void * IOLOCK; /* Definition for external use */ 155 #endif 156 157 #ifndef PL_HAVE_TERM_T 158 #define PL_HAVE_TERM_T 159 typedef uintptr_t term_t; /* opaque term handle */ 160 #endif 161 162 typedef struct io_functions 163 { Sread_function read; /* fill the buffer */ 164 Swrite_function write; /* empty the buffer */ 165 Sseek_function seek; /* seek to position */ 166 Sclose_function close; /* close stream */ 167 Scontrol_function control; /* Info/control */ 168 Sseek64_function seek64; /* seek to position (large files) */ 169 } IOFUNCTIONS; 170 171 typedef struct io_position 172 { int64_t byteno; /* byte-position in file */ 173 int64_t charno; /* character position in file */ 174 int lineno; /* lineno in file */ 175 int linepos; /* position in line */ 176 intptr_t reserved[2]; /* future extensions */ 177 } IOPOS; 178 179 /* NOTE: check with encoding_names */ 180 /* in pl-file.c */ 181 typedef enum 182 { ENC_UNKNOWN = 0, /* invalid/unknown */ 183 ENC_OCTET, /* raw 8 bit input */ 184 ENC_ASCII, /* US-ASCII (0..127) */ 185 ENC_ISO_LATIN_1, /* ISO Latin-1 (0..256) */ 186 ENC_ANSI, /* default (multibyte) codepage */ 187 ENC_UTF8, 188 ENC_UNICODE_BE, /* big endian unicode file */ 189 ENC_UNICODE_LE, /* little endian unicode file */ 190 ENC_WCHAR /* pl_wchar_t */ 191 } IOENC; 192 193 #define SIO_NL_POSIX 0 /* newline as \n */ 194 #define SIO_NL_DOS 1 /* newline as \r\n */ 195 #define SIO_NL_DETECT 3 /* detect processing mode */ 196 197 typedef struct io_stream 198 { char *bufp; /* `here' */ 199 char *limitp; /* read/write limit */ 200 char *buffer; /* the buffer */ 201 char *unbuffer; /* Sungetc buffer */ 202 int lastc; /* last character written */ 203 int magic; /* magic number SIO_MAGIC */ 204 int bufsize; /* size of the buffer */ 205 int flags; /* Status flags */ 206 IOPOS posbuf; /* location in file */ 207 IOPOS * position; /* pointer to above */ 208 void *handle; /* function's handle */ 209 IOFUNCTIONS *functions; /* open/close/read/write/seek */ 210 int timeout; /* timeout (milliseconds) */ 211 IOENC encoding; /* character encoding used */ 212 int locks; /* lock/unlock count */ 213 int references; /* Reference-count */ 214 IOLOCK * mutex; /* stream mutex */ 215 void (*close_hook)(void* closure); 216 void * closure; 217 mbstate_t * mbstate; /* ENC_ANSI decoding */ 218 struct io_stream * tee; /* copy data to this stream */ 219 struct io_stream * upstream; /* stream providing our input */ 220 struct io_stream * downstream; /* stream providing our output */ 221 unsigned newline : 2; /* Newline mode */ 222 unsigned erased : 1; /* Stream was erased */ 223 int io_errno; /* Save errno value */ 224 char * message; /* error/warning message */ 225 void * exception; /* pending exception (record_t) */ 226 void * context; /* getStreamContext() */ 227 struct PL_locale * locale; /* Locale associated to stream */ 228 intptr_t reserved[4]; /* reserved for extension */ 229 } IOSTREAM; 230 231 232 #define SmakeFlag(n) (1<<(n-1)) 233 234 #define SIO_FBUF SmakeFlag(1) /* full buffering */ 235 #define SIO_LBUF SmakeFlag(2) /* line buffering */ 236 #define SIO_NBUF SmakeFlag(3) /* no buffering */ 237 #define SIO_FEOF SmakeFlag(4) /* end-of-file */ 238 #define SIO_FERR SmakeFlag(5) /* error ocurred */ 239 #define SIO_USERBUF SmakeFlag(6) /* buffer is from user */ 240 #define SIO_INPUT SmakeFlag(7) /* input stream */ 241 #define SIO_OUTPUT SmakeFlag(8) /* output stream */ 242 #define SIO_NOLINENO SmakeFlag(9) /* line no. info is void */ 243 #define SIO_NOLINEPOS SmakeFlag(10) /* line pos is void */ 244 #define SIO_STATIC SmakeFlag(11) /* Stream in static memory */ 245 #define SIO_RECORDPOS SmakeFlag(12) /* Maintain position */ 246 #define SIO_FILE SmakeFlag(13) /* Stream refers to an OS file */ 247 #define SIO_NOERROR SmakeFlag(14) /* Ignore write errors */ 248 #define SIO_NOFEOF SmakeFlag(15) /* don't set SIO_FEOF flag */ 249 #define SIO_TEXT SmakeFlag(16) /* text-mode operation */ 250 #define SIO_FEOF2 SmakeFlag(17) /* attempt to read past eof */ 251 #define SIO_FEOF2ERR SmakeFlag(18) /* Sfpasteof() */ 252 #define SIO_NOCLOSE SmakeFlag(19) /* Do not close on abort */ 253 #define SIO_APPEND SmakeFlag(20) /* opened in append-mode */ 254 #define SIO_UPDATE SmakeFlag(21) /* opened in update-mode */ 255 #define SIO_ISATTY SmakeFlag(22) /* Stream is a tty */ 256 #define SIO_CLOSING SmakeFlag(23) /* We are closing the stream */ 257 #define SIO_TIMEOUT SmakeFlag(24) /* We had a timeout */ 258 #define SIO_NOMUTEX SmakeFlag(25) /* Do not allow multi-thread access */ 259 #define SIO_ADVLOCK SmakeFlag(26) /* File locked with advisory lock */ 260 #define SIO_WARN SmakeFlag(27) /* Pending warning */ 261 #define SIO_RAW SmakeFlag(28) /* TTY Stream is in raw mode */ 262 #define SIO_REPXML SmakeFlag(29) /* Bad char --> XML entity */ 263 #define SIO_REPPL SmakeFlag(30) /* Bad char --> Prolog \hex\ */ 264 #define SIO_BOM SmakeFlag(31) /* BOM was detected/written */ 265 266 #define SIO_SEEK_SET 0 /* From beginning of file. */ 267 #define SIO_SEEK_CUR 1 /* From current position. */ 268 #define SIO_SEEK_END 2 /* From end of file. */ 269 270 PL_EXPORT(IOSTREAM *) S__getiob(void); /* get DLL's __iob[] address */ 271 272 PL_EXPORT_DATA(IOFUNCTIONS) Sfilefunctions; /* OS file functions */ 273 PL_EXPORT_DATA(int) Slinesize; /* Sgets() linesize */ 274 #if defined(__CYGWIN__) && !defined(PL_KERNEL) 275 #define S__iob S__getiob() 276 #else 277 PL_EXPORT_DATA(IOSTREAM) S__iob[3]; /* Libs standard streams */ 278 #endif 279 280 #define Sinput (&S__iob[0]) /* Stream Sinput */ 281 #define Soutput (&S__iob[1]) /* Stream Soutput */ 282 #define Serror (&S__iob[2]) /* Stream Serror */ 283 284 #define Sgetchar() Sgetc(Sinput) 285 #define Sputchar(c) Sputc((c), Soutput) 286 287 #define S__updatefilepos_getc(s, c) \ 288 ((s)->position ? S__fupdatefilepos_getc((s), (c)) \ 289 : (c)) 290 291 #define Snpgetc(s) ((s)->bufp < (s)->limitp ? (int)(*(s)->bufp++)&0xff \ 292 : S__fillbuf(s)) 293 #define Sgetc(s) S__updatefilepos_getc((s), Snpgetc(s)) 294 295 /* Control-operations */ 296 #define SIO_GETSIZE (1) /* get size of underlying object */ 297 #define SIO_GETFILENO (2) /* get underlying file (if any) */ 298 #define SIO_SETENCODING (3) /* modify encoding of stream */ 299 #define SIO_FLUSHOUTPUT (4) /* flush output */ 300 #define SIO_LASTERROR (5) /* string holding last error */ 301 #ifdef __WINDOWS__ 302 #define SIO_GETWINSOCK (6) /* get underlying SOCKET object */ 303 #endif 304 #define SIO_GETPENDING (7) /* get #pending bytes */ 305 306 /* Sread_pending() */ 307 #define SIO_RP_BLOCK 0x1 /* wait for new input */ 308 #define SIO_RP_NOPOS 0x2 /* Do not update position */ 309 310 #if IOSTREAM_REPLACES_STDIO 311 312 #undef FILE 313 #undef stdin 314 #undef stdout 315 #undef stderr 316 #undef putc 317 #undef getc 318 #undef putchar 319 #undef getchar 320 #undef feof 321 #undef ferror 322 #undef fileno 323 #undef clearerr 324 325 #define FILE IOSTREAM 326 #define stdin Sinput 327 #define stdout Soutput 328 #define stderr Serror 329 330 #define putc Sputc 331 #define getc Sgetc 332 #define fputc Sputc 333 #define fgetc Sgetc 334 #define getw Sgetw 335 #define putw Sputw 336 #define fread Sfread 337 #define fwrite Sfwrite 338 #define ungetc Sungetc 339 #define putchar Sputchar 340 #define getchar Sgetchar 341 #define feof Sfeof 342 #define ferror Sferror 343 #define clearerr Sclearerr 344 #define fflush Sflush 345 #define fseek Sseek 346 #define ftell Stell 347 #define fclose Sclose 348 #define fgets Sfgets 349 #define gets Sgets 350 #define fputs Sfputs 351 #define puts Sputs 352 #define fprintf Sfprintf 353 #define printf Sprintf 354 #define vprintf Svprintf 355 #define vfprintf Svfprintf 356 #define sprintf Ssprintf 357 #define vsprintf Svsprintf 358 #define fopen Sopen_file 359 #define fdopen Sfdopen 360 #define fileno Sfileno 361 #define popen Sopen_pipe 362 363 #endif /*IOSTREAM_REPLACES_STDIO*/ 364 365 /******************************* 366 * PROTOTYPES * 367 *******************************/ 368 369 PL_EXPORT(void) SinitStreams(); 370 PL_EXPORT(void) Scleanup(void); 371 PL_EXPORT(void) Sreset(void); 372 PL_EXPORT(int) S__fupdatefilepos_getc(IOSTREAM *s, int c); 373 PL_EXPORT(int) S__fillbuf(IOSTREAM *s); 374 PL_EXPORT(int) Sset_timeout(IOSTREAM *s, int tmo); 375 PL_EXPORT(int) Sunit_size(IOSTREAM *s); 376 /* byte I/O */ 377 PL_EXPORT(int) Sputc(int c, IOSTREAM *s); 378 PL_EXPORT(int) Sfgetc(IOSTREAM *s); 379 PL_EXPORT(int) Sungetc(int c, IOSTREAM *s); 380 /* multibyte I/O */ 381 PL_EXPORT(int) Scanrepresent(int c, IOSTREAM *s); 382 PL_EXPORT(int) Sputcode(int c, IOSTREAM *s); 383 PL_EXPORT(int) Sgetcode(IOSTREAM *s); 384 PL_EXPORT(int) Speekcode(IOSTREAM *s); 385 /* word I/O */ 386 PL_EXPORT(int) Sputw(int w, IOSTREAM *s); 387 PL_EXPORT(int) Sgetw(IOSTREAM *s); 388 PL_EXPORT(size_t) Sfread(void *data, size_t size, size_t elems, 389 IOSTREAM *s); 390 PL_EXPORT(size_t) Sfwrite(const void *data, size_t size, size_t elems, 391 IOSTREAM *s); 392 PL_EXPORT(int) Sfeof(IOSTREAM *s); 393 PL_EXPORT(int) Sfpasteof(IOSTREAM *s); 394 PL_EXPORT(int) Sferror(IOSTREAM *s); 395 PL_EXPORT(void) Sclearerr(IOSTREAM *s); 396 PL_EXPORT(int) Sseterr(IOSTREAM *s, int which, const char *message); 397 PL_EXPORT(int) Sset_exception(IOSTREAM *s, term_t ex); 398 PL_EXPORT(int) Ssetenc(IOSTREAM *s, IOENC new_enc, IOENC *old_enc); 399 PL_EXPORT(int) Ssetlocale(IOSTREAM *s, 400 struct PL_locale *new_loc, 401 struct PL_locale **old_loc); 402 PL_EXPORT(int) Sflush(IOSTREAM *s); 403 PL_EXPORT(int64_t) Ssize(IOSTREAM *s); 404 PL_EXPORT(int) Sseek(IOSTREAM *s, long pos, int whence); 405 PL_EXPORT(long) Stell(IOSTREAM *s); 406 PL_EXPORT(int) Sclose(IOSTREAM *s); 407 PL_EXPORT(char *) Sfgets(char *buf, int n, IOSTREAM *s); 408 PL_EXPORT(char *) Sgets(char *buf); 409 PL_EXPORT(ssize_t) Sread_pending(IOSTREAM *s, 410 char *buf, size_t limit, int flags); 411 PL_EXPORT(size_t) Spending(IOSTREAM *s); 412 PL_EXPORT(int) Sfputs(const char *q, IOSTREAM *s); 413 PL_EXPORT(int) Sputs(const char *q); 414 PL_EXPORT(int) Sfprintf(IOSTREAM *s, const char *fm, ...); 415 PL_EXPORT(int) Sprintf(const char *fm, ...); 416 PL_EXPORT(int) Svprintf(const char *fm, va_list args); 417 PL_EXPORT(int) Svfprintf(IOSTREAM *s, const char *fm, va_list args); 418 PL_EXPORT(int) Ssprintf(char *buf, const char *fm, ...); 419 PL_EXPORT(int) Ssnprintf(char *buf, size_t size, const char *fm, ...); 420 PL_EXPORT(int) Svsprintf(char *buf, const char *fm, va_list args); 421 PL_EXPORT(int) Svsnprintf(char *buf, size_t size, const char *fm, va_list args); 422 PL_EXPORT(int) Svdprintf(const char *fm, va_list args); 423 PL_EXPORT(int) Sdprintf(const char *fm, ...); 424 PL_EXPORT(int) Slock(IOSTREAM *s); 425 PL_EXPORT(int) StryLock(IOSTREAM *s); 426 PL_EXPORT(int) Sunlock(IOSTREAM *s); 427 PL_EXPORT(IOSTREAM *) Snew(void *handle, int flags, IOFUNCTIONS *functions); 428 PL_EXPORT(IOSTREAM *) Sopen_file(const char *path, const char *how); 429 PL_EXPORT(IOSTREAM *) Sfdopen(int fd, const char *type); 430 PL_EXPORT(int) Sfileno(IOSTREAM *s); 431 #ifdef __WINDOWS__ 432 #if defined(_WINSOCKAPI_) || defined(NEEDS_SWINSOCK) /* have SOCKET */ 433 PL_EXPORT(SOCKET) Swinsock(IOSTREAM *s); 434 #endif 435 #endif 436 PL_EXPORT(IOSTREAM *) Sopen_pipe(const char *command, const char *type); 437 PL_EXPORT(IOSTREAM *) Sopenmem(char **buffer, size_t *sizep, const char *mode); 438 PL_EXPORT(IOSTREAM *) Sopen_string(IOSTREAM *s, char *buf, size_t sz, const char *m); 439 PL_EXPORT(int) Sclosehook(void (*hook)(IOSTREAM *s)); 440 PL_EXPORT(void) Sfree(void *ptr); 441 PL_EXPORT(int) Sset_filter(IOSTREAM *parent, IOSTREAM *filter); 442 PL_EXPORT(void) Ssetbuffer(IOSTREAM *s, char *buf, size_t size); 443 444 PL_EXPORT(int64_t) Stell64(IOSTREAM *s); 445 PL_EXPORT(int) Sseek64(IOSTREAM *s, int64_t pos, int whence); 446 447 PL_EXPORT(int) ScheckBOM(IOSTREAM *s); 448 PL_EXPORT(int) SwriteBOM(IOSTREAM *s); 449 450 #ifdef __cplusplus 451 } 452 #endif 453 454 #endif /*_PL_STREAM_H*/ 455