/************************************************************************** * * * File: iopreds.h * * Last rev: 5/2/88 * * mods: * * comments: Input/Output C implemented predicates * * * *************************************************************************/ #ifdef SCCS static char SccsId[] = "%W% %G%"; #endif #ifndef IOPREDS_H #define IOPREDS_H 1 #include #include "Yap.h" #include "Atoms.h" /* * This file defines main data-structure for stream management, * */ extern size_t Yap_page_size; #if defined(_MSC_VER) || defined(__MINGW32__) #include #endif #include #if HAVE_SOCKET extern int Yap_sockets_io; /****************** defines for sockets *********************************/ typedef enum{ /* in YAP, sockets may be in one of 4 possible status */ new_socket, server_socket, client_socket, server_session_socket, closed_socket } socket_info; typedef enum{ /* we accept two domains for the moment, IPV6 may follow */ af_inet, /* IPV4 */ af_unix /* or AF_FILE */ } socket_domain; extern Term Yap_InitSocketStream(int, socket_info, socket_domain); #define Yap_CheckStream( arg, kind, msg) Yap_CheckStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) extern int Yap_CheckStream__(const char *, const char *, int , Term, int, const char *); #define Yap_CheckTextStream( arg, kind, msg) Yap_CheckTextStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) extern int Yap_CheckTextStream__(const char *, const char *, int , Term, int, const char *); extern int Yap_CheckSocketStream(Term, const char *); extern socket_domain Yap_GetSocketDomain(int); extern socket_info Yap_GetSocketStatus(int); extern void Yap_UpdateSocketStream(int, socket_info, socket_domain); /* routines in ypsocks.c */ Int Yap_CloseSocket(int, socket_info, socket_domain); #endif /* USE_SOCKET */ /************ SWI compatible support for unicode representations ************/ typedef struct yap_io_position { int64_t byteno; /* byte-position in file */ int64_t charno; /* character position in file */ long int lineno; /* lineno in file */ long int linepos; /* position in line */ intptr_t reserved[2]; /* future extensions */ } yapIOPOS; #ifndef _PL_STREAM_H typedef struct { Atom file; /* current source file */ yapIOPOS position; /* Line, line pos, char and byte */ } yapSourceLocation; #endif #define RD_MAGIC 0xefebe128 typedef struct vlist_struct_t { struct VARSTRUCT *ve; struct vlist_struct_t *next; } vlist_t; typedef struct qq_struct_t { unsigned char *text; yapIOPOS start, mid, end; vlist_t *vlist; struct qq_struct_t *next; } qq_t; typedef struct read_data_t { unsigned char *here; /* current character */ unsigned char *base; /* base of clause */ unsigned char *end; /* end of the clause */ unsigned char *token_start; /* start of most recent read token */ int magic; /* RD_MAGIC */ struct stream_desc *stream; FILE *f; /* file. of known */ Term position; /* Line, line pos, char and byte */ void *posp; /* position pointer */ size_t posi; /* position number */ Term subtpos; /* Report Subterm positions */ bool cycles; /* Re-establish cycles */ yapSourceLocation start_of_term; /* Position of start of term */ struct mod_entry* module; /* Current source module */ unsigned int flags; /* Module syntax flags */ int styleCheck; /* style-checking mask */ bool backquoted_string; /* Read `hello` as string */ int *char_conversion_table; /* active conversion table */ Atom on_error; /* Handling of syntax errors */ int has_exception; /* exception is raised */ Term exception; /* raised exception */ Term variables; /* report variables */ Term singles; /* Report singleton variables */ Term varnames; /* Report variables+names */ int strictness; /* Strictness level */ #ifdef O_QUASIQUOTATIONS Term quasi_quotations; /* User option quasi_quotations(QQ) */ Term qq; /* Quasi quoted list */ Term qq_tail; /* Tail of the quoted stuff */ #endif Term comments; /* Report comments */ } read_data, *ReadData; Term Yap_read_term(int inp_stream, Term opts, int nargs); Term Yap_Parse( UInt prio ); void init_read_data(ReadData _PL_rd, struct stream_desc *s); typedef int (*GetsFunc)(int, UInt, char *); #if HAVE_SYS_TYPES_H #include #endif #if HAVE_SYS_SOCKET_H #include #endif typedef struct mem_desc { char *buf; /* where the file is being read from/written to */ int src; /* where the space comes from, 0 code space, 1 malloc */ Int max_size; /* maximum buffer size (may be changed dynamically) */ UInt pos; /* cursor */ volatile void *error_handler; } memHandle; typedef struct stream_desc { Atom name; Term user_name; FILE* file; // useful in memory streams char *nbuf; size_t nsize; union { struct { #define PLGETC_BUF_SIZE 4096 char *buf, *ptr; int left; } file; memHandle mem_string; struct { #if defined(__MINGW32__) || defined(_MSC_VER) HANDLE hdl; #else int fd; #endif } pipe; #if HAVE_SOCKET struct { socket_domain domain; socket_info flags; int fd; } socket; #endif struct { const char *buf, *ptr; } irl; } u; Int charcount, linecount, linepos; stream_flags_t status; int och; #if defined(YAPOR) || defined(THREADS) lockvar streamlock; /* protect stream access */ #endif int (* stream_putc)(int, int); /* function the stream uses for writing */ int (* stream_getc)(int); /* function the stream uses for reading */ GetsFunc stream_gets; /* function the stream uses for reading a sequence of characters */ /* function the stream uses for parser. It may be different if the ISO character conversion is on */ int (* stream_wgetc_for_read)(int); int (* stream_wgetc)(int); int (* stream_getc_for_utf8)(int); int (* stream_wputc)(int,wchar_t); uint64_t utf8_buf; /* used to translate to utf-8 */ encoding_t encoding; mbstate_t mbstate; } StreamDesc; static inline bool IsStreamTerm(Term t) { return !IsVarTerm(t) && (IsAtomTerm(t) || (IsApplTerm(t) && (FunctorOfTerm(t) == FunctorStream))); } static inline StreamDesc * Yap_GetStreamHandle(Term t) { int sno = Yap_CheckStream( t , 0, "stream search"); if (sno < 0) return NULL; return GLOBAL_Stream+sno; } #define YAP_ERROR NIL #define MaxStreams 64 #define EXPAND_FILENAME 0x000080 #define StdInStream 0 #define StdOutStream 1 #define StdErrStream 2 #define ALIASES_BLOCK_SIZE 8 void Yap_InitStdStreams (void); Term Yap_StreamPosition (int); static inline int GetCurInpPos (StreamDesc * inp_stream) { return (inp_stream->linecount); } #define PlIOError(type, culprit,...) PlIOError__(__FILE__, __FUNCTION__, __LINE__, type, culprit, __VA_ARGS__) Int PlIOError__( const char *, const char *, int, yap_error_number, Term, ...); int GetFreeStreamD(void); Term Yap_MkStream (int n); bool Yap_PrintWarning( Term twarning ); void Yap_plwrite(Term, struct stream_desc *, int, int, int); void Yap_WriteAtom(struct stream_desc *s, Atom atom); Term Yap_scan_num(struct stream_desc *); void Yap_DefaultStreamOps( StreamDesc *st ); void Yap_PipeOps( StreamDesc *st ); void Yap_MemOps( StreamDesc *st ); void Yap_ConsolePipeOps( StreamDesc *st ); void Yap_SocketOps( StreamDesc *st ); void Yap_ConsoleSocketOps( StreamDesc *st ); bool Yap_ReadlineOps( StreamDesc *st ); int Yap_OpenBufWriteStream( USES_REGS1); void Yap_ConsoleOps( StreamDesc *s ); void Yap_InitRandomPreds (void); void Yap_InitSignalPreds (void); void Yap_InitTimePreds (void); void Yap_init_socks(char *host, long interface_port); void Yap_InitPipes( void ); void Yap_InitMem( void ); void Yap_InitSockets( void ); void Yap_InitSocketLayer(void); void Yap_InitMems( void ); void Yap_InitConsole( void ); void Yap_InitReadline( void ); void Yap_InitChtypes(void); void Yap_InitCharsio(void); void Yap_InitFormat(void); void Yap_InitFiles(void); void Yap_InitIOStreams(void); void Yap_InitWriteTPreds(void); void Yap_InitReadTPreds(void); void Yap_socketStream( StreamDesc *s ); void Yap_ReadlineFlush( int sno ); int Yap_ReadlineForSIGINT(void); bool Yap_ReadlinePrompt( StreamDesc * s ); Int Yap_peek( int sno ); Term Yap_syntax_error (TokEntry * tokptr, int sno); int console_post_process_read_char( int, StreamDesc *); int console_post_process_eof( StreamDesc *); int post_process_read_char( int, StreamDesc *); int post_process_eof( StreamDesc *); int post_process_weof( StreamDesc *); bool is_same_tty(FILE *f1, FILE *f2); int ISOWGetc (int sno); int GetUTF8 (int sno); Term read_line(int sno); int PlGets (int sno, UInt size, char *buf); GetsFunc PlGetsFunc(void); int PlGetc (int sno); int FilePutc (int sno, int c); int DefaultGets( int,UInt,char*); int put_wchar(int sno, wchar_t ch); Int GetStreamFd(int sno); int ResetEOF(StreamDesc *s); void Yap_SetAlias (Atom arg, int sno); bool Yap_AddAlias (Atom arg, int sno); int Yap_CheckAlias (Atom arg); int Yap_RemoveAlias (Atom arg, int snoinline); void Yap_SetAlias (Atom arg, int sno); void Yap_InitAliases(void); void Yap_DeleteAliases (int sno); bool Yap_FindStreamForAlias (Atom al); bool Yap_FetchStreamAlias (int sno, Term t2 USES_REGS); INLINE_ONLY inline EXTERN void count_output_char(int ch, StreamDesc *s); Term Yap_StreamUserName(int sno); INLINE_ONLY inline EXTERN void count_output_char(int ch, StreamDesc *s) { if (ch == '\n') { #if MPWSHELL if (mpwshell && (sno == StdOutStream || sno == StdErrStream) && !(s->status & Null_Stream_f)) { putc (MPWSEP, s->file); if (!(GLOBAL_Stream[LOCAL_output_stream].status & Null_Stream_f)) fflush (stdout); } #endif /* Inform that we have written a newline */ ++s->charcount; ++s->linecount; s->linepos = 0; } else { #if MAC if ((sno == StdOutStream || sno == StdErrStream) && s->linepos > 200) sno->stream_putc(sno, '\n'); #endif ++s->charcount; ++s->linepos; } } inline static Term StreamName(int i) { return(GLOBAL_Stream[i].user_name); } inline static Atom StreamFullName(int i) { return(GLOBAL_Stream[i].name); } inline static void console_count_output_char(int ch, StreamDesc *s) { CACHE_REGS if (ch == '\n') { #if MPWSHELL if (mpwshell && (sno == StdOutStream || sno == StdErrStream) && !(s->status & Null_Stream_f)) { putc (MPWSEP, s->file); if (!(GLOBAL_Stream[LOCAL_output_stream].status & Null_Stream_f)) fflush (stdout); } #endif ++s->charcount; ++s->linecount; s->linepos = 0; LOCAL_newline = TRUE; /* Inform we are not at the start of a newline */ } else { LOCAL_newline = FALSE; #if MAC if ((sno == StdOutStream || sno == StdErrStream) && s->linepos > 200) sno->stream_putc(sno, '\n'); #endif ++s->charcount; ++s->linepos; } } inline static Term StreamPosition(int sno) { CACHE_REGS Term sargs[5]; Int cpos; cpos = GLOBAL_Stream[sno].charcount; sargs[0] = MkIntegerTerm (LOCAL_StartCharCount = cpos); sargs[1] = MkIntegerTerm (LOCAL_StartLineCount = GLOBAL_Stream[sno].linecount); sargs[2] = MkIntegerTerm (LOCAL_StartLinePos = GLOBAL_Stream[sno].linepos); sargs[3] = sargs[4] = MkIntTerm (0); return Yap_MkApplTerm (FunctorStreamPos, 5, sargs); } inline static Term CurrentPositionToTerm(void) { CACHE_REGS Term sargs[5]; sargs[0] = MkIntegerTerm (LOCAL_StartCharCount); sargs[1] = MkIntegerTerm (LOCAL_StartLineCount ); sargs[2] = MkIntegerTerm (LOCAL_StartLinePos ); sargs[3] = sargs[4] = MkIntTerm (0); return Yap_MkApplTerm (FunctorStreamPos, 5, sargs); } extern FILE *Yap_stdin; extern FILE *Yap_stdout; extern FILE *Yap_stderr; char *Yap_MemExportStreamPtr( int sno ); #endif