Simplify Input/Output

get rid of string I/O, did not add much
getc is never actually used by Prolog
try to use system I/O, even if it may be slower, at least for now.
extend IO C-interface to allow reading clauses
This commit is contained in:
Vítor Santos Costa 2016-02-21 19:06:25 +00:00
parent 19cedad41d
commit f7d23f9deb
11 changed files with 346 additions and 334 deletions

View File

@ -2153,6 +2153,7 @@ X_API Term YAP_Read(FILE *f) {
return o;
}
X_API Term YAP_ReadFromStream(int sno) {
Term o;
@ -2162,6 +2163,15 @@ X_API Term YAP_ReadFromStream(int sno) {
return o;
}
X_API Term YAP_ReadClauseFromStream(int sno) {
Term o;
BACKUP_MACHINE_REGS();
o = Yap_read_term(sno, TermNil, -1);
RECOVER_MACHINE_REGS();
return o;
}
X_API void YAP_Write(Term t, FILE *f, int flags) {
BACKUP_MACHINE_REGS();
int sno = Yap_OpenStream(f, NULL, TermNil, Output_Stream_f);
@ -2271,7 +2281,7 @@ static void do_bootfile(char *bootfilename USES_REGS) {
CACHE_REGS
YAP_Reset(YAP_FULL_RESET);
Yap_StartSlots();
t = YAP_ReadFromStream(bootfile);
t = YAP_ReadClauseFromStream(bootfile);
// Yap_DebugPlWrite(t);fprintf(stderr, "\n");
if (t == 0) {
fprintf(stderr,

View File

@ -1866,8 +1866,14 @@ extern X_API YAP_Int YAP_FastInit(char saved_state[]);
#define IOSTREAM void
#endif /* FPL_STREAM_H */
/// read a Prolog term from an operating system stream $s$.
extern X_API YAP_Term YAP_Read(FILE *s);
/// read a Prolog term from a Prolog opened stream $s$. Check YAP_OpenStream() for how to open
/// Prolog streams in `C`.
extern X_API YAP_Term YAP_ReadFromStream(int s);
/// read a Prolog clause from a Prolog opened stream $s$. Similar to YAP_ReadFromStream() but takes /// default options from read_clause/3.
extern X_API YAP_Term YAP_ReadFromStream(int s);
extern X_API void YAP_Write(YAP_Term t,FILE *s,int);
@ -1878,12 +1884,6 @@ extern X_API int YAP_InitConsult(int mode, const char *filename, int *previous_s
extern X_API void YAP_EndConsult(int s, int *previous_sno);
#ifndef _PL_STREAM_H
// if we don't know what a stream is, just don't assume nothing about the pointer
#undef IOSTREAM
#endif /* FPL_STREAM_H */
extern X_API void YAP_Exit(int);
/* void YAP_PutValue(YAP_Atom, YAP_Term) */

View File

@ -89,8 +89,9 @@ is_same_tty2 (USES_REGS1)
}
void
Yap_ConsoleOps( StreamDesc *s )
Yap_ConsoleOps( StreamDesc *s, bool recursive )
{
if (!recursive)
Yap_DefaultStreamOps( s );
/* the putc routine only has to check it is putting out a newline */
s->stream_putc = ConsolePutc;
@ -162,15 +163,15 @@ ConsoleGetc(int sno)
if (LOCAL_PrologMode & AbortMode) {
Yap_Error(ABORT_EVENT, TermNil, "");
LOCAL_ErrorMessage = "Abort";
return console_post_process_eof(s);
return EOF;
}
goto restart;
} else {
LOCAL_PrologMode &= ~ConsoleGetcMode;
}
if (ch == EOF)
return console_post_process_eof(s);
return console_post_process_read_char(ch, s);
return EOF;
return ch;
}
/** @pred prompt1(+ _A__)
@ -199,10 +200,8 @@ prompt1 ( USES_REGS1 )
/** @pred prompt(- _A_,+ _B_)
Changes YAP input prompt from _A_ to _B_, active on *next* standard input interaction.
*/
static Int
prompt ( USES_REGS1 )
@ -223,6 +222,21 @@ prompt ( USES_REGS1 )
return (TRUE);
}
/** @pred ensure_prompting
Make sure we have a prompt at this point, even if we have to
introduce a new line.
*/
static Int
ensure_prompting ( USES_REGS1 )
{ /* prompt(Old,New) */
if (!LOCAL_newline) {
GLOBAL_Stream[2].stream_wputc(2, 10); // hack!
}
return true;
}
int
Yap_GetCharForSIGINT(void)
{
@ -250,6 +264,7 @@ void Yap_InitConsole(void) {
Yap_InitCPred ("prompt1", 1, prompt1, SafePredFlag|SyncPredFlag);
Yap_InitCPred ("$is_same_tty", 2, is_same_tty2, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("prompt", 2, prompt, SafePredFlag|SyncPredFlag);
Yap_InitCPred ("$ensure_prompting", 0, ensure_prompting, SafePredFlag|SyncPredFlag);
}

203
os/getw.h Normal file
View File

@ -0,0 +1,203 @@
/// compose a wide char from a sequence of getchars
/// this is a slow lane routine, called if no specialised code
/// isavailable.
static int GETW(int sno) {
StreamDesc *st = GLOBAL_Stream + sno;
int ch = GETC();
if (ch == -1)
return post_process_weof(st);
switch (st->encoding) {
case ENC_OCTET:
// no error detection, all characters are ok.
case ENC_ISO_LATIN1:
return post_process_read_wchar(ch, 1, st);
// 7 bits code, anything above is bad news
case ENC_ISO_ASCII:
if (ch & 0x80) {
/* error */
}
return post_process_read_wchar(ch, 1, st);
// default OS encoding, depends on locale.
case ENC_ISO_ANSI: {
char buf[8];
int out;
int wch;
mbstate_t mbstate;
memset((void *)&(mbstate), 0, sizeof(mbstate_t));
buf[0] = ch;
int n=1;
while ((out = mbrtowc(&wch, buf, 1, &(mbstate))) != 1) {
int ch = buf[0] = GETC();
n++;
if (ch == -1)
return post_process_weof(st);
}
return post_process_read_wchar(wch, n, st);
}
// UTF-8 works o 8 bits.
case ENC_ISO_UTF8: {
int wch;
unsigned char buf[8];
if (ch < 0x80) {
return post_process_read_wchar(ch, 1, st);
}
// if ((ch - 0xc2) > (0xf4-0xc2)) return UTF8PROC_ERROR_INVALIDUTF8;
if (ch < 0xe0) { // 2-byte sequence
// Must have valid continuation character
int c1 = buf[0] = GETC();
if (c1 == -1)
return post_process_weof(st);
// if (!utf_cont(*str)) return UTF8PROC_ERROR_INVALIDUTF8;
wch = ((ch & 0x1f)<<6) | (c1 & 0x3f);
return post_process_read_wchar(wch, 2, st);
}
if (ch < 0xf0) { // 3-byte sequence
//if ((str + 1 >= end) || !utf_cont(*str) || !utf_cont(str[1]))
// return UTF8PROC_ERROR_INVALIDUTF8;
// Check for surrogate chars
//if (ch == 0xed && *str > 0x9f)
// return UTF8PROC_ERROR_INVALIDUTF8;
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
int c2 = GETC();
if (c2 == -1)
return post_process_weof(st);
wch = ((ch & 0xf)<<12) | ((c1 & 0x3f)<<6) | (c2 & 0x3f);
return post_process_read_wchar(wch, 3, st);
} else {
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
int c2 = GETC();
if (c2 == -1)
return post_process_weof(st);
int c3 = GETC();
if (c3 == -1)
return post_process_weof(st);
wch = ((ch & 7)<<18) | ((c1 & 0x3f)<<12) | ((c2 & 0x3f)<<6) | (c3 & 0x3f);
return post_process_read_wchar(wch, 4, st);
}
}
case ENC_UTF16_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch = (c1 << 8) + ch;
if (wch >= 0xd800 && wch < 0xdc00) {
int c2 = GETC();
if (c2 == -1)
return post_process_weof(st);
int c3 = GETC();
if (c3 == -1)
return post_process_weof(st);
wch = wch + (((c3 << 8) + c2)<<wch) + SURROGATE_OFFSET;
return post_process_read_wchar(wch, 4, st);
}
return post_process_read_wchar(wch, 2, st);
}
case ENC_UTF16_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch = (c1) + (ch<<8);
if (wch >= 0xd800 && wch < 0xdc00) {
int c3 = GETC();
if (c3 == -1)
return post_process_weof(st);
int c2 = GETC();
if (c2 == -1)
return post_process_weof(st);
wch = (((c3 << 8) + c2) << 10) + wch + SURROGATE_OFFSET;
return post_process_read_wchar(wch, 4, st);
}
return post_process_read_wchar(wch, 2, st);
}
case ENC_UCS2_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch = (c1) + (ch<<8);
return post_process_read_wchar(wch, 2, st);
}
case ENC_UCS2_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch = (c1 << 8) + ch;
return post_process_read_wchar(wch, 2, st);
}
case ENC_ISO_UTF32_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch = ch;
{
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch = wch + c1;
}
{
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch = (wch << 8 )+c1;
}
{
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch = (wch << 8) +c1;
}
return post_process_read_wchar(wch, 4, st);
}
case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch = ch;
{
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch += c1<<8;
}
{
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch += c1<<16;
}
{
int c1 = GETC();
if (c1 == -1)
return post_process_weof(st);
wch += c1<<24;
}
return post_process_read_wchar(wch, 4, st);
}
}
}

