diff --git a/os/charsio.c b/os/charsio.c index 3fd86f540..9480b286e 100644 --- a/os/charsio.c +++ b/os/charsio.c @@ -26,6 +26,7 @@ static char SccsId[] = "%W% %G%"; #include "Yap.h" #include "Yatom.h" #include "YapHeap.h" +#include "YapText.h" #include "yapio.h" #include #if HAVE_UNISTD_H @@ -84,18 +85,66 @@ Int Yap_peek(int sno) { Int ch; s = GLOBAL_Stream + sno; + if ( s->status & Readline_Stream_f) { + ch = Yap_ReadlinePeekChar( sno ); + if (ch == EOFCHAR) { + s->stream_getc = EOFPeek; + s->stream_wgetc = EOFWPeek; + s->status |= Push_Eof_Stream_f; + } + return ch; + } ocharcount = s->charcount; olinecount = s->linecount; olinepos = s->linepos; ch = s->stream_wgetc(sno); + s ->och = ch; + if (ch == EOFCHAR) { + s->stream_getc = EOFPeek; + s->stream_wgetc = EOFWPeek; + s->status |= Push_Eof_Stream_f; + return ch; + } s->charcount = ocharcount; s->linecount = olinecount; s->linepos = olinepos; /* buffer the character */ if (s->encoding == LOCAL_encoding) { ungetwc(ch, s->file); - } else { + } else if (s->encoding == ENC_OCTET || + s->encoding == ENC_ISO_LATIN1|| + s->encoding == ENC_ISO_ASCII) { + ungetc(ch, s->file); + } else if (s->encoding == ENC_ISO_UTF8) { + unsigned char cs[8]; + size_t n = put_utf8(cs, ch ); + while (n--) { + ungetc(cs[n-1], s->file); + } + } else if (s->encoding == ENC_UTF16_BE) { /* do the ungetc as if a write .. */ + unsigned long int c = ch; + if (c >((1<<16)-1)) { + ungetc(c/1<<16, s->file); + c %= 1<< 16; + } + ungetc(c, s->file); + } else if (s->encoding == ENC_UTF16_BE) { + /* do the ungetc as if a write .. */ + unsigned long int c = ch; + if (c > ((1<<16)-1)) { + ungetc(c/1<<16, s->file); + c %= 1<< 16; + } + } else if (s->encoding == ENC_UTF16_LE) { + /* do the ungetc as if a write .. */ + unsigned long int c = ch; + if (c >(( 1<<16)-1)) { + ungetc(c%1<<16, s->file); + c /= 1<< 16; + } + ungetc(c, s->file); + } else { int (*f)(int, int) = s->stream_putc; s->stream_putc = plUnGetc; put_wchar(sno, ch); diff --git a/os/iopreds.c b/os/iopreds.c index e85066ed0..09ebd9951 100644 --- a/os/iopreds.c +++ b/os/iopreds.c @@ -8,9 +8,9 @@ * * ************************************************************************** * * - * File: iopreds.c * + * File: iopreds.c * * Last rev: 5/2/88 * - * mods: * + * mods: * * comments: Input/Output C implemented predicates * * * *************************************************************************/ @@ -72,10 +72,10 @@ static char SccsId[] = "%W% %G%"; #endif #endif #if !HAVE_STRNCAT -#define strncat(X,Y,Z) strcat(X,Y) +#define strncat(X, Y, Z) strcat(X, Y) #endif #if !HAVE_STRNCPY -#define strncpy(X,Y,Z) strcpy(X,Y) +#define strncpy(X, Y, Z) strcpy(X, Y) #endif #if _MSC_VER || defined(__MINGW32__) #if HAVE_SOCKET @@ -83,24 +83,22 @@ static char SccsId[] = "%W% %G%"; #endif #include #ifndef S_ISDIR -#define S_ISDIR(x) (((x)&_S_IFDIR)==_S_IFDIR) +#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR) #endif #endif #include "iopreds.h" -static int get_wchar( int); -static int get_wchar_from_file( int); +static int get_wchar(int); +static int get_wchar_from_file(int); FILE *Yap_stdin; FILE *Yap_stdout; FILE *Yap_stderr; -static bool issolutions( Term t) -{ - if (t == TermFirst || - t == TermAll ) +static bool issolutions(Term t) { + if (t == TermFirst || t == TermAll) return true; - + if (IsVarTerm(t)) { Yap_Error(INSTANTIATION_ERROR, t, "solutions in {first, all}."); return false; @@ -111,38 +109,31 @@ static bool issolutions( Term t) } Yap_Error(TYPE_ERROR_ATOM, t, "solutions in {first, all}}"); return false; - } -static bool is_file_type( Term t) -{ - if (t == TermTxt || - t == TermProlog || - t == TermSource|| - t == TermExecutable|| - t == TermQly|| - t == TermDirectory ) +static bool is_file_type(Term t) { + if (t == TermTxt || t == TermProlog || t == TermSource || + t == TermExecutable || t == TermQly || t == TermDirectory) return true; - + if (IsVarTerm(t)) { - Yap_Error(INSTANTIATION_ERROR, t, "file_type in {txt,prolog,exe,directory...}"); + Yap_Error(INSTANTIATION_ERROR, t, + "file_type in {txt,prolog,exe,directory...}"); return false; } if (IsAtomTerm(t)) { - Yap_Error(DOMAIN_ERROR_FILE_TYPE, t, "file_type in {txt,prolog,exe,directory...}"); + Yap_Error(DOMAIN_ERROR_FILE_TYPE, t, + "file_type in {txt,prolog,exe,directory...}"); return false; } Yap_Error(TYPE_ERROR_ATOM, t, "file_type in {txt,prolog,exe,directory...}"); return false; - } -static bool is_file_errors( Term t) -{ - if (t == TermFail || - t == TermError ) +static bool is_file_errors(Term t) { + if (t == TermFail || t == TermError) return true; - + if (IsVarTerm(t)) { Yap_Error(INSTANTIATION_ERROR, t, "file_error in {fail,error}."); return false; @@ -153,14 +144,11 @@ static bool is_file_errors( Term t) } Yap_Error(TYPE_ERROR_ATOM, t, "file_error in {fail,error}."); return false; - } -void -Yap_DefaultStreamOps( StreamDesc * st) -{ +void Yap_DefaultStreamOps(StreamDesc *st) { st->stream_wputc = put_wchar; - if (!(st->status & (Tty_Stream_f|Reset_Eof_Stream_f|Promptable_Stream_f))) + if (!(st->status & (Tty_Stream_f | Reset_Eof_Stream_f | Promptable_Stream_f))) st->stream_wgetc = get_wchar_from_file; else st->stream_wgetc = get_wchar; @@ -168,33 +156,29 @@ Yap_DefaultStreamOps( StreamDesc * st) st->stream_wgetc_for_read = ISOWGetc; else st->stream_wgetc_for_read = st->stream_wgetc; - if (st->encoding == ENC_ISO_UTF8) + if (st->encoding == ENC_ISO_UTF8) st->stream_getc_for_utf8 = st->stream_getc; else st->stream_getc_for_utf8 = GetUTF8; } -static void -unix_upd_stream_info (StreamDesc * s) -{ +static void unix_upd_stream_info(StreamDesc *s) { if (s->status & InMemory_Stream_f) { s->status |= Seekable_Stream_f; return; } - Yap_socketStream( s ); -#if _MSC_VER || defined(__MINGW32__) + Yap_socketStream(s); +#if _MSC_VER || defined(__MINGW32__) { - if ( - _isatty(_fileno(s->u.file.file)) - ) { - s->status |= Tty_Stream_f|Reset_Eof_Stream_f|Promptable_Stream_f; + if (_isatty(_fileno(s->u.file.file))) { + s->status |= Tty_Stream_f | Reset_Eof_Stream_f | Promptable_Stream_f; /* make all console descriptors unbuffered */ setvbuf(s->u.file.file, NULL, _IONBF, 0); return; } #if _MSC_VER /* standard error stream should never be buffered */ - else if (StdErrStream == s-Stream) { + else if (StdErrStream == s - Stream) { setvbuf(s->u.file.file, NULL, _IONBF, 0); } #endif @@ -206,19 +190,19 @@ unix_upd_stream_info (StreamDesc * s) #if __simplescalar__ /* isatty does not seem to work with simplescar. I'll assume the first three streams will probably be ttys (pipes are not thatg different) */ - if (s-Stream < 3) { + if (s - Stream < 3) { s->name = AtomTty; - s->status |= Tty_Stream_f|Reset_Eof_Stream_f|Promptable_Stream_f; + s->status |= Tty_Stream_f | Reset_Eof_Stream_f | Promptable_Stream_f; } #else { int filedes; /* visualc */ - if (!s->file) { + if (!s->file) { s->name = AtomNil; return; } - filedes = fileno (s->file); - if (isatty (filedes)) { + filedes = fileno(s->file); + if (isatty(filedes)) { #if HAVE_TTYNAME char *ttys = ttyname(filedes); if (ttys == NULL) @@ -228,7 +212,7 @@ unix_upd_stream_info (StreamDesc * s) #else s->name = AtomTty; #endif - s->status |= Tty_Stream_f|Reset_Eof_Stream_f|Promptable_Stream_f; + s->status |= Tty_Stream_f | Reset_Eof_Stream_f | Promptable_Stream_f; return; } } @@ -238,34 +222,30 @@ unix_upd_stream_info (StreamDesc * s) s->status |= Seekable_Stream_f; } -GetsFunc -PlGetsFunc(void) -{ +GetsFunc PlGetsFunc(void) { if (GLOBAL_CharConversionTable) return DefaultGets; else return PlGets; } -static void -InitFileIO(StreamDesc *s) -{ +static void InitFileIO(StreamDesc *s) { s->stream_gets = PlGetsFunc(); if (s->status & Socket_Stream_f) { /* Console is a socket and socket will prompt */ - Yap_ConsoleSocketOps( s ); + Yap_ConsoleSocketOps(s); s->stream_wputc = put_wchar; - } else if (s->status & Pipe_Stream_f) { + } else if (s->status & Pipe_Stream_f) { /* Console is a socket and socket will prompt */ Yap_ConsolePipeOps(s); s->stream_wputc = put_wchar; } else if (s->status & InMemory_Stream_f) { - Yap_MemOps( s ); + Yap_MemOps(s); s->stream_wputc = put_wchar; } else { /* check if our console is promptable: may be tty or pipe */ if (s->status & (Promptable_Stream_f)) { - Yap_ConsoleOps( s ); + Yap_ConsoleOps(s); } else { /* we are reading from a file, no need to check for prompts */ s->stream_putc = FilePutc; @@ -273,16 +253,13 @@ InitFileIO(StreamDesc *s) s->stream_getc = PlGetc; s->stream_gets = PlGetsFunc(); s->stream_wgetc = get_wchar_from_file; - } + } } s->stream_wputc = put_wchar; s->stream_wgetc = get_wchar; } - -static void -InitStdStream (int sno, SMALLUNSGN flags, FILE * file) -{ +static void InitStdStream(int sno, SMALLUNSGN flags, FILE *file) { StreamDesc *s = &GLOBAL_Stream[sno]; s->file = file; s->status = flags; @@ -296,36 +273,33 @@ InitStdStream (int sno, SMALLUNSGN flags, FILE * file) between readers and writers to the stream :-( */ InitFileIO(s); - switch(sno) { - case 0: - s->name=AtomUserIn; - break; - case 1: - s->name=AtomUserOut; - break; - default: - s->name=AtomUserErr; - break; + switch (sno) { + case 0: + s->name = AtomUserIn; + break; + case 1: + s->name = AtomUserOut; + break; + default: + s->name = AtomUserErr; + break; } - s->user_name = MkAtomTerm (s->name); - Yap_DefaultStreamOps( s ); + s->user_name = MkAtomTerm(s->name); + Yap_DefaultStreamOps(s); #if LIGHT - s->status |= Tty_Stream_f|Promptable_Stream_f; + s->status |= Tty_Stream_f | Promptable_Stream_f; #endif #if HAVE_SETBUF - if (s->status & Tty_Stream_f && - sno == 0) { + if (s->status & Tty_Stream_f && sno == 0) { /* make sure input is unbuffered if it comes from stdin, this makes life simpler for interrupt handling */ - setbuf (stdin, NULL); + setbuf(stdin, NULL); // fprintf(stderr,"here I am\n"); } #endif /* HAVE_SETBUF */ - } -Term Yap_StreamUserName(int sno) -{ +Term Yap_StreamUserName(int sno) { Term atname; StreamDesc *s = &GLOBAL_Stream[sno]; if (s->user_name != 0L) { @@ -336,52 +310,43 @@ Term Yap_StreamUserName(int sno) return TermNil; } -static void -InitStdStreams (void) -{ +static void InitStdStreams(void) { CACHE_REGS if (LOCAL_sockets_io) { - InitStdStream (StdInStream, Input_Stream_f, NULL); - InitStdStream (StdOutStream, Output_Stream_f, NULL); - InitStdStream (StdErrStream, Output_Stream_f, NULL); + InitStdStream(StdInStream, Input_Stream_f, NULL); + InitStdStream(StdOutStream, Output_Stream_f, NULL); + InitStdStream(StdErrStream, Output_Stream_f, NULL); } else { - InitStdStream (StdInStream, Input_Stream_f, stdin); - InitStdStream (StdOutStream, Output_Stream_f, stdout); - InitStdStream (StdErrStream, Output_Stream_f, stderr); + InitStdStream(StdInStream, Input_Stream_f, stdin); + InitStdStream(StdOutStream, Output_Stream_f, stdout); + InitStdStream(StdErrStream, Output_Stream_f, stderr); } GLOBAL_Stream[StdInStream].name = Yap_LookupAtom("user_input"); GLOBAL_Stream[StdOutStream].name = Yap_LookupAtom("user_output"); - GLOBAL_Stream[StdErrStream].name = Yap_LookupAtom("user_error"); + GLOBAL_Stream[StdErrStream].name = Yap_LookupAtom("user_error"); LOCAL_c_input_stream = StdInStream; LOCAL_c_output_stream = StdOutStream; LOCAL_c_error_stream = StdErrStream; } -void -Yap_InitStdStreams (void) -{ - InitStdStreams(); -} +void Yap_InitStdStreams(void) { InitStdStreams(); } - - -Int -PlIOError__ (const char *file, const char *function, int lineno, yap_error_number type, Term culprit, ...) -{ - if (trueLocalPrologFlag(FILEERRORS_FLAG)|| +Int PlIOError__(const char *file, const char *function, int lineno, + yap_error_number type, Term culprit, ...) { + if (trueLocalPrologFlag(FILEERRORS_FLAG) || type == RESOURCE_ERROR_MAX_STREAMS /* do not catch resource errors */) { va_list args; const char *format; char who[1024]; - + va_start(args, culprit); format = va_arg(args, char *); if (format) { vsnprintf(who, 1023, format, args); } else { - who[0] ='\0'; + who[0] = '\0'; } - va_end( args ); + va_end(args); Yap_Error__(file, function, lineno, type, culprit, who); /* and fail */ return false; @@ -390,27 +355,22 @@ PlIOError__ (const char *file, const char *function, int lineno, yap_error_numb } } - #ifdef DEBUG -static int eolflg = 1; +static int eolflg = 1; +static char my_line[200] = {0}; +static char *lp = my_line; - -static char my_line[200] = {0}; -static char *lp = my_line; - -FILE * curfile, *Yap_logfile; +FILE *curfile, *Yap_logfile; bool Yap_Option[256]; #ifdef MACC -static void -InTTYLine(char *line) -{ - char *p = line; - char ch; +static void InTTYLine(char *line) { + char *p = line; + char ch; while ((ch = InKey()) != '\n' && ch != '\r') if (ch == 8) { if (line < p) @@ -422,10 +382,7 @@ InTTYLine(char *line) } #endif - -void -Yap_DebugSetIFile(char *fname) -{ +void Yap_DebugSetIFile(char *fname) { if (curfile) fclose(curfile); curfile = fopen(fname, "r"); @@ -435,18 +392,10 @@ Yap_DebugSetIFile(char *fname) } } +void Yap_DebugEndline() { *lp = 0; } -void -Yap_DebugEndline() -{ - *lp = 0; - -} - -int -Yap_DebugGetc() -{ - int ch; +int Yap_DebugGetc() { + int ch; if (eolflg) { if (curfile != NULL) { if (fgets(my_line, 200, curfile) == 0) @@ -466,64 +415,50 @@ Yap_DebugGetc() return (ch); } -int -Yap_DebugPutc( FILE *s, wchar_t ch) -{ +int Yap_DebugPutc(FILE *s, wchar_t ch) { if (Yap_Option['l' - 96]) - (void) putc(ch, Yap_logfile); + (void)putc(ch, Yap_logfile); return (putc(ch, s)); } -int -Yap_DebugPuts( FILE *s, const char *sch) -{ +int Yap_DebugPuts(FILE *s, const char *sch) { if (Yap_Option['l' - 96]) - (void) fputs(sch, Yap_logfile); - return fputs( sch, s); + (void)fputs(sch, Yap_logfile); + return fputs(sch, s); } -void Yap_DebugErrorPuts(const char *s) -{ - Yap_DebugPuts (stderr, s); -} +void Yap_DebugErrorPuts(const char *s) { Yap_DebugPuts(stderr, s); } - -void -Yap_DebugPlWrite(Term t) -{ +void Yap_DebugPlWrite(Term t) { if (t != 0) - Yap_plwrite(t,GLOBAL_Stream+2, 0, 0, 1200); + Yap_plwrite(t, GLOBAL_Stream + 2, 0, 0, GLOBAL_MaxPriority); } -void -Yap_DebugPlWriteln(Term t) -{ +void Yap_DebugPlWriteln(Term t) { CACHE_REGS - Yap_plwrite(t, NULL, 15, 0, 1200); - Yap_DebugPutc (GLOBAL_Stream[LOCAL_c_error_stream].file, '.'); - Yap_DebugPutc (GLOBAL_Stream[LOCAL_c_error_stream].file, 10); + Yap_plwrite(t, NULL, 15, 0, GLOBAL_MaxPriority); + Yap_DebugPutc(GLOBAL_Stream[LOCAL_c_error_stream].file, '.'); + Yap_DebugPutc(GLOBAL_Stream[LOCAL_c_error_stream].file, 10); } -void -Yap_DebugErrorPutc(int c) -{ +void Yap_DebugErrorPutc(int c) { CACHE_REGS - Yap_DebugPutc (GLOBAL_Stream[LOCAL_c_error_stream].file, c); + Yap_DebugPutc(GLOBAL_Stream[LOCAL_c_error_stream].file, c); } -void Yap_DebugWriteIndicator( PredEntry *ap ) -{ +void Yap_DebugWriteIndicator(PredEntry *ap) { CACHE_REGS Term tmod = ap->ModuleOfPred; - if (!tmod) tmod = TermProlog; + if (!tmod) + tmod = TermProlog; #if THREADS Yap_DebugPlWrite(MkIntegerTerm(worker_id)); - Yap_DebugPutc(stderr,' '); + Yap_DebugPutc(stderr, ' '); #endif - Yap_DebugPutc(stderr,'>'); - Yap_DebugPutc(stderr,'\t'); + Yap_DebugPutc(stderr, '>'); + Yap_DebugPutc(stderr, '\t'); Yap_DebugPlWrite(tmod); - Yap_DebugPutc(stderr,':'); + Yap_DebugPutc(stderr, ':'); if (ap->ModuleOfPred == IDB_MODULE) { Term t = Deref(ARG1); if (IsAtomTerm(t)) { @@ -534,7 +469,7 @@ void Yap_DebugWriteIndicator( PredEntry *ap ) Functor f = FunctorOfTerm(t); Atom At = NameOfFunctor(f); Yap_DebugPlWrite(MkAtomTerm(At)); - Yap_DebugPutc(stderr,'/'); + Yap_DebugPutc(stderr, '/'); Yap_DebugPlWrite(MkIntegerTerm(ArityOfFunctor(f))); } } else { @@ -545,86 +480,79 @@ void Yap_DebugWriteIndicator( PredEntry *ap ) Functor f = ap->FunctorOfPred; Atom At = NameOfFunctor(f); Yap_DebugPlWrite(MkAtomTerm(At)); - Yap_DebugPutc(stderr,'/'); + Yap_DebugPutc(stderr, '/'); Yap_DebugPlWrite(MkIntegerTerm(ArityOfFunctor(f))); } } - - Yap_DebugPutc(stderr,'\n'); -} + Yap_DebugPutc(stderr, '\n'); +} #endif /* static */ -int FilePutc(int sno, int ch) -{ +int FilePutc(int sno, int ch) { StreamDesc *s = &GLOBAL_Stream[sno]; #if MAC || _MSC_VER - if (ch == 10) - { + if (ch == 10) { ch = '\n'; } #endif putc(ch, s->file); #if MAC || _MSC_VER - if (ch == 10) - { + if (ch == 10) { fflush(s->file); } #endif - count_output_char(ch,s); - return ((int) ch); + count_output_char(ch, s); + return ((int)ch); } -static int -NullPutc (int sno, int ch) -{ +static int NullPutc(int sno, int ch) { StreamDesc *s = &GLOBAL_Stream[sno]; #if MAC || _MSC_VER - if (ch == 10) - { + if (ch == 10) { ch = '\n'; } #endif - count_output_char(ch,s); - return ((int) ch); + count_output_char(ch, s); + return ((int)ch); } -int -ResetEOF(StreamDesc *s) { +int ResetEOF(StreamDesc *s) { + s->status &= ~Push_Eof_Stream_f; if (s->status & Eof_Error_Stream_f) { - Yap_Error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,MkAtomTerm(s->name), + Yap_Error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM, MkAtomTerm(s->name), "GetC"); return FALSE; } else if (s->status & Reset_Eof_Stream_f) { /* reset the eof indicator on file */ - if (feof (s->file)) - clearerr (s->file); - /* reset our function for reading input */ + if (feof(s->file)) + clearerr(s->file); +/* reset our function for reading input */ #if HAVE_SOCKET if (s->status & Socket_Stream_f) { if (s->status & Promptable_Stream_f) - Yap_ConsoleSocketOps( s ); + Yap_ConsoleSocketOps(s); else - Yap_SocketOps( s ); + Yap_SocketOps(s); s->stream_wputc = put_wchar; } else #endif - if (s->status & Pipe_Stream_f) { - if (s->status & Promptable_Stream_f) - Yap_ConsolePipeOps( s ); - else - Yap_PipeOps( s ); - } else if (s->status & InMemory_Stream_f) { - Yap_MemOps( s ); - } else if (s->status & Promptable_Stream_f) { - Yap_ConsoleOps( s ); - } else { - s->stream_getc = PlGetc; - Yap_DefaultStreamOps( s ); - s->stream_gets = PlGetsFunc(); - } + if (s->status & Pipe_Stream_f) { + if (s->status & Promptable_Stream_f) + Yap_ConsolePipeOps(s); + else + Yap_PipeOps(s); + } else if (s->status & InMemory_Stream_f) { + Yap_MemOps(s); + } else if (s->status & Promptable_Stream_f) { + Yap_ConsoleOps(s); + } else { + s->stream_getc = PlGetc; + Yap_DefaultStreamOps(s); + s->stream_gets = PlGetsFunc(); + } /* next, reset our own error indicator */ s->status &= ~Eof_Stream_f; /* try reading again */ @@ -636,54 +564,53 @@ ResetEOF(StreamDesc *s) { } /* handle reading from a stream after having found an EOF */ -static int -EOFWGetc(int sno) -{ +static int EOFWGetc(int sno) { register StreamDesc *s = &GLOBAL_Stream[sno]; - + if (s->status & Push_Eof_Stream_f) { /* ok, we have pushed an EOF, send it away */ s->status &= ~Push_Eof_Stream_f; return EOF; } if (ResetEOF(s)) { - s->stream_wgetc = get_wchar; - return(s->stream_wgetc(sno)); + Yap_ConsoleOps(s); + return (s->stream_wgetc(sno)); } return EOF; } -static int -EOFGetc(int sno) -{ +static int EOFGetc(int sno) { register StreamDesc *s = &GLOBAL_Stream[sno]; - + if (s->status & Push_Eof_Stream_f) { /* ok, we have pushed an EOF, send it away */ s->status &= ~Push_Eof_Stream_f; + ResetEOF(s); return EOF; } if (ResetEOF(s)) { - s->stream_getc = PlGetc; - return(s->stream_getc(sno)); + Yap_ConsoleOps(s); + return s->stream_getc(sno); } return EOF; } /* check if we read a LOCAL_newline or an EOF */ -int -console_post_process_eof(StreamDesc *s) -{ +int console_post_process_eof(StreamDesc *s) { CACHE_REGS - s->stream_getc = EOFGetc; - LOCAL_newline = FALSE; + if (!ResetEOF(s)) { + s->status |= Eof_Stream_f; + s->stream_getc = EOFGetc; + s->stream_wgetc = EOFWGetc; + s->stream_wgetc_for_read = EOFWGetc; + s->stream_getc_for_utf8 = EOFGetc; + LOCAL_newline = true; + } return EOFCHAR; } /* check if we read a newline or an EOF */ -int -post_process_read_char(int ch, StreamDesc *s) -{ +int post_process_read_char(int ch, StreamDesc *s) { ++s->charcount; ++s->linepos; if (ch == '\n') { @@ -697,33 +624,51 @@ post_process_read_char(int ch, StreamDesc *s) } /* check if we read a newline or an EOF */ -int -post_process_eof(StreamDesc *s) -{ - s->status |= Eof_Stream_f; - s->stream_getc = EOFGetc; +int post_process_eof(StreamDesc *s) { + if (!ResetEOF(s)) { + s->status |= Eof_Stream_f; + s->stream_wgetc = EOFWGetc; + s->stream_getc = EOFGetc; + s->stream_wgetc_for_read = EOFWGetc; + s->stream_getc_for_utf8 = EOFGetc; + } return EOFCHAR; } -int -post_process_weof(StreamDesc *s) -{ - s->status |= Eof_Stream_f; - s->stream_wgetc = EOFWGetc; +int post_process_weof(StreamDesc *s) { + if (!ResetEOF(s)) { + s->status |= Eof_Stream_f; + s->stream_wgetc = EOFWGetc; + s->stream_wgetc = EOFWGetc; + s->stream_wgetc_for_read = EOFWGetc; + s->stream_getc_for_utf8 = EOFGetc; + } return EOFCHAR; } +/** + * caled after EOF found a peek, it just calls console_post_process to conclude the job. + * + * @param sno + * + * @return EOF + */ +int EOFPeek(int sno) { + return EOFGetc( sno ); +} + +int EOFWPeek(int sno) { + return EOFWGetc( sno ); +} /* standard routine, it should read from anything pointed by a FILE *. It could be made more efficient by doing our own buffering and avoiding post_process_read_char, something to think about */ -int -PlGetc (int sno) -{ +int PlGetc(int sno) { StreamDesc *s = &GLOBAL_Stream[sno]; Int ch; - - ch = getc (s->file); + + ch = getc(s->file); if (ch == EOF) { return post_process_eof(s); } @@ -732,63 +677,57 @@ PlGetc (int sno) /* standard routine, it should read from anything pointed by a FILE *. It could be made more efficient by doing our own buffering and avoiding - post_process_read_char, something to think about. It assumes codification in 8 bits. */ -int -PlGets (int sno, UInt size, char *buf) -{ + post_process_read_char, something to think about. It assumes codification in 8 + bits. */ +int PlGets(int sno, UInt size, char *buf) { register StreamDesc *s = &GLOBAL_Stream[sno]; UInt len; - - if (fgets (buf, size, s->file) == NULL) { + + if (fgets(buf, size, s->file) == NULL) { return post_process_eof(s); } len = strlen(buf); - s->charcount += len-1; - post_process_read_char(buf[len-2], s); + s->charcount += len - 1; + post_process_read_char(buf[len - 2], s); return strlen(buf); } /* standard routine, it should read from anything pointed by a FILE *. It could be made more efficient by doing our own buffering and avoiding post_process_read_char, something to think about */ -int -DefaultGets (int sno, UInt size, char *buf) -{ +int DefaultGets(int sno, UInt size, char *buf) { StreamDesc *s = &GLOBAL_Stream[sno]; char ch; char *pt = buf; - - + if (!size) return 0; - while((ch = *buf++ = s->stream_getc(sno)) != - -1 && ch != 10 && --size); + while ((ch = *buf++ = s->stream_getc(sno)) != -1 && ch != 10 && --size) + ; *buf++ = '\0'; - return (buf-pt)-1; + return (buf - pt) - 1; } -int -GetUTF8 (int sno) -{ +int GetUTF8(int sno) { StreamDesc *s = &GLOBAL_Stream[sno]; uint64_t bufi = s->utf8_buf; unsigned char *buf = (unsigned char *)&bufi; - + if (!bufi) { int32_t ch = get_wchar(sno); - if (ch < 128) return ch; + if (ch < 128) + return ch; put_utf8((unsigned char *)&bufi, ch); } else { - while (*buf++ == '\0'); + while (*buf++ == '\0') + ; } unsigned char c = *buf; buf[0] = '\0'; return c; } -static int -utf8_nof(char ch) -{ +static int utf8_nof(char ch) { if (!(ch & 0x20)) return 1; if (!(ch & 0x10)) @@ -800,115 +739,109 @@ utf8_nof(char ch) return 5; } -#define wide_char() \ - switch (GLOBAL_Stream[sno].encoding) { \ - case ENC_OCTET:\ - return ch;\ - case ENC_ISO_LATIN1:\ - return ch;\ - case ENC_ISO_ASCII:\ - if (ch & 0x80) {\ - /* error */\ - }\ - return ch;\ - case ENC_ISO_ANSI:\ - {\ - char buf[1];\ - int out;\ - \ - if (!how_many) {\ - memset((void *)&(GLOBAL_Stream[sno].mbstate), 0, sizeof(mbstate_t));\ - }\ - buf[0] = ch;\ - if ((out = mbrtowc(&wch, buf, 1, &(GLOBAL_Stream[sno].mbstate))) == 1)\ - return wch;\ - if (out == -1) {\ - /* error */\ - }\ - how_many++;\ - break;\ - }\ - case ENC_ISO_UTF8:\ - {\ - if (!how_many) {\ - if (ch & 0x80) {\ - how_many = utf8_nof(ch);\ - /*\ - keep a backup of the start character in case we meet an error,\ - useful if we are scanning ISO files.\ - */\ - GLOBAL_Stream[sno].och = ch;\ - wch = (ch & ((1<<(6-how_many))-1))<<(6*how_many);\ - } else {\ - return ch;\ - }\ - } else {\ - how_many--;\ - if ((ch & 0xc0) == 0x80) {\ - wch += (ch & ~0xc0) << (how_many*6);\ - } else {\ - /* error */\ - /* try to recover character, assume this is our first character */\ - wchar_t och = GLOBAL_Stream[sno].och;\ - return och;\ - }\ - if (!how_many) {\ - return wch;\ - }\ - }\ - }\ - break;\ - case ENC_UTF16_BE:\ - if (how_many) {\ - return wch+ch;\ - }\ - how_many=1;\ - wch = ch << 8;\ - break;\ - case ENC_UTF16_LE:\ - if (how_many) {\ - return wch+(ch<<8);\ - }\ - how_many=1;\ - wch = ch;\ - break;\ - case ENC_ISO_UTF32_LE:\ - if (!how_many) {\ - how_many = 4;\ - wch = 0;\ - }\ - how_many--;\ - wch += ((unsigned char) (ch & 0xff)) << (how_many*8);\ - if (how_many == 0)\ - return wch;\ - break;\ - case ENC_ISO_UTF32_BE:\ - if (!how_many) {\ - how_many = 4;\ - wch = 0;\ - }\ - how_many--;\ - wch += ((unsigned char) (ch & 0xff)) << ((3-how_many)*8);\ - if (how_many == 0)\ - return wch;\ - break;\ - }\ +#define wide_char() \ + switch (GLOBAL_Stream[sno].encoding) { \ + case ENC_OCTET: \ + return ch; \ + case ENC_ISO_LATIN1: \ + return ch; \ + case ENC_ISO_ASCII: \ + if (ch & 0x80) { \ + /* error */ \ + } \ + return ch; \ + case ENC_ISO_ANSI: { \ + char buf[1]; \ + int out; \ + \ + if (!how_many) { \ + memset((void *)&(GLOBAL_Stream[sno].mbstate), 0, sizeof(mbstate_t)); \ + } \ + buf[0] = ch; \ + if ((out = mbrtowc(&wch, buf, 1, &(GLOBAL_Stream[sno].mbstate))) == 1) \ + return wch; \ + if (out == -1) { \ + /* error */ \ + } \ + how_many++; \ + break; \ + } \ + case ENC_ISO_UTF8: { \ + if (!how_many) { \ + if (ch & 0x80) { \ + how_many = utf8_nof(ch); \ + /* \ + keep a backup of the start character in case we meet an error, \ + useful if we are scanning ISO files. \ + */ \ + GLOBAL_Stream[sno].och = ch; \ + wch = (ch & ((1 << (6 - how_many)) - 1)) << (6 * how_many); \ + } else { \ + return ch; \ + } \ + } else { \ + how_many--; \ + if ((ch & 0xc0) == 0x80) { \ + wch += (ch & ~0xc0) << (how_many * 6); \ + } else { \ + /* error */ \ + /* try to recover character, assume this is our first character */ \ + wchar_t och = GLOBAL_Stream[sno].och; \ + return och; \ + } \ + if (!how_many) { \ + return wch; \ + } \ + } \ + } break; \ + case ENC_UTF16_BE: \ + if (how_many) { \ + return wch + ch; \ + } \ + how_many = 1; \ + wch = ch << 8; \ + break; \ + case ENC_UTF16_LE: \ + if (how_many) { \ + return wch + (ch << 8); \ + } \ + how_many = 1; \ + wch = ch; \ + break; \ + case ENC_ISO_UTF32_LE: \ + if (!how_many) { \ + how_many = 4; \ + wch = 0; \ + } \ + how_many--; \ + wch += ((unsigned char)(ch & 0xff)) << (how_many * 8); \ + if (how_many == 0) \ + return wch; \ + break; \ + case ENC_ISO_UTF32_BE: \ + if (!how_many) { \ + how_many = 4; \ + wch = 0; \ + } \ + how_many--; \ + wch += ((unsigned char)(ch & 0xff)) << ((3 - how_many) * 8); \ + if (how_many == 0) \ + return wch; \ + break; \ + } - -static int -get_wchar(int sno) -{ +static int get_wchar(int sno) { int ch; wchar_t wch; int how_many = 0; - while (TRUE) { + while (true) { ch = GLOBAL_Stream[sno].stream_getc(sno); if (ch == -1) { if (how_many) { - /* error */ + /* error */ } - return EOF; + return post_process_weof(GLOBAL_Stream+sno); } wide_char(); } @@ -916,14 +849,12 @@ get_wchar(int sno) } // layered version -static int -get_wchar__(int sno) -{ +static int get_wchar__(int sno) { int ch; wchar_t wch; int how_many = 0; - StreamDesc *s = GLOBAL_Stream+sno; - + StreamDesc *s = GLOBAL_Stream + sno; + while (TRUE) { ch = getc(GLOBAL_Stream[sno].file); if (ch == -1) { @@ -937,19 +868,15 @@ get_wchar__(int sno) return EOF; } -static int -get_wchar_from_file(int sno) -{ - return post_process_read_char( get_wchar__( sno ), GLOBAL_Stream+sno ); +static int get_wchar_from_file(int sno) { + return post_process_read_char(get_wchar__(sno), GLOBAL_Stream + sno); } #ifndef MB_LEN_MAX #define MB_LEN_MAX 6 #endif -static int -handle_write_encoding_error(int sno, wchar_t ch) -{ +static int handle_write_encoding_error(int sno, wchar_t ch) { if (GLOBAL_Stream[sno].status & RepError_Xml_f) { /* use HTML/XML encoding in ASCII */ int i = ch, digits = 1; @@ -960,7 +887,7 @@ handle_write_encoding_error(int sno, wchar_t ch) if (digits > i) digits /= 10; while (i) { - GLOBAL_Stream[sno].stream_putc(sno, i/digits); + GLOBAL_Stream[sno].stream_putc(sno, i / digits); i %= 10; digits /= 10; } @@ -970,339 +897,312 @@ handle_write_encoding_error(int sno, wchar_t ch) /* write quoted */ GLOBAL_Stream[sno].stream_putc(sno, '\\'); GLOBAL_Stream[sno].stream_putc(sno, 'u'); - GLOBAL_Stream[sno].stream_putc(sno, ch>>24); - GLOBAL_Stream[sno].stream_putc(sno, 256&(ch>>16)); - GLOBAL_Stream[sno].stream_putc(sno, 256&(ch>>8)); - GLOBAL_Stream[sno].stream_putc(sno, 256&ch); + GLOBAL_Stream[sno].stream_putc(sno, ch >> 24); + GLOBAL_Stream[sno].stream_putc(sno, 256 & (ch >> 16)); + GLOBAL_Stream[sno].stream_putc(sno, 256 & (ch >> 8)); + GLOBAL_Stream[sno].stream_putc(sno, 256 & ch); return ch; } else { CACHE_REGS - Yap_Error(REPRESENTATION_ERROR_CHARACTER, MkIntegerTerm(ch),"charater %ld cannot be encoded in stream %d",(unsigned long int)ch,sno); + Yap_Error(REPRESENTATION_ERROR_CHARACTER, MkIntegerTerm(ch), + "charater %ld cannot be encoded in stream %d", + (unsigned long int)ch, sno); return -1; } } -int -put_wchar(int sno, wchar_t ch) -{ +int put_wchar(int sno, wchar_t ch) { /* pass the bucck if we can */ switch (GLOBAL_Stream[sno].encoding) { - case ENC_OCTET: - return GLOBAL_Stream[sno].stream_putc(sno, ch); - case ENC_ISO_LATIN1: - if (ch >= 0xff) { - return handle_write_encoding_error(sno,ch); - } - return GLOBAL_Stream[sno].stream_putc(sno, ch); - case ENC_ISO_ASCII: - if (ch >= 0x80) { - return handle_write_encoding_error(sno,ch); - } - return GLOBAL_Stream[sno].stream_putc(sno, ch); - case ENC_ISO_ANSI: - { - char buf[MB_LEN_MAX]; - int n; - - memset((void *)&(GLOBAL_Stream[sno].mbstate), 0, sizeof(mbstate_t)); - if ( (n = wcrtomb(buf, ch, &(GLOBAL_Stream[sno].mbstate))) < 0 ) { - /* error */ - GLOBAL_Stream[sno].stream_putc(sno, ch); - return -1; - } else { - int i; - - for (i =0; i< n; i++) { - GLOBAL_Stream[sno].stream_putc(sno, buf[i]); - } - return ch; - } - case ENC_ISO_UTF8: - if (ch < 0x80) { - return GLOBAL_Stream[sno].stream_putc(sno, ch); - } else if (ch < 0x800) { - GLOBAL_Stream[sno].stream_putc(sno, 0xC0 | ch>>6); - return GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F)); - } - else if (ch < 0x10000) { - GLOBAL_Stream[sno].stream_putc(sno, 0xE0 | ch>>12); - GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch>>6 & 0x3F)); - return GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F)); - } else if (ch < 0x200000) { - GLOBAL_Stream[sno].stream_putc(sno, 0xF0 | ch>>18); - GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch>>12 & 0x3F)); - GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch>>6 & 0x3F)); - return GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F)); - } else { - /* should never happen */ - return -1; - } - break; - case ENC_UTF16_BE: - GLOBAL_Stream[sno].stream_putc(sno, (ch>>8)); - return GLOBAL_Stream[sno].stream_putc(sno, (ch&0xff)); - case ENC_UTF16_LE: - GLOBAL_Stream[sno].stream_putc(sno, (ch&0xff)); - return GLOBAL_Stream[sno].stream_putc(sno, (ch>>8)); - case ENC_ISO_UTF32_BE: - GLOBAL_Stream[sno].stream_putc(sno, (ch>>24) & 0xff); - GLOBAL_Stream[sno].stream_putc(sno, (ch>>16) &0xff); - GLOBAL_Stream[sno].stream_putc(sno, (ch>>8) & 0xff); - return GLOBAL_Stream[sno].stream_putc(sno, ch&0xff); - case ENC_ISO_UTF32_LE: - GLOBAL_Stream[sno].stream_putc(sno, ch&0xff); - GLOBAL_Stream[sno].stream_putc(sno, (ch>>8) & 0xff); - GLOBAL_Stream[sno].stream_putc(sno, (ch>>16) &0xff); - return GLOBAL_Stream[sno].stream_putc(sno, (ch>>24) & 0xff); + case ENC_OCTET: + return GLOBAL_Stream[sno].stream_putc(sno, ch); + case ENC_ISO_LATIN1: + if (ch >= 0xff) { + return handle_write_encoding_error(sno, ch); } + return GLOBAL_Stream[sno].stream_putc(sno, ch); + case ENC_ISO_ASCII: + if (ch >= 0x80) { + return handle_write_encoding_error(sno, ch); + } + return GLOBAL_Stream[sno].stream_putc(sno, ch); + case ENC_ISO_ANSI: { + char buf[MB_LEN_MAX]; + int n; + + memset((void *)&(GLOBAL_Stream[sno].mbstate), 0, sizeof(mbstate_t)); + if ((n = wcrtomb(buf, ch, &(GLOBAL_Stream[sno].mbstate))) < 0) { + /* error */ + GLOBAL_Stream[sno].stream_putc(sno, ch); + return -1; + } else { + int i; + + for (i = 0; i < n; i++) { + GLOBAL_Stream[sno].stream_putc(sno, buf[i]); + } + return ch; + } + case ENC_ISO_UTF8: + if (ch < 0x80) { + return GLOBAL_Stream[sno].stream_putc(sno, ch); + } else if (ch < 0x800) { + GLOBAL_Stream[sno].stream_putc(sno, 0xC0 | ch >> 6); + return GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F)); + } else if (ch < 0x10000) { + GLOBAL_Stream[sno].stream_putc(sno, 0xE0 | ch >> 12); + GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch >> 6 & 0x3F)); + return GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F)); + } else if (ch < 0x200000) { + GLOBAL_Stream[sno].stream_putc(sno, 0xF0 | ch >> 18); + GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch >> 12 & 0x3F)); + GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch >> 6 & 0x3F)); + return GLOBAL_Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F)); + } else { + /* should never happen */ + return -1; + } + break; + case ENC_UTF16_BE: + GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8)); + return GLOBAL_Stream[sno].stream_putc(sno, (ch & 0xff)); + case ENC_UTF16_LE: + GLOBAL_Stream[sno].stream_putc(sno, (ch & 0xff)); + return GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8)); + case ENC_ISO_UTF32_BE: + GLOBAL_Stream[sno].stream_putc(sno, (ch >> 24) & 0xff); + GLOBAL_Stream[sno].stream_putc(sno, (ch >> 16) & 0xff); + GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8) & 0xff); + return GLOBAL_Stream[sno].stream_putc(sno, ch & 0xff); + case ENC_ISO_UTF32_LE: + GLOBAL_Stream[sno].stream_putc(sno, ch & 0xff); + GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8) & 0xff); + GLOBAL_Stream[sno].stream_putc(sno, (ch >> 16) & 0xff); + return GLOBAL_Stream[sno].stream_putc(sno, (ch >> 24) & 0xff); + } } return -1; } /* used by user-code to read characters from the current input stream */ -int -Yap_PlGetchar (void) -{ +int Yap_PlGetchar(void) { CACHE_REGS - return(GLOBAL_Stream[LOCAL_c_input_stream].stream_getc(LOCAL_c_input_stream)); + return ( + GLOBAL_Stream[LOCAL_c_input_stream].stream_getc(LOCAL_c_input_stream)); } -int -Yap_PlGetWchar (void) -{ +int Yap_PlGetWchar(void) { CACHE_REGS return get_wchar(LOCAL_c_input_stream); } /* avoid using a variable to call a function */ -int -Yap_PlFGetchar (void) -{ +int Yap_PlFGetchar(void) { CACHE_REGS - return(PlGetc(LOCAL_c_input_stream)); + return (PlGetc(LOCAL_c_input_stream)); } - -Term -Yap_MkStream (int n) -{ +Term Yap_MkStream(int n) { Term t[1]; - t[0] = MkIntTerm (n); - return (Yap_MkApplTerm (FunctorStream, 1, t)); + t[0] = MkIntTerm(n); + return (Yap_MkApplTerm(FunctorStream, 1, t)); } /* given a stream index, get the corresponding fd */ -Int -GetStreamFd(int sno) -{ +Int GetStreamFd(int sno) { #if HAVE_SOCKET if (GLOBAL_Stream[sno].status & Socket_Stream_f) { - return(GLOBAL_Stream[sno].u.socket.fd); + return (GLOBAL_Stream[sno].u.socket.fd); } else #endif - if (GLOBAL_Stream[sno].status & Pipe_Stream_f) { + if (GLOBAL_Stream[sno].status & Pipe_Stream_f) { #if _MSC_VER || defined(__MINGW32__) - return((Int)(GLOBAL_Stream[sno].u.pipe.hdl)); + return ((Int)(GLOBAL_Stream[sno].u.pipe.hdl)); #else - return(GLOBAL_Stream[sno].u.pipe.fd); + return (GLOBAL_Stream[sno].u.pipe.fd); #endif - } else if (GLOBAL_Stream[sno].status & InMemory_Stream_f) { - return(-1); - } - return(fileno(GLOBAL_Stream[sno].file)); + } else if (GLOBAL_Stream[sno].status & InMemory_Stream_f) { + return (-1); + } + return (fileno(GLOBAL_Stream[sno].file)); } -Int -Yap_GetStreamFd(int sno) -{ - return GetStreamFd(sno); -} +Int Yap_GetStreamFd(int sno) { return GetStreamFd(sno); } - -static int -binary_file(char *file_name) -{ +static int binary_file(char *file_name) { #if HAVE_STAT #if _MSC_VER || defined(__MINGW32__) struct _stat ss; if (_stat(file_name, &ss) != 0) #else - struct stat ss; + struct stat ss; if (stat(file_name, &ss) != 0) #endif { /* ignore errors while checking a file */ - return(FALSE); + return (FALSE); } return (S_ISDIR(ss.st_mode)); #else - return(FALSE); + return (FALSE); #endif } -static int -write_bom(int sno, StreamDesc *st) -{ +static int write_bom(int sno, StreamDesc *st) { /* dump encoding */ switch (st->encoding) { - case ENC_ISO_UTF8: - if (st->stream_putc(sno,0xEF)<0) - return FALSE; - if (st->stream_putc(sno,0xBB)<0) - return FALSE; - if (st->stream_putc(sno,0xBF)<0) - return FALSE; - st->status |= HAS_BOM_f; - return TRUE; - case ENC_UTF16_BE: - if (st->stream_putc(sno,0xFE)<0) - return FALSE; - if (st->stream_putc(sno,0xFF)<0) - return FALSE; - st->status |= HAS_BOM_f; - return TRUE; - case ENC_UTF16_LE: - if (st->stream_putc(sno,0xFF)<0) - return FALSE; - if (st->stream_putc(sno,0xFE)<0) - return FALSE; - case ENC_ISO_UTF32_BE: - if (st->stream_putc(sno,0x00)<0) - return FALSE; - if (st->stream_putc(sno,0x00)<0) - return FALSE; - if (st->stream_putc(sno,0xFE)<0) - return FALSE; - if (st->stream_putc(sno,0xFF)<0) - return FALSE; - case ENC_ISO_UTF32_LE: - if (st->stream_putc(sno,0xFF)<0) - return FALSE; - if (st->stream_putc(sno,0xFE)<0) - return FALSE; - if (st->stream_putc(sno,0x00)<0) - return FALSE; - if (st->stream_putc(sno,0x00)<0) - return FALSE; - default: - return TRUE; - } -} - - -static void -check_bom(int sno, StreamDesc *st) -{ - int ch1, ch2, ch3, ch4; - - ch1 = st->stream_getc(sno); - switch(ch1) { - case 0x00: - { - ch2 = st->stream_getc(sno); - if ( ch2 != 0x00) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - return; - } else { - ch3 = st->stream_getc(sno); - if (ch3 == EOFCHAR || ch3 != 0xFE) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - ungetc( ch3, st->file ); - return; - } else { - ch4 = st->stream_getc(sno); - if (ch4 == EOFCHAR || ch3 != 0xFF) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - ungetc( ch3, st->file ); - ungetc( ch4, st->file ); - return; - } else { - st->status |= HAS_BOM_f; - st->encoding = ENC_ISO_UTF32_BE; - return; - } - } - } - } - case 0xFE: - { - ch2 = st->stream_getc(sno); - if (ch2 != 0xFF) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - return; - } else { - st->status |= HAS_BOM_f; - st->encoding = ENC_UTF16_BE; - return; - } - } - case 0xFF: - { - ch2 = st->stream_getc(sno); - if (ch2 != 0xFE) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - return; - } else { - ch3 = st->stream_getc(sno); - if ( ch3 != 0x00) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - ungetc( ch3, st->file ); - return; - } else { - ch4 = st->stream_getc(sno); - if (ch4 != 0x00) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - ungetc( ch3, st->file ); - ungetc( ch4, st->file ); - return; - } else { - st->status |= HAS_BOM_f; - st->encoding = ENC_ISO_UTF32_LE; - return; - } - } - st->status |= HAS_BOM_f; - st->encoding = ENC_UTF16_LE; - return; - } - } - case 0xEF: - ch2 = st->stream_getc(sno); - if (ch2 != 0xBB) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - return; - } else { - ch3 = st->stream_getc(sno); - if (ch3 != 0xBF) { - ungetc( ch1, st->file ); - ungetc( ch2, st->file ); - ungetc( ch3, st->file ); - return; - } else { - st->status |= HAS_BOM_f; - st->encoding = ENC_ISO_UTF8; - return; - } - } + case ENC_ISO_UTF8: + if (st->stream_putc(sno, 0xEF) < 0) + return FALSE; + if (st->stream_putc(sno, 0xBB) < 0) + return FALSE; + if (st->stream_putc(sno, 0xBF) < 0) + return FALSE; + st->status |= HAS_BOM_f; + return TRUE; + case ENC_UTF16_BE: + if (st->stream_putc(sno, 0xFE) < 0) + return FALSE; + if (st->stream_putc(sno, 0xFF) < 0) + return FALSE; + st->status |= HAS_BOM_f; + return TRUE; + case ENC_UTF16_LE: + if (st->stream_putc(sno, 0xFF) < 0) + return FALSE; + if (st->stream_putc(sno, 0xFE) < 0) + return FALSE; + case ENC_ISO_UTF32_BE: + if (st->stream_putc(sno, 0x00) < 0) + return FALSE; + if (st->stream_putc(sno, 0x00) < 0) + return FALSE; + if (st->stream_putc(sno, 0xFE) < 0) + return FALSE; + if (st->stream_putc(sno, 0xFF) < 0) + return FALSE; + case ENC_ISO_UTF32_LE: + if (st->stream_putc(sno, 0xFF) < 0) + return FALSE; + if (st->stream_putc(sno, 0xFE) < 0) + return FALSE; + if (st->stream_putc(sno, 0x00) < 0) + return FALSE; + if (st->stream_putc(sno, 0x00) < 0) + return FALSE; default: - ungetc( ch1, st->file ); + return TRUE; } } -static bool -initStream(int sno, FILE *fd, const char *name, Term file_name, encoding_t encoding, stream_flags_t flags, Atom open_mode ) -{ +static void check_bom(int sno, StreamDesc *st) { + int ch1, ch2, ch3, ch4; + + ch1 = st->stream_getc(sno); + switch (ch1) { + case 0x00: { + ch2 = st->stream_getc(sno); + if (ch2 != 0x00) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + return; + } else { + ch3 = st->stream_getc(sno); + if (ch3 == EOFCHAR || ch3 != 0xFE) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + ungetc(ch3, st->file); + return; + } else { + ch4 = st->stream_getc(sno); + if (ch4 == EOFCHAR || ch3 != 0xFF) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + ungetc(ch3, st->file); + ungetc(ch4, st->file); + return; + } else { + st->status |= HAS_BOM_f; + st->encoding = ENC_ISO_UTF32_BE; + return; + } + } + } + } + case 0xFE: { + ch2 = st->stream_getc(sno); + if (ch2 != 0xFF) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + return; + } else { + st->status |= HAS_BOM_f; + st->encoding = ENC_UTF16_BE; + return; + } + } + case 0xFF: { + ch2 = st->stream_getc(sno); + if (ch2 != 0xFE) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + return; + } else { + ch3 = st->stream_getc(sno); + if (ch3 != 0x00) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + ungetc(ch3, st->file); + return; + } else { + ch4 = st->stream_getc(sno); + if (ch4 != 0x00) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + ungetc(ch3, st->file); + ungetc(ch4, st->file); + return; + } else { + st->status |= HAS_BOM_f; + st->encoding = ENC_ISO_UTF32_LE; + return; + } + } + st->status |= HAS_BOM_f; + st->encoding = ENC_UTF16_LE; + return; + } + } + case 0xEF: + ch2 = st->stream_getc(sno); + if (ch2 != 0xBB) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + return; + } else { + ch3 = st->stream_getc(sno); + if (ch3 != 0xBF) { + ungetc(ch1, st->file); + ungetc(ch2, st->file); + ungetc(ch3, st->file); + return; + } else { + st->status |= HAS_BOM_f; + st->encoding = ENC_ISO_UTF8; + return; + } + } + default: + ungetc(ch1, st->file); + } +} + +static bool initStream(int sno, FILE *fd, const char *name, Term file_name, + encoding_t encoding, stream_flags_t flags, + Atom open_mode) { StreamDesc *st = &GLOBAL_Stream[sno]; st->status = flags; - + st->charcount = 0; st->linecount = 1; if (flags & Binary_Stream_f) { @@ -1310,175 +1210,156 @@ initStream(int sno, FILE *fd, const char *name, Term file_name, encoding_t encod } else { st->encoding = encoding; } - + if (name == NULL) { - char buf[YAP_FILENAME_MAX+1]; + char buf[YAP_FILENAME_MAX + 1]; name = Yap_guessFileName(fileno(fd), sno, buf, YAP_FILENAME_MAX); st->name = Yap_LookupAtom(name); } st->user_name = file_name; - st->file = fd; + st->file = fd; st->linepos = 0; if (flags & Pipe_Stream_f) { - Yap_PipeOps( st ); - Yap_DefaultStreamOps( st); + Yap_PipeOps(st); + Yap_DefaultStreamOps(st); } else if (flags & Tty_Stream_f) { - Yap_ConsoleOps( st ); - Yap_DefaultStreamOps( st); + Yap_ConsoleOps(st); + Yap_DefaultStreamOps(st); } else { st->stream_putc = FilePutc; st->stream_getc = PlGetc; - unix_upd_stream_info (st); - Yap_DefaultStreamOps( st); + unix_upd_stream_info(st); + Yap_DefaultStreamOps(st); } st->stream_gets = PlGetsFunc(); return true; } +#define OPEN_DEFS() \ + PAR("alias", isatom, OPEN_ALIAS), PAR("bom", boolean, OPEN_BOM), \ + PAR("buffer", isatom, OPEN_BUFFER), \ + PAR("close_on_abort", boolean, OPEN_CLOSE_ON_ABORT), \ + PAR("create", isatom, OPEN_CREATE), \ + PAR("encoding", isatom, OPEN_ENCODING), \ + PAR("eof_action", isatom, OPEN_EOF_ACTION), \ + PAR("expand_filename", boolean, OPEN_EXPAND_FILENAME), \ + PAR("file_name", isatom, OPEN_FILE_NAME), PAR("input", ok, OPEN_INPUT), \ + PAR("locale", isatom, OPEN_LOCALE), PAR("lock", isatom, OPEN_LOCK), \ + PAR("mode", isatom, OPEN_MODE), PAR("output", ok, OPEN_OUTPUT), \ + PAR("representation_errors", boolean, OPEN_REPRESENTATION_ERRORS), \ + PAR("reposition", boolean, OPEN_REPOSITION), \ + PAR("type", isatom, OPEN_TYPE), PAR("wait", boolean, OPEN_WAIT), \ + PAR(NULL, ok, OPEN_END) -#define OPEN_DEFS() \ -PAR( "alias", isatom, OPEN_ALIAS), \ -PAR( "bom", boolean, OPEN_BOM ), \ -PAR( "buffer", isatom, OPEN_BUFFER ), \ -PAR( "close_on_abort", boolean, OPEN_CLOSE_ON_ABORT ), \ -PAR( "create", isatom, OPEN_CREATE ), \ -PAR( "encoding", isatom, OPEN_ENCODING ), \ -PAR( "eof_action", isatom, OPEN_EOF_ACTION ), \ -PAR( "expand_filename", boolean, OPEN_EXPAND_FILENAME ), \ -PAR( "file_name", isatom, OPEN_FILE_NAME ), \ -PAR( "input", ok, OPEN_INPUT ), \ -PAR( "locale", isatom, OPEN_LOCALE ), \ -PAR( "lock", isatom, OPEN_LOCK ), \ -PAR( "mode", isatom, OPEN_MODE ), \ -PAR( "output", ok, OPEN_OUTPUT ), \ -PAR( "representation_errors", boolean, OPEN_REPRESENTATION_ERRORS ), \ -PAR( "reposition", boolean, OPEN_REPOSITION ), \ -PAR( "type", isatom, OPEN_TYPE ), \ -PAR( "wait", boolean, OPEN_WAIT ), \ -PAR( NULL, ok, OPEN_END ) - -#define PAR(x,y,z) z -typedef enum open_enum_choices -{ - OPEN_DEFS() -} open_choices_t; +#define PAR(x, y, z) z +typedef enum open_enum_choices { OPEN_DEFS() } open_choices_t; #undef PAR -#define PAR(x,y,z) { x , y, z } +#define PAR(x, y, z) \ + { x, y, z } - -static const param_t open_defs[] = -{ - OPEN_DEFS() -}; +static const param_t open_defs[] = {OPEN_DEFS()}; #undef PAR - static Int -do_open ( Term file_name, Term t2, Term tlist USES_REGS ) -{ /* '$open'(+File,+Mode,?Stream,-ReturnCode) */ +do_open(Term file_name, Term t2, + Term tlist USES_REGS) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */ Atom open_mode; int sno; SMALLUNSGN s; char io_mode[8]; StreamDesc *st; - bool avoid_bom = false, needs_bom = true, bin = false; + bool avoid_bom = true, needs_bom = false, bin = false; char *fname; stream_flags_t flags; FILE *fd; encoding_t encoding; Term tenc; - + // original file name - if (IsVarTerm (file_name)) { - Yap_Error(INSTANTIATION_ERROR,file_name, "open/3"); + if (IsVarTerm(file_name)) { + Yap_Error(INSTANTIATION_ERROR, file_name, "open/3"); return FALSE; } - if (!IsAtomTerm (file_name)) { - if (IsStringTerm( file_name )) { - fname = (char *)StringOfTerm( file_name ); + if (!IsAtomTerm(file_name)) { + if (IsStringTerm(file_name)) { + fname = (char *)StringOfTerm(file_name); } else { - Yap_Error(DOMAIN_ERROR_SOURCE_SINK,file_name, "open/3"); + Yap_Error(DOMAIN_ERROR_SOURCE_SINK, file_name, "open/3"); return FALSE; } } else { - fname = RepAtom (AtomOfTerm (file_name))->StrOfAE; + fname = RepAtom(AtomOfTerm(file_name))->StrOfAE; } // open mode - if (IsVarTerm (t2)) { - Yap_Error(INSTANTIATION_ERROR,t2, "open/3"); + if (IsVarTerm(t2)) { + Yap_Error(INSTANTIATION_ERROR, t2, "open/3"); return FALSE; } - if (!IsAtomTerm (t2)) { - if (IsStringTerm( t2 )) { - open_mode = Yap_LookupAtom( StringOfTerm( t2 ) ); + if (!IsAtomTerm(t2)) { + if (IsStringTerm(t2)) { + open_mode = Yap_LookupAtom(StringOfTerm(t2)); } else { - Yap_Error(TYPE_ERROR_ATOM,t2, "open/3"); - return(FALSE); + Yap_Error(TYPE_ERROR_ATOM, t2, "open/3"); + return (FALSE); } } else { - open_mode = AtomOfTerm (t2); + open_mode = AtomOfTerm(t2); } // read, write, append if (open_mode == AtomRead) { - strncpy(io_mode,"rb", 8); + strncpy(io_mode, "rb", 8); s = Input_Stream_f; } else if (open_mode == AtomWrite) { - strncpy(io_mode,"w",8); + strncpy(io_mode, "w", 8); s = Output_Stream_f; } else if (open_mode == AtomAppend) { - strncpy(io_mode,"a",8); + strncpy(io_mode, "a", 8); s = Append_Stream_f | Output_Stream_f; } else { Yap_Error(DOMAIN_ERROR_IO_MODE, t2, "open/3"); - return(FALSE); + return (FALSE); } /* get options */ - xarg *args = Yap_ArgListToVector ( tlist, open_defs, OPEN_END ); + xarg *args = Yap_ArgListToVector(tlist, open_defs, OPEN_END); if (args == NULL) { - if (LOCAL_Error_TYPE) - Yap_Error(LOCAL_Error_TYPE, LOCAL_Error_Term, "option handling in open/3"); + if (LOCAL_Error_TYPE) + Yap_Error(LOCAL_Error_TYPE, LOCAL_Error_Term, + "option handling in open/3"); return FALSE; - } + } /* done */ sno = GetFreeStreamD(); if (sno < 0) - return PlIOError (RESOURCE_ERROR_MAX_STREAMS,TermNil, "open/3"); + return PlIOError(RESOURCE_ERROR_MAX_STREAMS, TermNil, "open/3"); st = &GLOBAL_Stream[sno]; st->user_name = file_name; flags = s; // user requested encoding? if (args[OPEN_ALIAS].used) { Atom al = AtomOfTerm(args[OPEN_ALIAS].tvalue); - if (!Yap_AddAlias(al,sno)) + if (!Yap_AddAlias(al, sno)) return false; - } else { - st->encoding = LOCAL_encoding; } if (args[OPEN_ENCODING].used) { tenc = args[OPEN_ENCODING].tvalue; - encoding = enc_id( RepAtom(AtomOfTerm(tenc))->StrOfAE ); + encoding = enc_id(RepAtom(AtomOfTerm(tenc))->StrOfAE); } else { encoding = LOCAL_encoding; } - bool ok = - ( - args[OPEN_EXPAND_FILENAME].used - ? - args[OPEN_EXPAND_FILENAME].tvalue == TermTrue - : - false - ) - || trueGlobalPrologFlag(OPEN_EXPANDS_FILENAME_FLAG); + bool ok = (args[OPEN_EXPAND_FILENAME].used + ? args[OPEN_EXPAND_FILENAME].tvalue == TermTrue + : false) || + trueGlobalPrologFlag(OPEN_EXPANDS_FILENAME_FLAG); // expand file name? - fname = Yap_AbsoluteFile( fname, LOCAL_FileNameBuf, ok ); + fname = Yap_AbsoluteFile(fname, LOCAL_FileNameBuf, ok); st->name = Yap_LookupAtom(fname); // binary type if (args[OPEN_TYPE].used) { Term t = args[OPEN_TYPE].tvalue; - bool bin = ( t == TermBinary ); + bool bin = (t == TermBinary); if (bin) { #ifdef _WIN32 strncat(io_mode, "b", 8); @@ -1486,129 +1367,128 @@ do_open ( Term file_name, Term t2, Term tlist USES_REGS ) flags |= Binary_Stream_f; encoding = ENC_OCTET; avoid_bom = true; - } else if ( t == TermText ) { + } else if (t == TermText) { #ifdef _WIN32 strncat(io_mode, "t", 8); #endif - /* note that this matters for UNICODE style conversions */ +/* note that this matters for UNICODE style conversions */ #if MAC - if (open_mode == AtomWrite) - { - Yap_SetTextFile (RepAtom (AtomOfTerm (file_name))->StrOfAE); + if (open_mode == AtomWrite) { + Yap_SetTextFile(RepAtom(AtomOfTerm(file_name))->StrOfAE); } #endif } else { - Yap_Error(DOMAIN_ERROR_STREAM, tlist, "type is ~a, must be one of binary or text", t); + Yap_Error(DOMAIN_ERROR_STREAM, tlist, + "type is ~a, must be one of binary or text", t); } } // BOM mess - if (encoding == ENC_ISO_ASCII || + if ((encoding == ENC_OCTET || + encoding == ENC_ISO_ASCII || encoding == ENC_ISO_LATIN1 || - bin) { + encoding == ENC_ISO_UTF8 || bin)) { avoid_bom = true; } if (args[OPEN_BOM].used) { if (args[OPEN_BOM].tvalue == TermTrue) { needs_bom = true; if (avoid_bom) { - return (PlIOError (SYSTEM_ERROR_INTERNAL,file_name,"BOM not compatible with encoding")); + return (PlIOError(SYSTEM_ERROR_INTERNAL, file_name, + "BOM not compatible with encoding")); } - } - else if (args[OPEN_BOM].tvalue == TermFalse) { + } else if (args[OPEN_BOM].tvalue == TermFalse) { needs_bom = false; avoid_bom = true; } else { - Yap_Error(DOMAIN_ERROR_STREAM, tlist, "bom is ~a, should be one of true or false", args[OPEN_BOM].tvalue); + Yap_Error(DOMAIN_ERROR_STREAM, tlist, + "bom is ~a, should be one of true or false", + args[OPEN_BOM].tvalue); } - }else if (st-GLOBAL_Stream < 3) { + } else if (st - GLOBAL_Stream < 3) { flags |= RepError_Prolog_f; } - if ((fd = fopen (fname, io_mode)) == NULL || - (!(flags & Binary_Stream_f) && binary_file(fname))) - { + if ((fd = fopen(fname, io_mode)) == NULL || + (!(flags & Binary_Stream_f) && binary_file(fname))) { UNLOCK(st->streamlock); if (errno == ENOENT) - return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK,ARG6,"%s: %s", fname, strerror(errno))); + return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, ARG6, "%s: %s", fname, + strerror(errno))); else - return (PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK,file_name,"%s: %s", fname, strerror(errno))); + return (PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, file_name, "%s: %s", + fname, strerror(errno))); } #if MAC - if (open_mode == AtomWrite) - { - Yap_SetTextFile (RepAtom (AtomOfTerm (file_name))->StrOfAE); + if (open_mode == AtomWrite) { + Yap_SetTextFile(RepAtom(AtomOfTerm(file_name))->StrOfAE); } #endif flags &= ~(Free_Stream_f); - if (!initStream( sno, fd, fname, file_name, encoding, flags, open_mode )) + if (!initStream(sno, fd, fname, file_name, encoding, flags, open_mode)) return false; - if (open_mode == AtomWrite ) { - if (needs_bom && !write_bom(sno,st)) + if (open_mode == AtomWrite) { + if (needs_bom && !write_bom(sno, st)) return FALSE; - } else if ((open_mode == AtomRead) && - !avoid_bom && + } else if ((open_mode == AtomRead) && !avoid_bom && (needs_bom || (flags & Seekable_Stream_f))) { check_bom(sno, st); // can change encoding if (st->encoding == ENC_ISO_UTF32_BE) { - Yap_Error(DOMAIN_ERROR_STREAM_ENCODING, ARG1, "UTF-32 (BE) stream encoding unsupported"); + Yap_Error(DOMAIN_ERROR_STREAM_ENCODING, ARG1, + "UTF-32 (BE) stream encoding unsupported"); return FALSE; } else if (st->encoding == ENC_ISO_UTF32_LE) { - Yap_Error(DOMAIN_ERROR_STREAM_ENCODING, ARG1, "UTF-32 (LE) stream encoding unsupported"); + Yap_Error(DOMAIN_ERROR_STREAM_ENCODING, ARG1, + "UTF-32 (LE) stream encoding unsupported"); return FALSE; } } - - + UNLOCK(st->streamlock); { - Term t = Yap_MkStream (sno); - return (Yap_unify (ARG3, t)); + Term t = Yap_MkStream(sno); + return (Yap_unify(ARG3, t)); } } -static Int -open3 ( USES_REGS1 ) -{ /* '$open'(+File,+Mode,?Stream,-ReturnCode) */ - return do_open(Deref(ARG1), Deref(ARG2), TermNil PASS_REGS ); +static Int open3(USES_REGS1) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */ + return do_open(Deref(ARG1), Deref(ARG2), TermNil PASS_REGS); } -static Int -open4 ( USES_REGS1 ) -{ /* '$open'(+File,+Mode,?Stream,-ReturnCode) */ - return do_open(Deref(ARG1), Deref(ARG2), Deref( ARG4 ) PASS_REGS ); +static Int open4(USES_REGS1) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */ + return do_open(Deref(ARG1), Deref(ARG2), Deref(ARG4) PASS_REGS); } -static Int -p_file_expansion (USES_REGS1) -{ /* '$file_expansion'(+File,-Name) */ +static Int p_file_expansion(USES_REGS1) { /* '$file_expansion'(+File,-Name) */ Term file_name = Deref(ARG1); - + /* we know file_name is bound */ - if (!IsAtomTerm (file_name)) { + if (!IsAtomTerm(file_name)) { PlIOError(TYPE_ERROR_ATOM, file_name, "absolute_file_name/3"); - return(FALSE); + return (FALSE); } - if (!Yap_TrueFileName (RepAtom (AtomOfTerm (file_name))->StrOfAE, LOCAL_FileNameBuf, FALSE)) - return (PlIOError (EXISTENCE_ERROR_SOURCE_SINK,file_name,"absolute_file_name/3")); - return(Yap_unify(ARG2,MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf)))); + if (!Yap_TrueFileName(RepAtom(AtomOfTerm(file_name))->StrOfAE, + LOCAL_FileNameBuf, FALSE)) + return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name, + "absolute_file_name/3")); + return (Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf)))); } -static Int -p_open_null_stream (USES_REGS1) -{ +static Int p_open_null_stream(USES_REGS1) { Term t; StreamDesc *st; int sno = GetFreeStreamD(); if (sno < 0) - return (PlIOError (SYSTEM_ERROR_INTERNAL,TermNil, "new stream not available for open_null_stream/1")); + return (PlIOError(SYSTEM_ERROR_INTERNAL, TermNil, + "new stream not available for open_null_stream/1")); st = &GLOBAL_Stream[sno]; st->status = Append_Stream_f | Output_Stream_f | Null_Stream_f; #if _WIN32 - st->file = fopen("NUL","w"); + st->file = fopen("NUL", "w"); #else - st->file = fopen("/dev/null","w"); + st->file = fopen("/dev/null", "w"); #endif if (st->file == NULL) { - Yap_Error( SYSTEM_ERROR_INTERNAL, TermNil, "Could not open NULL stream (/dev/null,NUL)" ); + Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, + "Could not open NULL stream (/dev/null,NUL)"); return false; } st->linepos = 0; @@ -1620,26 +1500,25 @@ p_open_null_stream (USES_REGS1) st->stream_gets = PlGets; st->stream_wgetc = get_wchar; st->stream_wgetc_for_read = get_wchar; - if (st->encoding == ENC_ISO_UTF8) + if (st->encoding == ENC_ISO_UTF8) st->stream_getc_for_utf8 = st->stream_getc; else st->stream_getc_for_utf8 = GetUTF8; - st->user_name = MkAtomTerm (st->name = AtomDevNull); + st->user_name = MkAtomTerm(st->name = AtomDevNull); UNLOCK(st->streamlock); - t = Yap_MkStream (sno); - return (Yap_unify (ARG1, t)); + t = Yap_MkStream(sno); + return (Yap_unify(ARG1, t)); } -int -Yap_OpenStream(FILE *fd, char *name, Term file_name, int flags) -{ +int Yap_OpenStream(FILE *fd, char *name, Term file_name, int flags) { CACHE_REGS int sno; Atom at; - + sno = GetFreeStreamD(); - if (sno < 0) - return (PlIOError (RESOURCE_ERROR_MAX_STREAMS,file_name, "new stream not available for opening")); + if (sno < 0) + return (PlIOError(RESOURCE_ERROR_MAX_STREAMS, file_name, + "new stream not available for opening")); if (flags & Output_Stream_f) { if (flags & Append_Stream_f) at = AtomAppend; @@ -1647,28 +1526,28 @@ Yap_OpenStream(FILE *fd, char *name, Term file_name, int flags) at = AtomWrite; } else at = AtomRead; - initStream(sno, fd, name, file_name, LOCAL_encoding, flags, at ); + initStream(sno, fd, name, file_name, LOCAL_encoding, flags, at); return sno; } -#define CheckStream( arg, kind, msg) CheckStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) +#define CheckStream(arg, kind, msg) \ + CheckStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) -static int -CheckStream__ (const char *file, const char *f, int line, Term arg, int kind, const char *msg) -{ +static int CheckStream__(const char *file, const char *f, int line, Term arg, + int kind, const char *msg) { int sno = -1; - arg = Deref (arg); - if (IsVarTerm (arg)) { + arg = Deref(arg); + if (IsVarTerm(arg)) { Yap_Error(INSTANTIATION_ERROR, arg, msg); return -1; - } else if (IsAtomTerm (arg)) { - Atom sname = AtomOfTerm (arg); - + } else if (IsAtomTerm(arg)) { + Atom sname = AtomOfTerm(arg); + if (sname == AtomUser) { if (kind & Input_Stream_f) { - if (kind & (Output_Stream_f|Append_Stream_f)) { - PlIOError__(file, f, line, PERMISSION_ERROR_INPUT_STREAM, arg, - "ambiguous use of 'user' as a stream"); + if (kind & (Output_Stream_f | Append_Stream_f)) { + PlIOError__(file, f, line, PERMISSION_ERROR_INPUT_STREAM, arg, + "ambiguous use of 'user' as a stream"); return (-1); } sname = AtomUserIn; @@ -1678,63 +1557,58 @@ CheckStream__ (const char *file, const char *f, int line, Term arg, int kind, co } if ((sno = Yap_CheckAlias(sname)) < 0) { UNLOCK(GLOBAL_Stream[sno].streamlock); - PlIOError__(file, f, line, EXISTENCE_ERROR_STREAM, arg, msg); + PlIOError__(file, f, line, EXISTENCE_ERROR_STREAM, arg, msg); return -1; } else { LOCK(GLOBAL_Stream[sno].streamlock); return sno; } - } else if (IsApplTerm (arg) && FunctorOfTerm (arg) == FunctorStream) { - arg = ArgOfTerm (1, arg); - if (!IsVarTerm (arg) && IsIntegerTerm (arg)) { + } else if (IsApplTerm(arg) && FunctorOfTerm(arg) == FunctorStream) { + arg = ArgOfTerm(1, arg); + if (!IsVarTerm(arg) && IsIntegerTerm(arg)) { sno = IntegerOfTerm(arg); } } - if (sno < 0) - { + if (sno < 0) { Yap_Error(DOMAIN_ERROR_STREAM_OR_ALIAS, arg, msg); return (-1); } - if (GLOBAL_Stream[sno].status & Free_Stream_f) - { - PlIOError__(file, f, line, EXISTENCE_ERROR_STREAM, arg, msg); + if (GLOBAL_Stream[sno].status & Free_Stream_f) { + PlIOError__(file, f, line, EXISTENCE_ERROR_STREAM, arg, msg); return (-1); } LOCK(GLOBAL_Stream[sno].streamlock); - if (( GLOBAL_Stream[sno].status & Input_Stream_f) && !(kind & Input_Stream_f)) - { - UNLOCK(GLOBAL_Stream[sno].streamlock); - PlIOError__(file, f, line, PERMISSION_ERROR_INPUT_STREAM, arg, msg); - } - if ((GLOBAL_Stream[sno].status & (Append_Stream_f|Output_Stream_f)) && ! ( kind & Output_Stream_f)) - { + if ((GLOBAL_Stream[sno].status & Input_Stream_f) && + !(kind & Input_Stream_f)) { UNLOCK(GLOBAL_Stream[sno].streamlock); - PlIOError__(file, f, line, PERMISSION_ERROR_OUTPUT_STREAM, arg, msg); + PlIOError__(file, f, line, PERMISSION_ERROR_INPUT_STREAM, arg, msg); + } + if ((GLOBAL_Stream[sno].status & (Append_Stream_f | Output_Stream_f)) && + !(kind & Output_Stream_f)) { + UNLOCK(GLOBAL_Stream[sno].streamlock); + PlIOError__(file, f, line, PERMISSION_ERROR_OUTPUT_STREAM, arg, msg); } return (sno); } -int -Yap_CheckStream__ (const char *file, const char *f, int line, Term arg, int kind, const char *msg) -{ +int Yap_CheckStream__(const char *file, const char *f, int line, Term arg, + int kind, const char *msg) { return CheckStream__(file, f, line, arg, kind, msg); } -int -Yap_CheckTextStream__ (const char *file, const char *f, int line, Term arg, int kind, const char *msg) -{ +int Yap_CheckTextStream__(const char *file, const char *f, int line, Term arg, + int kind, const char *msg) { int sno; - if ((sno = CheckStream__(file, f, line, arg, kind, msg)) < 0) + if ((sno = CheckStream__(file, f, line, arg, kind, msg)) < 0) return -1; if ((GLOBAL_Stream[sno].status & Binary_Stream_f)) { - PlIOError__(file, f, line, PERMISSION_ERROR_INPUT_BINARY_STREAM, arg, msg); + PlIOError__(file, f, line, PERMISSION_ERROR_INPUT_BINARY_STREAM, arg, msg); UNLOCK(GLOBAL_Stream[sno].streamlock); return -1; } return sno; } - /* used from C-interface */ int Yap_GetFreeStreamDForReading(void) { int sno = GetFreeStreamD(); @@ -1747,34 +1621,30 @@ int Yap_GetFreeStreamDForReading(void) { s->charcount = 0; s->linecount = 1; s->linepos = 0; - Yap_DefaultStreamOps( s ); + Yap_DefaultStreamOps(s); UNLOCK(s->streamlock); return sno; } -static Int -always_prompt_user( USES_REGS1 ) -{ - StreamDesc *s = GLOBAL_Stream+StdInStream; - +static Int always_prompt_user(USES_REGS1) { + StreamDesc *s = GLOBAL_Stream + StdInStream; + s->status |= Promptable_Stream_f; #if USE_SOCKET if (s->status & Socket_Stream_f) { - Yap_ConsoleSocketOps( s ); + Yap_ConsoleSocketOps(s); } else #endif - if (s->status & Pipe_Stream_f) { - Yap_ConsolePipeOps( s ); - } else - Yap_ConsoleOps( s ); - return(TRUE); + if (s->status & Pipe_Stream_f) { + Yap_ConsolePipeOps(s); + } else + Yap_ConsoleOps(s); + return (TRUE); } - -static Int -close1 (USES_REGS1) -{ /* '$close'(+GLOBAL_Stream) */ - Int sno = CheckStream(ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f), "close/2"); +static Int close1(USES_REGS1) { /* '$close'(+GLOBAL_Stream) */ + Int sno = CheckStream( + ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f), "close/2"); if (sno < 0) return (FALSE); if (sno <= StdErrStream) { @@ -1786,32 +1656,24 @@ close1 (USES_REGS1) return (TRUE); } -#define CLOSE_DEFS() \ -PAR( "force", boolean, CLOSE_FORCE), \ -PAR( NULL, ok, CLOSE_END ) +#define CLOSE_DEFS() \ + PAR("force", boolean, CLOSE_FORCE), PAR(NULL, ok, CLOSE_END) -#define PAR(x,y,z) z +#define PAR(x, y, z) z -typedef enum close_enum_choices -{ - CLOSE_DEFS() -} close_choices_t; +typedef enum close_enum_choices { CLOSE_DEFS() } close_choices_t; #undef PAR -#define PAR(x,y,z) { x , y, z } +#define PAR(x, y, z) \ + { x, y, z } - -static const param_t close_defs[] = -{ - CLOSE_DEFS() -}; +static const param_t close_defs[] = {CLOSE_DEFS()}; #undef PAR -static Int -close2 (USES_REGS1) -{ /* '$close'(+GLOBAL_Stream) */ - Int sno = CheckStream (ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f), "close/2"); +static Int close2(USES_REGS1) { /* '$close'(+GLOBAL_Stream) */ + Int sno = CheckStream( + ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f), "close/2"); Term tlist; if (sno < 0) return (FALSE); @@ -1819,7 +1681,8 @@ close2 (USES_REGS1) UNLOCK(GLOBAL_Stream[sno].streamlock); return TRUE; } - xarg *args = Yap_ArgListToVector ( (tlist = Deref(ARG2) ), close_defs, CLOSE_END ); + xarg *args = + Yap_ArgListToVector((tlist = Deref(ARG2)), close_defs, CLOSE_END); if (args == NULL) return FALSE; // if (args[CLOSE_FORCE].used) { @@ -1829,68 +1692,63 @@ close2 (USES_REGS1) return (TRUE); } - -Term -read_line(int sno) -{ +Term read_line(int sno) { CACHE_REGS Term tail; Int ch; - + if ((ch = GLOBAL_Stream[sno].stream_wgetc(sno)) == 10) { - return(TermNil); + return (TermNil); } tail = read_line(sno); - return(MkPairTerm(MkIntTerm(ch),tail)); + return (MkPairTerm(MkIntTerm(ch), tail)); } +#define ABSOLUTE_FILE_NAME_DEFS() \ + PAR("access", isatom, ABSOLUTE_FILE_NAME_ACCESS), \ + PAR("expand", boolean, ABSOLUTE_FILE_NAME_EXPAND), \ + PAR("extensions", ok, ABSOLUTE_FILE_NAME_EXTENSIONS), \ + PAR("file_type", is_file_type, ABSOLUTE_FILE_NAME_FILE_TYPE), \ + PAR("file_errors", is_file_errors, ABSOLUTE_FILE_NAME_FILE_ERRORS), \ + PAR("glob", ok, ABSOLUTE_FILE_NAME_GLOB), \ + PAR("relative_to", isatom, ABSOLUTE_FILE_NAME_RELATIVE_TO), \ + PAR("solutions", issolutions, ABSOLUTE_FILE_NAME_SOLUTIONS), \ + PAR("verbose_file_search", boolean, \ + ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH), \ + PAR(NULL, ok, ABSOLUTE_FILE_NAME_END) +#define PAR(x, y, z) z -#define ABSOLUTE_FILE_NAME_DEFS() \ - PAR( "access", isatom, ABSOLUTE_FILE_NAME_ACCESS ), \ - PAR( "expand", boolean, ABSOLUTE_FILE_NAME_EXPAND ), \ - PAR( "extensions", ok, ABSOLUTE_FILE_NAME_EXTENSIONS), \ - PAR( "file_type", is_file_type, ABSOLUTE_FILE_NAME_FILE_TYPE ), \ - PAR( "file_errors", is_file_errors, ABSOLUTE_FILE_NAME_FILE_ERRORS ), \ - PAR( "glob", ok, ABSOLUTE_FILE_NAME_GLOB), \ - PAR( "relative_to", isatom, ABSOLUTE_FILE_NAME_RELATIVE_TO ), \ - PAR( "solutions", issolutions, ABSOLUTE_FILE_NAME_SOLUTIONS ), \ - PAR( "verbose_file_search", boolean, ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH), \ - PAR( NULL, ok, ABSOLUTE_FILE_NAME_END ) - -#define PAR(x,y,z) z - -typedef enum ABSOLUTE_FILE_NAME_enum_ -{ +typedef enum ABSOLUTE_FILE_NAME_enum_ { ABSOLUTE_FILE_NAME_DEFS() } absolute_file_name_choices_t; #undef PAR -#define PAR(x,y,z) { x , y, z } +#define PAR(x, y, z) \ + { x, y, z } -static const param_t absolute_file_name_search_defs[] = -{ - ABSOLUTE_FILE_NAME_DEFS() -}; +static const param_t absolute_file_name_search_defs[] = { + ABSOLUTE_FILE_NAME_DEFS()}; #undef PAR - -static Int abs_file_parameters ( USES_REGS1 ) -{ +static Int abs_file_parameters(USES_REGS1) { Term t[ABSOLUTE_FILE_NAME_END]; Term tlist = Deref(ARG1), tf; /* get options */ - xarg *args = Yap_ArgListToVector ( tlist,absolute_file_name_search_defs, ABSOLUTE_FILE_NAME_END ); + xarg *args = Yap_ArgListToVector(tlist, absolute_file_name_search_defs, + ABSOLUTE_FILE_NAME_END); if (args == NULL) return FALSE; /* done */ if (args[ABSOLUTE_FILE_NAME_EXTENSIONS].used) - t[ABSOLUTE_FILE_NAME_EXTENSIONS] = args[ABSOLUTE_FILE_NAME_EXTENSIONS].tvalue; + t[ABSOLUTE_FILE_NAME_EXTENSIONS] = + args[ABSOLUTE_FILE_NAME_EXTENSIONS].tvalue; else t[ABSOLUTE_FILE_NAME_EXTENSIONS] = TermNil; if (args[ABSOLUTE_FILE_NAME_RELATIVE_TO].used) - t[ABSOLUTE_FILE_NAME_RELATIVE_TO] = args[ABSOLUTE_FILE_NAME_RELATIVE_TO].tvalue; + t[ABSOLUTE_FILE_NAME_RELATIVE_TO] = + args[ABSOLUTE_FILE_NAME_RELATIVE_TO].tvalue; else t[ABSOLUTE_FILE_NAME_RELATIVE_TO] = TermEmptyAtom; if (args[ABSOLUTE_FILE_NAME_FILE_TYPE].used) @@ -1902,7 +1760,8 @@ static Int abs_file_parameters ( USES_REGS1 ) else t[ABSOLUTE_FILE_NAME_ACCESS] = TermNone; if (args[ABSOLUTE_FILE_NAME_FILE_ERRORS].used) - t[ABSOLUTE_FILE_NAME_FILE_ERRORS] = args[ABSOLUTE_FILE_NAME_FILE_ERRORS].tvalue; + t[ABSOLUTE_FILE_NAME_FILE_ERRORS] = + args[ABSOLUTE_FILE_NAME_FILE_ERRORS].tvalue; else t[ABSOLUTE_FILE_NAME_FILE_ERRORS] = TermError; if (args[ABSOLUTE_FILE_NAME_SOLUTIONS].used) @@ -1916,53 +1775,55 @@ static Int abs_file_parameters ( USES_REGS1 ) if (args[ABSOLUTE_FILE_NAME_GLOB].used) t[ABSOLUTE_FILE_NAME_GLOB] = args[ABSOLUTE_FILE_NAME_GLOB].tvalue; else - t[ABSOLUTE_FILE_NAME_GLOB] = TermEmptyAtom; + t[ABSOLUTE_FILE_NAME_GLOB] = TermEmptyAtom; if (args[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH].used) - t[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH] = args[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH].tvalue; + t[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH] = + args[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH].tvalue; else - t[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH] = TermFalse; - tf = Yap_MkApplTerm(Yap_MkFunctor(AtomOpt,ABSOLUTE_FILE_NAME_END), ABSOLUTE_FILE_NAME_END, t); - return (Yap_unify (ARG2, tf)); - + t[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH] = + (trueGlobalPrologFlag(VERBOSE_FILE_SEARCH_FLAG) ? TermTrue : TermFalse); + tf = Yap_MkApplTerm(Yap_MkFunctor(AtomOpt, ABSOLUTE_FILE_NAME_END), + ABSOLUTE_FILE_NAME_END, t); + return (Yap_unify(ARG2, tf)); } -static Int get_abs_file_parameter ( USES_REGS1 ) -{ +static Int get_abs_file_parameter(USES_REGS1) { Term t = Deref(ARG1), topts = ARG2; /* get options */ /* done */ if (t == TermExtensions) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_EXTENSIONS +1, topts ) ); + return Yap_unify(ARG3, ArgOfTerm(ABSOLUTE_FILE_NAME_EXTENSIONS + 1, topts)); if (t == TermRelativeTo) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_RELATIVE_TO +1, topts ) ); + return Yap_unify(ARG3, + ArgOfTerm(ABSOLUTE_FILE_NAME_RELATIVE_TO + 1, topts)); if (t == TermFileType) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_FILE_TYPE +1, topts ) ); + return Yap_unify(ARG3, ArgOfTerm(ABSOLUTE_FILE_NAME_FILE_TYPE + 1, topts)); if (t == TermAccess) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_ACCESS +1, topts ) ); + return Yap_unify(ARG3, ArgOfTerm(ABSOLUTE_FILE_NAME_ACCESS + 1, topts)); if (t == TermFileErrors) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_FILE_ERRORS +1, topts ) ); + return Yap_unify(ARG3, + ArgOfTerm(ABSOLUTE_FILE_NAME_FILE_ERRORS + 1, topts)); if (t == TermSolutions) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_SOLUTIONS +1, topts ) ); + return Yap_unify(ARG3, ArgOfTerm(ABSOLUTE_FILE_NAME_SOLUTIONS + 1, topts)); if (t == TermGlob) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_GLOB +1, topts ) ); + return Yap_unify(ARG3, ArgOfTerm(ABSOLUTE_FILE_NAME_GLOB + 1, topts)); if (t == TermExpand) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_EXPAND +1, topts ) ); + return Yap_unify(ARG3, ArgOfTerm(ABSOLUTE_FILE_NAME_EXPAND + 1, topts)); if (t == TermVerboseFileSearch) - return Yap_unify( ARG3, ArgOfTerm( ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH +1, topts ) ); + return Yap_unify( + ARG3, ArgOfTerm(ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH + 1, topts)); Yap_Error(DOMAIN_ERROR_ABSOLUTE_FILE_NAME_OPTION, ARG2, NULL); return false; - } -void -Yap_InitPlIO (void) -{ +void Yap_InitPlIO(void) { Int i; - + Yap_stdin = stdin; Yap_stdout = stdout; Yap_stderr = stderr; - GLOBAL_Stream = (StreamDesc *)Yap_AllocCodeSpace(sizeof(StreamDesc)*MaxStreams); + GLOBAL_Stream = + (StreamDesc *)Yap_AllocCodeSpace(sizeof(StreamDesc) * MaxStreams); for (i = 0; i < MaxStreams; ++i) { INIT_LOCK(GLOBAL_Stream[i].streamlock); GLOBAL_Stream[i].status = Free_Stream_f; @@ -1970,26 +1831,29 @@ Yap_InitPlIO (void) InitStdStreams(); } -void -Yap_InitIOPreds(void) -{ +void Yap_InitIOPreds(void) { /* here the Input/Output predicates */ - Yap_InitCPred ("always_prompt_user", 0, always_prompt_user, SafePredFlag|SyncPredFlag); - Yap_InitCPred ("close", 1, close1, SafePredFlag|SyncPredFlag); - Yap_InitCPred ("close", 2, close2, SafePredFlag|SyncPredFlag); - Yap_InitCPred ("open", 4, open4, SyncPredFlag); - Yap_InitCPred ("open", 3, open3, SyncPredFlag); - Yap_InitCPred ("abs_file_parameters", 2, abs_file_parameters, SyncPredFlag|HiddenPredFlag); - Yap_InitCPred ("get_abs_file_parameter", 3, get_abs_file_parameter, SafePredFlag|SyncPredFlag|HiddenPredFlag); - Yap_InitCPred ("$file_expansion", 2, p_file_expansion, SafePredFlag|SyncPredFlag|HiddenPredFlag); - Yap_InitCPred ("$open_null_stream", 1, p_open_null_stream, SafePredFlag|SyncPredFlag|HiddenPredFlag); + Yap_InitCPred("always_prompt_user", 0, always_prompt_user, + SafePredFlag | SyncPredFlag); + Yap_InitCPred("close", 1, close1, SafePredFlag | SyncPredFlag); + Yap_InitCPred("close", 2, close2, SafePredFlag | SyncPredFlag); + Yap_InitCPred("open", 4, open4, SyncPredFlag); + Yap_InitCPred("open", 3, open3, SyncPredFlag); + Yap_InitCPred("abs_file_parameters", 2, abs_file_parameters, + SyncPredFlag | HiddenPredFlag); + Yap_InitCPred("get_abs_file_parameter", 3, get_abs_file_parameter, + SafePredFlag | SyncPredFlag | HiddenPredFlag); + Yap_InitCPred("$file_expansion", 2, p_file_expansion, + SafePredFlag | SyncPredFlag | HiddenPredFlag); + Yap_InitCPred("$open_null_stream", 1, p_open_null_stream, + SafePredFlag | SyncPredFlag | HiddenPredFlag); Yap_InitIOStreams(); Yap_InitCharsio(); Yap_InitChtypes(); Yap_InitConsole(); - Yap_InitReadUtil (); + Yap_InitReadUtil(); Yap_InitMems(); - Yap_InitPipes( ); + Yap_InitPipes(); Yap_InitFiles(); Yap_InitWriteTPreds(); Yap_InitReadTPreds(); diff --git a/os/iopreds.h b/os/iopreds.h index 92bc98890..b992bfb4a 100644 --- a/os/iopreds.h +++ b/os/iopreds.h @@ -301,6 +301,7 @@ void Yap_InitWriteTPreds(void); void Yap_InitReadTPreds(void); void Yap_socketStream( StreamDesc *s ); void Yap_ReadlineFlush( int sno ); +Int Yap_ReadlinePeekChar( int sno ); int Yap_ReadlineForSIGINT(void); bool Yap_ReadlinePrompt( StreamDesc * s ); @@ -327,6 +328,8 @@ int DefaultGets( int,UInt,char*); int put_wchar(int sno, wchar_t ch); Int GetStreamFd(int sno); int ResetEOF(StreamDesc *s); +int EOFPeek(int sno); +int EOFWPeek(int sno); void Yap_SetAlias (Atom arg, int sno); bool Yap_AddAlias (Atom arg, int sno); diff --git a/os/readline.c b/os/readline.c index d067d0551..2e6b0575c 100644 --- a/os/readline.c +++ b/os/readline.c @@ -300,6 +300,42 @@ static int ReadlineGetc(int sno) { return console_post_process_read_char(ch, s); } + +/** + @brief Yap_ReadlinePeekChar peeks the next char from the + readline buffer, but does not actually grab it. + + The idea is to take advantage of the buffering. Special care must be taken with EOF, though. + +*/ +Int Yap_ReadlinePeekChar( int sno) { + StreamDesc *s = &GLOBAL_Stream[sno]; + int ch; + + if (s->u.irl.buf) { + const char *ttyptr = s->u.irl.ptr; + ch = *ttyptr; + if (ch == '\0') { + ch = '\n'; + } + } if (getLine(sno, StdErrStream) ) { + CACHE_REGS + ch = s->u.irl.ptr[0]; + if (ch == '\0') { + ch = '\n'; + } + if (ch == '\n') { + LOCAL_newline = true; + } else { + LOCAL_newline = false; + } + } else { + return EOF; + } + return ch; +} + + int Yap_ReadlineForSIGINT(void) { CACHE_REGS int ch; diff --git a/os/streams.c b/os/streams.c index a13133d02..4330aab9b 100644 --- a/os/streams.c +++ b/os/streams.c @@ -140,6 +140,7 @@ int GetFreeStreamD(void) { LOCK(GLOBAL_Stream[sno].streamlock); UNLOCK(GLOBAL_StreamDescLock); GLOBAL_Stream[sno].encoding = LOCAL_encoding; + GLOBAL_Stream[sno].och = '\0'; return sno; }