/************************************************************************* * * * YAP Prolog * * * * Yap Prolog was developed at NCCUP - Universidade do Porto * * * * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * * * ************************************************************************** * * * File: iopreds.c * * Last rev: 5/2/88 * * mods: * * comments: Input/Output C implemented predicates * * * *************************************************************************/ #ifdef SCCS static char SccsId[] = "%W% %G%"; #endif /* * This file includes the definition of a miscellania of standard predicates * for yap refering to: Files and GLOBAL_Streams, Simple Input/Output, * */ #include "Yap.h" #if HAVE_FCNTL_H /* for O_BINARY and O_TEXT in WIN32 */ #include #endif #include "Yatom.h" #include "YapHeap.h" #include "yapio.h" #include "eval.h" #include "YapText.h" #include #if HAVE_STDARG_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #if HAVE_CTYPE_H #include #endif #if HAVE_WCTYPE_H #include #endif #if HAVE_SYS_PARAM_H #include #endif #if HAVE_SYS_TIME_H #include #endif #if HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #if HAVE_SYS_SELECT_H && !_MSC_VER && !defined(__MINGW32__) #include #endif #if HAVE_STRING_H #include #endif #if HAVE_SIGNAL_H #include #endif #ifdef _WIN32 #if HAVE_IO_H /* Windows */ #include #endif #endif #if !HAVE_STRNCAT #define strncat(X,Y,Z) strcat(X,Y) #endif #if !HAVE_STRNCPY #define strncpy(X,Y,Z) strcpy(X,Y) #endif #if _MSC_VER || defined(__MINGW32__) #if HAVE_SOCKET #include #endif #include #ifndef S_ISDIR #define S_ISDIR(x) (((x)&_S_IFDIR)==_S_IFDIR) #endif #endif #include "iopreds.h" #if _MSC_VER || defined(__MINGW32__) #define SYSTEM_STAT _stat #else #define SYSTEM_STAT stat #endif static void CloseStream(int sno); FILE *Yap_GetInputStream(Term t, const char *msg) { int sno = Yap_CheckStream (t, Input_Stream_f, msg); FILE *rc; if(!(GLOBAL_Stream[sno].status & (Tty_Stream_f|Socket_Stream_f|Pipe_Stream_f))) rc = GLOBAL_Stream[sno].file; else rc = NULL; UNLOCK(GLOBAL_Stream[sno].streamlock); return rc; } FILE *Yap_GetOutputStream(Term t, const char *msg) { int sno = Yap_CheckStream (t, Output_Stream_f, msg); FILE *rc; if(!(GLOBAL_Stream[sno].status & (Tty_Stream_f|Socket_Stream_f))) rc = GLOBAL_Stream[sno].file; else rc = NULL; UNLOCK(GLOBAL_Stream[sno].streamlock); return rc; } int GetFreeStreamD(void) { CACHE_REGS int sno; for (sno = 0; sno < MaxStreams; ++sno) { LOCK(GLOBAL_Stream[sno].streamlock); if (GLOBAL_Stream[sno].status & Free_Stream_f) { break; } UNLOCK(GLOBAL_Stream[sno].streamlock); } if (sno == MaxStreams) { return -1; } GLOBAL_Stream[sno].encoding = LOCAL_encoding; return sno; } int Yap_GetFreeStreamD(void) { return GetFreeStreamD(); } /* used from C-interface */ int Yap_GetFreeStreamDForReading(void) { CACHE_REGS int sno = GetFreeStreamD(); StreamDesc *s; if (sno < 0) return sno; s = GLOBAL_Stream+sno; s->status |= User_Stream_f|Input_Stream_f; s->charcount = 0; s->linecount = 1; s->linepos = 0; s->stream_wgetc = get_wchar; s->stream_wputc = put_wchar; s->encoding = LOCAL_encoding; if (GLOBAL_CharConversionTable != NULL) s->stream_wgetc_for_read = ISOWGetc; else s->stream_wgetc_for_read = s->stream_wgetc; UNLOCK(s->streamlock); return sno; } static Int p_stream_flags ( USES_REGS1 ) { /* '$stream_flags'(+N,-Flags) */ Term trm; trm = Deref (ARG1); if (IsVarTerm (trm) || !IsIntTerm (trm)) return (FALSE); return (Yap_unify_constant (ARG2, MkIntTerm (GLOBAL_Stream[IntOfTerm (trm)].status))); } static Int p_check_stream (USES_REGS1) { /* '$check_stream'(Stream,Mode) */ Term mode = Deref (ARG2); int sno = Yap_CheckStream (ARG1, AtomOfTerm (mode) == AtomRead ? Input_Stream_f : Output_Stream_f, "check_stream/2"); if (sno != -1) UNLOCK(GLOBAL_Stream[sno].streamlock); return sno != -1; } static Int p_check_if_stream (USES_REGS1) { /* '$check_stream'(Stream) */ int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f | Socket_Stream_f, "check_stream/1"); if (sno != -1) UNLOCK(GLOBAL_Stream[sno].streamlock); return sno != -1; } static Int is_input ( int sno USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ bool rc = GLOBAL_Stream[sno].status & Input_Stream_f; return rc; } static Int is_output ( int sno USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ bool rc = GLOBAL_Stream[sno].status & (Output_Stream_f|Append_Stream_f); return rc; } static Int has_bom ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ bool rc = GLOBAL_Stream[sno].status & Seekable_Stream_f; if (!IsVarTerm(t2) && !boolean(t2)) { return FALSE; } if (rc) { return Yap_unify_constant(t2,TermTrue); } else { return Yap_unify_constant(t2, TermFalse); } } static Int has_reposition ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ bool rc = GLOBAL_Stream[sno].status & Seekable_Stream_f; if (!IsVarTerm(t2) && !boolean(t2)) { return FALSE; } if (rc) { return Yap_unify_constant(t2,TermTrue); } else { return Yap_unify_constant(t2, TermFalse); } } char * Yap_guessFileName(int f, int sno, char *nameb, size_t max) { #if __linux__ char path[256]; if (snprintf(path, 255, "/proc/self/fd/~d",f) && readlink( path, nameb, max) ) return nameb; #elif __APPLE__ if (fcntl(f, F_GETPATH, nameb) != -1) { return nameb; } #elif __WIN32_ FILE_NAME_INFO *fni = (FILE_NAME_INFO *)malloc(sizeof(FILE_NAME_INFO)+sizeof(WCHAR)*MAXPATHLEN); HANDLE handle = (HANDLE)_get_osfhandle(f); if (GetFileInformationByHandleEx(handle, FileNameInfo, &fni, max)) { int i; char *ptr = nameb; for(i=0; iFileNameLength; i++) *ptr = _PL__utf8_put_char(ptr,fni->FileName[i]); *ptr = '\0'; return nameb; } #endif return RepAtom(AtomOfTerm(StreamName(sno)))->StrOfAE; } static Int representation_error ( int sno, Term t2 USES_REGS ) { stream_flags_t flags = GLOBAL_Stream[sno].status & (RepError_Xml_f|RepError_Prolog_f); /* '$representation_error'(+Stream,-ErrorMessage) */ if (!IsVarTerm(t2) && isatom(t2)) { return false; } if (flags & RepError_Xml_f) { return Yap_unify( t2, TermXml ); } if (flags & RepError_Prolog_f) { return Yap_unify( t2, TermProlog ); } return Yap_unify( t2, TermError ); } static Int file_name ( int sno, Term t2 USES_REGS ) { char s[MAXPATHLEN+1]; int f = Yap_GetStreamFd(sno); Term rc; char *name = Yap_guessFileName(f, sno, s, MAXPATHLEN); if (name) rc = MkAtomTerm(Yap_LookupAtom(name)); else return false; if (!IsVarTerm(t2) && !isatom(t2)) { return FALSE; } return Yap_unify_constant(t2,rc); } static Int file_no ( int sno, Term t2 USES_REGS ) { int f = Yap_GetStreamFd(sno); Term rc = MkIntTerm(f) ; if (!IsVarTerm(t2) && !IsIntTerm(t2)) { return false; } return Yap_unify_constant(t2,rc); } static bool SetCloseOnAbort( int sno, bool close ) { if (close) { GLOBAL_Stream[sno].status |= DoNotCloseOnAbort_Stream_f; } else { GLOBAL_Stream[sno].status &= ~DoNotCloseOnAbort_Stream_f; } return true; } static Int has_close_on_abort ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ bool rc = GLOBAL_Stream[sno].status & DoNotCloseOnAbort_Stream_f; if (!IsVarTerm(t2)) { return t2 ==(rc ? TermTrue : TermFalse ) ; } if (rc) { return Yap_unify_constant(t2,TermTrue); } else { return Yap_unify_constant(t2, TermFalse); } } static bool has_encoding ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ if (!IsVarTerm(t2) && !(isatom(t2))) { return FALSE; } if (0 && IsAtomTerm(t2)) { encoding_t e = enc_id(RepAtom(AtomOfTerm(t2))->StrOfAE); GLOBAL_Stream[sno].encoding = e; return true; } else { const char *s = enc_name( LOCAL_encoding ); return Yap_unify( t2, MkAtomTerm(Yap_LookupAtom( s ))); } } static bool found_eof ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ stream_flags_t flags = GLOBAL_Stream[sno].status & (Past_Eof_Stream_f|Eof_Stream_f); if (!IsVarTerm(t2) && !(isatom(t2))) { return FALSE; } if (flags & Past_Eof_Stream_f) return Yap_unify( t2, MkAtomTerm(AtomPast)); if (flags & Eof_Stream_f) return Yap_unify( t2, MkAtomTerm(AtomAt)); return Yap_unify( t2, MkAtomTerm(AtomNot)); } static bool stream_mode ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ stream_flags_t flags = GLOBAL_Stream[sno].status & (Input_Stream_f|Output_Stream_f|Append_Stream_f); if (!IsVarTerm(t2) && !(isatom(t2))) { return FALSE; } if (flags & Input_Stream_f) return Yap_unify( t2, TermRead); if (flags & Output_Stream_f) return Yap_unify( t2, TermWrite); if (flags & Append_Stream_f) return Yap_unify( t2, TermAppend); return false; } static bool stream_tty ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ stream_flags_t flags = GLOBAL_Stream[sno].status & (Tty_Stream_f); if (!IsVarTerm(t2) && !(isatom(t2))) { return FALSE; } if (flags & Tty_Stream_f) return Yap_unify( t2, TermTrue); return Yap_unify( t2, TermFalse); } static bool stream_type ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ stream_flags_t flags = GLOBAL_Stream[sno].status & (Binary_Stream_f); if (!IsVarTerm(t2) && !(isatom(t2))) { return FALSE; } if (flags & Binary_Stream_f) return Yap_unify( t2, TermBinary); return Yap_unify( t2, TermText); } static bool stream_position ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ Term tout = StreamPosition(sno); return Yap_unify (t2, tout); } static bool SetBuffering ( int sno, Atom at ) { /* '$set_bufferingt'(+Stream,-ErrorMessage) */ if (at == AtomFull) { if (setvbuf( GLOBAL_Stream[sno].file, NULL, _IOFBF, 0) < 0) return PlIOError( SYSTEM_ERROR, Yap_MkStream( sno ), "could not set buffer"); } else if (at == AtomLine) { if (setvbuf( GLOBAL_Stream[sno].file, NULL, _IOLBF, 0) < 0) return PlIOError( SYSTEM_ERROR, Yap_MkStream( sno ), "could not set line buffering"); } else if (at == AtomFalse) { if (setvbuf( GLOBAL_Stream[sno].file, NULL, _IONBF, 0) < 0) return PlIOError( SYSTEM_ERROR, Yap_MkStream( sno ), "could not set disable buffering"); } else { CACHE_REGS LOCAL_Error_TYPE = DOMAIN_ERROR_OUT_OF_RANGE; LOCAL_ErrorMessage = "in set_stream/2:buffer"; return false; } return true; } static bool SetBuffer ( int sno, Int sz ) { /* '$set_bufferingt'(+Stream,-ErrorMessage) */ if (setvbuf( GLOBAL_Stream[sno].file, NULL, _IOFBF, sz) < 0) { return PlIOError( SYSTEM_ERROR, Yap_MkStream( sno ), "could not set buffer"); } return true; } static bool eof_action ( int sno, Term t2 USES_REGS ) { /* '$set_output'(+Stream,-ErrorMessage) */ stream_flags_t flags = GLOBAL_Stream[sno].status & (Eof_Error_Stream_f|Reset_Eof_Stream_f|Push_Eof_Stream_f); if (!IsVarTerm(t2) && !(isatom(t2))) { return FALSE; } if (flags & Eof_Error_Stream_f) { return Yap_unify( t2, TermError); } if (flags & Reset_Eof_Stream_f) { return Yap_unify( t2, TermReset); } return Yap_unify( t2, TermEOfCode); } #define STREAM_PROPERTY_DEFS() \ PAR( "alias", filler, STREAM_PROPERTY_ALIAS ), \ PAR( "bom", filler, STREAM_PROPERTY_BOM ), \ PAR( "close_on_abort", filler, STREAM_PROPERTY_CLOSE_ON_ABORT ), \ PAR( "encoding", filler, STREAM_PROPERTY_ENCODING ), \ PAR( "end_of_stream", filler, STREAM_PROPERTY_END_OF_STREAM ), \ PAR( "eof_action", filler, STREAM_PROPERTY_EOF_ACTION ), \ PAR( "file_name", filler, STREAM_PROPERTY_FILE_NAME), \ PAR( "file_no", filler, STREAM_PROPERTY_FILE_NO), \ PAR( "input", ok, STREAM_PROPERTY_INPUT ), \ PAR( "mode", filler, STREAM_PROPERTY_MODE ), \ PAR( "output", filler, STREAM_PROPERTY_OUTPUT ), \ PAR( "position", isatom, STREAM_PROPERTY_POSITION ), \ PAR( "reposition", filler, STREAM_PROPERTY_REPOSITION ), \ PAR( "representation_errors", filler, STREAM_PROPERTY_REPRESENTATION_ERRORS ), \ PAR( "type", filler, STREAM_PROPERTY_TYPE ), \ PAR( "tty", filler, STREAM_PROPERTY_TTY ), \ PAR( NULL, ok, STREAM_PROPERTY_END ) #define PAR(x,y,z) z typedef enum stream_property_enum_choices { STREAM_PROPERTY_DEFS() } stream_property_choices_t; #undef PAR #define PAR(x,y,z) { x , y, z } static const param_t stream_property_defs[] = { STREAM_PROPERTY_DEFS() }; #undef PAR static bool do_stream_property (int sno, Term opts USES_REGS) { /* Init current_stream */ xarg *args; stream_property_choices_t i; bool rc = true; args = Yap_ArgListToVector ( opts, stream_property_defs, STREAM_PROPERTY_END ); if (args == NULL) { return false; } for (i=0; i < STREAM_PROPERTY_END; i ++) { if (args[i].used) { switch (i) { case STREAM_PROPERTY_ALIAS: rc = rc && Yap_FetchStreamAlias ( sno, args[STREAM_PROPERTY_ALIAS].tvalue PASS_REGS); break; case STREAM_PROPERTY_BOM: rc = rc && has_bom ( sno, args[STREAM_PROPERTY_BOM].tvalue PASS_REGS); break; case STREAM_PROPERTY_CLOSE_ON_ABORT: rc = rc && has_close_on_abort ( sno, args[STREAM_PROPERTY_CLOSE_ON_ABORT].tvalue PASS_REGS); break; case STREAM_PROPERTY_ENCODING: rc = rc && has_encoding ( sno, args[STREAM_PROPERTY_ENCODING].tvalue PASS_REGS); break; case STREAM_PROPERTY_END_OF_STREAM: rc = rc && found_eof ( sno, args[STREAM_PROPERTY_END_OF_STREAM].tvalue PASS_REGS); break; case STREAM_PROPERTY_EOF_ACTION: rc = rc && eof_action ( sno, args[STREAM_PROPERTY_EOF_ACTION].tvalue PASS_REGS); break; case STREAM_PROPERTY_FILE_NAME: rc = rc && file_name ( sno, args[STREAM_PROPERTY_FILE_NAME].tvalue PASS_REGS); break; case STREAM_PROPERTY_FILE_NO: rc = rc && file_no ( sno, args[STREAM_PROPERTY_FILE_NO].tvalue PASS_REGS); break; case STREAM_PROPERTY_INPUT: rc = rc && is_input ( sno PASS_REGS); break; case STREAM_PROPERTY_MODE: rc = rc && stream_mode ( sno, args[STREAM_PROPERTY_MODE].tvalue PASS_REGS); break; case STREAM_PROPERTY_OUTPUT: rc = rc && is_output ( sno PASS_REGS); break; case STREAM_PROPERTY_POSITION: rc = rc && stream_position ( sno, args[STREAM_PROPERTY_POSITION].tvalue PASS_REGS); break; case STREAM_PROPERTY_REPOSITION: rc = rc && has_reposition ( sno, args[STREAM_PROPERTY_MODE].tvalue PASS_REGS); break; case STREAM_PROPERTY_REPRESENTATION_ERRORS: rc = rc && representation_error ( sno, args[STREAM_PROPERTY_REPRESENTATION_ERRORS].tvalue PASS_REGS); break; case STREAM_PROPERTY_TYPE: rc = rc && stream_type ( sno, args[STREAM_PROPERTY_TYPE].tvalue PASS_REGS); break; case STREAM_PROPERTY_TTY: rc = rc && stream_tty ( sno, args[STREAM_PROPERTY_TTY].tvalue PASS_REGS); break; case STREAM_PROPERTY_END: rc = false; break; } } } UNLOCK(GLOBAL_Stream[sno].streamlock); return rc; } static Int cont_stream_property (USES_REGS1) { /* current_stream */ int i = IntOfTerm (EXTRA_CBACK_ARG (2, 1)), i0; LOCK(GLOBAL_Stream[i].streamlock); i0=i; while (i < MaxStreams) { if (GLOBAL_Stream[i].status & Free_Stream_f) { ++i; continue; } if (i != i0) { LOCK(GLOBAL_Stream[i].streamlock); UNLOCK(GLOBAL_Stream[i0].streamlock); } ++i; EXTRA_CBACK_ARG (2, 1) = MkIntTerm (i); if (i == MaxStreams) do_cut( true ); if ( do_stream_property(i-1, Deref(ARG2) PASS_REGS) ) { Yap_unify(ARG1, Yap_MkStream(i-1)); return true; } } UNLOCK(GLOBAL_Stream[i0].streamlock); cut_fail(); } static Int stream_property (USES_REGS1) { /* Init current_stream */ Term t1 = Deref(ARG1); /* make valgrind happy by always filling in memory */ EXTRA_CBACK_ARG (2, 1) = MkIntTerm (0); if (!IsVarTerm(t1)) { Int i; i = Yap_CheckStream (t1, Input_Stream_f|Output_Stream_f|Append_Stream_f, "current_stream/3"); do_cut(0); if (i < 0) return false; return do_stream_property( i, Deref(ARG2) PASS_REGS); } else { return (cont_stream_property (PASS_REGS1)); } } #define SET_STREAM_DEFS() \ PAR( "alias", isatom, SET_STREAM_ALIAS ), \ PAR( "buffer", boolean, SET_STREAM_BUFFER ), \ PAR( "buffer_size", nat, SET_STREAM_BUFFER_SIZE ), \ PAR( "close_on_abort", boolean, SET_STREAM_CLOSE_ON_ABORT ), \ PAR( "encoding", isatom, SET_STREAM_ENCODING ), \ PAR( "eof_action", isatom, SET_STREAM_EOF_ACTION ), \ PAR( "file_name", isatom, SET_STREAM_FILE_NAME), \ PAR( "line_position", nat, SET_STREAM_LINE_POSITION ), \ PAR( "newline", filler, SET_STREAM_NEWLINE), \ PAR( "record_position", isatom, SET_STREAM_RECORD_POSITION ), \ PAR( "representation_errors", isatom, SET_STREAM_REPRESENTATION_ERRORS ), \ PAR( "type", isatom, SET_STREAM_TYPE ), \ PAR( "tty", filler, SET_STREAM_TTY ), \ PAR( NULL, ok, SET_STREAM_END ) #define PAR(x,y,z) z typedef enum set_stream_enum_choices { SET_STREAM_DEFS() } set_stream_enum_choices_t; #undef PAR #define PAR(x,y,z) { x , y, z } static const param_t set_stream_defs[] = { SET_STREAM_DEFS() }; #undef PAR static bool do_set_stream (int sno, Term opts USES_REGS) { /* Init current_stream */ xarg *args; set_stream_enum_choices_t i; bool rc = true; args = Yap_ArgListToVector ( opts, set_stream_defs, SET_STREAM_END ); if (args == NULL) { UNLOCK(GLOBAL_Stream[sno].streamlock); return false; } for (i=0; i < SET_STREAM_END; i ++) { if (args[i].used) { Term t = args[i].tvalue; switch (i) { case SET_STREAM_ALIAS: rc = rc && Yap_AddAlias ( AtomOfTerm(t), sno ); break; case SET_STREAM_BUFFER: rc = rc && SetBuffering ( sno, AtomOfTerm(t) ); break; case SET_STREAM_BUFFER_SIZE: rc = rc && SetBuffer ( sno, IntegerOfTerm(t) ); break; case SET_STREAM_CLOSE_ON_ABORT: rc = rc && SetCloseOnAbort ( sno, (args[SET_STREAM_CLOSE_ON_ABORT].tvalue == TermTrue)); break; case SET_STREAM_ENCODING: GLOBAL_Stream[sno]. encoding = enc_id(AtomOfTerm(args[SET_STREAM_ENCODING].tvalue)->StrOfAE); has_encoding ( sno, args[SET_STREAM_ENCODING].tvalue PASS_REGS); break; case SET_STREAM_EOF_ACTION: { Term t2 = args[SET_STREAM_EOF_ACTION].tvalue; if (t2 == TermError) { GLOBAL_Stream[sno].status |= Eof_Error_Stream_f; GLOBAL_Stream[sno].status &= ~Reset_Eof_Stream_f; } else if (t2 == TermReset) {GLOBAL_Stream[sno].status |= GLOBAL_Stream[sno].status &= ~Eof_Error_Stream_f; GLOBAL_Stream[sno].status |= Reset_Eof_Stream_f; } else if (t2 == TermEOfCode) { GLOBAL_Stream[sno].status &= ~Eof_Error_Stream_f; GLOBAL_Stream[sno].status &= ~Reset_Eof_Stream_f; } else { LOCAL_Error_TYPE = DOMAIN_ERROR_OUT_OF_RANGE; LOCAL_ErrorMessage = "in set_stream/2:eof_action"; rc = false; } break; case SET_STREAM_FILE_NAME: GLOBAL_Stream[sno].user_name = args[SET_STREAM_FILE_NAME].tvalue; break; case SET_STREAM_LINE_POSITION: GLOBAL_Stream[sno].linepos = IntegerOfTerm(args[SET_STREAM_FILE_NAME].tvalue); break; case SET_STREAM_NEWLINE: printf("not yet\n"); break; case SET_STREAM_RECORD_POSITION: if (args[SET_STREAM_RECORD_POSITION].tvalue == TermTrue) GLOBAL_Stream[sno].status |= Seekable_Stream_f; else GLOBAL_Stream[sno].status &= ~Seekable_Stream_f; break; case SET_STREAM_REPRESENTATION_ERRORS: { Term t2 = args[SET_STREAM_EOF_ACTION].tvalue; if (t2 == TermXml) { GLOBAL_Stream[sno].status |= RepError_Xml_f; GLOBAL_Stream[sno].status &= ~RepError_Prolog_f; } else if (t2 == TermError) {GLOBAL_Stream[sno].status |= GLOBAL_Stream[sno].status &= ~RepError_Xml_f; GLOBAL_Stream[sno].status |= RepError_Prolog_f; } else if (t2 == TermEOfCode) { GLOBAL_Stream[sno].status &= ~RepError_Xml_f; GLOBAL_Stream[sno].status |= RepError_Prolog_f; } else { LOCAL_Error_TYPE = DOMAIN_ERROR_OUT_OF_RANGE; LOCAL_ErrorMessage = "in set_stream/2:eof_action"; rc = false; } } break; case SET_STREAM_TYPE: rc &= stream_type ( sno, args[SET_STREAM_TYPE].tvalue PASS_REGS); break; case SET_STREAM_TTY: rc &= stream_tty ( sno, args[SET_STREAM_TTY].tvalue PASS_REGS); break; case SET_STREAM_END: rc = false; break; } } } } UNLOCK(GLOBAL_Stream[sno].streamlock); return rc; } static Int set_stream (USES_REGS1) { /* Init current_stream */ int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, "set_stream_position/2"); if (sno < 0) { return (FALSE); } return do_set_stream( sno, Deref(ARG2) PASS_REGS); } /* * Called when you want to close all open streams, except for stdin, stdout * and stderr */ void Yap_CloseStreams (int loud) { CACHE_REGS int sno; for (sno = 3; sno < MaxStreams; ++sno) { if (GLOBAL_Stream[sno].status & Free_Stream_f) continue; if ((GLOBAL_Stream[sno].status & Popen_Stream_f)) pclose (GLOBAL_Stream[sno].file); #if _MSC_VER || defined(__MINGW32__) if (GLOBAL_Stream[sno].status & Pipe_Stream_f) CloseHandle (GLOBAL_Stream[sno].u.pipe.hdl); #else if (GLOBAL_Stream[sno].status & (Pipe_Stream_f|Socket_Stream_f)) close (GLOBAL_Stream[sno].u.pipe.fd); #endif else if (GLOBAL_Stream[sno].status & (Socket_Stream_f)) { Yap_CloseSocket(GLOBAL_Stream[sno].u.socket.fd, GLOBAL_Stream[sno].u.socket.flags, GLOBAL_Stream[sno].u.socket.domain); } else if (GLOBAL_Stream[sno].status & InMemory_Stream_f) { if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_CODE) { Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf); } else if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) { free(GLOBAL_Stream[sno].u.mem_string.buf); } } else if (!(GLOBAL_Stream[sno].status & Null_Stream_f)) { fclose (GLOBAL_Stream[sno].file); } else { if (loud) fprintf (Yap_stderr, "%% YAP Error: while closing stream: %s\n", RepAtom (GLOBAL_Stream[sno].name)->StrOfAE); } if (LOCAL_c_input_stream == sno) { LOCAL_c_input_stream = StdInStream; } else if (LOCAL_c_output_stream == sno) { LOCAL_c_output_stream = StdOutStream; } GLOBAL_Stream[sno].status = Free_Stream_f; } } static void CloseStream(int sno) { CACHE_REGS if (!(GLOBAL_Stream[sno].status & (Null_Stream_f|Socket_Stream_f|InMemory_Stream_f|Pipe_Stream_f))) fclose (GLOBAL_Stream[sno].file); #if HAVE_SOCKET else if (GLOBAL_Stream[sno].status & (Socket_Stream_f)) { Yap_CloseSocket(GLOBAL_Stream[sno].u.socket.fd, GLOBAL_Stream[sno].u.socket.flags, GLOBAL_Stream[sno].u.socket.domain); } #endif else if (GLOBAL_Stream[sno].status & Pipe_Stream_f) { #if _MSC_VER || defined(__MINGW32__) CloseHandle (GLOBAL_Stream[sno].u.pipe.hdl); #else close(GLOBAL_Stream[sno].u.pipe.fd); #endif } else if (GLOBAL_Stream[sno].status & (InMemory_Stream_f)) { if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_CODE) Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf); else if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) { free(GLOBAL_Stream[sno].u.mem_string.buf); } } GLOBAL_Stream[sno].status = Free_Stream_f; Yap_DeleteAliases(sno); if (LOCAL_c_input_stream == sno) { LOCAL_c_input_stream = StdInStream; } else if (LOCAL_c_output_stream == sno) { LOCAL_c_output_stream = StdOutStream; } else if (LOCAL_c_error_stream == sno) { LOCAL_c_error_stream = StdErrStream; } /* if (st->status == Socket_Stream_f|Input_Stream_f|Output_Stream_f) { Yap_CloseSocket(); } */ } void Yap_CloseStream(int sno) { CloseStream(sno); } void Yap_ReleaseStream(int sno) { CACHE_REGS GLOBAL_Stream[sno].status = Free_Stream_f; Yap_DeleteAliases(sno); if (LOCAL_c_input_stream == sno) { LOCAL_c_input_stream = StdInStream; } else if (LOCAL_c_output_stream == sno) { LOCAL_c_output_stream = StdOutStream; } else if (LOCAL_c_error_stream == sno) { LOCAL_c_error_stream = StdErrStream; } /* if (st->status == Socket_Stream_f|Input_Stream_f|Output_Stream_f) { Yap_CloseSocket(); } */ } static Int current_input ( USES_REGS1 ) { /* current_input(?Stream) */ Term t1 = Deref(ARG1); if (IsVarTerm(t1)) { Term t = Yap_MkStream (LOCAL_c_input_stream); YapBind(VarOfTerm(t1), t); return TRUE; } else if (!IsApplTerm(t1) || FunctorOfTerm(t1) != FunctorStream || !IsIntTerm((t1=ArgOfTerm(1,t1)))) { Yap_Error(DOMAIN_ERROR_STREAM,t1,"current_input/1"); return FALSE; } else { return LOCAL_c_input_stream == IntOfTerm(t1); } } /** @pred set_input(+ _S_) is iso * Set stream _S_ as the current input stream. Predicates like read/1 * and get/1 will start using stream _S_ by default. * * * @param Input-mode stream * */ static Int set_input ( USES_REGS1 ) { /* '$show_stream_position'(+Stream,Pos) */ int sno = Yap_CheckStream (ARG1, Input_Stream_f, "set_input/1"); if (sno < 0) return false; LOCAL_c_input_stream = sno; UNLOCK(GLOBAL_Stream[sno].streamlock); return true; } static Int current_output ( USES_REGS1 ) { /* current_output(?Stream) */ Term t1 = Deref(ARG1); if (IsVarTerm(t1)) { Term t = Yap_MkStream (LOCAL_c_output_stream); YapBind(VarOfTerm(t1), t); return TRUE; } else if (!IsApplTerm(t1) || FunctorOfTerm(t1) != FunctorStream || !IsIntTerm((t1=ArgOfTerm(1,t1)))) { Yap_Error(DOMAIN_ERROR_STREAM,t1,"current_output/1"); return FALSE; } else { return(LOCAL_c_output_stream == IntOfTerm(t1)); } } /** @pred set_input(+ _S_) is iso * Set stream _S_ as the current input stream. Predicates like read/1 * and get/1 will start using stream _S_ by default. * * * @param Output-mode stream * */ static Int set_output ( USES_REGS1 ) { /* '$show_stream_position'(+Stream,Pos) */ int sno = Yap_CheckStream (ARG1, Output_Stream_f | Append_Stream_f, "set_output/2"); if (sno < 0) return false; LOCAL_c_output_stream = sno; UNLOCK(GLOBAL_Stream[sno].streamlock); return true; } static Int p_user_file_name ( USES_REGS1 ) { Term tout; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f,"user_file_name/2"); if (sno < 0) return (FALSE); tout = Yap_StreamUserName(sno); UNLOCK(GLOBAL_Stream[sno].streamlock); return (Yap_unify_constant (ARG2, tout)); } static Int p_file_name ( USES_REGS1 ) { Term tout; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f,"file_name/2"); if (sno < 0) return (FALSE); #if HAVE_SOCKET if (GLOBAL_Stream[sno].status & Socket_Stream_f) tout = MkAtomTerm(AtomSocket); else #endif if (GLOBAL_Stream[sno].status & Pipe_Stream_f) tout = MkAtomTerm(AtomPipe); else if (GLOBAL_Stream[sno].status & InMemory_Stream_f) tout = MkAtomTerm(AtomCharsio); else tout = MkAtomTerm(GLOBAL_Stream[sno].name); UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify_constant (ARG2, tout); } static Int p_cur_line_no ( USES_REGS1 ) { /* '$current_line_number'(+Stream,-N) */ Term tout; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f,"current_line_number/2"); if (sno < 0) return (FALSE); /* one has to be somewhat more careful because of terminals */ if (GLOBAL_Stream[sno].status & Tty_Stream_f) { Int no = 1; int i; Atom my_stream; #if HAVE_SOCKET if (GLOBAL_Stream[sno].status & Socket_Stream_f) my_stream = AtomSocket; else #endif if (GLOBAL_Stream[sno].status & Pipe_Stream_f) my_stream = AtomPipe; else if (GLOBAL_Stream[sno].status & InMemory_Stream_f) my_stream = AtomCharsio; else my_stream = GLOBAL_Stream[sno].name; for (i = 0; i < MaxStreams; i++) { if (!(GLOBAL_Stream[i].status & (Free_Stream_f|Socket_Stream_f|Pipe_Stream_f|InMemory_Stream_f)) && GLOBAL_Stream[i].name == my_stream) no += GLOBAL_Stream[i].linecount - 1; } tout = MkIntTerm (no); } else tout = MkIntTerm (GLOBAL_Stream[sno].linecount); UNLOCK(GLOBAL_Stream[sno].streamlock); return (Yap_unify_constant (ARG2, tout)); } static Int p_line_position ( USES_REGS1 ) { /* '$line_position'(+Stream,-N) */ Term tout; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, "line_position/2"); if (sno < 0) return (FALSE); if (GLOBAL_Stream[sno].status & Tty_Stream_f) { Int no = 0; int i; Atom my_stream = GLOBAL_Stream[sno].name; for (i = 0; i < MaxStreams; i++) { if (!(GLOBAL_Stream[i].status & Free_Stream_f) && GLOBAL_Stream[i].name == my_stream) no += GLOBAL_Stream[i].linepos; } tout = MkIntTerm (no); } else tout = MkIntTerm (GLOBAL_Stream[sno].linepos); UNLOCK(GLOBAL_Stream[sno].streamlock); return (Yap_unify_constant (ARG2, tout)); } static Int p_character_count ( USES_REGS1 ) { /* '$character_count'(+Stream,-N) */ Term tout; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, "character_count/2"); if (sno < 0) return (FALSE); if (GLOBAL_Stream[sno].status & Tty_Stream_f) { Int no = 0; int i; Atom my_stream = GLOBAL_Stream[sno].name; for (i = 0; i < MaxStreams; i++) { if (!(GLOBAL_Stream[i].status & Free_Stream_f) && GLOBAL_Stream[i].name == my_stream) no += GLOBAL_Stream[i].charcount; } tout = MkIntTerm (no); } else if (GLOBAL_Stream[sno].status & Null_Stream_f) tout = MkIntTerm (GLOBAL_Stream[sno].charcount); else tout = MkIntTerm (ftell (GLOBAL_Stream[sno].file)); UNLOCK(GLOBAL_Stream[sno].streamlock); return (Yap_unify_constant (ARG2, tout)); } static Int p_show_stream_flags( USES_REGS1 ) { /* '$show_stream_flags'(+Stream,Pos) */ Term tout; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, "stream_property/2"); if (sno < 0) return (FALSE); tout = MkIntTerm(GLOBAL_Stream[sno].status); UNLOCK(GLOBAL_Stream[sno].streamlock); return (Yap_unify (ARG2, tout)); } Term Yap_StreamPosition(int sno) { return StreamPosition(sno); } static Int p_show_stream_position ( USES_REGS1 ) { /* '$show_stream_position'(+Stream,Pos) */ Term tout; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, "stream_position/2"); if (sno < 0) return (FALSE); tout = StreamPosition(sno); UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify (ARG2, tout); } static Int set_stream_position ( USES_REGS1 ) { /* '$set_stream_position'(+Stream,Pos) */ Term tin, tp; Int char_pos; int sno = Yap_CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, "set_stream_position/2"); if (sno < 0) { return (FALSE); } tin = Deref (ARG2); if (IsVarTerm (tin)) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(INSTANTIATION_ERROR, tin, "set_stream_position/2"); return (FALSE); } else if (!(IsApplTerm (tin))) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(DOMAIN_ERROR_STREAM_POSITION, tin, "set_stream_position/2"); return (FALSE); } if (FunctorOfTerm (tin) == FunctorStreamPos) { if (IsVarTerm (tp = ArgOfTerm (1, tin))) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(INSTANTIATION_ERROR, tp, "set_stream_position/2"); return (FALSE); } else if (!IsIntTerm (tp)) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(DOMAIN_ERROR_STREAM_POSITION, tin, "set_stream_position/2"); return (FALSE); } if (!(GLOBAL_Stream[sno].status & Seekable_Stream_f) ) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(PERMISSION_ERROR_REPOSITION_STREAM, ARG1,"set_stream_position/2"); return(FALSE); } char_pos = IntOfTerm (tp); if (IsVarTerm (tp = ArgOfTerm (2, tin))) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(INSTANTIATION_ERROR, tp, "set_stream_position/2"); return (FALSE); } else if (!IsIntTerm (tp)) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(DOMAIN_ERROR_STREAM_POSITION, tin, "set_stream_position/2"); return (FALSE); } GLOBAL_Stream[sno].charcount = char_pos; GLOBAL_Stream[sno].linecount = IntOfTerm (tp); if (IsVarTerm (tp = ArgOfTerm (3, tin))) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(INSTANTIATION_ERROR, tp, "set_stream_position/2"); return (FALSE); } else if (!IsIntTerm (tp)) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(DOMAIN_ERROR_STREAM_POSITION, tin, "set_stream_position/2"); return (FALSE); } GLOBAL_Stream[sno].linepos = IntOfTerm (tp); if (fseek (GLOBAL_Stream[sno].file, (long) (char_pos), 0) == -1) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(SYSTEM_ERROR, tp, "fseek failed for set_stream_position/2"); return(FALSE); } GLOBAL_Stream[sno].stream_getc = PlGetc; GLOBAL_Stream[sno].stream_gets = PlGetsFunc(); } else if (FunctorOfTerm (tin) == FunctorStreamEOS) { if (IsVarTerm (tp = ArgOfTerm (1, tin))) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(INSTANTIATION_ERROR, tp, "set_stream_position/2"); return (FALSE); } else if (tp != MkAtomTerm(AtomAt)) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(DOMAIN_ERROR_STREAM_POSITION, tin, "set_stream_position/2"); return (FALSE); } if (!(GLOBAL_Stream[sno].status & Seekable_Stream_f) ) { UNLOCK(GLOBAL_Stream[sno].streamlock); PlIOError(PERMISSION_ERROR_REPOSITION_STREAM, ARG1,"set_stream_position/2"); return(FALSE); } if (fseek (GLOBAL_Stream[sno].file, 0L, SEEK_END) == -1) { UNLOCK(GLOBAL_Stream[sno].streamlock); PlIOError(SYSTEM_ERROR, tp, "fseek failed for set_stream_position/2: %s", strerror(errno)); return(FALSE); } GLOBAL_Stream[sno].stream_getc = PlGetc; GLOBAL_Stream[sno].stream_gets = PlGetsFunc(); /* reset the counters */ GLOBAL_Stream[sno].linepos = 0; GLOBAL_Stream[sno].linecount = 1; GLOBAL_Stream[sno].charcount = 0; } UNLOCK(GLOBAL_Stream[sno].streamlock); return (TRUE); } #if HAVE_SELECT /* stream_select(+Streams,+TimeOut,-Result) */ static Int p_stream_select( USES_REGS1 ) { Term t1 = Deref(ARG1), t2; fd_set readfds, writefds, exceptfds; struct timeval timeout, *ptime; #if _MSC_VER u_int fdmax=0; #else int fdmax=0; #endif Term tout = TermNil, ti, Head; if (IsVarTerm(t1)) { Yap_Error(INSTANTIATION_ERROR,t1,"stream_select/3"); return FALSE; } if (!IsPairTerm(t1)) { Yap_Error(TYPE_ERROR_LIST,t1,"stream_select/3"); return(FALSE); } FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); ti = t1; while (ti != TermNil) { #if _MSC_VER u_int fd; #else int fd; #endif int sno; Head = HeadOfTerm(ti); sno = Yap_CheckStream(Head, Input_Stream_f, "stream_select/3"); if (sno < 0) return(FALSE); fd = GetStreamFd(sno); FD_SET(fd, &readfds); UNLOCK(GLOBAL_Stream[sno].streamlock); if (fd > fdmax) fdmax = fd; ti = TailOfTerm(ti); } t2 = Deref(ARG2); if (IsVarTerm(t2)) { Yap_Error(INSTANTIATION_ERROR,t2,"stream_select/3"); return(FALSE); } if (IsAtomTerm(t2)) { if (t2 == MkAtomTerm(AtomOff)) { /* wait indefinitely */ ptime = NULL; } else { Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t1,"stream_select/3"); return(FALSE); } } else { Term t21, t22; if (!IsApplTerm(t2) || FunctorOfTerm(t2) != FunctorModule) { Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3"); return(FALSE); } t21 = ArgOfTerm(1, t2); if (IsVarTerm(t21)) { Yap_Error(INSTANTIATION_ERROR,t2,"stream_select/3"); return(FALSE); } if (!IsIntegerTerm(t21)) { Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3"); return(FALSE); } timeout.tv_sec = IntegerOfTerm(t21); if (timeout.tv_sec < 0) { Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3"); return(FALSE); } t22 = ArgOfTerm(2, t2); if (IsVarTerm(t22)) { Yap_Error(INSTANTIATION_ERROR,t2,"stream_select/3"); return(FALSE); } if (!IsIntegerTerm(t22)) { Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3"); return(FALSE); } timeout.tv_usec = IntegerOfTerm(t22); if (timeout.tv_usec < 0) { Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3"); return(FALSE); } ptime = &timeout; } /* do the real work */ if (select(fdmax+1, &readfds, &writefds, &exceptfds, ptime) < 0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR, TermNil, "stream_select/3 (select: %s)", strerror(errno)); #else Yap_Error(SYSTEM_ERROR, TermNil, "stream_select/3 (select)"); #endif } while (t1 != TermNil) { int fd; int sno; Head = HeadOfTerm(t1); sno = Yap_CheckStream(Head, Input_Stream_f, "stream_select/3"); fd = GetStreamFd(sno); if (FD_ISSET(fd, &readfds)) tout = MkPairTerm(Head,tout); else tout = MkPairTerm(TermNil,tout); UNLOCK(GLOBAL_Stream[sno].streamlock); t1 = TailOfTerm(t1); } /* we're done, just pass the info back */ return(Yap_unify(ARG3,tout)); } #endif Int Yap_StreamToFileNo(Term t) { int sno = Yap_CheckStream(t, (Input_Stream_f|Output_Stream_f), "StreamToFileNo"); if (GLOBAL_Stream[sno].status & Pipe_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); #if _MSC_VER || defined(__MINGW32__) return((Int)(GLOBAL_Stream[sno].u.pipe.hdl)); #else return(GLOBAL_Stream[sno].u.pipe.fd); #endif #if HAVE_SOCKET } else if (GLOBAL_Stream[sno].status & Socket_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); return(GLOBAL_Stream[sno].u.socket.fd); #endif } else if (GLOBAL_Stream[sno].status & (Null_Stream_f)) { UNLOCK(GLOBAL_Stream[sno].streamlock); return(-1); } else { UNLOCK(GLOBAL_Stream[sno].streamlock); return(fileno(GLOBAL_Stream[sno].file)); } } static Int p_stream( USES_REGS1 ) { Term in = Deref(ARG1); if (IsVarTerm(in)) return(FALSE); if (IsAtomTerm(in)) return(Yap_CheckAlias(AtomOfTerm(in)) >= 0); if (IsApplTerm(in)) return(FunctorOfTerm(in) == FunctorStream); return(FALSE); } FILE * Yap_FileDescriptorFromStream(Term t) { int sno = Yap_CheckStream (t, Input_Stream_f|Output_Stream_f, "FileDescriptorFromStream"); FILE *rc; if (sno < 0) return NULL; if (GLOBAL_Stream[sno].status & (Null_Stream_f| Socket_Stream_f| Pipe_Stream_f| Free_Stream_f)) rc = NULL; else rc = GLOBAL_Stream[sno].file; UNLOCK(GLOBAL_Stream[sno].streamlock); return rc; } void Yap_InitBackIO (void) { Yap_InitCPredBack ("stream_property", 2, 1, stream_property, cont_stream_property, SafePredFlag|SyncPredFlag); } void Yap_InitIOStreams(void) { Yap_InitCPred ("$stream_flags", 2, p_stream_flags, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred ("$check_stream", 2, p_check_stream, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred ("$check_stream", 1, p_check_if_stream, SafePredFlag|SyncPredFlag|HiddenPredFlag|HiddenPredFlag); Yap_InitCPred ("$current_line_number", 2, p_cur_line_no, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred ("$line_position", 2, p_line_position, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred ("$character_count", 2, p_character_count, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred ("$show_stream_flags", 2, p_show_stream_flags, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred ("$user_file_name", 2, p_user_file_name, SafePredFlag|SyncPredFlag), Yap_InitCPred ("$file_name", 2, p_file_name, SafePredFlag|SyncPredFlag), Yap_InitCPred ("current_input", 1, current_input, SafePredFlag|SyncPredFlag); Yap_InitCPred ("current_output", 1, current_output, SafePredFlag|SyncPredFlag); Yap_InitCPred ("set_input", 1, set_input, SafePredFlag|SyncPredFlag); Yap_InitCPred ("set_output", 1, set_output, SafePredFlag|SyncPredFlag); Yap_InitCPred ("$stream", 1, p_stream, SafePredFlag|TestPredFlag); Yap_InitCPred ("$stream", 1, p_stream, SafePredFlag|TestPredFlag); #if HAVE_SELECT Yap_InitCPred ("stream_select", 3, p_stream_select, SafePredFlag|SyncPredFlag); #endif Yap_InitCPred ("$show_stream_position", 2, p_show_stream_position, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred ("set_stream_position", 2, set_stream_position, SafePredFlag|SyncPredFlag); Yap_InitCPred ("set_stream", 2, set_stream, SafePredFlag|SyncPredFlag); }