View File

@ -96,7 +96,17 @@ static char SccsId[] = "%W% %G%";
#endif
#include "iopreds.h"
static int get_wchar(int);
#define GETW get_wchar_from_FILE
#define GETC() fgetwc(st->file)
#include "getw.h"
#undef GETW
#undef GETC
#define GETW get_wchar
#define GETC() st->stream_getc(sno)
#include "getw.h"
static int get_wchar_from_file(int);
FILE *Yap_stdin;
@ -180,10 +190,13 @@ static bool is_file_errors(Term t) {
void Yap_DefaultStreamOps(StreamDesc *st) {
st->stream_wputc = put_wchar;
if (!(st->status & (Tty_Stream_f | Reset_Eof_Stream_f | Promptable_Stream_f)))
st->stream_wgetc = get_wchar_from_file;
else
if (st->status & (Promptable_Stream_f)) {
st->stream_wgetc = get_wchar;
Yap_ConsoleOps(st, true);
} else if (st->encoding == LOCAL_encoding) {
st->stream_wgetc = get_wchar_from_file;
} else
st->stream_wgetc = get_wchar_from_FILE;
if (GLOBAL_CharConversionTable != NULL)
st->stream_wgetc_for_read = ISOWGetc;
else
@ -250,15 +263,8 @@ static void unix_upd_stream_info(StreamDesc *s) {
s->status |= Seekable_Stream_f;
}
GetsFunc PlGetsFunc(void) {
if (GLOBAL_CharConversionTable)
return DefaultGets;
else
return PlGets;
}
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);
@ -273,14 +279,16 @@ static void InitFileIO(StreamDesc *s) {
} else {
/* check if our console is promptable: may be tty or pipe */
if (s->status & (Promptable_Stream_f)) {
Yap_ConsoleOps(s);
Yap_ConsoleOps(s, false);
} else {
/* we are reading from a file, no need to check for prompts */
s->stream_putc = FilePutc;
s->stream_wputc = put_wchar;
s->stream_getc = PlGetc;
s->stream_gets = PlGetsFunc();
s->stream_wgetc = get_wchar_from_file;
if (s->encoding == LOCAL_encoding)
s->stream_wgetc = get_wchar_from_file;
else
s->stream_wgetc = get_wchar_from_FILE;
}
}
s->stream_wputc = put_wchar;
@ -571,12 +579,11 @@ int ResetEOF(StreamDesc *s) {
} else if (s->status & InMemory_Stream_f) {
Yap_MemOps(s);
} else if (s->status & Promptable_Stream_f) {
Yap_ConsoleOps(s);
Yap_ConsoleOps(s, false);
} 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 */
@ -597,7 +604,7 @@ static int EOFWGetc(int sno) {
return EOF;
}
if (ResetEOF(s)) {
Yap_ConsoleOps(s);
Yap_ConsoleOps(s, false);
return (s->stream_wgetc(sno));
}
return EOF;
@ -613,7 +620,7 @@ static int EOFGetc(int sno) {
return EOF;
}
if (ResetEOF(s)) {
Yap_ConsoleOps(s);
Yap_ConsoleOps(s, false);
return s->stream_getc(sno);
}
return EOF;
@ -633,9 +640,12 @@ int console_post_process_eof(StreamDesc *s) {
}
/* check if we read a newline or an EOF */
int post_process_read_char(int ch, StreamDesc *s) {
++s->charcount;
++s->linepos;
int post_process_read_wchar(int ch, ssize_t n, StreamDesc *s) {
if (ch == EOF) {
return post_process_weof(s);
}
s->charcount += n;
s->linepos += n;
if (ch == '\n') {
++s->linecount;
s->linepos = 0;
@ -646,22 +656,12 @@ int post_process_read_char(int ch, StreamDesc *s) {
return ch;
}
/* check if we read a newline or an EOF */
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;
}
return EOFCHAR;
}
int post_process_weof(StreamDesc *s) {
if (!ResetEOF(s)) {
s->status |= Eof_Stream_f;
s->stream_wgetc = EOFWGetc;
s->stream_wgetc = EOFWGetc;
s->stream_getc = EOFGetc;
s->stream_wgetc_for_read = EOFWGetc;
}
return EOFCHAR;
@ -684,249 +684,16 @@ int EOFWPeek(int sno) { return EOFWGetc(sno); }
post_process_read_char, something to think about */
int PlGetc(int sno) {
StreamDesc *s = &GLOBAL_Stream[sno];
Int ch;
ch = fgetc(s->file);
if (ch == EOF) {
return post_process_eof(s);
}
return post_process_read_char(ch, s);
return fgetc(s->file);
}
/* 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) {
register StreamDesc *s = &GLOBAL_Stream[sno];
UInt len;
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);
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) {
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)
;
*buf++ = '\0';
return (buf - pt) - 1;
}
/// compose a wide char from a sequence of getchars \
// this is a slow lane routine, called if no specialised code
// isavailable.
static int get_wchar(int sno) {
StreamDesc *st = GLOBAL_Stream + sno;
int ch = st->stream_getc(sno);
if (ch == -1)
return post_process_weof(st);
switch (st->encoding) {
case ENC_OCTET:
return ch;
// no error detection, all characters are ok.
case ENC_ISO_LATIN1:
return ch;
// 7 bits code, anything above is bad news
case ENC_ISO_ASCII:
if (ch & 0x80) {
/* error */
}
return ch;
// default OS encoding, depends on locale.
case ENC_ISO_ANSI: {
char buf[8];
int out;
int wch;
mbstate_t mbstate;
memset((void *)&(mbstate), 0, sizeof(mbstate_t));
buf[0] = ch;
while ((out = mbrtowc(&wch, buf, 1, &(mbstate))) != 1) {
int ch = buf[0] = st->stream_getc(sno);
if (ch == -1)
return post_process_weof(st);
}
return wch;
}
// UTF-8 works o 8 bits.
case ENC_ISO_UTF8: {
unsigned char buf[8];
if (ch < 0x80) {
return ch;
}
// if ((ch - 0xc2) > (0xf4-0xc2)) return UTF8PROC_ERROR_INVALIDUTF8;
if (ch < 0xe0) { // 2-byte sequence
// Must have valid continuation character
int c1 = buf[0] = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
// if (!utf_cont(*str)) return UTF8PROC_ERROR_INVALIDUTF8;
return ((ch & 0x1f)<<6) | (c1 & 0x3f);
}
if (ch < 0xf0) { // 3-byte sequence
//if ((str + 1 >= end) || !utf_cont(*str) || !utf_cont(str[1]))
// return UTF8PROC_ERROR_INVALIDUTF8;
// Check for surrogate chars
//if (ch == 0xed && *str > 0x9f)
// return UTF8PROC_ERROR_INVALIDUTF8;
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
int c2 = st->stream_getc(sno);
if (c2 == -1)
return post_process_weof(st);
return ((ch & 0xf)<<12) | ((c1 & 0x3f)<<6) | (c2 & 0x3f);
} else {
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
int c2 = st->stream_getc(sno);
if (c2 == -1)
return post_process_weof(st);
int c3 = st->stream_getc(sno);
if (c3 == -1)
return post_process_weof(st);
return ((ch & 7)<<18) | ((c1 & 0x3f)<<12) | ((c2 & 0x3f)<<6) | (c3 & 0x3f);
}
}
case ENC_UTF16_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch = (c1 << 8) + ch;
if (wch >= 0xd800 && wch < 0xdc00) {
int c2 = st->stream_getc(sno);
if (c2 == -1)
return post_process_weof(st);
int c3 = st->stream_getc(sno);
if (c3 == -1)
return post_process_weof(st);
wch = wch + (((c3 << 8) + c2)<<wch) + SURROGATE_OFFSET;
}
return wch;
}
case ENC_UTF16_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch = (c1) + (ch<<8);
if (wch >= 0xd800 && wch < 0xdc00) {
int c3 = st->stream_getc(sno);
if (c3 == -1)
return post_process_weof(st);
int c2 = st->stream_getc(sno);
if (c2 == -1)
return post_process_weof(st);
wch = (((c3 << 8) + c2) << 10) + wch + SURROGATE_OFFSET;
}
return wch;
}
case ENC_UCS2_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch = (c1) + (ch<<8);
return wch;
}
case ENC_UCS2_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch;
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch = (c1 << 8) + ch;
return wch;
}
case ENC_ISO_UTF32_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch = ch;
{
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch = wch + c1;
}
{
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch = (wch << 8 )+c1;
}
{
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch = (wch << 8) +c1;
}
return wch;
}
case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
// little-endian: start with big shot
{
int wch = ch;
{
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch += c1<<8;
}
{
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch += c1<<16;
}
{
int c1 = st->stream_getc(sno);
if (c1 == -1)
return post_process_weof(st);
wch += c1<<24;
}
return wch;
}
}
}
// layered version
static int get_wchar__(int sno) { return get_wchar(sno); }
static int get_wchar__(int sno) { return fgetwc(GLOBAL_Stream[sno].file); }
static int get_wchar_from_file(int sno) {
return post_process_read_char(get_wchar__(sno), GLOBAL_Stream + sno);
return post_process_read_wchar(get_wchar__(sno), 1, GLOBAL_Stream + sno);
}
#ifndef MB_LEN_MAX
@ -1214,23 +981,23 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
static void check_bom(int sno, StreamDesc *st) {
int ch1, ch2, ch3, ch4;
ch1 = st->stream_getc(sno);
ch1 = fgetc(st->file);
switch (ch1) {
case 0x00: {
ch2 = st->stream_getc(sno);
ch2 = fgetc(st->file);
if (ch2 != 0x00) {
ungetc(ch1, st->file);
ungetc(ch2, st->file);
return;
} else {
ch3 = st->stream_getc(sno);
ch3 = fgetc(st->file);
if (ch3 == EOFCHAR || ch3 != 0xFE) {
ungetc(ch1, st->file);
ungetc(ch2, st->file);
ungetc(ch3, st->file);
return;
} else {
ch4 = st->stream_getc(sno);
ch4 = fgetc(st->file);
if (ch4 == EOFCHAR || ch3 != 0xFF) {
ungetc(ch1, st->file);
ungetc(ch2, st->file);
@ -1246,7 +1013,7 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
}
}
case 0xFE: {
ch2 = st->stream_getc(sno);
ch2 = fgetc(st->file);
if (ch2 != 0xFF) {
ungetc(ch1, st->file);
ungetc(ch2, st->file);
@ -1258,17 +1025,17 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
}
}
case 0xFF: {
ch2 = st->stream_getc(sno);
ch2 = fgetc(st->file);
if (ch2 != 0xFE) {
ungetc(ch1, st->file);
ungetc(ch2, st->file);
return;
} else {
ch3 = st->stream_getc(sno);
ch3 = fgetc(st->file);
if (ch3 != 0x00) {
ungetc(ch3, st->file);
} else {
ch4 = st->stream_getc(sno);
ch4 = fgetc(st->file);
if (ch4 == 0x00) {
st->status |= HAS_BOM_f;
st->encoding = ENC_ISO_UTF32_LE;
@ -1284,13 +1051,13 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
return;
}
case 0xEF:
ch2 = st->stream_getc(sno);
ch2 = fgetc(st->file);
if (ch2 != 0xBB) {
ungetc(ch1, st->file);
ungetc(ch2, st->file);
return;
} else {
ch3 = st->stream_getc(sno);
ch3 = fgetc(st->file);
if (ch3 != 0xBF) {
ungetc(ch1, st->file);
ungetc(ch2, st->file);
@ -1334,7 +1101,7 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
Yap_PipeOps(st);
Yap_DefaultStreamOps(st);
} else if (flags & Tty_Stream_f) {
Yap_ConsoleOps(st);
Yap_ConsoleOps(st, false);
Yap_DefaultStreamOps(st);
} else {
st->stream_putc = FilePutc;
@ -1342,7 +1109,6 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
unix_upd_stream_info(st);
Yap_DefaultStreamOps(st);
}
st->stream_gets = PlGetsFunc();
return true;
}
@ -1747,7 +1513,6 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
st->stream_putc = NullPutc;
st->stream_wputc = put_wchar;
st->stream_getc = PlGetc;
st->stream_gets = PlGets;
st->stream_wgetc = get_wchar;
st->stream_wgetc_for_read = get_wchar;
st->user_name = MkAtomTerm(st->name = AtomDevNull);
@ -1896,7 +1661,7 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
if (s->status & Pipe_Stream_f) {
Yap_ConsolePipeOps(s);
} else
Yap_ConsoleOps(s);
Yap_ConsoleOps(s, false);
return (TRUE);
}

View File

@ -203,20 +203,16 @@ typedef struct stream_desc {
} u;
Int charcount, linecount, linepos;
stream_flags_t status;
int och;
#if defined(YAPOR) || defined(THREADS)
lockvar streamlock; /* protect stream access */
#endif
int (*stream_putc)(int, int); /* function the stream uses for writing */
int (*stream_getc)(int); /* function the stream uses for reading */
GetsFunc stream_gets; /* function the stream uses for reading a sequence of
characters */
/* function the stream uses for parser. It may be different if the ISO
character conversion is on */
int (*stream_wgetc_for_read)(int);
int (*stream_wgetc)(int);
int (*stream_wputc)(int, wchar_t);
encoding_t encoding;
int (*stream_putc)(int, int); /** function the stream uses for writing a single octet */
int (*stream_wputc)(int, wchar_t); /** function the stream uses for writing a character */
int (*stream_getc)(int); /** function the stream uses for reading an octet. */
int (*stream_wgetc)(int); /** function the stream uses for reading a character. */
int (*stream_wgetc_for_read)(int); /* function the stream uses for parser. It may be different from above if the ISO character conversion is on */
encoding_t encoding; /** current encoding for stream */
} StreamDesc;
static inline bool IsStreamTerm(Term t) {
@ -274,8 +270,8 @@ void Yap_ConsolePipeOps(StreamDesc *st);
void Yap_SocketOps(StreamDesc *st);
void Yap_ConsoleSocketOps(StreamDesc *st);
bool Yap_ReadlineOps(StreamDesc *st);
int Yap_OpenBufWriteStream(USES_REGS1);
void Yap_ConsoleOps(StreamDesc *s);
int Yap_OpenBufWriteStream(USES_REGS1);
void Yap_ConsoleOps(StreamDesc *s, bool recursive);
void Yap_InitRandomPreds(void);
void Yap_InitSignalPreds(void);
@ -309,8 +305,7 @@ Term Yap_syntax_error(TokEntry *tokptr, int sno);
int console_post_process_read_char(int, StreamDesc *);
int console_post_process_eof(StreamDesc *);
int post_process_read_char(int, StreamDesc *);
int post_process_eof(StreamDesc *);
int post_process_read_wchar(int, ssize_t, StreamDesc *);
int post_process_weof(StreamDesc *);
bool is_same_tty(FILE *f1, FILE *f2);

View File

@ -172,7 +172,7 @@ PipeGetc(int sno)
int count;
count = read(s->u.pipe.fd, &c, sizeof(char));
if (count == 0) {
return post_process_eof(s);
return EOF;
} else if (count > 0) {
ch = c;
} else {
@ -181,9 +181,9 @@ PipeGetc(int sno)
#else
Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "at pipe getc");
#endif
return post_process_eof(s);
return EOF;
}
return post_process_read_char(ch, s);
return ch;
}
void

View File

@ -734,7 +734,6 @@ static parser_state_t scanEOF(FEnv *fe, int inp_stream) {
fe->t = 0;
if (fe->tp && !Yap_unify(fe->tp, fe->tpos))
fe->t = 0;
post_process_eof(GLOBAL_Stream + inp_stream);
#if DEBUG
if (GLOBAL_Option['p' - 'a' + 1]) {
fprintf(stderr, "[ end_of_file %p ]\n", GLOBAL_Stream[inp_stream].name);
@ -1082,7 +1081,7 @@ static xarg *setClauseReadEnv(Term opts, FEnv *fe, struct renv *re,
static Int read_clause2(USES_REGS1) {
Term rc;
yhandle_t h = Yap_InitSlot(ARG1);
rc = Yap_read_term(LOCAL_c_input_stream, Deref(ARG2), 2);
rc = Yap_read_term(LOCAL_c_input_stream, Deref(ARG2), -2);
Term tf = Yap_GetFromSlot(h);
Yap_RecoverSlots(1, h);
return rc && Yap_unify(tf, rc);

View File

@ -33,9 +33,10 @@ static Int
rl_to_codes(Term TEnd, int do_as_binary, int arity USES_REGS)
{
int sno = Yap_CheckStream (ARG1, Input_Stream_f, "read_line_to_codes/2");
StreamDesc *st = GLOBAL_Stream+sno;
Int status;
UInt max_inp, buf_sz, sz;
char *buf;
int *buf;
bool binary_stream;
if (sno < 0)
@ -47,15 +48,28 @@ rl_to_codes(Term TEnd, int do_as_binary, int arity USES_REGS)
return Yap_unify_constant(ARG2, MkAtomTerm (AtomEof));
}
max_inp = (ASP-HR)/2-1024;
buf = (char *)TR;
buf_sz = (char *)LOCAL_TrailTop-buf;
buf = (int *)TR;
buf_sz = (int *)LOCAL_TrailTop-buf;
while (TRUE) {
if ( buf_sz > max_inp ) {
buf_sz = max_inp;
}
if (do_as_binary && !binary_stream)
if (do_as_binary && !binary_stream) {
GLOBAL_Stream[sno].status |= Binary_Stream_f;
sz = GLOBAL_Stream[sno].stream_gets(sno, buf_sz, buf);
}
if (st->status & Binary_Stream_f) {
char *b = (char *)TR;
sz = fread( b,1 , buf_sz, GLOBAL_Stream[sno].file);
} else {
int ch;
int *pt = buf;
do {
*pt++ = ch = st->stream_wgetc_for_read(sno);
if (pt+1 == buf+buf_sz)
break;
} while (ch != '\n');
sz = pt-buf;
}
if (do_as_binary && !binary_stream)
GLOBAL_Stream[sno].status &= ~Binary_Stream_f;
if (sz == -1 || sz == 0) {
@ -117,7 +131,8 @@ read_line_to_string( USES_REGS1 )
int sno = Yap_CheckStream (ARG1, Input_Stream_f, "read_line_to_codes/2");
Int status;
UInt max_inp, buf_sz;
char *buf;
int *buf;
StreamDesc *st = GLOBAL_Stream+sno;
if (sno < 0)
return FALSE;
@ -127,15 +142,27 @@ read_line_to_string( USES_REGS1 )
return Yap_unify_constant(ARG2, MkAtomTerm (AtomEof));
}
max_inp = (ASP-HR)/2-1024;
buf = (char *)TR;
buf_sz = (char *)LOCAL_TrailTop-buf;
buf = (int *)TR;
buf_sz = (int *)LOCAL_TrailTop-buf;
while (true) {
size_t sz;
if ( buf_sz > max_inp ) {
buf_sz = max_inp;
}
sz = GLOBAL_Stream[sno].stream_gets(sno, buf_sz, buf);
if (st->status & Binary_Stream_f) {
char *b = (char *)TR;
sz = fread( b,1 , buf_sz, GLOBAL_Stream[sno].file);
} else {
int ch;
int *pt = buf;
do {
*pt++ = ch = st->stream_wgetc_for_read(sno);
if (pt+1 == buf+buf_sz)
break;
} while (ch != '\n');
sz = pt-buf;
}
if (sz == -1 || sz == 0) {
if (GLOBAL_Stream[sno].status & Eof_Stream_f) {
UNLOCK(GLOBAL_Stream[sno].streamlock);

View File

@ -103,7 +103,7 @@ SocketGetc(int sno)
#endif
if (count == 0) {
s->u.socket.flags = closed_socket;
return post_process_eof(s);
return EOF;
} else if (count > 0) {
ch = c;
} else {
@ -114,9 +114,9 @@ SocketGetc(int sno)
Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"(socket_getc)");
#endif
return post_process_eof(s);
return EOF;
}
return post_process_read_char(ch, s);
return ch;
}
/*
@ -158,7 +158,7 @@ ConsoleSocketGetc(int sno)
Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "read");
return console_post_process_eof(s);
}
return console_post_process_read_char(ch, s);
return ch;
}
/* static */

View File

@ -140,7 +140,6 @@ int GetFreeStreamD(void) {
LOCK(GLOBAL_Stream[sno].streamlock);
UNLOCK(GLOBAL_StreamDescLock);
GLOBAL_Stream[sno].encoding = LOCAL_encoding;
GLOBAL_Stream[sno].och = '\0';
return sno;
}
@ -648,7 +647,8 @@ static Int cont_stream_property(USES_REGS1) { /* current_stream */
if (p == STREAM_PROPERTY_END ) {
// move to next existing stream
LOCK(GLOBAL_StreamDescLock);
while (++i < MaxStreams && GLOBAL_Stream[i].status & Free_Stream_f) ;
while (++i < MaxStreams && GLOBAL_Stream[i].status & Free_Stream_f)
{}
UNLOCK(GLOBAL_StreamDescLock);
if (i < MaxStreams) {
EXTRA_CBACK_ARG(2, 1) = MkIntTerm(i);
@ -1221,7 +1221,6 @@ static Int
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);
@ -1245,8 +1244,7 @@ static Int
return (FALSE);
}
GLOBAL_Stream[sno].stream_getc = PlGetc;
GLOBAL_Stream[sno].stream_gets = PlGetsFunc();
/* reset the counters */
/* reset the counters */
GLOBAL_Stream[sno].linepos = 0;
GLOBAL_Stream[sno].linecount = 1;
GLOBAL_Stream[sno].charcount = 0;