2001-04-09 20:54:03 +01:00
|
|
|
/*************************************************************************
|
|
|
|
* *
|
|
|
|
* YAP Prolog *
|
|
|
|
* *
|
|
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
|
|
* *
|
|
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
|
|
* *
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
|
|
|
* File: iopreds.c *
|
|
|
|
* Last rev: 5/2/88 *
|
|
|
|
* mods: *
|
|
|
|
* comments: Input/Output C implemented predicates *
|
|
|
|
* *
|
|
|
|
*************************************************************************/
|
|
|
|
#ifdef SCCS
|
|
|
|
static char SccsId[] = "%W% %G%";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file includes the definition of a miscellania of standard predicates
|
|
|
|
* for yap refering to: Files and Streams, Simple Input/Output,
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Yap.h"
|
|
|
|
#include "Yatom.h"
|
2009-10-23 14:22:17 +01:00
|
|
|
#include "YapHeap.h"
|
2001-04-09 20:54:03 +01:00
|
|
|
#include "yapio.h"
|
2010-05-28 15:29:20 +01:00
|
|
|
#include "eval.h"
|
2001-04-09 20:54:03 +01:00
|
|
|
#include <stdlib.h>
|
2001-04-27 17:02:43 +01:00
|
|
|
#if HAVE_STDARG_H
|
|
|
|
#include <stdarg.h>
|
|
|
|
#endif
|
2007-12-29 12:26:41 +00:00
|
|
|
#if HAVE_CTYPE_H
|
|
|
|
#include <ctype.h>
|
|
|
|
#endif
|
|
|
|
#if HAVE_WCTYPE_H
|
|
|
|
#include <wctype.h>
|
|
|
|
#endif
|
2001-04-09 20:54:03 +01:00
|
|
|
#if HAVE_SYS_TIME_H
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif
|
|
|
|
#if HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#endif
|
|
|
|
#if HAVE_SYS_SELECT_H && !_MSC_VER && !defined(__MINGW32__)
|
|
|
|
#include <sys/select.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#if HAVE_STRING_H
|
|
|
|
#include <string.h>
|
|
|
|
#endif
|
2001-06-22 18:53:36 +01:00
|
|
|
#if HAVE_SIGNAL_H
|
|
|
|
#include <signal.h>
|
|
|
|
#endif
|
2001-05-28 20:54:53 +01:00
|
|
|
#if HAVE_FCNTL_H
|
|
|
|
/* for O_BINARY and O_TEXT in WIN32 */
|
|
|
|
#include <fcntl.h>
|
|
|
|
#endif
|
2008-06-05 17:24:08 +01:00
|
|
|
#ifdef _WIN32
|
2001-05-28 20:54:53 +01:00
|
|
|
#if HAVE_IO_H
|
|
|
|
/* Windows */
|
|
|
|
#include <io.h>
|
|
|
|
#endif
|
2008-06-05 17:24:08 +01:00
|
|
|
#endif
|
2001-04-09 20:54:03 +01:00
|
|
|
#if !HAVE_STRNCAT
|
|
|
|
#define strncat(X,Y,Z) strcat(X,Y)
|
|
|
|
#endif
|
|
|
|
#if !HAVE_STRNCPY
|
|
|
|
#define strncpy(X,Y,Z) strcpy(X,Y)
|
|
|
|
#endif
|
2002-08-28 15:02:35 +01:00
|
|
|
#if _MSC_VER || defined(__MINGW32__)
|
2010-07-20 11:28:45 +01:00
|
|
|
#include <windows.h>
|
2001-04-09 20:54:03 +01:00
|
|
|
#ifndef S_ISDIR
|
|
|
|
#define S_ISDIR(x) (((x)&_S_IFDIR)==_S_IFDIR)
|
|
|
|
#endif
|
|
|
|
#endif
|
2002-06-01 02:46:06 +01:00
|
|
|
#include "iopreds.h"
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
STATIC_PROTO (Int PlIOError, (yap_error_number, Term, char *));
|
|
|
|
STATIC_PROTO (int FilePutc, (int, int));
|
2007-01-28 14:26:37 +00:00
|
|
|
STATIC_PROTO (int console_post_process_read_char, (int, StreamDesc *));
|
2006-12-13 16:10:26 +00:00
|
|
|
STATIC_PROTO (int console_post_process_eof, (StreamDesc *));
|
2002-12-06 20:03:26 +00:00
|
|
|
STATIC_PROTO (int post_process_read_char, (int, StreamDesc *));
|
2006-12-13 16:10:26 +00:00
|
|
|
STATIC_PROTO (int post_process_eof, (StreamDesc *));
|
2001-04-09 20:54:03 +01:00
|
|
|
STATIC_PROTO (int ConsolePutc, (int, int));
|
|
|
|
STATIC_PROTO (int PlGetc, (int));
|
2006-08-02 19:18:31 +01:00
|
|
|
STATIC_PROTO (int DefaultGets, (int,UInt,char*));
|
|
|
|
STATIC_PROTO (int PlGets, (int,UInt,char*));
|
2007-01-28 14:26:37 +00:00
|
|
|
STATIC_PROTO (int ISOWGetc, (int));
|
2001-04-09 20:54:03 +01:00
|
|
|
STATIC_PROTO (int ConsoleGetc, (int));
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2001-04-09 20:54:03 +01:00
|
|
|
STATIC_PROTO (int ReadlineGetc, (int));
|
2001-06-11 18:40:16 +01:00
|
|
|
STATIC_PROTO (int ReadlinePutc, (int,int));
|
2001-04-09 20:54:03 +01:00
|
|
|
#endif
|
|
|
|
STATIC_PROTO (int PlUnGetc, (int));
|
|
|
|
STATIC_PROTO (Term MkStream, (int));
|
|
|
|
STATIC_PROTO (int CheckStream, (Term, int, char *));
|
|
|
|
STATIC_PROTO (Int p_close, (void));
|
|
|
|
STATIC_PROTO (Int p_write, (void));
|
|
|
|
STATIC_PROTO (Int p_write2, (void));
|
|
|
|
STATIC_PROTO (Int p_set_read_error_handler, (void));
|
|
|
|
STATIC_PROTO (Int p_get_read_error_handler, (void));
|
|
|
|
STATIC_PROTO (Int p_read, (void));
|
|
|
|
STATIC_PROTO (Int p_past_eof, (void));
|
|
|
|
STATIC_PROTO (Int p_skip, (void));
|
|
|
|
STATIC_PROTO (Int p_write_depth, (void));
|
|
|
|
STATIC_PROTO (Int p_user_file_name, (void));
|
|
|
|
STATIC_PROTO (Int p_format, (void));
|
|
|
|
STATIC_PROTO (Int p_startline, (void));
|
|
|
|
STATIC_PROTO (Int p_change_type_of_char, (void));
|
|
|
|
STATIC_PROTO (Int p_type_of_char, (void));
|
2002-11-11 17:38:10 +00:00
|
|
|
STATIC_PROTO (void CloseStream, (int));
|
2007-01-28 14:26:37 +00:00
|
|
|
STATIC_PROTO (int get_wchar, (int));
|
|
|
|
STATIC_PROTO (int put_wchar, (int,wchar_t));
|
2008-02-12 17:03:59 +00:00
|
|
|
STATIC_PROTO (Term StreamPosition, (int));
|
2006-11-27 17:42:03 +00:00
|
|
|
|
|
|
|
static encoding_t
|
|
|
|
DefaultEncoding(void)
|
|
|
|
{
|
|
|
|
char *s = getenv("LANG");
|
2009-05-02 16:54:09 +01:00
|
|
|
size_t sz;
|
|
|
|
|
2010-05-05 12:45:11 +01:00
|
|
|
/* if we don't have a LANG then just use ISO_LATIN1 */
|
|
|
|
if (s == NULL)
|
|
|
|
s = getenv("LC_CTYPE");
|
2006-11-27 17:42:03 +00:00
|
|
|
if (s == NULL)
|
|
|
|
return ENC_ISO_LATIN1;
|
2009-05-02 16:54:09 +01:00
|
|
|
sz = strlen(s);
|
2010-05-05 12:45:11 +01:00
|
|
|
if (sz >= 5) {
|
2006-11-27 17:42:03 +00:00
|
|
|
if (s[sz-5] == 'U' &&
|
|
|
|
s[sz-4] == 'T' &&
|
|
|
|
s[sz-3] == 'F' &&
|
|
|
|
s[sz-2] == '-' &&
|
|
|
|
s[sz-1] == '8') {
|
|
|
|
return ENC_ISO_UTF8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ENC_ISO_ANSI;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2004-06-09 04:32:03 +01:00
|
|
|
static int
|
|
|
|
GetFreeStreamD(void)
|
|
|
|
{
|
|
|
|
int sno;
|
|
|
|
|
2010-07-26 12:54:22 +01:00
|
|
|
for (sno = 0; sno < MaxStreams; ++sno) {
|
|
|
|
LOCK(Stream[sno].streamlock);
|
|
|
|
if (Stream[sno].status & Free_Stream_f) {
|
2004-06-09 04:32:03 +01:00
|
|
|
break;
|
2010-07-26 12:54:22 +01:00
|
|
|
}
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
}
|
2004-06-09 04:32:03 +01:00
|
|
|
if (sno == MaxStreams) {
|
|
|
|
return -1;
|
|
|
|
}
|
2007-02-18 00:26:36 +00:00
|
|
|
Stream[sno].encoding = DefaultEncoding();
|
2004-06-09 04:32:03 +01:00
|
|
|
return sno;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
Yap_GetFreeStreamD(void)
|
|
|
|
{
|
|
|
|
return GetFreeStreamD();
|
|
|
|
}
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
/* used from C-interface */
|
|
|
|
int
|
|
|
|
Yap_GetFreeStreamDForReading(void)
|
|
|
|
{
|
|
|
|
int sno = GetFreeStreamD();
|
|
|
|
StreamDesc *s;
|
|
|
|
|
|
|
|
if (sno < 0) return sno;
|
|
|
|
s = Stream+sno;
|
|
|
|
s->status |= User_Stream_f|Input_Stream_f;
|
2010-03-23 16:15:55 +00:00
|
|
|
s->charcount = 0;
|
|
|
|
s->linecount = 1;
|
|
|
|
s->linepos = 0;
|
2006-11-27 17:42:03 +00:00
|
|
|
s->stream_wgetc = get_wchar;
|
|
|
|
s->encoding = DefaultEncoding();
|
|
|
|
if (CharConversionTable != NULL)
|
|
|
|
s->stream_wgetc_for_read = ISOWGetc;
|
|
|
|
else
|
|
|
|
s->stream_wgetc_for_read = s->stream_wgetc;
|
2010-07-26 12:54:22 +01:00
|
|
|
UNLOCK(s->streamlock);
|
2006-11-27 17:42:03 +00:00
|
|
|
return sno;
|
|
|
|
}
|
|
|
|
|
2004-06-09 04:32:03 +01:00
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static void
|
|
|
|
unix_upd_stream_info (StreamDesc * s)
|
|
|
|
{
|
2004-05-17 22:42:12 +01:00
|
|
|
#if _MSC_VER || defined(__MINGW32__)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2004-05-17 22:42:12 +01:00
|
|
|
if (
|
|
|
|
_isatty(_fileno(s->u.file.file))
|
|
|
|
) {
|
2001-08-09 15:00:51 +01:00
|
|
|
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);
|
2010-03-04 00:50:56 +00:00
|
|
|
return;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-05-17 22:42:12 +01:00
|
|
|
#if _MSC_VER
|
2002-12-10 19:08:25 +00:00
|
|
|
/* standard error stream should never be buffered */
|
2004-05-17 22:42:12 +01:00
|
|
|
else if (StdErrStream == s-Stream) {
|
2002-12-10 19:08:25 +00:00
|
|
|
setvbuf(s->u.file.file, NULL, _IONBF, 0);
|
|
|
|
}
|
2004-05-17 22:42:12 +01:00
|
|
|
#endif
|
2010-03-04 00:50:56 +00:00
|
|
|
s->status |= Seekable_Stream_f;
|
2001-04-09 20:54:03 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#if HAVE_ISATTY
|
2002-01-23 02:28:31 +00:00
|
|
|
#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) {
|
2008-12-23 01:53:52 +00:00
|
|
|
s->u.file.name = AtomTty;
|
2002-01-23 02:28:31 +00:00
|
|
|
s->status |= Tty_Stream_f|Reset_Eof_Stream_f|Promptable_Stream_f;
|
|
|
|
}
|
|
|
|
#else
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
|
|
|
int filedes; /* visualc */
|
|
|
|
filedes = YP_fileno (s->u.file.file);
|
2001-04-27 17:02:43 +01:00
|
|
|
if (isatty (filedes)) {
|
2002-08-19 00:18:18 +01:00
|
|
|
#if HAVE_TTYNAME
|
2001-04-09 20:54:03 +01:00
|
|
|
char *ttys = ttyname(filedes);
|
|
|
|
if (ttys == NULL)
|
2008-12-23 01:53:52 +00:00
|
|
|
s->u.file.name = AtomTty;
|
2001-04-09 20:54:03 +01:00
|
|
|
else
|
2008-12-23 01:53:52 +00:00
|
|
|
s->u.file.name = AtomTtys;
|
2002-08-19 00:18:18 +01:00
|
|
|
#else
|
2008-12-23 01:53:52 +00:00
|
|
|
s->u.file.name = AtomTty;
|
2002-08-19 00:18:18 +01:00
|
|
|
#endif
|
2001-04-09 20:54:03 +01:00
|
|
|
s->status |= Tty_Stream_f|Reset_Eof_Stream_f|Promptable_Stream_f;
|
|
|
|
return;
|
2001-04-27 17:02:43 +01:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2002-01-23 02:28:31 +00:00
|
|
|
#endif
|
2001-04-09 20:54:03 +01:00
|
|
|
#endif /* HAVE_ISATTY */
|
|
|
|
#endif /* _MSC_VER */
|
|
|
|
s->status |= Seekable_Stream_f;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_always_prompt_user(void)
|
|
|
|
{
|
|
|
|
StreamDesc *s = Stream+StdInStream;
|
|
|
|
|
|
|
|
s->status |= Promptable_Stream_f;
|
2006-08-02 19:18:31 +01:00
|
|
|
s->stream_gets = DefaultGets;
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2001-04-09 20:54:03 +01:00
|
|
|
if (s->status & Tty_Stream_f) {
|
|
|
|
s->stream_getc = ReadlineGetc;
|
2001-06-11 18:47:02 +01:00
|
|
|
if (Stream[0].status & Tty_Stream_f &&
|
2001-06-11 18:40:16 +01:00
|
|
|
s->u.file.name == Stream[0].u.file.name)
|
|
|
|
s->stream_putc = ReadlinePutc;
|
2006-11-27 17:42:03 +00:00
|
|
|
s->stream_wputc = put_wchar;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
/* else just PlGet plus checking for prompt */
|
|
|
|
s->stream_getc = ConsoleGetc;
|
|
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
2002-05-28 17:26:00 +01:00
|
|
|
static int
|
|
|
|
is_same_tty(YP_File f1, YP_File f2)
|
|
|
|
{
|
|
|
|
#if HAVE_TTYNAME
|
2002-12-06 20:03:26 +00:00
|
|
|
return(ttyname(YP_fileno(f1)) == ttyname(YP_fileno(f2)));
|
2002-05-28 17:26:00 +01:00
|
|
|
#else
|
|
|
|
return(TRUE);
|
|
|
|
#endif
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2006-08-02 19:18:31 +01:00
|
|
|
static GetsFunc
|
|
|
|
PlGetsFunc(void)
|
|
|
|
{
|
|
|
|
if (CharConversionTable)
|
|
|
|
return DefaultGets;
|
|
|
|
else
|
|
|
|
return PlGets;
|
|
|
|
}
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
static void
|
2002-05-28 17:26:00 +01:00
|
|
|
InitStdStreams (void)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_c_input_stream = StdInStream;
|
|
|
|
Yap_c_output_stream = StdOutStream;
|
|
|
|
Yap_c_error_stream = StdErrStream;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2002-05-28 17:26:00 +01:00
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitStdStreams (void)
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
|
|
|
InitStdStreams();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-05-28 17:26:00 +01:00
|
|
|
InitPlIO (void)
|
|
|
|
{
|
|
|
|
Int i;
|
|
|
|
|
2010-02-10 09:03:03 +00:00
|
|
|
for (i = 0; i < MaxStreams; ++i) {
|
|
|
|
INIT_LOCK(Stream[i].streamlock);
|
2002-05-28 17:26:00 +01:00
|
|
|
Stream[i].status = Free_Stream_f;
|
2010-02-10 09:03:03 +00:00
|
|
|
}
|
2002-05-28 17:26:00 +01:00
|
|
|
InitStdStreams();
|
|
|
|
}
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitPlIO (void)
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
|
|
|
InitPlIO ();
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static Int
|
|
|
|
PlIOError (yap_error_number type, Term culprit, char *who)
|
|
|
|
{
|
2009-06-12 19:46:44 +01:00
|
|
|
if (Yap_GetValue(AtomFileerrors) == MkIntTerm(1) ||
|
|
|
|
type == RESOURCE_ERROR_MAX_STREAMS /* do not catch resource errors */) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(type, culprit, who);
|
2001-04-09 20:54:03 +01:00
|
|
|
/* and fail */
|
2005-02-08 18:14:30 +00:00
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else {
|
2005-02-08 18:14:30 +00:00
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Used by the prompts to check if they are after a newline, and then a
|
2001-08-08 22:17:27 +01:00
|
|
|
* prompt should be output, or if we are in the middle of a line.
|
2001-04-09 20:54:03 +01:00
|
|
|
*/
|
2002-11-11 17:38:10 +00:00
|
|
|
static int newline = TRUE;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
static void
|
2002-12-06 20:03:26 +00:00
|
|
|
count_output_char(int ch, StreamDesc *s)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
|
|
|
if (ch == '\n')
|
|
|
|
{
|
|
|
|
#if MPWSHELL
|
|
|
|
if (mpwshell && (sno == StdOutStream || sno ==
|
2011-02-12 23:45:19 +00:00
|
|
|
StdErrStream))
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2001-04-27 17:02:43 +01:00
|
|
|
putc (MPWSEP, s->u.file.file);
|
2011-02-12 23:45:19 +00:00
|
|
|
fflush (stdout);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* Inform that we have written a newline */
|
|
|
|
++s->charcount;
|
|
|
|
++s->linecount;
|
|
|
|
s->linepos = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#if MAC
|
|
|
|
if ((sno == StdOutStream || sno == StdErrStream)
|
|
|
|
&& s->linepos > 200)
|
|
|
|
sno->stream_putc(sno, '\n');
|
|
|
|
#endif
|
|
|
|
++s->charcount;
|
|
|
|
++s->linepos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-12-06 20:03:26 +00:00
|
|
|
console_count_output_char(int ch, StreamDesc *s)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
|
|
|
if (ch == '\n')
|
|
|
|
{
|
|
|
|
#if MPWSHELL
|
|
|
|
if (mpwshell && (sno == StdOutStream || sno ==
|
2011-02-12 23:45:19 +00:00
|
|
|
StdErrStream))
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2001-04-27 17:02:43 +01:00
|
|
|
putc (MPWSEP, s->u.file.file);
|
2011-02-12 23:45:19 +00:00
|
|
|
fflush (stdout);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
++s->charcount;
|
|
|
|
++s->linecount;
|
|
|
|
s->linepos = 0;
|
|
|
|
newline = TRUE;
|
|
|
|
/* Inform we are not at the start of a newline */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
newline = FALSE;
|
|
|
|
#if MAC
|
|
|
|
if ((sno == StdOutStream || sno == StdErrStream)
|
|
|
|
&& s->linepos > 200)
|
|
|
|
sno->stream_putc(sno, '\n');
|
|
|
|
#endif
|
|
|
|
++s->charcount;
|
|
|
|
++s->linepos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
|
|
|
|
static int eolflg = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char my_line[200] = {0};
|
|
|
|
static char *lp = my_line;
|
|
|
|
|
|
|
|
static YP_File curfile;
|
|
|
|
|
|
|
|
#ifdef MACC
|
|
|
|
|
|
|
|
static void
|
|
|
|
InTTYLine(char *line)
|
|
|
|
{
|
|
|
|
char *p = line;
|
|
|
|
char ch;
|
|
|
|
while ((ch = InKey()) != '\n' && ch != '\r')
|
|
|
|
if (ch == 8) {
|
|
|
|
if (line < p)
|
|
|
|
BackupTTY(*--p);
|
|
|
|
} else
|
|
|
|
TTYChar(*p++ = ch);
|
|
|
|
TTYChar('\n');
|
|
|
|
*p = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_DebugSetIFile(char *fname)
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
|
|
|
if (curfile)
|
|
|
|
YP_fclose(curfile);
|
|
|
|
curfile = YP_fopen(fname, "r");
|
|
|
|
if (curfile == NULL) {
|
|
|
|
curfile = stdin;
|
2004-06-23 18:24:20 +01:00
|
|
|
fprintf(stderr,"%% YAP Warning: can not open %s for input\n", fname);
|
2002-11-11 17:38:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_DebugEndline()
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
|
|
|
*lp = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_DebugGetc()
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
|
|
|
int ch;
|
|
|
|
if (eolflg) {
|
|
|
|
if (curfile != NULL) {
|
|
|
|
if (YP_fgets(my_line, 200, curfile) == 0)
|
|
|
|
curfile = NULL;
|
|
|
|
}
|
|
|
|
if (curfile == NULL)
|
2010-01-14 15:43:18 +00:00
|
|
|
if (YP_fgets(my_line, 200, stdin) == NULL) {
|
|
|
|
return EOF;
|
|
|
|
}
|
2002-11-11 17:38:10 +00:00
|
|
|
eolflg = 0;
|
|
|
|
lp = my_line;
|
|
|
|
}
|
|
|
|
if ((ch = *lp++) == 0)
|
|
|
|
ch = '\n', eolflg = 1;
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_Option['l' - 96])
|
|
|
|
putc(ch, Yap_logfile);
|
2002-11-11 17:38:10 +00:00
|
|
|
return (ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2007-01-28 14:26:37 +00:00
|
|
|
Yap_DebugPutc(int sno, wchar_t ch)
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_Option['l' - 96])
|
|
|
|
(void) putc(ch, Yap_logfile);
|
|
|
|
return (putc(ch, Yap_stderr));
|
2002-11-11 17:38:10 +00:00
|
|
|
}
|
2005-12-05 17:16:12 +00:00
|
|
|
|
2008-02-01 22:40:05 +00:00
|
|
|
void
|
|
|
|
Yap_DebugPlWrite(Term t)
|
|
|
|
{
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite(t, Yap_DebugPutc, 0, 1200);
|
2008-02-01 22:40:05 +00:00
|
|
|
}
|
|
|
|
|
2011-02-12 18:42:44 +00:00
|
|
|
void
|
|
|
|
Yap_PlWriteToStream(Term t, int sno, int flags)
|
|
|
|
{
|
|
|
|
Yap_plwrite(t, Stream[sno].stream_wputc, flags, 1200);
|
|
|
|
}
|
|
|
|
|
2005-12-05 17:16:12 +00:00
|
|
|
void
|
|
|
|
Yap_DebugErrorPutc(int c)
|
|
|
|
{
|
|
|
|
Yap_DebugPutc (Yap_c_error_stream, c);
|
|
|
|
}
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
#endif
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
/* static */
|
|
|
|
static int
|
|
|
|
FilePutc(int sno, int ch)
|
|
|
|
{
|
|
|
|
StreamDesc *s = &Stream[sno];
|
|
|
|
#if MAC || _MSC_VER
|
|
|
|
if (ch == 10)
|
|
|
|
{
|
|
|
|
ch = '\n';
|
|
|
|
}
|
|
|
|
#endif
|
2001-04-27 17:02:43 +01:00
|
|
|
putc(ch, s->u.file.file);
|
|
|
|
#if MAC || _MSC_VER
|
|
|
|
if (ch == 10)
|
|
|
|
{
|
|
|
|
fflush(s->u.file.file);
|
|
|
|
}
|
|
|
|
#endif
|
2002-12-06 20:03:26 +00:00
|
|
|
count_output_char(ch,s);
|
2001-04-09 20:54:03 +01:00
|
|
|
return ((int) ch);
|
|
|
|
}
|
|
|
|
|
2010-06-23 11:46:16 +01:00
|
|
|
/* static */
|
|
|
|
static int
|
|
|
|
IOSWIPutc(int sno, int ch)
|
|
|
|
{
|
2010-07-19 14:40:52 +01:00
|
|
|
int i;
|
|
|
|
Yap_StartSlots();
|
|
|
|
i = (SWIPutc)(ch, Stream[sno].u.swi_stream.swi_ptr);
|
|
|
|
Yap_CloseSlots();
|
|
|
|
YENV = ENV;
|
|
|
|
return i;
|
2010-06-23 11:46:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
static int
|
2010-07-19 22:42:19 +01:00
|
|
|
IOSWIGetc(int sno)
|
2010-06-23 11:46:16 +01:00
|
|
|
{
|
2010-12-19 14:10:25 +00:00
|
|
|
int ch;
|
2010-07-19 14:40:52 +01:00
|
|
|
Yap_StartSlots();
|
2010-12-19 14:10:25 +00:00
|
|
|
ch = (SWIGetc)(Stream[sno].u.swi_stream.swi_ptr);
|
|
|
|
if (ch == EOF) {
|
|
|
|
return post_process_eof(Stream+sno);
|
|
|
|
}
|
|
|
|
return post_process_read_char(ch, Stream+sno);
|
2010-07-19 14:40:52 +01:00
|
|
|
Yap_CloseSlots();
|
|
|
|
YENV = ENV;
|
2010-12-19 14:10:25 +00:00
|
|
|
return ch;
|
2010-06-23 11:46:16 +01:00
|
|
|
}
|
|
|
|
|
2010-07-21 10:58:24 +01:00
|
|
|
/* static */
|
|
|
|
static int
|
|
|
|
IOSWIWidePutc(int sno, int ch)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
Yap_StartSlots();
|
|
|
|
i = (SWIWidePutc)(ch, Stream[sno].u.swi_stream.swi_ptr);
|
|
|
|
Yap_CloseSlots();
|
|
|
|
YENV = ENV;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
static int
|
|
|
|
IOSWIWideGetc(int sno)
|
|
|
|
{
|
2010-12-19 14:10:25 +00:00
|
|
|
int ch;
|
2010-07-21 10:58:24 +01:00
|
|
|
Yap_StartSlots();
|
2010-12-19 14:10:25 +00:00
|
|
|
ch = (SWIWideGetc)(Stream[sno].u.swi_stream.swi_ptr);
|
|
|
|
if (ch == EOF) {
|
|
|
|
return post_process_eof(Stream+sno);
|
|
|
|
}
|
|
|
|
return post_process_read_char(ch, Stream+sno);
|
2010-07-21 10:58:24 +01:00
|
|
|
Yap_CloseSlots();
|
|
|
|
YENV = ENV;
|
2010-12-19 14:10:25 +00:00
|
|
|
return ch;
|
2010-07-21 10:58:24 +01:00
|
|
|
}
|
|
|
|
|
2001-05-21 21:00:05 +01:00
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
/* static */
|
|
|
|
static int
|
|
|
|
ConsolePutc (int sno, int ch)
|
|
|
|
{
|
|
|
|
StreamDesc *s = &Stream[sno];
|
2002-12-10 19:08:25 +00:00
|
|
|
#if MAC || _MSC_VER || defined(__MINGW32__)
|
2001-04-09 20:54:03 +01:00
|
|
|
if (ch == 10)
|
|
|
|
{
|
2002-12-10 19:08:25 +00:00
|
|
|
putc ('\n', s->u.file.file);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2002-12-10 19:08:25 +00:00
|
|
|
else
|
2001-04-09 20:54:03 +01:00
|
|
|
#endif
|
2002-12-10 19:08:25 +00:00
|
|
|
putc (ch, s->u.file.file);
|
2002-12-06 20:03:26 +00:00
|
|
|
console_count_output_char(ch,s);
|
2001-04-09 20:54:03 +01:00
|
|
|
return ((int) ch);
|
|
|
|
}
|
|
|
|
|
2003-02-24 11:01:01 +00:00
|
|
|
static Int
|
|
|
|
p_is_same_tty (void)
|
|
|
|
{ /* 'prompt(Atom) */
|
|
|
|
int sni = CheckStream (ARG1, Input_Stream_f, "put/2");
|
|
|
|
int sno = CheckStream (ARG2, Output_Stream_f, "put/2");
|
2006-04-28 16:48:33 +01:00
|
|
|
int out = (Stream[sni].status & Tty_Stream_f) &&
|
|
|
|
(Stream[sno].status & Tty_Stream_f) &&
|
|
|
|
is_same_tty(Stream[sno].u.file.file,Stream[sni].u.file.file);
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
UNLOCK(Stream[sni].streamlock);
|
|
|
|
return out;
|
2003-02-24 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2002-12-10 14:44:47 +00:00
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
#include <readline/readline.h>
|
2006-05-02 15:05:13 +01:00
|
|
|
#include <readline/history.h>
|
2002-12-10 14:44:47 +00:00
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static char *ttyptr = NULL;
|
|
|
|
|
2002-11-19 17:10:45 +00:00
|
|
|
static char *myrl_line = (char *) NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2001-06-11 18:40:16 +01:00
|
|
|
static int cur_out_sno = 2;
|
|
|
|
|
|
|
|
#define READLINE_OUT_BUF_MAX 256
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static void
|
|
|
|
InitReadline(void) {
|
2002-11-18 18:18:05 +00:00
|
|
|
ReadlineBuf = (char *)Yap_AllocAtomSpace(READLINE_OUT_BUF_MAX+1);
|
2001-06-11 18:40:16 +01:00
|
|
|
ReadlinePos = ReadlineBuf;
|
2001-06-22 18:53:36 +01:00
|
|
|
#if _MSC_VER || defined(__MINGW32__)
|
|
|
|
rl_instream = stdin;
|
|
|
|
rl_outstream = stdout;
|
|
|
|
#endif
|
2001-06-11 18:40:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ReadlinePutc (int sno, int ch)
|
|
|
|
{
|
|
|
|
if (ReadlinePos != ReadlineBuf &&
|
2001-06-12 18:25:28 +01:00
|
|
|
(ReadlinePos - ReadlineBuf == READLINE_OUT_BUF_MAX-1 /* overflow */ ||
|
2001-06-11 18:40:16 +01:00
|
|
|
#if MAC || _MSC_VER
|
|
|
|
ch == 10 ||
|
|
|
|
#endif
|
|
|
|
ch == '\n')) {
|
|
|
|
#if MAC || _MSC_VER
|
|
|
|
if (ch == 10)
|
|
|
|
{
|
|
|
|
ch = '\n';
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (ch == '\n') {
|
|
|
|
ReadlinePos[0] = '\n';
|
|
|
|
ReadlinePos++;
|
|
|
|
}
|
|
|
|
ReadlinePos[0] = '\0';
|
|
|
|
fputs( ReadlineBuf, Stream[sno].u.file.file);
|
|
|
|
ReadlinePos = ReadlineBuf;
|
|
|
|
if (ch == '\n') {
|
2002-12-06 20:03:26 +00:00
|
|
|
console_count_output_char(ch,Stream+sno);
|
2001-06-11 18:40:16 +01:00
|
|
|
return((int) '\n');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*ReadlinePos++ = ch;
|
2002-12-06 20:03:26 +00:00
|
|
|
console_count_output_char(ch,Stream+sno);
|
2001-06-11 18:40:16 +01:00
|
|
|
return ((int) ch);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
reading from the console is complicated because we need to
|
|
|
|
know whether to prompt and so on...
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ReadlineGetc(int sno)
|
|
|
|
{
|
|
|
|
register StreamDesc *s = &Stream[sno];
|
2006-12-13 16:10:26 +00:00
|
|
|
register wchar_t ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2001-08-08 22:17:27 +01:00
|
|
|
while (ttyptr == NULL) {
|
2001-04-09 20:54:03 +01:00
|
|
|
/* Only sends a newline if we are at the start of a line */
|
2009-02-09 21:56:40 +00:00
|
|
|
if (myrl_line) {
|
2002-11-19 17:10:45 +00:00
|
|
|
free (myrl_line);
|
2009-02-09 21:56:40 +00:00
|
|
|
myrl_line = NULL;
|
|
|
|
}
|
2001-06-11 18:40:16 +01:00
|
|
|
rl_instream = Stream[sno].u.file.file;
|
|
|
|
rl_outstream = Stream[cur_out_sno].u.file.file;
|
2001-04-09 20:54:03 +01:00
|
|
|
/* window of vulnerability opened */
|
|
|
|
if (newline) {
|
2011-02-14 15:19:37 +00:00
|
|
|
Yap_PrologMode |= ConsoleGetcMode;
|
|
|
|
myrl_line = readline (NULL);
|
2001-04-09 20:54:03 +01:00
|
|
|
} else {
|
2001-06-11 18:40:16 +01:00
|
|
|
if (ReadlinePos != ReadlineBuf) {
|
|
|
|
ReadlinePos[0] = '\0';
|
|
|
|
ReadlinePos = ReadlineBuf;
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_PrologMode |= ConsoleGetcMode;
|
2002-11-19 17:10:45 +00:00
|
|
|
myrl_line = readline (ReadlineBuf);
|
2001-06-11 18:40:16 +01:00
|
|
|
} else {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_PrologMode |= ConsoleGetcMode;
|
2002-11-19 17:10:45 +00:00
|
|
|
myrl_line = readline (NULL);
|
2001-06-11 18:40:16 +01:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2001-09-21 15:22:32 +01:00
|
|
|
/* Do it the gnu way */
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_PrologMode & InterruptMode) {
|
|
|
|
Yap_PrologMode &= ~InterruptMode;
|
|
|
|
Yap_ProcessSIGINT();
|
|
|
|
Yap_PrologMode &= ~ConsoleGetcMode;
|
|
|
|
if (Yap_PrologMode & AbortMode) {
|
|
|
|
Yap_Error(PURE_ABORT, TermNil, "");
|
|
|
|
Yap_ErrorMessage = "Abort";
|
2006-12-13 16:10:26 +00:00
|
|
|
return console_post_process_eof(s);
|
2001-09-21 15:22:32 +01:00
|
|
|
}
|
|
|
|
continue;
|
2002-02-12 18:24:21 +00:00
|
|
|
} else {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_PrologMode &= ~ConsoleGetcMode;
|
2001-09-21 15:22:32 +01:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
newline=FALSE;
|
2009-10-30 23:59:00 +00:00
|
|
|
strncpy (Prompt, RepAtom (AtPrompt)->StrOfAE, MAX_PROMPT);
|
2001-04-09 20:54:03 +01:00
|
|
|
/* window of vulnerability closed */
|
2006-11-27 17:42:03 +00:00
|
|
|
if (myrl_line == NULL)
|
2006-12-13 16:10:26 +00:00
|
|
|
return console_post_process_eof(s);
|
2002-11-19 17:10:45 +00:00
|
|
|
if (myrl_line[0] != '\0' && myrl_line[1] != '\0')
|
|
|
|
add_history (myrl_line);
|
|
|
|
ttyptr = myrl_line;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
if (*ttyptr == '\0') {
|
|
|
|
ttyptr = NIL;
|
|
|
|
ch = '\n';
|
|
|
|
} else {
|
2006-11-27 17:42:03 +00:00
|
|
|
ch = *((unsigned char *)ttyptr);
|
|
|
|
ttyptr++;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2006-12-13 16:10:26 +00:00
|
|
|
return console_post_process_read_char(ch, s);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2002-11-12 10:29:31 +00:00
|
|
|
#endif /* HAVE_LIBREADLINE */
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2007-08-02 18:22:00 +01:00
|
|
|
static Int
|
|
|
|
p_has_readline(void)
|
|
|
|
{
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2007-08-02 18:22:00 +01:00
|
|
|
return TRUE;
|
|
|
|
#else
|
|
|
|
return FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2002-11-12 10:29:31 +00:00
|
|
|
int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_GetCharForSIGINT(void)
|
2002-11-12 10:29:31 +00:00
|
|
|
{
|
2007-01-28 14:26:37 +00:00
|
|
|
int ch;
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2002-11-19 17:10:45 +00:00
|
|
|
if ((Yap_PrologMode & ConsoleGetcMode) && myrl_line != (char *) NULL) {
|
|
|
|
ch = myrl_line[0];
|
|
|
|
free(myrl_line);
|
|
|
|
myrl_line = NULL;
|
2002-11-12 10:29:31 +00:00
|
|
|
} else {
|
2002-11-19 17:10:45 +00:00
|
|
|
myrl_line = readline ("Action (h for help): ");
|
2006-11-27 17:42:03 +00:00
|
|
|
if (!myrl_line) {
|
2002-11-12 10:29:31 +00:00
|
|
|
ch = EOF;
|
|
|
|
} else {
|
2002-11-19 17:10:45 +00:00
|
|
|
ch = myrl_line[0];
|
|
|
|
free(myrl_line);
|
|
|
|
myrl_line = NULL;
|
2002-11-12 10:29:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
/* ask for a new line */
|
|
|
|
fprintf(stderr, "Action (h for help): ");
|
|
|
|
ch = getc(stdin);
|
|
|
|
/* first process up to end of line */
|
|
|
|
while ((fgetc(stdin)) != '\n');
|
|
|
|
#endif
|
|
|
|
newline = TRUE;
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
/* handle reading from a stream after having found an EOF */
|
|
|
|
static int
|
|
|
|
EOFGetc(int sno)
|
|
|
|
{
|
|
|
|
register StreamDesc *s = &Stream[sno];
|
|
|
|
|
|
|
|
if (s->status & Push_Eof_Stream_f) {
|
|
|
|
/* ok, we have pushed an EOF, send it away */
|
|
|
|
s->status &= ~Push_Eof_Stream_f;
|
2006-11-27 17:42:03 +00:00
|
|
|
return EOF;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
if (s->status & Eof_Error_Stream_f) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,MkAtomTerm(s->u.file.name),
|
2001-04-09 20:54:03 +01:00
|
|
|
"GetC");
|
|
|
|
} else if (s->status & Reset_Eof_Stream_f) {
|
|
|
|
/* reset the eof indicator on file */
|
|
|
|
if (YP_feof (s->u.file.file))
|
|
|
|
YP_clearerr (s->u.file.file);
|
|
|
|
/* reset our function for reading input */
|
2011-02-12 23:42:15 +00:00
|
|
|
if (s->status & Promptable_Stream_f) {
|
2001-04-09 20:54:03 +01:00
|
|
|
s->stream_putc = ConsolePutc;
|
2006-11-27 17:42:03 +00:00
|
|
|
s->stream_wputc = put_wchar;
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2001-04-09 20:54:03 +01:00
|
|
|
if (s->status & Tty_Stream_f) {
|
|
|
|
s->stream_getc = ReadlineGetc;
|
2001-06-11 18:47:02 +01:00
|
|
|
if (Stream[0].status & Tty_Stream_f &&
|
2002-05-28 17:26:00 +01:00
|
|
|
is_same_tty(s->u.file.file,Stream[0].u.file.file))
|
2001-06-11 18:40:16 +01:00
|
|
|
s->stream_putc = ReadlinePutc;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
s->stream_getc = ConsoleGetc;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
s->stream_getc = PlGetc;
|
2006-08-02 19:18:31 +01:00
|
|
|
s->stream_gets = PlGetsFunc();
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2010-07-21 10:58:24 +01:00
|
|
|
if (s->status & SWI_Stream_f)
|
|
|
|
s->stream_wgetc = IOSWIWideGetc;
|
|
|
|
else
|
|
|
|
s->stream_wgetc = get_wchar;
|
2001-04-09 20:54:03 +01:00
|
|
|
if (CharConversionTable != NULL)
|
2006-11-27 17:42:03 +00:00
|
|
|
s->stream_wgetc_for_read = ISOWGetc;
|
2001-04-09 20:54:03 +01:00
|
|
|
else
|
2006-11-27 17:42:03 +00:00
|
|
|
s->stream_wgetc_for_read = s->stream_wgetc;
|
2001-04-09 20:54:03 +01:00
|
|
|
/* next, reset our own error indicator */
|
|
|
|
s->status &= ~Eof_Stream_f;
|
|
|
|
/* try reading again */
|
|
|
|
return(s->stream_getc(sno));
|
|
|
|
} else {
|
|
|
|
s->status |= Past_Eof_Stream_f;
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
return EOF;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check if we read a newline or an EOF */
|
|
|
|
static int
|
2002-12-06 20:03:26 +00:00
|
|
|
post_process_read_char(int ch, StreamDesc *s)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2006-12-13 16:10:26 +00:00
|
|
|
++s->charcount;
|
|
|
|
++s->linepos;
|
2001-04-09 20:54:03 +01:00
|
|
|
if (ch == '\n') {
|
|
|
|
++s->linecount;
|
|
|
|
s->linepos = 0;
|
|
|
|
/* don't convert if the stream is binary */
|
2002-12-06 20:03:26 +00:00
|
|
|
if (!(s->status & Binary_Stream_f))
|
2001-04-09 20:54:03 +01:00
|
|
|
ch = 10;
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
return ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check if we read a newline or an EOF */
|
|
|
|
static int
|
2006-12-13 16:10:26 +00:00
|
|
|
post_process_eof(StreamDesc *s)
|
|
|
|
{
|
|
|
|
s->status |= Eof_Stream_f;
|
|
|
|
s->stream_getc = EOFGetc;
|
|
|
|
s->stream_wgetc = get_wchar;
|
|
|
|
if (CharConversionTable != NULL)
|
|
|
|
s->stream_wgetc_for_read = ISOWGetc;
|
|
|
|
else
|
|
|
|
s->stream_wgetc_for_read = s->stream_wgetc;
|
|
|
|
return EOFCHAR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check if we read a newline or an EOF */
|
|
|
|
static int
|
2007-01-28 14:26:37 +00:00
|
|
|
console_post_process_read_char(int ch, StreamDesc *s)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2008-02-22 15:08:37 +00:00
|
|
|
/* the character is also going to be output by the console handler */
|
|
|
|
console_count_output_char(ch,Stream+StdErrStream);
|
2001-04-09 20:54:03 +01:00
|
|
|
if (ch == '\n') {
|
|
|
|
++s->linecount;
|
|
|
|
++s->charcount;
|
|
|
|
s->linepos = 0;
|
|
|
|
newline = TRUE;
|
|
|
|
} else {
|
|
|
|
++s->charcount;
|
|
|
|
++s->linepos;
|
|
|
|
newline = FALSE;
|
|
|
|
}
|
2006-12-13 16:10:26 +00:00
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check if we read a newline or an EOF */
|
|
|
|
static int
|
|
|
|
console_post_process_eof(StreamDesc *s)
|
|
|
|
{
|
|
|
|
s->status |= Eof_Stream_f;
|
|
|
|
s->stream_getc = EOFGetc;
|
|
|
|
s->stream_wgetc = get_wchar;
|
|
|
|
if (CharConversionTable != NULL)
|
|
|
|
s->stream_wgetc_for_read = ISOWGetc;
|
|
|
|
else
|
|
|
|
s->stream_wgetc_for_read = s->stream_wgetc;
|
|
|
|
newline = FALSE;
|
|
|
|
return EOFCHAR;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 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 */
|
|
|
|
static int
|
|
|
|
PlGetc (int sno)
|
|
|
|
{
|
2008-01-28 23:35:04 +00:00
|
|
|
StreamDesc *s = &Stream[sno];
|
|
|
|
Int ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
ch = YP_getc (s->u.file.file);
|
2008-01-28 23:35:04 +00:00
|
|
|
if (ch == EOF) {
|
2006-12-13 16:10:26 +00:00
|
|
|
return post_process_eof(s);
|
2008-01-28 23:35:04 +00:00
|
|
|
}
|
2006-12-13 16:10:26 +00:00
|
|
|
return post_process_read_char(ch, s);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2006-08-02 19:18:31 +01:00
|
|
|
/* 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 */
|
|
|
|
static int
|
|
|
|
PlGets (int sno, UInt size, char *buf)
|
|
|
|
{
|
|
|
|
register StreamDesc *s = &Stream[sno];
|
|
|
|
UInt len;
|
|
|
|
|
2006-12-13 16:10:26 +00:00
|
|
|
if (fgets (buf, size, s->u.file.file) == NULL) {
|
|
|
|
return post_process_eof(s);
|
|
|
|
}
|
2006-08-02 19:18:31 +01:00
|
|
|
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 */
|
|
|
|
static int
|
|
|
|
DefaultGets (int sno, UInt size, char *buf)
|
|
|
|
{
|
|
|
|
StreamDesc *s = &Stream[sno];
|
2006-12-13 16:10:26 +00:00
|
|
|
char ch;
|
2006-08-02 19:18:31 +01:00
|
|
|
char *pt = buf;
|
|
|
|
|
|
|
|
|
|
|
|
if (!size)
|
|
|
|
return 0;
|
|
|
|
while((ch = *buf++ = s->stream_getc(sno)) !=
|
|
|
|
-1 && ch != 10 && --size);
|
|
|
|
*buf++ = '\0';
|
2008-01-28 10:42:20 +00:00
|
|
|
return (buf-pt)-1;
|
2006-08-02 19:18:31 +01:00
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
/* I dispise this code!!!!! */
|
2007-01-28 14:26:37 +00:00
|
|
|
static int
|
2006-11-27 17:42:03 +00:00
|
|
|
ISOWGetc (int sno)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2007-01-28 14:26:37 +00:00
|
|
|
int ch = Stream[sno].stream_wgetc(sno);
|
2001-04-09 20:54:03 +01:00
|
|
|
if (ch != EOF && CharConversionTable != NULL) {
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
if (ch < NUMBER_OF_CHARS) {
|
|
|
|
/* only do this in ASCII */
|
|
|
|
return CharConversionTable[ch];
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
return ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* send a prompt, and use the system for internal buffering. Speed is
|
|
|
|
not of the essence here !!! */
|
|
|
|
static int
|
|
|
|
ConsoleGetc(int sno)
|
|
|
|
{
|
|
|
|
register StreamDesc *s = &Stream[sno];
|
2006-12-13 16:10:26 +00:00
|
|
|
int ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2001-06-22 18:53:36 +01:00
|
|
|
restart:
|
2008-12-22 12:44:49 +00:00
|
|
|
/* keep the prompt around, just in case, but don't actually
|
|
|
|
show it in silent mode */
|
2001-04-09 20:54:03 +01:00
|
|
|
if (newline) {
|
2008-12-22 12:44:49 +00:00
|
|
|
if (!yap_flags[QUIET_MODE_FLAG]) {
|
|
|
|
char *cptr = Prompt, ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2008-12-22 12:44:49 +00:00
|
|
|
/* use the default routine */
|
|
|
|
while ((ch = *cptr++) != '\0') {
|
|
|
|
Stream[StdErrStream].stream_putc(StdErrStream, ch);
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2009-10-30 23:59:00 +00:00
|
|
|
strncpy (Prompt, RepAtom (AtPrompt)->StrOfAE, MAX_PROMPT);
|
2001-04-09 20:54:03 +01:00
|
|
|
newline = FALSE;
|
|
|
|
}
|
2001-06-22 18:53:36 +01:00
|
|
|
#if HAVE_SIGINTERRUPT
|
|
|
|
siginterrupt(SIGINT, TRUE);
|
2001-04-09 20:54:03 +01:00
|
|
|
#endif
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_PrologMode |= ConsoleGetcMode;
|
2001-06-22 18:53:36 +01:00
|
|
|
ch = YP_fgetc(s->u.file.file);
|
|
|
|
#if HAVE_SIGINTERRUPT
|
|
|
|
siginterrupt(SIGINT, FALSE);
|
2001-04-09 20:54:03 +01:00
|
|
|
#endif
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_PrologMode & InterruptMode) {
|
|
|
|
Yap_PrologMode &= ~InterruptMode;
|
|
|
|
Yap_ProcessSIGINT();
|
|
|
|
Yap_PrologMode &= ~ConsoleGetcMode;
|
2001-06-22 18:53:36 +01:00
|
|
|
newline = TRUE;
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_PrologMode & AbortMode) {
|
|
|
|
Yap_Error(PURE_ABORT, TermNil, "");
|
|
|
|
Yap_ErrorMessage = "Abort";
|
2006-12-13 16:10:26 +00:00
|
|
|
return console_post_process_eof(s);
|
2001-06-27 14:22:30 +01:00
|
|
|
}
|
2001-06-22 18:53:36 +01:00
|
|
|
goto restart;
|
2002-02-12 18:24:21 +00:00
|
|
|
} else {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_PrologMode &= ~ConsoleGetcMode;
|
2001-06-22 18:53:36 +01:00
|
|
|
}
|
2006-12-13 16:10:26 +00:00
|
|
|
if (ch == EOF)
|
|
|
|
return console_post_process_eof(s);
|
|
|
|
return console_post_process_read_char(ch, s);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* reads a character from a buffer and does the rest */
|
|
|
|
static int
|
|
|
|
PlUnGetc (int sno)
|
|
|
|
{
|
|
|
|
register StreamDesc *s = &Stream[sno];
|
|
|
|
Int ch;
|
|
|
|
|
2001-11-29 20:29:52 +00:00
|
|
|
if (s->stream_getc != PlUnGetc)
|
|
|
|
return(s->stream_getc(sno));
|
2001-04-09 20:54:03 +01:00
|
|
|
ch = s->och;
|
2011-02-12 23:38:24 +00:00
|
|
|
if (s->status & Promptable_Stream_f) {
|
2001-04-09 20:54:03 +01:00
|
|
|
s->stream_putc = ConsolePutc;
|
2006-11-27 17:42:03 +00:00
|
|
|
s->stream_wputc = put_wchar;
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2001-04-09 20:54:03 +01:00
|
|
|
if (s->status & Tty_Stream_f) {
|
|
|
|
s->stream_getc = ReadlineGetc;
|
2001-06-11 18:47:02 +01:00
|
|
|
if (Stream[0].status & Tty_Stream_f &&
|
2002-05-28 17:26:00 +01:00
|
|
|
is_same_tty(s->u.file.file,Stream[0].u.file.file))
|
2001-06-11 18:40:16 +01:00
|
|
|
s->stream_putc = ReadlinePutc;
|
2006-11-27 17:42:03 +00:00
|
|
|
s->stream_wputc = put_wchar;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
s->stream_getc = ConsoleGetc;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
s->stream_getc = PlGetc;
|
2008-01-28 10:42:20 +00:00
|
|
|
s->stream_gets = PlGetsFunc();
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2008-06-12 11:55:52 +01:00
|
|
|
return(ch);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
static int
|
|
|
|
utf8_nof(char ch)
|
|
|
|
{
|
|
|
|
if (!(ch & 0x20))
|
|
|
|
return 1;
|
|
|
|
if (!(ch & 0x10))
|
|
|
|
return 2;
|
|
|
|
if (!(ch & 0x08))
|
|
|
|
return 3;
|
|
|
|
if (!(ch & 0x04))
|
|
|
|
return 4;
|
|
|
|
return 5;
|
|
|
|
}
|
|
|
|
|
2007-01-28 14:26:37 +00:00
|
|
|
static int
|
2006-11-27 17:42:03 +00:00
|
|
|
get_wchar(int sno)
|
|
|
|
{
|
|
|
|
int ch;
|
2007-01-28 14:26:37 +00:00
|
|
|
wchar_t wch;
|
2006-11-27 17:42:03 +00:00
|
|
|
int how_many = 0;
|
|
|
|
|
|
|
|
while (TRUE) {
|
|
|
|
ch = Stream[sno].stream_getc(sno);
|
|
|
|
if (ch == -1) {
|
|
|
|
if (how_many) {
|
|
|
|
/* error */
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
switch (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 *)&(Stream[sno].mbstate), 0, sizeof(mbstate_t));
|
|
|
|
}
|
|
|
|
buf[0] = ch;
|
|
|
|
if ((out = mbrtowc(&wch, buf, 1, &(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.
|
|
|
|
*/
|
|
|
|
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 = Stream[sno].och;
|
|
|
|
|
|
|
|
Stream[sno].och = ch;
|
|
|
|
Stream[sno].stream_getc = PlUnGetc;
|
|
|
|
Stream[sno].stream_wgetc = get_wchar;
|
2008-01-28 10:42:20 +00:00
|
|
|
Stream[sno].stream_gets = DefaultGets;
|
2006-11-27 17:42:03 +00:00
|
|
|
return och;
|
|
|
|
}
|
|
|
|
if (!how_many) {
|
|
|
|
return wch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ENC_UNICODE_BE:
|
|
|
|
if (how_many) {
|
|
|
|
return wch+ch;
|
|
|
|
}
|
|
|
|
how_many=1;
|
|
|
|
wch = ch << 8;
|
|
|
|
break;
|
|
|
|
case ENC_UNICODE_LE:
|
|
|
|
if (how_many) {
|
|
|
|
return wch+(ch<<8);
|
|
|
|
}
|
|
|
|
how_many=1;
|
2007-04-03 00:04:48 +01:00
|
|
|
wch = ch;
|
2006-11-27 17:42:03 +00:00
|
|
|
break;
|
2010-10-27 14:49:27 +01:00
|
|
|
case ENC_ISO_UTF32_LE:
|
|
|
|
if (!how_many) {
|
|
|
|
how_many = 4;
|
|
|
|
wch = 0;
|
|
|
|
}
|
|
|
|
how_many--;
|
2010-10-28 18:05:42 +01:00
|
|
|
wch += ((unsigned char) (ch & 0xff)) << ((3-how_many)*8);
|
2010-10-27 14:49:27 +01:00
|
|
|
if (how_many == 0)
|
|
|
|
return wch;
|
|
|
|
break;
|
|
|
|
case ENC_ISO_UTF32_BE:
|
|
|
|
if (!how_many) {
|
|
|
|
how_many = 4;
|
|
|
|
wch = 0;
|
|
|
|
}
|
|
|
|
how_many--;
|
2010-10-28 18:05:42 +01:00
|
|
|
wch += ((unsigned char) (ch & 0xff)) << (how_many*8);
|
2010-10-27 14:49:27 +01:00
|
|
|
if (how_many == 0)
|
|
|
|
return wch;
|
|
|
|
break;
|
2006-11-27 17:42:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef MB_LEN_MAX
|
|
|
|
#define MB_LEN_MAX 6
|
|
|
|
#endif
|
|
|
|
|
2007-04-03 16:03:11 +01:00
|
|
|
static int
|
|
|
|
handle_write_encoding_error(int sno, wchar_t ch)
|
|
|
|
{
|
|
|
|
if (Stream[sno].status & RepError_Xml_f) {
|
|
|
|
/* use HTML/XML encoding in ASCII */
|
|
|
|
int i = ch, digits = 1;
|
|
|
|
Stream[sno].stream_putc(sno, '&');
|
|
|
|
Stream[sno].stream_putc(sno, '#');
|
|
|
|
while (digits < i)
|
|
|
|
digits *= 10;
|
|
|
|
if (digits > i)
|
|
|
|
digits /= 10;
|
|
|
|
while (i) {
|
|
|
|
Stream[sno].stream_putc(sno, i/digits);
|
|
|
|
i %= 10;
|
|
|
|
digits /= 10;
|
|
|
|
}
|
|
|
|
Stream[sno].stream_putc(sno, ';');
|
|
|
|
return ch;
|
|
|
|
} else if (Stream[sno].status & RepError_Prolog_f) {
|
|
|
|
/* write quoted */
|
|
|
|
Stream[sno].stream_putc(sno, '\\');
|
|
|
|
Stream[sno].stream_putc(sno, 'u');
|
|
|
|
Stream[sno].stream_putc(sno, ch>>24);
|
|
|
|
Stream[sno].stream_putc(sno, 256&(ch>>16));
|
|
|
|
Stream[sno].stream_putc(sno, 256&(ch>>8));
|
|
|
|
Stream[sno].stream_putc(sno, 256&ch);
|
|
|
|
return ch;
|
|
|
|
} else {
|
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, MkIntegerTerm(ch),"charater %ld cannot be encoded in stream %d",(unsigned long int)ch,sno);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-28 14:26:37 +00:00
|
|
|
static int
|
2006-11-27 17:42:03 +00:00
|
|
|
put_wchar(int sno, wchar_t ch)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* pass the bug if we can */
|
|
|
|
switch (Stream[sno].encoding) {
|
|
|
|
case ENC_OCTET:
|
|
|
|
return Stream[sno].stream_putc(sno, ch);
|
|
|
|
case ENC_ISO_LATIN1:
|
|
|
|
if (ch >= 0xff) {
|
2007-04-03 16:03:11 +01:00
|
|
|
return handle_write_encoding_error(sno,ch);
|
2006-11-27 17:42:03 +00:00
|
|
|
}
|
|
|
|
return Stream[sno].stream_putc(sno, ch);
|
|
|
|
case ENC_ISO_ASCII:
|
|
|
|
if (ch >= 0x80) {
|
2007-04-03 16:03:11 +01:00
|
|
|
return handle_write_encoding_error(sno,ch);
|
2006-11-27 17:42:03 +00:00
|
|
|
}
|
|
|
|
return Stream[sno].stream_putc(sno, ch);
|
|
|
|
case ENC_ISO_ANSI:
|
|
|
|
{
|
|
|
|
char buf[MB_LEN_MAX];
|
|
|
|
int n;
|
|
|
|
|
|
|
|
memset((void *)&(Stream[sno].mbstate), 0, sizeof(mbstate_t));
|
|
|
|
if ( (n = wcrtomb(buf, ch, &(Stream[sno].mbstate))) < 0 ) {
|
|
|
|
/* error */
|
|
|
|
Stream[sno].stream_putc(sno, ch);
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i =0; i< n; i++) {
|
|
|
|
Stream[sno].stream_putc(sno, buf[i]);
|
|
|
|
}
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
case ENC_ISO_UTF8:
|
2007-04-03 00:04:48 +01:00
|
|
|
if (ch < 0x80) {
|
|
|
|
return Stream[sno].stream_putc(sno, ch);
|
|
|
|
} else if (ch < 0x800) {
|
|
|
|
Stream[sno].stream_putc(sno, 0xC0 | ch>>6);
|
|
|
|
return Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F));
|
|
|
|
}
|
|
|
|
else if (ch < 0x10000) {
|
|
|
|
Stream[sno].stream_putc(sno, 0xE0 | ch>>12);
|
|
|
|
Stream[sno].stream_putc(sno, 0x80 | (ch>>6 & 0x3F));
|
|
|
|
return Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F));
|
|
|
|
} else if (ch < 0x200000) {
|
|
|
|
Stream[sno].stream_putc(sno, 0xF0 | ch>>18);
|
|
|
|
Stream[sno].stream_putc(sno, 0x80 | (ch>>12 & 0x3F));
|
|
|
|
Stream[sno].stream_putc(sno, 0x80 | (ch>>6 & 0x3F));
|
|
|
|
return Stream[sno].stream_putc(sno, 0x80 | (ch & 0x3F));
|
|
|
|
} else {
|
|
|
|
/* should never happen */
|
|
|
|
return -1;
|
2006-11-27 17:42:03 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ENC_UNICODE_BE:
|
|
|
|
Stream[sno].stream_putc(sno, (ch>>8));
|
|
|
|
return Stream[sno].stream_putc(sno, (ch&0xff));
|
|
|
|
case ENC_UNICODE_LE:
|
|
|
|
Stream[sno].stream_putc(sno, (ch&0xff));
|
|
|
|
return Stream[sno].stream_putc(sno, (ch>>8));
|
2010-10-27 14:49:27 +01:00
|
|
|
case ENC_ISO_UTF32_BE:
|
|
|
|
Stream[sno].stream_putc(sno, (ch>>24) & 0xff);
|
|
|
|
Stream[sno].stream_putc(sno, (ch>>16) &0xff);
|
|
|
|
Stream[sno].stream_putc(sno, (ch>>8) & 0xff);
|
|
|
|
return Stream[sno].stream_putc(sno, ch&0xff);
|
|
|
|
case ENC_ISO_UTF32_LE:
|
|
|
|
Stream[sno].stream_putc(sno, ch&0xff);
|
|
|
|
Stream[sno].stream_putc(sno, (ch>>8) & 0xff);
|
|
|
|
Stream[sno].stream_putc(sno, (ch>>16) &0xff);
|
|
|
|
return Stream[sno].stream_putc(sno, (ch>>24) & 0xff);
|
2006-11-27 17:42:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
/* used by user-code to read characters from the current input stream */
|
|
|
|
int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_PlGetchar (void)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
return(Stream[Yap_c_input_stream].stream_getc(Yap_c_input_stream));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2007-01-28 14:26:37 +00:00
|
|
|
int
|
2006-11-27 17:42:03 +00:00
|
|
|
Yap_PlGetWchar (void)
|
|
|
|
{
|
|
|
|
return get_wchar(Yap_c_input_stream);
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
/* avoid using a variable to call a function */
|
|
|
|
int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_PlFGetchar (void)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
return(PlGetc(Yap_c_input_stream));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Term
|
|
|
|
MkStream (int n)
|
|
|
|
{
|
|
|
|
Term t[1];
|
|
|
|
t[0] = MkIntTerm (n);
|
2002-11-18 18:18:05 +00:00
|
|
|
return (Yap_MkApplTerm (FunctorStream, 1, t));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* given a stream index, get the corresponding fd */
|
2010-05-06 15:00:44 +01:00
|
|
|
static Int
|
2001-04-09 20:54:03 +01:00
|
|
|
GetStreamFd(int sno)
|
|
|
|
{
|
|
|
|
return(YP_fileno(Stream[sno].u.file.file));
|
|
|
|
}
|
|
|
|
|
2010-05-06 15:00:44 +01:00
|
|
|
Int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_GetStreamFd(int sno)
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
|
|
|
return GetStreamFd(sno);
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
/* given a socket file descriptor, get the corresponding stream descripor */
|
|
|
|
int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_CheckIOStream(Term stream, char * error)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2011-02-12 23:38:24 +00:00
|
|
|
int sno = CheckStream(stream, Input_Stream_f|Output_Stream_f, error);
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
return(sno);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-27 16:25:34 +01:00
|
|
|
#if _MSC_VER || defined(__MINGW32__)
|
2007-09-27 23:40:22 +01:00
|
|
|
#define SYSTEM_STAT _stat
|
2007-09-27 16:25:34 +01:00
|
|
|
#else
|
2007-09-27 23:40:22 +01:00
|
|
|
#define SYSTEM_STAT stat
|
2007-09-27 16:25:34 +01:00
|
|
|
#endif
|
2007-09-27 23:40:22 +01:00
|
|
|
|
|
|
|
static Int
|
|
|
|
p_access(void)
|
|
|
|
{
|
|
|
|
Term tname = Deref(ARG1);
|
|
|
|
char *file_name;
|
|
|
|
|
|
|
|
if (IsVarTerm(tname)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, tname, "access");
|
2007-09-27 16:25:34 +01:00
|
|
|
return FALSE;
|
2007-09-27 23:40:22 +01:00
|
|
|
} else if (!IsAtomTerm (tname)) {
|
|
|
|
Yap_Error(TYPE_ERROR_ATOM, tname, "access");
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
#if HAVE_STAT
|
|
|
|
struct SYSTEM_STAT ss;
|
|
|
|
|
|
|
|
file_name = RepAtom(AtomOfTerm(tname))->StrOfAE;
|
|
|
|
if (SYSTEM_STAT(file_name, &ss) != 0) {
|
|
|
|
/* ignore errors while checking a file */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
2007-09-27 16:25:34 +01:00
|
|
|
#else
|
2007-09-27 23:40:22 +01:00
|
|
|
return FALSE;
|
2007-09-27 16:25:34 +01:00
|
|
|
#endif
|
2007-09-27 23:40:22 +01:00
|
|
|
}
|
2007-09-27 16:25:34 +01:00
|
|
|
}
|
2007-04-03 00:04:48 +01:00
|
|
|
|
2010-02-11 18:07:08 +00:00
|
|
|
static Int
|
|
|
|
p_exists_directory(void)
|
|
|
|
{
|
|
|
|
Term tname = Deref(ARG1);
|
|
|
|
char *file_name;
|
|
|
|
|
|
|
|
if (IsVarTerm(tname)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, tname, "exists_directory/1");
|
|
|
|
return FALSE;
|
|
|
|
} else if (!IsAtomTerm (tname)) {
|
|
|
|
Yap_Error(TYPE_ERROR_ATOM, tname, "exists_directory/1");
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
#if HAVE_STAT
|
|
|
|
struct SYSTEM_STAT ss;
|
|
|
|
|
|
|
|
file_name = RepAtom(AtomOfTerm(tname))->StrOfAE;
|
|
|
|
if (SYSTEM_STAT(file_name, &ss) != 0) {
|
|
|
|
/* ignore errors while checking a file */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return (S_ISDIR(ss.st_mode));
|
|
|
|
#else
|
|
|
|
return FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-02 05:35:20 +00:00
|
|
|
static Int
|
|
|
|
p_file_expansion (void)
|
|
|
|
{ /* '$file_expansion'(+File,-Name) */
|
|
|
|
Term file_name = Deref(ARG1);
|
|
|
|
|
|
|
|
/* we know file_name is bound */
|
|
|
|
if (!IsAtomTerm (file_name)) {
|
|
|
|
PlIOError(TYPE_ERROR_ATOM, file_name, "absolute_file_name/3");
|
|
|
|
return(FALSE);
|
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
if (!Yap_TrueFileName (RepAtom (AtomOfTerm (file_name))->StrOfAE, Yap_FileNameBuf, FALSE))
|
2002-01-02 05:35:20 +00:00
|
|
|
return (PlIOError (EXISTENCE_ERROR_SOURCE_SINK,file_name,"absolute_file_name/3"));
|
2002-11-18 18:18:05 +00:00
|
|
|
return(Yap_unify(ARG2,MkAtomTerm(Yap_LookupAtom(Yap_FileNameBuf))));
|
2002-01-02 05:35:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-21 21:00:05 +01:00
|
|
|
Term
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_OpenStream(FILE *fd, char *name, Term file_name, int flags)
|
2001-05-21 21:00:05 +01:00
|
|
|
{
|
|
|
|
Term t;
|
|
|
|
StreamDesc *st;
|
|
|
|
int sno;
|
|
|
|
|
2004-06-09 04:32:03 +01:00
|
|
|
sno = GetFreeStreamD();
|
|
|
|
if (sno < 0)
|
2009-06-12 19:44:22 +01:00
|
|
|
return (PlIOError (RESOURCE_ERROR_MAX_STREAMS,TermNil, "new stream not available for open_null_stream/1"));
|
2001-05-21 21:00:05 +01:00
|
|
|
st = &Stream[sno];
|
|
|
|
st->status = 0;
|
|
|
|
if (flags & YAP_INPUT_STREAM)
|
|
|
|
st->status |= Input_Stream_f;
|
|
|
|
if (flags & YAP_OUTPUT_STREAM)
|
|
|
|
st->status |= Output_Stream_f;
|
|
|
|
if (flags & YAP_APPEND_STREAM)
|
|
|
|
st->status |= Append_Stream_f;
|
|
|
|
/*
|
|
|
|
pipes assume an integer file descriptor, not a FILE *:
|
|
|
|
if (flags & YAP_PIPE_STREAM)
|
|
|
|
st->status |= Pipe_Stream_f;
|
|
|
|
*/
|
|
|
|
if (flags & YAP_TTY_STREAM)
|
|
|
|
st->status |= Tty_Stream_f;
|
|
|
|
if (flags & YAP_POPEN_STREAM)
|
|
|
|
st->status |= Popen_Stream_f;
|
|
|
|
if (flags & YAP_BINARY_STREAM)
|
|
|
|
st->status |= Binary_Stream_f;
|
|
|
|
if (flags & YAP_SEEKABLE_STREAM)
|
|
|
|
st->status |= Seekable_Stream_f;
|
|
|
|
st->charcount = 0;
|
|
|
|
st->linecount = 1;
|
2002-11-18 18:18:05 +00:00
|
|
|
st->u.file.name = Yap_LookupAtom(name);
|
2001-05-21 21:00:05 +01:00
|
|
|
st->u.file.user_name = file_name;
|
|
|
|
st->u.file.file = fd;
|
|
|
|
st->linepos = 0;
|
2006-08-02 19:18:31 +01:00
|
|
|
st->stream_gets = PlGetsFunc();
|
2011-02-12 23:42:15 +00:00
|
|
|
if (flags & YAP_TTY_STREAM) {
|
2001-05-21 21:00:05 +01:00
|
|
|
st->stream_putc = ConsolePutc;
|
2006-11-27 17:42:03 +00:00
|
|
|
st->stream_wputc = put_wchar;
|
2001-05-21 21:00:05 +01:00
|
|
|
st->stream_getc = ConsoleGetc;
|
|
|
|
} else {
|
|
|
|
st->stream_putc = FilePutc;
|
2006-11-27 17:42:03 +00:00
|
|
|
st->stream_wputc = put_wchar;
|
2001-05-21 21:00:05 +01:00
|
|
|
st->stream_getc = PlGetc;
|
|
|
|
unix_upd_stream_info (st);
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
st->stream_wgetc = get_wchar;
|
2001-05-21 21:00:05 +01:00
|
|
|
if (CharConversionTable != NULL)
|
2006-11-27 17:42:03 +00:00
|
|
|
st->stream_wgetc_for_read = ISOWGetc;
|
2001-05-21 21:00:05 +01:00
|
|
|
else
|
2006-11-27 17:42:03 +00:00
|
|
|
st->stream_wgetc_for_read = st->stream_wgetc;
|
2010-07-26 12:54:22 +01:00
|
|
|
UNLOCK(st->streamlock);
|
2001-05-21 21:00:05 +01:00
|
|
|
t = MkStream (sno);
|
2006-11-27 17:42:03 +00:00
|
|
|
return t;
|
2001-05-21 21:00:05 +01:00
|
|
|
}
|
|
|
|
|
2005-10-28 18:38:50 +01:00
|
|
|
|
2010-06-23 11:46:16 +01:00
|
|
|
static int
|
|
|
|
LookupSWIStream (struct io_stream *swi_s)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
while (i < MaxStreams) {
|
|
|
|
LOCK(Stream[i].streamlock);
|
|
|
|
if (Stream[i].status & SWI_Stream_f &&
|
|
|
|
Stream[i].u.swi_stream.swi_ptr == swi_s
|
|
|
|
) {
|
|
|
|
UNLOCK(Stream[i].streamlock);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
UNLOCK(Stream[i].streamlock);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
i = GetFreeStreamD();
|
|
|
|
if (i < 0)
|
|
|
|
return i;
|
|
|
|
Stream[i].u.swi_stream.swi_ptr = swi_s;
|
|
|
|
Stream[i].status = SWI_Stream_f|Output_Stream_f|Input_Stream_f|Append_Stream_f|Tty_Stream_f|Promptable_Stream_f;
|
|
|
|
Stream[i].linepos = 0;
|
|
|
|
Stream[i].linecount = 1;
|
|
|
|
Stream[i].charcount = 0;
|
|
|
|
Stream[i].encoding = DefaultEncoding();
|
|
|
|
Stream[i].stream_getc = IOSWIGetc;
|
|
|
|
Stream[i].stream_putc = IOSWIPutc;
|
2010-07-21 10:58:24 +01:00
|
|
|
Stream[i].stream_wputc = IOSWIWidePutc;
|
|
|
|
Stream[i].stream_wgetc = IOSWIWideGetc;
|
2010-06-23 11:46:16 +01:00
|
|
|
Stream[i].stream_gets = DefaultGets;
|
|
|
|
if (CharConversionTable != NULL)
|
|
|
|
Stream[i].stream_wgetc_for_read = ISOWGetc;
|
|
|
|
else
|
2010-07-21 10:58:24 +01:00
|
|
|
Stream[i].stream_wgetc_for_read = IOSWIWideGetc;
|
2010-07-26 12:54:22 +01:00
|
|
|
UNLOCK(Stream[i].streamlock);
|
2010-06-23 11:46:16 +01:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2011-02-12 18:42:44 +00:00
|
|
|
int
|
|
|
|
Yap_LookupSWIStream (void *swi_s)
|
|
|
|
{
|
|
|
|
return LookupSWIStream (swi_s);
|
|
|
|
}
|
|
|
|
|
2011-02-12 14:14:12 +00:00
|
|
|
typedef struct stream_ref
|
|
|
|
{ struct io_stream *read;
|
|
|
|
struct io_stream *write;
|
|
|
|
} stream_ref;
|
|
|
|
|
|
|
|
extern stream_ref *PL_blob_data(Atom, void *, void *);
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static int
|
|
|
|
CheckStream (Term arg, int kind, char *msg)
|
|
|
|
{
|
|
|
|
int sno = -1;
|
|
|
|
arg = Deref (arg);
|
|
|
|
if (IsVarTerm (arg)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR, arg, msg);
|
2006-01-02 02:16:19 +00:00
|
|
|
return -1;
|
|
|
|
} else if (IsAtomTerm (arg)) {
|
2011-02-14 14:59:15 +00:00
|
|
|
struct io_stream *swi_stream;
|
|
|
|
Atom sname = AtomOfTerm(arg);
|
2010-12-13 12:38:37 +00:00
|
|
|
|
2011-02-14 14:59:15 +00:00
|
|
|
if (IsBlob(sname)) {
|
2011-02-12 14:14:12 +00:00
|
|
|
struct io_stream *s;
|
|
|
|
stream_ref *ref;
|
|
|
|
|
|
|
|
ref = PL_blob_data(sname, NULL, NULL);
|
|
|
|
{
|
|
|
|
if ( ref->read )
|
|
|
|
{
|
|
|
|
if ( ref->write && (kind&Output_Stream_f) )
|
|
|
|
s = ref->write;
|
|
|
|
else
|
|
|
|
s = ref->read;
|
|
|
|
} else
|
|
|
|
s = ref->write;
|
|
|
|
}
|
|
|
|
sno = LookupSWIStream(s);
|
|
|
|
return sno;
|
|
|
|
}
|
2011-02-14 14:59:15 +00:00
|
|
|
|
|
|
|
if (Yap_get_stream_handle(arg, kind & Input_Stream_f, kind & Output_Stream_f, &swi_stream)) {
|
|
|
|
sno = LookupSWIStream(swi_stream);
|
|
|
|
return sno;
|
|
|
|
}
|
2001-04-16 17:41:04 +01:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
if (sno < 0)
|
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_STREAM_OR_ALIAS, arg, msg);
|
2001-04-09 20:54:03 +01:00
|
|
|
return (-1);
|
|
|
|
}
|
2010-07-27 17:28:27 +01:00
|
|
|
LOCK(Stream[sno].streamlock);
|
2001-04-09 20:54:03 +01:00
|
|
|
if (Stream[sno].status & Free_Stream_f)
|
|
|
|
{
|
2010-07-27 17:28:27 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(EXISTENCE_ERROR_STREAM, arg, msg);
|
2001-04-09 20:54:03 +01:00
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if ((Stream[sno].status & kind) == 0)
|
|
|
|
{
|
2010-07-27 17:28:27 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2001-04-09 20:54:03 +01:00
|
|
|
if (kind & Input_Stream_f)
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(PERMISSION_ERROR_INPUT_STREAM, arg, msg);
|
2001-04-09 20:54:03 +01:00
|
|
|
else
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(PERMISSION_ERROR_OUTPUT_STREAM, arg, msg);
|
2001-04-09 20:54:03 +01:00
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
return (sno);
|
|
|
|
}
|
|
|
|
|
2006-08-02 19:18:31 +01:00
|
|
|
int
|
|
|
|
Yap_CheckStream (Term arg, int kind, char *msg)
|
|
|
|
{
|
|
|
|
return CheckStream(arg, kind, msg);
|
|
|
|
}
|
|
|
|
|
2007-11-26 23:43:10 +00:00
|
|
|
|
|
|
|
#if defined(YAPOR) || defined(THREADS)
|
|
|
|
void
|
|
|
|
Yap_LockStream (int sno)
|
|
|
|
{
|
|
|
|
LOCK(Stream[sno].streamlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Yap_UnLockStream (int sno)
|
|
|
|
{
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-05-21 21:00:05 +01:00
|
|
|
static Term
|
|
|
|
StreamName(int i)
|
|
|
|
{
|
2002-01-27 22:00:32 +00:00
|
|
|
if (i < 3) return(MkAtomTerm(AtomUser));
|
2011-02-12 18:42:44 +00:00
|
|
|
return(Stream[i].u.file.user_name);
|
2001-05-21 21:00:05 +01:00
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Called when you want to close all open streams, except for stdin, stdout
|
|
|
|
* and stderr
|
|
|
|
*/
|
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_CloseStreams (int loud)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
|
|
|
int sno;
|
2001-05-21 21:00:05 +01:00
|
|
|
for (sno = 3; sno < MaxStreams; ++sno) {
|
|
|
|
if (Stream[sno].status & Free_Stream_f)
|
|
|
|
continue;
|
|
|
|
if ((Stream[sno].status & Popen_Stream_f))
|
|
|
|
pclose (Stream[sno].u.file.file);
|
2011-02-12 18:42:44 +00:00
|
|
|
else if (Stream[sno].status & (SWI_Stream_f)) {
|
2010-12-15 20:03:22 +00:00
|
|
|
SWIClose(Stream[sno].u.swi_stream.swi_ptr);
|
|
|
|
} else {
|
2011-02-12 23:45:19 +00:00
|
|
|
YP_fclose (Stream[sno].u.file.file);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-09-27 21:45:04 +01:00
|
|
|
if (Yap_c_input_stream == sno) {
|
|
|
|
Yap_c_input_stream = StdInStream;
|
|
|
|
} else if (Yap_c_output_stream == sno) {
|
|
|
|
Yap_c_output_stream = StdOutStream;
|
|
|
|
}
|
|
|
|
Stream[sno].status = Free_Stream_f;
|
2001-05-21 21:00:05 +01:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-06 20:03:26 +00:00
|
|
|
static void
|
2001-04-09 20:54:03 +01:00
|
|
|
CloseStream(int sno)
|
|
|
|
{
|
2011-02-12 23:45:19 +00:00
|
|
|
if (!(Stream[sno].status & (SWI_Stream_f))) {
|
2001-04-09 20:54:03 +01:00
|
|
|
YP_fclose (Stream[sno].u.file.file);
|
2011-02-12 18:42:44 +00:00
|
|
|
} else if (Stream[sno].status & (SWI_Stream_f)) {
|
2010-06-23 11:46:16 +01:00
|
|
|
SWIClose(Stream[sno].u.swi_stream.swi_ptr);
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
Stream[sno].status = Free_Stream_f;
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_c_input_stream == sno)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_c_input_stream = StdInStream;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
else if (Yap_c_output_stream == sno)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_c_output_stream = StdOutStream;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_CloseStream(int sno)
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
|
|
|
CloseStream(sno);
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static Int
|
|
|
|
p_close (void)
|
|
|
|
{ /* '$close'(+Stream) */
|
2011-02-12 23:38:24 +00:00
|
|
|
Int sno = CheckStream (ARG1, (Input_Stream_f | Output_Stream_f), "close/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
if (sno < 0)
|
|
|
|
return (FALSE);
|
2010-02-26 10:59:43 +00:00
|
|
|
if (sno <= StdErrStream) {
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
CloseStream(sno);
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2001-04-09 20:54:03 +01:00
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_past_eof (void)
|
|
|
|
{ /* at_end_of_stream */
|
|
|
|
/* the next character is a EOF */
|
|
|
|
int sno = CheckStream (ARG1, Input_Stream_f, "past_eof/1");
|
2006-04-28 16:48:33 +01:00
|
|
|
Int out;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
if (sno < 0)
|
|
|
|
return (FALSE);
|
2006-11-16 13:56:08 +00:00
|
|
|
if (Stream[sno].stream_getc == PlUnGetc) {
|
2008-01-28 12:47:45 +00:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2006-11-16 13:56:08 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2006-04-28 16:48:33 +01:00
|
|
|
out = Stream[sno].status & Eof_Stream_f;
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
return out;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2007-04-03 00:04:48 +01:00
|
|
|
static Int
|
|
|
|
p_has_bom (void)
|
|
|
|
{ /* '$set_output'(+Stream,-ErrorMessage) */
|
2007-04-03 16:03:11 +01:00
|
|
|
Int sno = CheckStream (ARG1, Input_Stream_f|Output_Stream_f, "has_bom/1");
|
2007-04-03 00:04:48 +01:00
|
|
|
if (sno < 0)
|
|
|
|
return (FALSE);
|
2008-01-28 12:47:45 +00:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2007-04-03 00:04:48 +01:00
|
|
|
return ((Stream[sno].status & HAS_BOM_f));
|
|
|
|
}
|
|
|
|
|
2007-04-03 16:03:11 +01:00
|
|
|
static Int
|
|
|
|
p_representation_error (void)
|
2009-05-02 16:54:09 +01:00
|
|
|
{
|
|
|
|
/* '$representation_error'(+Stream,-ErrorMessage) */
|
|
|
|
Term t;
|
2007-04-03 16:03:11 +01:00
|
|
|
Int sno = CheckStream (ARG1, Input_Stream_f|Output_Stream_f, "representation_errors/1");
|
|
|
|
if (sno < 0)
|
|
|
|
return (FALSE);
|
2009-05-02 16:54:09 +01:00
|
|
|
t = Deref(ARG2);
|
2007-04-03 16:03:11 +01:00
|
|
|
|
|
|
|
if (IsVarTerm(t)) {
|
2008-01-28 12:47:45 +00:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2007-04-03 16:03:11 +01:00
|
|
|
if (Stream[sno].status & RepError_Prolog_f) {
|
|
|
|
return Yap_unify(ARG2, MkIntegerTerm(512));
|
|
|
|
}
|
|
|
|
if (Stream[sno].status & RepError_Xml_f) {
|
|
|
|
return Yap_unify(ARG2, MkIntegerTerm(1024));
|
|
|
|
}
|
|
|
|
return Yap_unify(ARG2, MkIntegerTerm(0));
|
|
|
|
} else {
|
|
|
|
Int i = IntegerOfTerm(t);
|
|
|
|
switch (i) {
|
|
|
|
case 512:
|
|
|
|
Stream[sno].status &= ~RepError_Xml_f;
|
|
|
|
Stream[sno].status |= RepError_Prolog_f;
|
|
|
|
break;
|
|
|
|
case 1024:
|
|
|
|
Stream[sno].status &= ~RepError_Prolog_f;
|
|
|
|
Stream[sno].status |= RepError_Xml_f;
|
|
|
|
default:
|
|
|
|
Stream[sno].status &= ~(RepError_Prolog_f|RepError_Xml_f);
|
|
|
|
}
|
|
|
|
}
|
2007-04-16 16:24:24 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2007-04-03 16:03:11 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-09-08 23:06:45 +01:00
|
|
|
#ifdef BEAM
|
|
|
|
int beam_write (void)
|
|
|
|
{
|
|
|
|
Yap_StartSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite (ARG1, Stream[Yap_c_output_stream].stream_wputc, 0, 1200);
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2005-09-08 23:06:45 +01:00
|
|
|
if (EX != 0L) {
|
2010-07-27 23:21:15 +01:00
|
|
|
Term ball = Yap_PopTermFromDB(EX);
|
2005-09-08 23:06:45 +01:00
|
|
|
EX = 0L;
|
|
|
|
Yap_JumpToEnv(ball);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static Int
|
|
|
|
p_write (void)
|
2009-05-22 19:24:27 +01:00
|
|
|
{
|
|
|
|
/* '$write'(+Flags,?Term) */
|
2002-10-17 01:05:29 +01:00
|
|
|
int flags = (int) IntOfTerm (Deref (ARG1));
|
|
|
|
/* notice: we must have ASP well set when using portray, otherwise
|
|
|
|
we cannot make recursive Prolog calls */
|
2004-08-16 22:02:04 +01:00
|
|
|
Yap_StartSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite (ARG2, Stream[Yap_c_output_stream].stream_wputc, flags, 1200);
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
if (EX != 0L) {
|
2010-07-27 23:21:15 +01:00
|
|
|
Term ball = Yap_PopTermFromDB(EX);
|
|
|
|
EX = NULL;
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_JumpToEnv(ball);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_write_prio (void)
|
|
|
|
{
|
|
|
|
/* '$write'(+Flags,?Term) */
|
|
|
|
int flags = (int) IntOfTerm (Deref (ARG1));
|
|
|
|
/* notice: we must have ASP well set when using portray, otherwise
|
|
|
|
we cannot make recursive Prolog calls */
|
|
|
|
Yap_StartSlots();
|
|
|
|
Yap_plwrite (ARG3, Stream[Yap_c_output_stream].stream_wputc, flags, (int)IntOfTerm(Deref(ARG2)));
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
if (EX != 0L) {
|
2010-07-27 23:21:15 +01:00
|
|
|
Term ball = Yap_PopTermFromDB(EX);
|
|
|
|
EX = NULL;
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_JumpToEnv(ball);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_write2_prio (void)
|
|
|
|
{ /* '$write'(+Stream,+Flags,?Term) */
|
|
|
|
int old_output_stream = Yap_c_output_stream;
|
2010-12-13 12:38:37 +00:00
|
|
|
Int flags = IntegerOfTerm(Deref(ARG2));
|
|
|
|
int stream_f;
|
|
|
|
|
|
|
|
if (flags & Use_SWI_Stream_f) {
|
|
|
|
stream_f = Output_Stream_f|SWI_Stream_f;
|
|
|
|
} else {
|
|
|
|
stream_f = Output_Stream_f;
|
|
|
|
}
|
|
|
|
Yap_c_output_stream = CheckStream (ARG1, stream_f, "write/2");
|
2009-05-22 19:24:27 +01:00
|
|
|
if (Yap_c_output_stream == -1) {
|
|
|
|
Yap_c_output_stream = old_output_stream;
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
UNLOCK(Stream[Yap_c_output_stream].streamlock);
|
|
|
|
/* notice: we must have ASP well set when using portray, otherwise
|
|
|
|
we cannot make recursive Prolog calls */
|
|
|
|
Yap_StartSlots();
|
2010-12-13 12:38:37 +00:00
|
|
|
Yap_plwrite (ARG4, Stream[Yap_c_output_stream].stream_wputc, (int) flags, (int) IntOfTerm (Deref (ARG3)));
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_c_output_stream = old_output_stream;
|
2002-05-14 19:24:34 +01:00
|
|
|
if (EX != 0L) {
|
2010-07-27 23:21:15 +01:00
|
|
|
Term ball = Yap_PopTermFromDB(EX);
|
|
|
|
EX = NULL;
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_JumpToEnv(ball);
|
2002-05-14 19:24:34 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_write2 (void)
|
2001-07-16 16:26:14 +01:00
|
|
|
{ /* '$write'(+Stream,+Flags,?Term) */
|
2002-11-18 18:18:05 +00:00
|
|
|
int old_output_stream = Yap_c_output_stream;
|
|
|
|
Yap_c_output_stream = CheckStream (ARG1, Output_Stream_f, "write/2");
|
|
|
|
if (Yap_c_output_stream == -1) {
|
|
|
|
Yap_c_output_stream = old_output_stream;
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[Yap_c_output_stream].streamlock);
|
2002-10-17 01:05:29 +01:00
|
|
|
/* notice: we must have ASP well set when using portray, otherwise
|
|
|
|
we cannot make recursive Prolog calls */
|
2004-08-16 22:02:04 +01:00
|
|
|
Yap_StartSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite (ARG3, Stream[Yap_c_output_stream].stream_wputc, (int) IntOfTerm (Deref (ARG2)), 1200);
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_c_output_stream = old_output_stream;
|
2002-05-14 19:24:34 +01:00
|
|
|
if (EX != 0L) {
|
2010-07-27 23:21:15 +01:00
|
|
|
Term ball = Yap_PopTermFromDB(EX);
|
|
|
|
EX = NULL;
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_JumpToEnv(ball);
|
2002-05-14 19:24:34 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
2002-04-16 20:48:45 +01:00
|
|
|
static void
|
|
|
|
clean_vars(VarEntry *p)
|
|
|
|
{
|
|
|
|
if (p == NULL) return;
|
|
|
|
p->VarAdr = TermNil;
|
|
|
|
clean_vars(p->VarLeft);
|
|
|
|
clean_vars(p->VarRight);
|
|
|
|
}
|
|
|
|
|
2002-04-11 16:31:58 +01:00
|
|
|
static Term
|
2009-10-26 22:56:18 +00:00
|
|
|
syntax_error (TokEntry * tokptr, int sno, Term *outp)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
|
|
|
Term info;
|
2002-04-11 16:31:58 +01:00
|
|
|
int count = 0, out = 0;
|
|
|
|
Int start, err = 0, end;
|
2008-11-26 09:56:18 +00:00
|
|
|
Term tf[7];
|
2002-04-11 16:31:58 +01:00
|
|
|
Term *error = tf+3;
|
2002-04-19 15:42:58 +01:00
|
|
|
CELL *Hi = H;
|
2002-04-11 16:31:58 +01:00
|
|
|
|
2010-03-02 22:21:48 +00:00
|
|
|
/* make sure to globalise variable */
|
|
|
|
Yap_unify(*outp, MkVarTerm());
|
2002-04-11 16:31:58 +01:00
|
|
|
start = tokptr->TokPos;
|
2002-11-18 18:18:05 +00:00
|
|
|
clean_vars(Yap_VarTable);
|
|
|
|
clean_vars(Yap_AnonVarTable);
|
2002-04-11 16:31:58 +01:00
|
|
|
while (1) {
|
|
|
|
Term ts[2];
|
|
|
|
|
2002-04-19 15:42:58 +01:00
|
|
|
if (H > ASP-1024) {
|
|
|
|
tf[3] = TermNil;
|
|
|
|
err = 0;
|
|
|
|
end = 0;
|
2004-09-10 21:18:01 +01:00
|
|
|
/* for some reason moving this earlier confuses gcc on solaris */
|
|
|
|
H = Hi;
|
2002-04-19 15:42:58 +01:00
|
|
|
break;
|
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
if (tokptr == Yap_toktide) {
|
2002-04-11 16:31:58 +01:00
|
|
|
err = tokptr->TokPos;
|
|
|
|
out = count;
|
|
|
|
}
|
|
|
|
info = tokptr->TokInfo;
|
|
|
|
switch (tokptr->Tok) {
|
|
|
|
case Name_tok:
|
|
|
|
{
|
2004-09-10 21:18:01 +01:00
|
|
|
Term t0[1];
|
|
|
|
t0[0] = MkAtomTerm((Atom)info);
|
2008-12-23 01:53:52 +00:00
|
|
|
ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomAtom,1),1,t0);
|
2002-04-11 16:31:58 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Number_tok:
|
2008-12-23 01:53:52 +00:00
|
|
|
ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomNumber,1),1,&(tokptr->TokInfo));
|
2002-04-11 16:31:58 +01:00
|
|
|
break;
|
|
|
|
case Var_tok:
|
|
|
|
{
|
|
|
|
Term t[3];
|
|
|
|
VarEntry *varinfo = (VarEntry *)info;
|
|
|
|
|
|
|
|
t[0] = MkIntTerm(0);
|
2002-11-18 18:18:05 +00:00
|
|
|
t[1] = Yap_StringToList(varinfo->VarRep);
|
2002-04-11 16:31:58 +01:00
|
|
|
if (varinfo->VarAdr == TermNil) {
|
2002-04-16 20:48:45 +01:00
|
|
|
t[2] = varinfo->VarAdr = MkVarTerm();
|
|
|
|
} else {
|
|
|
|
t[2] = varinfo->VarAdr;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2008-12-23 01:53:52 +00:00
|
|
|
ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomGVar,3),3,t);
|
2002-04-11 16:31:58 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case String_tok:
|
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
Term t0 = Yap_StringToList((char *)info);
|
2008-12-23 01:53:52 +00:00
|
|
|
ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomString,1),1,&t0);
|
2002-04-11 16:31:58 +01:00
|
|
|
}
|
|
|
|
break;
|
2006-11-27 17:42:03 +00:00
|
|
|
case WString_tok:
|
|
|
|
{
|
2008-07-24 17:02:04 +01:00
|
|
|
Term t0 = Yap_WideStringToList((wchar_t *)info);
|
2008-12-23 01:53:52 +00:00
|
|
|
ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomString,1),1,&t0);
|
2006-11-27 17:42:03 +00:00
|
|
|
}
|
|
|
|
break;
|
2002-11-19 17:10:45 +00:00
|
|
|
case Error_tok:
|
2005-12-17 03:25:39 +00:00
|
|
|
case eot_tok:
|
2002-11-19 17:10:45 +00:00
|
|
|
break;
|
2002-04-11 16:31:58 +01:00
|
|
|
case Ponctuation_tok:
|
|
|
|
{
|
|
|
|
char s[2];
|
|
|
|
s[1] = '\0';
|
|
|
|
if (Ord (info) == 'l') {
|
|
|
|
s[0] = '(';
|
|
|
|
} else {
|
|
|
|
s[0] = (char)info;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
ts[0] = MkAtomTerm(Yap_LookupAtom(s));
|
2002-04-11 16:31:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tokptr->Tok == Ord (eot_tok)) {
|
|
|
|
*error = TermNil;
|
|
|
|
end = tokptr->TokPos;
|
|
|
|
break;
|
2002-11-19 17:10:45 +00:00
|
|
|
} else if (tokptr->Tok != Ord (Error_tok)) {
|
|
|
|
ts[1] = MkIntegerTerm(tokptr->TokPos);
|
|
|
|
*error =
|
2008-12-24 09:04:44 +00:00
|
|
|
MkPairTerm(Yap_MkApplTerm(FunctorMinus,2,ts),TermNil);
|
2002-11-19 17:10:45 +00:00
|
|
|
error = RepPair(*error)+1;
|
|
|
|
count++;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2002-04-11 16:31:58 +01:00
|
|
|
tokptr = tokptr->TokNext;
|
|
|
|
}
|
2010-03-02 23:18:04 +00:00
|
|
|
if (IsVarTerm(*outp) && (VarOfTerm(*outp) > H || VarOfTerm(*outp) < H0)) {
|
|
|
|
tf[0] = Yap_MkNewApplTerm(Yap_MkFunctor(AtomRead,1),1);
|
|
|
|
} else {
|
|
|
|
tf[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomRead,1),1,outp);
|
|
|
|
}
|
2002-04-11 16:31:58 +01:00
|
|
|
{
|
|
|
|
Term t[3];
|
2008-06-12 11:55:52 +01:00
|
|
|
|
2002-04-11 16:31:58 +01:00
|
|
|
t[0] = MkIntegerTerm(start);
|
|
|
|
t[1] = MkIntegerTerm(err);
|
|
|
|
t[2] = MkIntegerTerm(end);
|
2008-12-23 01:53:52 +00:00
|
|
|
tf[1] = Yap_MkApplTerm(Yap_MkFunctor(AtomBetween,3),3,t);
|
2002-04-11 16:31:58 +01:00
|
|
|
}
|
2008-12-23 01:53:52 +00:00
|
|
|
tf[2] = MkAtomTerm(AtomHERE);
|
2002-04-11 16:31:58 +01:00
|
|
|
tf[4] = MkIntegerTerm(out);
|
2002-06-17 16:28:01 +01:00
|
|
|
tf[5] = MkIntegerTerm(err);
|
2008-06-12 11:55:52 +01:00
|
|
|
tf[6] = StreamName(sno);
|
2008-12-24 09:04:44 +00:00
|
|
|
return(Yap_MkApplTerm(FunctorSyntaxError,7,tf));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2002-06-17 16:28:01 +01:00
|
|
|
Int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_FirstLineInParse (void)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2008-06-16 22:22:15 +01:00
|
|
|
return StartLine;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_startline (void)
|
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
return (Yap_unify_constant (ARG1, MkIntegerTerm (StartLine)));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* control the parser error handler */
|
|
|
|
static Int
|
|
|
|
p_set_read_error_handler(void)
|
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
char *s;
|
|
|
|
if (IsVarTerm(t)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR,t,"set_read_error_handler");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
if (!IsAtomTerm(t)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(TYPE_ERROR_ATOM,t,"bad syntax_error handler");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
s = RepAtom(AtomOfTerm(t))->StrOfAE;
|
|
|
|
if (!strcmp(s, "fail")) {
|
2002-06-05 02:34:06 +01:00
|
|
|
ParserErrorStyle = FAIL_ON_PARSER_ERROR;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else if (!strcmp(s, "error")) {
|
2002-06-05 02:34:06 +01:00
|
|
|
ParserErrorStyle = EXCEPTION_ON_PARSER_ERROR;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else if (!strcmp(s, "quiet")) {
|
2002-06-05 02:34:06 +01:00
|
|
|
ParserErrorStyle = QUIET_ON_PARSER_ERROR;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else if (!strcmp(s, "dec10")) {
|
2002-06-05 02:34:06 +01:00
|
|
|
ParserErrorStyle = CONTINUE_ON_PARSER_ERROR;
|
2001-04-09 20:54:03 +01:00
|
|
|
} else {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_SYNTAX_ERROR_HANDLER,t,"bad syntax_error handler");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return the status for the parser error handler */
|
|
|
|
static Int
|
|
|
|
p_get_read_error_handler(void)
|
|
|
|
{
|
|
|
|
Term t;
|
|
|
|
|
2002-06-05 02:34:06 +01:00
|
|
|
switch (ParserErrorStyle) {
|
2001-04-09 20:54:03 +01:00
|
|
|
case FAIL_ON_PARSER_ERROR:
|
2008-12-23 01:53:52 +00:00
|
|
|
t = MkAtomTerm(AtomFail);
|
2001-04-09 20:54:03 +01:00
|
|
|
break;
|
|
|
|
case EXCEPTION_ON_PARSER_ERROR:
|
2008-12-23 01:53:52 +00:00
|
|
|
t = MkAtomTerm(AtomError);
|
2001-04-09 20:54:03 +01:00
|
|
|
break;
|
|
|
|
case QUIET_ON_PARSER_ERROR:
|
2008-12-23 01:53:52 +00:00
|
|
|
t = MkAtomTerm(AtomQuiet);
|
2001-04-09 20:54:03 +01:00
|
|
|
break;
|
|
|
|
case CONTINUE_ON_PARSER_ERROR:
|
2008-12-23 01:53:52 +00:00
|
|
|
t = MkAtomTerm(AtomDec10);
|
2001-04-09 20:54:03 +01:00
|
|
|
break;
|
|
|
|
default:
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(SYSTEM_ERROR,TermNil,"corrupted syntax_error handler");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
return (Yap_unify_constant (ARG1, t));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2011-02-12 18:42:44 +00:00
|
|
|
int
|
|
|
|
Yap_readTerm(int sno, Term *tp, Term *varnames, Term *terror, Term *tpos)
|
|
|
|
{
|
|
|
|
TokEntry *tokstart;
|
|
|
|
Term pt;
|
|
|
|
|
|
|
|
if (sno < 0) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
tokstart = Yap_tokptr = Yap_toktide = Yap_tokenizer(sno, tpos);
|
|
|
|
if (Yap_ErrorMessage)
|
|
|
|
{
|
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
|
|
|
if (terror)
|
|
|
|
*terror = MkAtomTerm(Yap_LookupAtom(Yap_ErrorMessage));
|
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
pt = Yap_Parse();
|
|
|
|
if (Yap_ErrorMessage) {
|
|
|
|
Term t0 = MkVarTerm();
|
|
|
|
*terror = syntax_error(tokstart, sno, &t0);
|
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (varnames) {
|
|
|
|
*varnames = Yap_VarNames(Yap_VarTable, TermNil);
|
|
|
|
if (!*varnames) {
|
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*tp = pt;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-10-21 17:09:03 +01:00
|
|
|
/*
|
|
|
|
Assumes
|
|
|
|
Flag: ARG1
|
|
|
|
Term: ARG2
|
|
|
|
Module: ARG3
|
|
|
|
Vars: ARG4
|
|
|
|
Pos: ARG5
|
|
|
|
Err: ARG6
|
|
|
|
*/
|
2001-04-09 20:54:03 +01:00
|
|
|
static Int
|
2005-12-17 03:25:39 +00:00
|
|
|
do_read(int inp_stream, int nargs)
|
2003-01-08 16:45:35 +00:00
|
|
|
{
|
2001-04-09 20:54:03 +01:00
|
|
|
Term t, v;
|
2003-01-08 16:45:35 +00:00
|
|
|
TokEntry *tokstart;
|
2001-04-09 20:54:03 +01:00
|
|
|
#if EMACS
|
|
|
|
int emacs_cares = FALSE;
|
|
|
|
#endif
|
2008-02-12 17:03:59 +00:00
|
|
|
Term tmod = Deref(ARG3), OCurrentModule = CurrentModule, tpos;
|
2005-10-21 17:09:03 +01:00
|
|
|
|
|
|
|
if (IsVarTerm(tmod)) {
|
|
|
|
tmod = CurrentModule;
|
|
|
|
} else if (!IsAtomTerm(tmod)) {
|
|
|
|
Yap_Error(TYPE_ERROR_ATOM, tmod, "read_term/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
if (Stream[inp_stream].status & Binary_Stream_f) {
|
|
|
|
Yap_Error(PERMISSION_ERROR_INPUT_BINARY_STREAM, MkAtomTerm(Stream[inp_stream].u.file.name), "read_term/2");
|
2005-10-21 17:09:03 +01:00
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2005-12-18 17:12:33 +00:00
|
|
|
Yap_Error_TYPE = YAP_NO_ERROR;
|
2010-08-02 13:03:48 +01:00
|
|
|
tpos = StreamPosition(inp_stream);
|
|
|
|
if (!Yap_unify(tpos,ARG5)) {
|
|
|
|
/* do this early so that we do not have to protect it in case of stack expansion */
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
while (TRUE) {
|
2002-10-28 20:00:59 +00:00
|
|
|
CELL *old_H;
|
2005-12-17 03:25:39 +00:00
|
|
|
UInt cpos = 0;
|
|
|
|
int seekable = Stream[inp_stream].status & Seekable_Stream_f;
|
|
|
|
#if HAVE_FGETPOS
|
|
|
|
fpos_t rpos;
|
|
|
|
#endif
|
2009-12-19 21:57:20 +00:00
|
|
|
int ungetc_oldc = 0;
|
|
|
|
int had_ungetc = FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2005-12-17 03:25:39 +00:00
|
|
|
/* two cases where we can seek: memory and console */
|
|
|
|
if (seekable) {
|
2009-12-19 21:57:20 +00:00
|
|
|
if (Stream[inp_stream].stream_getc == PlUnGetc) {
|
|
|
|
had_ungetc = TRUE;
|
|
|
|
ungetc_oldc = Stream[inp_stream].och;
|
|
|
|
}
|
2011-02-12 18:42:44 +00:00
|
|
|
cpos = Stream[inp_stream].charcount;
|
2005-12-17 03:25:39 +00:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
/* Scans the term using stack space */
|
2005-12-17 03:25:39 +00:00
|
|
|
while (TRUE) {
|
|
|
|
old_H = H;
|
|
|
|
Yap_eot_before_eof = FALSE;
|
2008-02-12 17:03:59 +00:00
|
|
|
tpos = StreamPosition(inp_stream);
|
2008-10-23 22:17:45 +01:00
|
|
|
tokstart = Yap_tokptr = Yap_toktide = Yap_tokenizer(inp_stream, &tpos);
|
2006-07-27 20:04:56 +01:00
|
|
|
if (Yap_Error_TYPE != YAP_NO_ERROR && seekable) {
|
2005-12-17 03:25:39 +00:00
|
|
|
H = old_H;
|
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
2009-12-19 21:57:20 +00:00
|
|
|
if (had_ungetc) {
|
|
|
|
Stream[inp_stream].stream_getc = PlUnGetc;
|
|
|
|
Stream[inp_stream].och = ungetc_oldc;
|
|
|
|
}
|
2010-04-14 10:57:00 +01:00
|
|
|
if (seekable) {
|
2011-02-12 18:42:44 +00:00
|
|
|
if (Stream[inp_stream].status) {
|
2005-12-17 03:25:39 +00:00
|
|
|
#if HAVE_FGETPOS
|
2010-04-14 10:57:00 +01:00
|
|
|
fsetpos(Stream[inp_stream].u.file.file, &rpos);
|
2005-12-17 03:25:39 +00:00
|
|
|
#else
|
2010-04-14 10:57:00 +01:00
|
|
|
fseek(Stream[inp_stream].u.file.file, cpos, 0L);
|
2005-12-17 03:25:39 +00:00
|
|
|
#endif
|
2010-04-14 10:57:00 +01:00
|
|
|
}
|
2005-12-17 03:25:39 +00:00
|
|
|
}
|
|
|
|
if (Yap_Error_TYPE == OUT_OF_TRAIL_ERROR) {
|
|
|
|
Yap_Error_TYPE = YAP_NO_ERROR;
|
2010-05-11 12:25:49 +01:00
|
|
|
if (!Yap_growtrail (sizeof(CELL) * K16, FALSE)) {
|
2005-12-17 03:25:39 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
} else if (Yap_Error_TYPE == OUT_OF_AUXSPACE_ERROR) {
|
|
|
|
Yap_Error_TYPE = YAP_NO_ERROR;
|
2009-05-23 00:35:24 +01:00
|
|
|
if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE)) {
|
2005-12-17 03:25:39 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2006-02-01 13:58:30 +00:00
|
|
|
} else if (Yap_Error_TYPE == OUT_OF_HEAP_ERROR) {
|
|
|
|
Yap_Error_TYPE = YAP_NO_ERROR;
|
|
|
|
if (!Yap_growheap(FALSE, 0, NULL)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-12-17 03:25:39 +00:00
|
|
|
} else if (Yap_Error_TYPE == OUT_OF_STACK_ERROR) {
|
|
|
|
Yap_Error_TYPE = YAP_NO_ERROR;
|
2006-08-07 19:51:44 +01:00
|
|
|
if (!Yap_gcl(Yap_Error_Size, nargs, ENV, CP)) {
|
2005-12-17 03:25:39 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* done with this */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Yap_Error_TYPE = YAP_NO_ERROR;
|
2002-10-28 20:00:59 +00:00
|
|
|
/* preserve value of H after scanning: otherwise we may lose strings
|
|
|
|
and floats */
|
|
|
|
old_H = H;
|
2003-10-06 15:16:23 +01:00
|
|
|
if (Stream[inp_stream].status & Eof_Stream_f) {
|
2011-02-12 18:42:44 +00:00
|
|
|
if (Yap_eot_before_eof) {
|
2003-10-06 15:16:23 +01:00
|
|
|
/* next read should give out an end of file */
|
|
|
|
Stream[inp_stream].status |= Push_Eof_Stream_f;
|
|
|
|
} else {
|
2004-11-22 22:28:06 +00:00
|
|
|
if (tokstart != NULL && tokstart->Tok != Ord (eot_tok)) {
|
2003-10-06 15:16:23 +01:00
|
|
|
/* we got the end of file from an abort */
|
2008-05-23 22:06:44 +01:00
|
|
|
if (Yap_ErrorMessage &&
|
2008-05-28 18:18:35 +01:00
|
|
|
!strcmp(Yap_ErrorMessage,"Abort")) {
|
2004-02-05 16:57:02 +00:00
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-10-06 15:16:23 +01:00
|
|
|
/* we need to force the next reading to also give end of file.*/
|
|
|
|
Stream[inp_stream].status |= Push_Eof_Stream_f;
|
|
|
|
Yap_ErrorMessage = "end of file found before end of term";
|
|
|
|
} else {
|
2004-02-05 16:57:02 +00:00
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
2002-06-17 16:28:01 +01:00
|
|
|
|
2010-08-02 13:03:48 +01:00
|
|
|
return Yap_unify_constant(ARG2, MkAtomTerm (AtomEof))
|
2009-07-21 06:11:44 +01:00
|
|
|
&& Yap_unify_constant(ARG4, TermNil);
|
2003-10-06 15:16:23 +01:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
repeat_cycle:
|
2005-10-21 17:09:03 +01:00
|
|
|
CurrentModule = tmod;
|
2004-10-28 21:12:23 +01:00
|
|
|
if (Yap_ErrorMessage || (t = Yap_Parse()) == 0) {
|
2005-10-21 17:09:03 +01:00
|
|
|
CurrentModule = OCurrentModule;
|
2005-01-03 17:06:05 +00:00
|
|
|
if (Yap_ErrorMessage) {
|
|
|
|
int res;
|
|
|
|
|
|
|
|
if (!strcmp(Yap_ErrorMessage,"Stack Overflow") ||
|
2007-04-18 07:30:41 +01:00
|
|
|
!strcmp(Yap_ErrorMessage,"Trail Overflow") ||
|
|
|
|
!strcmp(Yap_ErrorMessage,"Heap Overflow")) {
|
2005-01-03 17:06:05 +00:00
|
|
|
/* ignore term we just built */
|
|
|
|
tr_fr_ptr old_TR = TR;
|
|
|
|
|
2007-04-18 07:30:41 +01:00
|
|
|
|
2005-01-03 17:06:05 +00:00
|
|
|
H = old_H;
|
|
|
|
TR = (tr_fr_ptr)ScannerStack;
|
|
|
|
|
|
|
|
if (!strcmp(Yap_ErrorMessage,"Stack Overflow"))
|
|
|
|
res = Yap_growstack_in_parser(&old_TR, &tokstart, &Yap_VarTable);
|
2007-04-18 07:30:41 +01:00
|
|
|
else if (!strcmp(Yap_ErrorMessage,"Heap Overflow"))
|
|
|
|
res = Yap_growheap_in_parser(&old_TR, &tokstart, &Yap_VarTable);
|
2005-01-03 17:06:05 +00:00
|
|
|
else
|
|
|
|
res = Yap_growtrail_in_parser(&old_TR, &tokstart, &Yap_VarTable);
|
|
|
|
if (res) {
|
|
|
|
ScannerStack = (char *)TR;
|
|
|
|
TR = old_TR;
|
|
|
|
old_H = H;
|
|
|
|
Yap_tokptr = Yap_toktide = tokstart;
|
|
|
|
Yap_ErrorMessage = NULL;
|
|
|
|
goto repeat_cycle;
|
|
|
|
}
|
2004-10-28 21:12:23 +01:00
|
|
|
ScannerStack = (char *)TR;
|
|
|
|
TR = old_TR;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
2002-06-05 02:34:06 +01:00
|
|
|
if (ParserErrorStyle == QUIET_ON_PARSER_ERROR) {
|
2002-06-05 02:22:57 +01:00
|
|
|
/* just fail */
|
2004-02-05 16:57:02 +00:00
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
|
|
|
return FALSE;
|
2002-06-05 02:34:06 +01:00
|
|
|
} else if (ParserErrorStyle == CONTINUE_ON_PARSER_ERROR) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_ErrorMessage = NULL;
|
2002-06-05 02:22:57 +01:00
|
|
|
/* try again */
|
|
|
|
goto repeat_cycle;
|
2002-04-19 15:42:58 +01:00
|
|
|
} else {
|
2009-10-26 22:56:18 +00:00
|
|
|
Term terr = syntax_error(tokstart, inp_stream, &ARG2);
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_ErrorMessage == NULL)
|
|
|
|
Yap_ErrorMessage = "SYNTAX ERROR";
|
2002-06-05 02:22:57 +01:00
|
|
|
|
2002-06-05 02:34:06 +01:00
|
|
|
if (ParserErrorStyle == EXCEPTION_ON_PARSER_ERROR) {
|
2004-02-05 16:57:02 +00:00
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(SYNTAX_ERROR,terr,Yap_ErrorMessage);
|
2004-02-05 16:57:02 +00:00
|
|
|
return FALSE;
|
2002-06-05 02:22:57 +01:00
|
|
|
} else /* FAIL ON PARSER ERROR */ {
|
2008-02-12 22:53:02 +00:00
|
|
|
Term t[2];
|
2002-06-05 02:22:57 +01:00
|
|
|
t[0] = terr;
|
2002-11-18 18:18:05 +00:00
|
|
|
t[1] = MkAtomTerm(Yap_LookupAtom(Yap_ErrorMessage));
|
2004-02-05 16:57:02 +00:00
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
2010-08-02 13:03:48 +01:00
|
|
|
return Yap_unify(ARG6,Yap_MkApplTerm(Yap_MkFunctor(AtomError,2),2,t));
|
2002-06-05 02:22:57 +01:00
|
|
|
}
|
2002-04-11 16:31:58 +01:00
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
} else {
|
2005-10-21 17:09:03 +01:00
|
|
|
CurrentModule = OCurrentModule;
|
2001-04-09 20:54:03 +01:00
|
|
|
/* parsing succeeded */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#if EMACS
|
|
|
|
first_char = tokstart->TokPos;
|
|
|
|
#endif /* EMACS */
|
2010-08-02 13:03:48 +01:00
|
|
|
if (!Yap_unify(t, ARG2))
|
2010-08-02 11:56:14 +01:00
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
if (AtomOfTerm (Deref (ARG1)) == AtomTrue) {
|
|
|
|
while (TRUE) {
|
|
|
|
CELL *old_H = H;
|
|
|
|
|
2010-10-27 14:49:27 +01:00
|
|
|
if (setjmp(Yap_IOBotch) == 0) {
|
2002-11-18 18:18:05 +00:00
|
|
|
v = Yap_VarNames(Yap_VarTable, TermNil);
|
2001-04-09 20:54:03 +01:00
|
|
|
break;
|
|
|
|
} else {
|
2006-01-02 02:16:19 +00:00
|
|
|
tr_fr_ptr old_TR;
|
|
|
|
restore_machine_regs();
|
|
|
|
|
|
|
|
old_TR = TR;
|
2001-04-09 20:54:03 +01:00
|
|
|
/* restart global */
|
|
|
|
H = old_H;
|
2004-10-28 21:12:23 +01:00
|
|
|
TR = (tr_fr_ptr)ScannerStack;
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_growstack_in_parser(&old_TR, &tokstart, &Yap_VarTable);
|
2004-10-28 21:12:23 +01:00
|
|
|
ScannerStack = (char *)TR;
|
|
|
|
TR = old_TR;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
2004-02-05 16:57:02 +00:00
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
2010-08-02 11:56:14 +01:00
|
|
|
return Yap_unify (v, ARG4);
|
2001-04-09 20:54:03 +01:00
|
|
|
} else {
|
2004-02-05 16:57:02 +00:00
|
|
|
Yap_clean_tokenizer(tokstart, Yap_VarTable, Yap_AnonVarTable);
|
2010-08-02 11:56:14 +01:00
|
|
|
return TRUE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-01-08 16:45:35 +00:00
|
|
|
static Int
|
|
|
|
p_read (void)
|
2005-10-21 17:09:03 +01:00
|
|
|
{ /* '$read'(+Flag,?Term,?Module,?Vars,-Pos,-Err) */
|
2006-11-27 17:42:03 +00:00
|
|
|
return do_read(Yap_c_input_stream, 6);
|
2003-01-08 16:45:35 +00:00
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static Int
|
|
|
|
p_read2 (void)
|
2005-10-21 17:09:03 +01:00
|
|
|
{ /* '$read2'(+Flag,?Term,?Module,?Vars,-Pos,-Err,+Stream) */
|
2003-01-08 16:45:35 +00:00
|
|
|
int inp_stream;
|
2006-04-28 16:48:33 +01:00
|
|
|
Int out;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2002-11-18 18:18:05 +00:00
|
|
|
/* needs to change Yap_c_output_stream for write */
|
2005-10-21 17:09:03 +01:00
|
|
|
inp_stream = CheckStream (ARG7, Input_Stream_f, "read/3");
|
2003-01-08 16:45:35 +00:00
|
|
|
if (inp_stream == -1) {
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[inp_stream].streamlock);
|
|
|
|
out = do_read(inp_stream, 7);
|
|
|
|
return out;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_user_file_name (void)
|
|
|
|
{
|
|
|
|
Term tout;
|
|
|
|
int sno = CheckStream (ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f,"user_file_name/2");
|
|
|
|
if (sno < 0)
|
|
|
|
return (FALSE);
|
2011-02-12 23:42:15 +00:00
|
|
|
tout = Stream[sno].u.file.user_name;
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2002-11-18 18:18:05 +00:00
|
|
|
return (Yap_unify_constant (ARG2, tout));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2011-02-14 20:14:31 +00:00
|
|
|
|
2008-02-12 17:03:59 +00:00
|
|
|
static Term
|
|
|
|
StreamPosition(int sno)
|
|
|
|
{
|
2011-02-14 20:14:31 +00:00
|
|
|
return TermNil;
|
2008-02-12 17:03:59 +00:00
|
|
|
}
|
|
|
|
|
2008-10-23 22:17:45 +01:00
|
|
|
Term
|
|
|
|
Yap_StreamPosition(int sno)
|
|
|
|
{
|
|
|
|
return StreamPosition(sno);
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
static Term
|
|
|
|
read_line(int sno)
|
|
|
|
{
|
|
|
|
Term tail;
|
|
|
|
Int ch;
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
if ((ch = Stream[sno].stream_wgetc(sno)) == 10) {
|
2001-04-09 20:54:03 +01:00
|
|
|
return(TermNil);
|
|
|
|
}
|
|
|
|
tail = read_line(sno);
|
|
|
|
return(MkPairTerm(MkIntTerm(ch),tail));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_get0_line_codes (void)
|
|
|
|
{ /* '$get0'(Stream,-N) */
|
|
|
|
int sno = CheckStream (ARG1, Input_Stream_f, "get0/2");
|
|
|
|
Int status;
|
|
|
|
Term out;
|
2006-11-16 13:56:08 +00:00
|
|
|
Int ch = '\0';
|
|
|
|
int rewind;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
if (sno < 0)
|
|
|
|
return(FALSE);
|
2006-11-16 13:56:08 +00:00
|
|
|
if (Stream[sno].stream_getc == PlUnGetc) {
|
|
|
|
ch = PlUnGetc(sno);
|
|
|
|
rewind = TRUE;
|
|
|
|
} else {
|
|
|
|
rewind = FALSE;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
status = Stream[sno].status;
|
2006-11-27 17:42:03 +00:00
|
|
|
if (status & Binary_Stream_f) {
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
Yap_Error(PERMISSION_ERROR_INPUT_BINARY_STREAM, ARG1, "get0/2");
|
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2010-08-04 11:37:12 +01:00
|
|
|
out = read_line(sno);
|
2006-11-16 13:56:08 +00:00
|
|
|
if (rewind)
|
|
|
|
return Yap_unify(MkPairTerm(MkIntegerTerm(ch),out), ARG2);
|
|
|
|
else
|
|
|
|
return Yap_unify(out,ARG2);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#define FORMAT_MAX_SIZE 256
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
Int pos; /* tab point */
|
|
|
|
char pad; /* ok, it's not standard english */
|
|
|
|
} pads;
|
|
|
|
|
2005-10-28 18:38:50 +01:00
|
|
|
typedef struct format_status {
|
|
|
|
int format_error;
|
|
|
|
char *format_ptr, *format_base, *format_max;
|
|
|
|
int format_buf_size;
|
|
|
|
pads pad_entries[16], *pad_max;
|
|
|
|
} format_info;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2007-01-28 14:26:37 +00:00
|
|
|
static int
|
2006-11-27 17:42:03 +00:00
|
|
|
format_putc(int sno, wchar_t ch) {
|
2005-10-28 18:38:50 +01:00
|
|
|
if (FormatInfo->format_buf_size == -1)
|
|
|
|
return EOF;
|
2001-04-09 20:54:03 +01:00
|
|
|
if (ch == 10) {
|
2005-10-28 18:38:50 +01:00
|
|
|
char *ptr = FormatInfo->format_base;
|
2001-04-09 20:54:03 +01:00
|
|
|
#if MAC || _MSC_VER
|
|
|
|
ch = '\n';
|
|
|
|
#endif
|
2005-10-28 18:38:50 +01:00
|
|
|
for (ptr = FormatInfo->format_base; ptr < FormatInfo->format_ptr; ptr++) {
|
2001-04-09 20:54:03 +01:00
|
|
|
Stream[sno].stream_putc(sno, *ptr);
|
|
|
|
}
|
|
|
|
/* reset line */
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo->format_ptr = FormatInfo->format_base;
|
|
|
|
FormatInfo->pad_max = FormatInfo->pad_entries;
|
2001-04-09 20:54:03 +01:00
|
|
|
Stream[sno].stream_putc(sno, '\n');
|
|
|
|
return((int)10);
|
|
|
|
} else {
|
2005-10-28 18:38:50 +01:00
|
|
|
*FormatInfo->format_ptr++ = (char)ch;
|
|
|
|
if (FormatInfo->format_ptr == FormatInfo->format_max) {
|
2002-04-11 16:31:58 +01:00
|
|
|
/* oops, we have reached an overflow */
|
2005-10-28 18:38:50 +01:00
|
|
|
Int new_max_size = FormatInfo->format_buf_size + FORMAT_MAX_SIZE;
|
2002-04-11 16:31:58 +01:00
|
|
|
char *newbuf;
|
|
|
|
|
2002-11-18 18:18:05 +00:00
|
|
|
if ((newbuf = Yap_AllocAtomSpace(new_max_size*sizeof(char))) == NULL) {
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo->format_buf_size = -1;
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(SYSTEM_ERROR, TermNil, "YAP could not grow heap for format/2");
|
2002-04-11 16:31:58 +01:00
|
|
|
return(EOF);
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
#if HAVE_MEMMOVE
|
2005-10-28 18:38:50 +01:00
|
|
|
memmove((void *)newbuf, (void *)FormatInfo->format_base, (size_t)((FormatInfo->format_ptr-FormatInfo->format_base)*sizeof(char)));
|
2001-04-09 20:54:03 +01:00
|
|
|
#else
|
2002-04-11 16:31:58 +01:00
|
|
|
{
|
2005-10-28 18:38:50 +01:00
|
|
|
Int n = FormatInfo->format_ptr-FormatInfo->format_base;
|
2002-04-11 16:31:58 +01:00
|
|
|
char *to = newbuf;
|
2005-10-28 18:38:50 +01:00
|
|
|
char *from = FormatInfo->format_base;
|
2002-04-11 16:31:58 +01:00
|
|
|
while (n-- >= 0) {
|
|
|
|
*to++ = *from++;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
#endif
|
2005-10-28 18:38:50 +01:00
|
|
|
Yap_FreeAtomSpace(FormatInfo->format_base);
|
|
|
|
FormatInfo->format_ptr = newbuf+(FormatInfo->format_ptr-FormatInfo->format_base);
|
|
|
|
FormatInfo->format_base = newbuf;
|
|
|
|
FormatInfo->format_max = newbuf+new_max_size;
|
|
|
|
FormatInfo->format_buf_size = new_max_size;
|
2004-01-29 13:37:10 +00:00
|
|
|
if (ActiveSignals & YAP_CDOVF_SIGNAL) {
|
|
|
|
if (!Yap_growheap(FALSE, 0, NULL)) {
|
2004-08-11 17:14:55 +01:00
|
|
|
Yap_Error(OUT_OF_HEAP_ERROR, TermNil, "YAP failed to grow heap at format");
|
2004-01-29 13:37:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
return ((int) ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fill_pads(int nchars)
|
|
|
|
{
|
|
|
|
int nfillers, fill_space, lfill_space;
|
|
|
|
|
|
|
|
if (nchars <= 0) return; /* ignore */
|
2005-10-28 18:38:50 +01:00
|
|
|
nfillers = FormatInfo->pad_max-FormatInfo->pad_entries;
|
2001-04-09 20:54:03 +01:00
|
|
|
if (nfillers == 0) {
|
|
|
|
/* OK, just pad with spaces */
|
|
|
|
while (nchars--) {
|
2005-10-28 18:38:50 +01:00
|
|
|
*FormatInfo->format_ptr++ = ' ';
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fill_space = nchars/nfillers;
|
|
|
|
lfill_space = nchars%nfillers;
|
|
|
|
|
|
|
|
if (fill_space) {
|
2005-10-28 18:38:50 +01:00
|
|
|
pads *padi = FormatInfo->pad_max;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2005-10-28 18:38:50 +01:00
|
|
|
while (padi > FormatInfo->pad_entries) {
|
2001-04-09 20:54:03 +01:00
|
|
|
char *start_pos;
|
|
|
|
int n, i;
|
|
|
|
padi--;
|
2005-10-28 18:38:50 +01:00
|
|
|
start_pos = FormatInfo->format_base+padi->pos;
|
|
|
|
n = FormatInfo->format_ptr-start_pos;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
#if HAVE_MEMMOVE
|
|
|
|
memmove((void *)(start_pos+fill_space), (void *)start_pos, (size_t)(n*sizeof(char)));
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
char *to = start_pos+(fill_space+n);
|
2005-10-28 18:38:50 +01:00
|
|
|
char *from = FormatInfo->format_ptr;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
while (n-- > 0) {
|
|
|
|
*--to = *--from;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo->format_ptr += fill_space;
|
2001-04-09 20:54:03 +01:00
|
|
|
for (i = 0; i < fill_space; i++) {
|
|
|
|
*start_pos++ = padi->pad;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (lfill_space--) {
|
2005-10-28 18:38:50 +01:00
|
|
|
*FormatInfo->format_ptr++ = FormatInfo->pad_max[-1].pad;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-13 18:39:29 +00:00
|
|
|
static int
|
2007-01-28 14:26:37 +00:00
|
|
|
format_print_str (Int sno, Int size, Int has_size, Term args, int (* f_putc)(int, wchar_t))
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
|
|
|
Term arghd;
|
2004-02-13 18:39:29 +00:00
|
|
|
while (!has_size || size > 0) {
|
|
|
|
if (IsVarTerm(args)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, args, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
} else if (args == TermNil) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (!IsPairTerm (args)) {
|
|
|
|
Yap_Error(TYPE_ERROR_LIST, args, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
arghd = HeadOfTerm (args);
|
|
|
|
args = TailOfTerm (args);
|
|
|
|
if (IsVarTerm(arghd)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, arghd, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
} else if (!IsIntTerm (arghd)) {
|
|
|
|
Yap_Error(TYPE_ERROR_LIST, arghd, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-07-15 16:47:08 +01:00
|
|
|
f_putc(sno, (int) IntOfTerm (arghd));
|
2004-02-13 18:39:29 +00:00
|
|
|
size--;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
fst_ok,
|
|
|
|
fst_error,
|
|
|
|
fst_too_long
|
|
|
|
} format_cp_res;
|
|
|
|
|
|
|
|
static format_cp_res
|
|
|
|
copy_format_string(Term inp, char *out, int max)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
while (inp != TermNil) {
|
|
|
|
Term hd;
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
if (IsVarTerm(inp)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR,inp,"format/2");
|
|
|
|
return fst_error;
|
|
|
|
}
|
|
|
|
if (!IsPairTerm(inp)) {
|
|
|
|
Yap_Error(TYPE_ERROR_LIST,inp,"format/2");
|
|
|
|
return fst_error;
|
|
|
|
}
|
|
|
|
hd = HeadOfTerm(inp);
|
|
|
|
if (IsVarTerm(hd)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR,hd,"format/2");
|
|
|
|
return fst_error;
|
|
|
|
}
|
|
|
|
if (!IsIntTerm(hd)) {
|
|
|
|
Yap_Error(TYPE_ERROR_INTEGER,hd,"format/2");
|
|
|
|
return fst_error;
|
|
|
|
}
|
|
|
|
ch = IntOfTerm(hd);
|
|
|
|
if (ch < 0) {
|
|
|
|
Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO,hd,"format/2");
|
|
|
|
return fst_error;
|
|
|
|
}
|
|
|
|
if (i+1 == max) {
|
|
|
|
return fst_too_long;
|
|
|
|
}
|
|
|
|
/* we've got a character */
|
|
|
|
out[i++] = ch;
|
|
|
|
/* done */
|
|
|
|
inp = TailOfTerm(inp);
|
|
|
|
}
|
|
|
|
out[i] = '\0';
|
|
|
|
return fst_ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define FORMAT_COPY_ARGS_ERROR -1
|
|
|
|
#define FORMAT_COPY_ARGS_OVERFLOW -2
|
|
|
|
|
|
|
|
static Int
|
|
|
|
format_copy_args(Term args, Term *targs, Int tsz)
|
|
|
|
{
|
|
|
|
Int n = 0;
|
|
|
|
while (args != TermNil) {
|
|
|
|
if (IsVarTerm(args)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR,args,"format/2");
|
|
|
|
return FORMAT_COPY_ARGS_ERROR;
|
|
|
|
}
|
|
|
|
if (!IsPairTerm(args)) {
|
|
|
|
Yap_Error(TYPE_ERROR_LIST,args,"format/2");
|
|
|
|
return FORMAT_COPY_ARGS_ERROR;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
if (n == tsz)
|
|
|
|
return FORMAT_COPY_ARGS_OVERFLOW;
|
|
|
|
targs[n] = HeadOfTerm(args);
|
|
|
|
args = TailOfTerm(args);
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
format_clean_up(char *format_base, char *fstr, Term *targs)
|
|
|
|
{
|
|
|
|
if (format_base)
|
|
|
|
Yap_FreeAtomSpace(format_base);
|
|
|
|
if (fstr)
|
|
|
|
Yap_FreeAtomSpace(fstr);
|
|
|
|
if (targs)
|
|
|
|
Yap_FreeAtomSpace((char *)targs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
fetch_index_from_args(Term t)
|
|
|
|
{
|
|
|
|
Int i;
|
|
|
|
|
|
|
|
if (IsVarTerm(t))
|
|
|
|
return -1;
|
|
|
|
if (!IsIntegerTerm(t))
|
|
|
|
return -1;
|
|
|
|
i = IntegerOfTerm(t);
|
|
|
|
if (i < 0)
|
|
|
|
return -1;
|
|
|
|
return i;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2004-07-06 19:24:40 +01:00
|
|
|
static int
|
|
|
|
format_has_tabs(const char *seq)
|
|
|
|
{
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
while ((ch = *seq++)) {
|
|
|
|
if (ch == '~') {
|
|
|
|
ch = *seq++;
|
2005-11-10 01:55:12 +00:00
|
|
|
if (ch == 'p' || ch == '@') {
|
|
|
|
return TRUE;
|
|
|
|
}
|
2004-07-22 22:32:23 +01:00
|
|
|
if (ch == '*') {
|
|
|
|
ch = *seq++;
|
2005-11-09 00:46:53 +00:00
|
|
|
} else {
|
|
|
|
while (ch >= '0' && ch <= '9') ch = *seq++;
|
2004-07-22 22:32:23 +01:00
|
|
|
}
|
2005-11-10 01:55:12 +00:00
|
|
|
if (ch == 't' || ch == '|' || ch == '+') {
|
2004-07-06 19:24:40 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
2005-11-09 00:46:53 +00:00
|
|
|
if (!ch)
|
|
|
|
return FALSE;
|
2004-07-06 19:24:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-01-24 10:01:40 +00:00
|
|
|
static wchar_t
|
|
|
|
base_dig(Int dig, Int ch)
|
|
|
|
{
|
|
|
|
if (dig < 10)
|
|
|
|
return dig+'0';
|
|
|
|
else if (ch == 'r')
|
|
|
|
return (dig-10)+'a';
|
|
|
|
else /* ch == 'R' */
|
|
|
|
return (dig-10)+'A';
|
|
|
|
}
|
|
|
|
|
2010-05-28 15:29:20 +01:00
|
|
|
#define TMP_STRING_SIZE 1024
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
static Int
|
2004-07-28 23:09:02 +01:00
|
|
|
format(volatile Term otail, volatile Term oargs, int sno)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2010-05-28 15:29:20 +01:00
|
|
|
char tmp1[TMP_STRING_SIZE], *tmpbase;
|
2001-04-09 20:54:03 +01:00
|
|
|
int ch;
|
2004-07-28 23:09:02 +01:00
|
|
|
int column_boundary;
|
2004-02-13 18:39:29 +00:00
|
|
|
Term mytargs[8], *targs;
|
2004-07-28 23:09:02 +01:00
|
|
|
Int tnum, targ;
|
2004-02-13 18:39:29 +00:00
|
|
|
char *fstr = NULL, *fptr;
|
2004-07-28 23:09:02 +01:00
|
|
|
Term args;
|
|
|
|
Term tail;
|
2007-01-28 14:26:37 +00:00
|
|
|
int (* f_putc)(int, wchar_t);
|
2004-07-06 19:24:40 +01:00
|
|
|
int has_tabs;
|
2004-11-04 18:22:36 +00:00
|
|
|
volatile void *old_handler;
|
2005-10-28 18:38:50 +01:00
|
|
|
format_info finfo;
|
|
|
|
Term fmod = CurrentModule;
|
2004-07-28 23:09:02 +01:00
|
|
|
|
2005-12-18 17:12:33 +00:00
|
|
|
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo = &finfo;
|
|
|
|
finfo.pad_max = finfo.pad_entries;
|
|
|
|
finfo.format_error = FALSE;
|
2011-02-12 18:42:44 +00:00
|
|
|
old_handler = NULL;
|
2004-07-28 23:09:02 +01:00
|
|
|
args = oargs;
|
|
|
|
tail = otail;
|
|
|
|
targ = 0;
|
|
|
|
column_boundary = 0;
|
2001-04-09 20:54:03 +01:00
|
|
|
if (IsVarTerm(tail)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR,tail,"format/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
2004-02-13 18:39:29 +00:00
|
|
|
} else if (IsPairTerm (tail)) {
|
|
|
|
int sz = 256;
|
|
|
|
do {
|
|
|
|
format_cp_res fr;
|
|
|
|
|
|
|
|
fstr = fptr = Yap_AllocAtomSpace(sz*sizeof(char));
|
|
|
|
if ((fr = copy_format_string(tail, fstr, sz)) == fst_ok)
|
|
|
|
break;
|
|
|
|
if (fr == fst_error) return FALSE;
|
|
|
|
sz += 256;
|
|
|
|
Yap_FreeCodeSpace(fstr);
|
|
|
|
} while (TRUE);
|
|
|
|
} else if (IsAtomTerm(tail)) {
|
|
|
|
fstr = fptr = RepAtom(AtomOfTerm(tail))->StrOfAE;
|
|
|
|
} else {
|
|
|
|
Yap_Error(CONSISTENCY_ERROR, tail, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-10-28 18:38:50 +01:00
|
|
|
if (IsVarTerm(args)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, args, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
while (IsApplTerm(args) && FunctorOfTerm(args) == FunctorModule) {
|
|
|
|
fmod = ArgOfTerm(1,args);
|
|
|
|
args = ArgOfTerm(2,args);
|
|
|
|
if (IsVarTerm(fmod)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, fmod, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (!IsAtomTerm(fmod)) {
|
|
|
|
Yap_Error(TYPE_ERROR_ATOM, fmod, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (IsVarTerm(args)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, args, "format/2");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
if (IsPairTerm(args)) {
|
|
|
|
Int tsz = 8;
|
|
|
|
|
|
|
|
targs = mytargs;
|
|
|
|
do {
|
|
|
|
tnum = format_copy_args(args, targs, tsz);
|
|
|
|
if (tnum == FORMAT_COPY_ARGS_ERROR)
|
|
|
|
return FALSE;
|
|
|
|
else if (tnum == FORMAT_COPY_ARGS_OVERFLOW) {
|
|
|
|
if (mytargs != targs) {
|
|
|
|
Yap_FreeCodeSpace((char *)targs);
|
|
|
|
}
|
|
|
|
tsz += 16;
|
|
|
|
targs = (Term *)Yap_AllocAtomSpace(tsz*sizeof(Term));
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (TRUE);
|
|
|
|
} else if (args != TermNil) {
|
|
|
|
tnum = 1;
|
|
|
|
mytargs[0] = args;
|
|
|
|
targs = mytargs;
|
|
|
|
} else {
|
|
|
|
tnum = 0;
|
|
|
|
targs = mytargs;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.format_error = FALSE;
|
2004-02-13 18:39:29 +00:00
|
|
|
|
2004-07-06 19:24:40 +01:00
|
|
|
if ((has_tabs = format_has_tabs(fptr))) {
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.format_base = finfo.format_ptr = Yap_AllocAtomSpace(FORMAT_MAX_SIZE*sizeof(char));
|
|
|
|
finfo.format_max = finfo.format_base+FORMAT_MAX_SIZE;
|
|
|
|
if (finfo.format_ptr == NULL) {
|
2004-07-22 22:32:23 +01:00
|
|
|
Yap_Error(INSTANTIATION_ERROR,tail,"format/2");
|
|
|
|
return(FALSE);
|
|
|
|
}
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.format_buf_size = FORMAT_MAX_SIZE;
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc = format_putc;
|
|
|
|
} else {
|
2006-11-27 17:42:03 +00:00
|
|
|
f_putc = Stream[sno].stream_wputc;
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.format_base = NULL;
|
2004-07-06 19:24:40 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
while ((ch = *fptr++)) {
|
|
|
|
Term t = TermNil;
|
|
|
|
int has_repeats = FALSE;
|
2004-11-19 17:14:15 +00:00
|
|
|
int repeats = 0;
|
2004-02-13 18:39:29 +00:00
|
|
|
|
|
|
|
if (ch == '~') {
|
|
|
|
/* start command */
|
|
|
|
ch = *fptr++;
|
|
|
|
if (ch == '*') {
|
|
|
|
ch = *fptr++;
|
|
|
|
has_repeats = TRUE;
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1) {
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
}
|
|
|
|
repeats = fetch_index_from_args(targs[targ++]);
|
|
|
|
if (repeats == -1)
|
|
|
|
goto do_consistency_error;
|
|
|
|
} else if (ch == '`') {
|
|
|
|
/* next character is kept as code */
|
2004-02-13 22:10:10 +00:00
|
|
|
has_repeats = TRUE;
|
2004-02-13 18:39:29 +00:00
|
|
|
repeats = *fptr++;
|
|
|
|
ch = *fptr++;
|
|
|
|
} else if (ch >= '0' && ch <= '9') {
|
|
|
|
has_repeats = TRUE;
|
|
|
|
repeats = 0;
|
|
|
|
while (ch >= '0' && ch <= '9') {
|
|
|
|
repeats = repeats*10+(ch-'0');
|
|
|
|
ch = *fptr++;
|
|
|
|
}
|
2002-10-10 06:58:49 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
switch (ch) {
|
|
|
|
case 'a':
|
|
|
|
/* print an atom */
|
2004-05-18 16:13:05 +01:00
|
|
|
if (has_repeats || targ > tnum-1)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
|
|
|
if (IsVarTerm(t))
|
|
|
|
goto do_instantiation_error;
|
|
|
|
if (!IsAtomTerm(t))
|
|
|
|
goto do_type_atom_error;
|
2009-05-24 21:15:36 +01:00
|
|
|
Yap_StartSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite (t, f_putc, Handle_vars_f|To_heap_f, 1200);
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo = &finfo;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case 'c':
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2004-02-13 18:39:29 +00:00
|
|
|
Int nch, i;
|
|
|
|
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
|
|
|
if (IsVarTerm(t))
|
|
|
|
goto do_instantiation_error;
|
|
|
|
if (!IsIntegerTerm(t))
|
|
|
|
goto do_type_int_error;
|
|
|
|
nch = IntegerOfTerm(t);
|
|
|
|
if (nch < 0)
|
|
|
|
goto do_domain_not_less_zero_error;
|
|
|
|
if (!has_repeats)
|
|
|
|
repeats = 1;
|
|
|
|
for (i = 0; i < repeats; i++)
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc(sno, nch);
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
case 'f':
|
|
|
|
case 'g':
|
|
|
|
case 'G':
|
|
|
|
{
|
|
|
|
Float fl;
|
|
|
|
char *ptr;
|
|
|
|
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
|
|
|
if (IsVarTerm(t))
|
|
|
|
goto do_instantiation_error;
|
|
|
|
if (!IsNumTerm(t))
|
|
|
|
goto do_type_number_error;
|
|
|
|
if (IsIntegerTerm(t)) {
|
|
|
|
fl = (Float)IntegerOfTerm(t);
|
|
|
|
#ifdef USE_GMP
|
|
|
|
} else if (IsBigIntTerm(t)) {
|
2010-05-28 12:07:01 +01:00
|
|
|
fl = Yap_gmp_to_float(t);
|
2004-02-13 18:39:29 +00:00
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
fl = FloatOfTerm(t);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
if (!has_repeats)
|
|
|
|
repeats = 6;
|
|
|
|
tmp1[0] = '%';
|
|
|
|
tmp1[1] = '.';
|
|
|
|
ptr = tmp1+2;
|
2009-05-29 16:26:48 +01:00
|
|
|
#if HAVE_SNPRINTF
|
|
|
|
snprintf(ptr,256-5,"%d",repeats);
|
|
|
|
#else
|
2004-02-13 18:39:29 +00:00
|
|
|
sprintf(ptr,"%d",repeats);
|
2009-05-29 16:26:48 +01:00
|
|
|
#endif
|
2004-02-13 18:39:29 +00:00
|
|
|
while (*ptr) ptr++;
|
|
|
|
ptr[0] = ch;
|
|
|
|
ptr[1] = '\0';
|
2009-05-29 16:26:48 +01:00
|
|
|
{
|
|
|
|
char *tmp2;
|
|
|
|
if (!(tmp2 = Yap_AllocCodeSpace(repeats+10)))
|
|
|
|
goto do_type_int_error;
|
|
|
|
#if HAVE_SNPRINTF
|
|
|
|
snprintf (tmp2, repeats+10, tmp1, fl);
|
|
|
|
#else
|
|
|
|
sprintf (tmp2, tmp1, fl);
|
|
|
|
#endif
|
|
|
|
ptr = tmp2;
|
|
|
|
while ((ch = *ptr++) != 0)
|
|
|
|
f_putc(sno, ch);
|
|
|
|
Yap_FreeCodeSpace(tmp2);
|
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
case 'D':
|
|
|
|
/* print a decimal, using weird . stuff */
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
|
|
|
if (IsVarTerm(t))
|
|
|
|
goto do_instantiation_error;
|
2005-11-13 01:58:11 +00:00
|
|
|
if (!IsIntegerTerm(t)
|
|
|
|
#ifdef USE_GMP
|
|
|
|
&& !IsBigIntTerm(t)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_type_int_error;
|
|
|
|
|
2005-11-13 02:43:52 +00:00
|
|
|
{
|
2007-01-24 10:01:40 +00:00
|
|
|
Int siz = 0;
|
2005-11-13 02:43:52 +00:00
|
|
|
char *ptr = tmp1;
|
2010-05-28 15:29:20 +01:00
|
|
|
tmpbase = tmp1;
|
2005-11-13 02:43:52 +00:00
|
|
|
|
|
|
|
if (IsIntegerTerm(t)) {
|
2005-11-21 12:34:07 +00:00
|
|
|
Int il = IntegerOfTerm(t);
|
2005-11-13 02:43:52 +00:00
|
|
|
#if HAVE_SNPRINTF
|
2006-02-01 13:58:30 +00:00
|
|
|
snprintf(tmp1, 256, "%ld", (long int)il);
|
2005-11-13 02:43:52 +00:00
|
|
|
#else
|
|
|
|
sprintf(tmp1, "%ld", (long int)il);
|
|
|
|
#endif
|
|
|
|
siz = strlen(tmp1);
|
|
|
|
if (il < 0) siz--;
|
2005-11-13 01:58:11 +00:00
|
|
|
#ifdef USE_GMP
|
2010-05-28 15:29:20 +01:00
|
|
|
} else if (IsBigIntTerm(t) && RepAppl(t)[1] == BIG_INT) {
|
|
|
|
char *res;
|
2005-11-13 02:43:52 +00:00
|
|
|
|
2010-05-28 15:29:20 +01:00
|
|
|
tmpbase = tmp1;
|
|
|
|
|
|
|
|
while (!(res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE, 10))) {
|
|
|
|
if (tmpbase == tmp1) {
|
|
|
|
tmpbase = NULL;
|
|
|
|
} else {
|
|
|
|
tmpbase = res;
|
|
|
|
goto do_type_int_error;
|
|
|
|
}
|
2005-11-13 01:58:11 +00:00
|
|
|
}
|
2010-05-28 15:29:20 +01:00
|
|
|
tmpbase = res;
|
|
|
|
ptr = tmpbase;
|
2005-11-13 02:43:52 +00:00
|
|
|
#endif
|
2010-05-28 15:29:20 +01:00
|
|
|
siz = strlen(tmpbase);
|
|
|
|
} else {
|
|
|
|
goto do_type_int_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tmpbase[0] == '-') {
|
2005-11-13 02:43:52 +00:00
|
|
|
f_putc(sno, (int) '-');
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
if (ch == 'D') {
|
|
|
|
int first = TRUE;
|
2005-11-13 01:58:11 +00:00
|
|
|
|
|
|
|
while (siz > repeats) {
|
2005-11-13 02:43:52 +00:00
|
|
|
if ((siz-repeats) % 3 == 0 &&
|
|
|
|
!first) {
|
2005-11-13 01:58:11 +00:00
|
|
|
f_putc(sno, (int) ',');
|
|
|
|
}
|
|
|
|
f_putc(sno, (int) (*ptr++));
|
2005-11-13 02:43:52 +00:00
|
|
|
first = FALSE;
|
2005-11-13 01:58:11 +00:00
|
|
|
siz--;
|
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
} else {
|
|
|
|
while (siz > repeats) {
|
2005-11-13 02:43:52 +00:00
|
|
|
f_putc(sno, (int) (*ptr++));
|
2004-02-13 18:39:29 +00:00
|
|
|
siz--;
|
2005-11-10 01:55:12 +00:00
|
|
|
}
|
|
|
|
}
|
2005-11-13 02:43:52 +00:00
|
|
|
if (repeats) {
|
2010-05-28 15:29:20 +01:00
|
|
|
if (ptr == tmpbase ||
|
2005-11-13 09:49:18 +00:00
|
|
|
ptr[-1] == '-') {
|
|
|
|
f_putc(sno, (int) '0');
|
|
|
|
}
|
2005-11-13 02:43:52 +00:00
|
|
|
f_putc(sno, (int) '.');
|
2005-11-13 09:49:18 +00:00
|
|
|
while (repeats > siz) {
|
|
|
|
f_putc(sno, (int) '0');
|
|
|
|
repeats--;
|
|
|
|
}
|
2005-11-13 02:43:52 +00:00
|
|
|
while (repeats) {
|
|
|
|
f_putc(sno, (int) (*ptr++));
|
|
|
|
repeats--;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2010-05-28 15:29:20 +01:00
|
|
|
if (tmpbase != tmp1)
|
|
|
|
free(tmpbase);
|
2005-11-13 02:43:52 +00:00
|
|
|
break;
|
2004-02-13 18:39:29 +00:00
|
|
|
case 'r':
|
|
|
|
case 'R':
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2008-04-03 23:27:29 +01:00
|
|
|
Int numb, radix;
|
|
|
|
UInt divfactor = 1, size = 1, i;
|
2007-01-24 10:01:40 +00:00
|
|
|
wchar_t och;
|
2004-02-13 18:39:29 +00:00
|
|
|
|
|
|
|
/* print a decimal, using weird . stuff */
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
|
|
|
if (IsVarTerm(t))
|
|
|
|
goto do_instantiation_error;
|
|
|
|
if (!has_repeats)
|
|
|
|
radix = 8;
|
|
|
|
else
|
|
|
|
radix = repeats;
|
|
|
|
if (radix > 36 || radix < 2)
|
|
|
|
goto do_domain_error_radix;
|
2008-04-03 23:27:29 +01:00
|
|
|
#ifdef USE_GMP
|
2010-05-28 15:29:20 +01:00
|
|
|
if (IsBigIntTerm(t) && RepAppl(t)[1] == BIG_INT) {
|
|
|
|
char *pt, *res;
|
|
|
|
|
|
|
|
tmpbase = tmp1;
|
|
|
|
while (!(res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE, radix))) {
|
|
|
|
if (tmpbase == tmp1) {
|
|
|
|
tmpbase = NULL;
|
|
|
|
} else {
|
|
|
|
tmpbase = res;
|
2008-04-03 23:27:29 +01:00
|
|
|
goto do_type_int_error;
|
2010-05-28 15:29:20 +01:00
|
|
|
}
|
2008-04-03 23:27:29 +01:00
|
|
|
}
|
2010-05-28 15:29:20 +01:00
|
|
|
tmpbase = res;
|
|
|
|
pt = tmpbase;
|
2008-04-03 23:27:29 +01:00
|
|
|
while ((ch = *pt++))
|
|
|
|
f_putc(sno, ch);
|
2010-05-28 15:29:20 +01:00
|
|
|
if (tmpbase != tmp1)
|
|
|
|
free(tmpbase);
|
2008-04-03 23:27:29 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (!IsIntegerTerm(t))
|
|
|
|
goto do_type_int_error;
|
2004-02-13 18:39:29 +00:00
|
|
|
numb = IntegerOfTerm(t);
|
|
|
|
if (numb < 0) {
|
|
|
|
numb = -numb;
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc(sno, (int) '-');
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2008-12-22 12:16:31 +00:00
|
|
|
while (numb/divfactor >= radix) {
|
2008-04-03 23:27:29 +01:00
|
|
|
divfactor *= radix;
|
2007-01-24 10:01:40 +00:00
|
|
|
size++;
|
|
|
|
}
|
|
|
|
for (i = 1; i < size; i++) {
|
2008-04-03 23:27:29 +01:00
|
|
|
Int dig = numb/divfactor;
|
2007-01-24 10:01:40 +00:00
|
|
|
och = base_dig(dig, ch);
|
|
|
|
f_putc(sno, och);
|
2008-04-03 23:27:29 +01:00
|
|
|
numb %= divfactor;
|
|
|
|
divfactor /= radix;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2007-01-24 10:01:40 +00:00
|
|
|
och = base_dig(numb, ch);
|
|
|
|
f_putc(sno, och);
|
2001-04-09 20:54:03 +01:00
|
|
|
break;
|
2004-02-13 18:39:29 +00:00
|
|
|
}
|
|
|
|
case 's':
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
2004-07-15 16:47:08 +01:00
|
|
|
if (!format_print_str (sno, repeats, has_repeats, t, f_putc)) {
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_default_error;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'i':
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1 || has_repeats)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
targ++;
|
|
|
|
break;
|
|
|
|
case 'k':
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1 || has_repeats)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
2004-08-16 22:02:04 +01:00
|
|
|
Yap_StartSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite (t, f_putc, Quote_illegal_f|Ignore_ops_f|To_heap_f , 1200);
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo = &finfo;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
2005-10-28 18:38:50 +01:00
|
|
|
case '@':
|
|
|
|
t = targs[targ++];
|
|
|
|
Yap_StartSlots();
|
|
|
|
{
|
2010-05-10 10:21:56 +01:00
|
|
|
Int sl = Yap_InitSlot(args);
|
|
|
|
Int sl2;
|
2005-10-28 18:38:50 +01:00
|
|
|
Int res;
|
|
|
|
Term ta[2];
|
|
|
|
Term ts;
|
|
|
|
|
|
|
|
ta[0] = fmod;
|
|
|
|
ta[1] = t;
|
|
|
|
ta[0] = Yap_MkApplTerm(FunctorModule, 2, ta);
|
|
|
|
ta[1] = MkVarTerm();
|
|
|
|
sl2 = Yap_InitSlot(ta[1]);
|
|
|
|
ts = Yap_MkApplTerm(FunctorGFormatAt, 2, ta);
|
2009-10-21 00:07:31 +01:00
|
|
|
res = Yap_execute_goal(ts, 0, CurrentModule);
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo = &finfo;
|
|
|
|
args = Yap_GetFromSlot(sl);
|
|
|
|
if (EX) goto ex_handler;
|
|
|
|
if (!res) return FALSE;
|
|
|
|
ts = Yap_GetFromSlot(sl2);
|
|
|
|
Yap_RecoverSlots(2);
|
|
|
|
if (!format_print_str (sno, repeats, has_repeats, ts, f_putc)) {
|
|
|
|
goto do_default_error;
|
|
|
|
}
|
|
|
|
}
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2005-10-28 18:38:50 +01:00
|
|
|
break;
|
2004-02-13 18:39:29 +00:00
|
|
|
case 'p':
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1 || has_repeats)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
2004-08-16 22:02:04 +01:00
|
|
|
Yap_StartSlots();
|
2004-02-13 18:39:29 +00:00
|
|
|
{
|
2010-05-10 10:21:56 +01:00
|
|
|
Int sl = Yap_InitSlot(args);
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite(t, f_putc, Handle_vars_f|Use_portray_f|To_heap_f, 1200);
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo = &finfo;
|
2004-02-13 18:39:29 +00:00
|
|
|
args = Yap_GetFromSlot(sl);
|
|
|
|
Yap_RecoverSlots(1);
|
|
|
|
}
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2004-02-13 18:39:29 +00:00
|
|
|
if (EX != 0L) {
|
2005-10-28 18:38:50 +01:00
|
|
|
Term ball;
|
|
|
|
|
|
|
|
ex_handler:
|
2010-07-27 23:21:15 +01:00
|
|
|
ball = Yap_PopTermFromDB(EX);
|
|
|
|
EX = NULL;
|
2004-02-13 18:39:29 +00:00
|
|
|
if (tnum <= 8)
|
|
|
|
targs = NULL;
|
|
|
|
if (IsAtomTerm(tail)) {
|
|
|
|
fstr = NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2005-10-28 18:38:50 +01:00
|
|
|
format_clean_up(finfo.format_base, fstr, targs);
|
2004-02-13 18:39:29 +00:00
|
|
|
Yap_JumpToEnv(ball);
|
2005-10-28 18:38:50 +01:00
|
|
|
return FALSE;
|
2004-02-13 18:39:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'q':
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1 || has_repeats)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
2004-08-16 22:02:04 +01:00
|
|
|
Yap_StartSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite (t, f_putc, Handle_vars_f|Quote_illegal_f|To_heap_f, 1200);
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo = &finfo;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case 'w':
|
2004-05-18 16:13:05 +01:00
|
|
|
if (targ > tnum-1 || has_repeats)
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_consistency_error;
|
|
|
|
t = targs[targ++];
|
2004-08-16 22:02:04 +01:00
|
|
|
Yap_StartSlots();
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_plwrite (t, f_putc, Handle_vars_f|To_heap_f, 1200);
|
2010-06-01 00:40:58 +01:00
|
|
|
Yap_CloseSlots();
|
2005-10-28 18:38:50 +01:00
|
|
|
FormatInfo = &finfo;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case '~':
|
|
|
|
if (has_repeats)
|
|
|
|
goto do_consistency_error;
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc(sno, (int) '~');
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
if (!has_repeats)
|
|
|
|
repeats = 1;
|
|
|
|
while (repeats--) {
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc(sno, (int) '\n');
|
2004-02-13 18:39:29 +00:00
|
|
|
}
|
|
|
|
column_boundary = 0;
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.pad_max = finfo.pad_entries;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case 'N':
|
|
|
|
if (!has_repeats)
|
|
|
|
has_repeats = 1;
|
|
|
|
if (Stream[sno].linepos != 0) {
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc(sno, (int) '\n');
|
2001-04-09 20:54:03 +01:00
|
|
|
column_boundary = 0;
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.pad_max = finfo.pad_entries;
|
2004-02-13 18:39:29 +00:00
|
|
|
}
|
|
|
|
if (repeats > 1) {
|
|
|
|
Int i;
|
|
|
|
for (i = 1; i < repeats; i++)
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc(sno, (int) '\n');
|
2004-02-13 18:39:29 +00:00
|
|
|
column_boundary = 0;
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.pad_max = finfo.pad_entries;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
/* padding */
|
|
|
|
case '|':
|
|
|
|
if (has_repeats) {
|
2005-10-28 18:38:50 +01:00
|
|
|
fill_pads(repeats-(finfo.format_ptr-finfo.format_base));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.pad_max = finfo.pad_entries;
|
2005-12-17 03:25:39 +00:00
|
|
|
if (repeats)
|
|
|
|
column_boundary = repeats;
|
|
|
|
else
|
|
|
|
column_boundary = finfo.format_ptr-finfo.format_base;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case '+':
|
|
|
|
if (has_repeats) {
|
2005-10-28 18:38:50 +01:00
|
|
|
fill_pads((repeats+column_boundary)-(finfo.format_ptr-finfo.format_base));
|
2004-02-13 18:39:29 +00:00
|
|
|
} else {
|
2004-02-13 22:10:10 +00:00
|
|
|
repeats = 8;
|
2004-02-13 18:39:29 +00:00
|
|
|
fill_pads(8);
|
|
|
|
}
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.pad_max = finfo.pad_entries;
|
2004-02-13 22:10:10 +00:00
|
|
|
column_boundary = repeats+column_boundary;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (!has_repeats)
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.pad_max->pad = ' ';
|
2004-02-13 18:39:29 +00:00
|
|
|
else
|
2005-10-28 18:38:50 +01:00
|
|
|
finfo.pad_max->pad = fptr[-2];
|
|
|
|
finfo.pad_max->pos = finfo.format_ptr-finfo.format_base;
|
|
|
|
finfo.pad_max++;
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc = format_putc;
|
2004-02-13 18:39:29 +00:00
|
|
|
break;
|
|
|
|
do_instantiation_error:
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = INSTANTIATION_ERROR;
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_default_error;
|
|
|
|
do_type_int_error:
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = TYPE_ERROR_INTEGER;
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_default_error;
|
|
|
|
do_type_number_error:
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = TYPE_ERROR_NUMBER;
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_default_error;
|
|
|
|
do_type_atom_error:
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = TYPE_ERROR_ATOM;
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_default_error;
|
|
|
|
do_domain_not_less_zero_error:
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = DOMAIN_ERROR_NOT_LESS_THAN_ZERO;
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_default_error;
|
|
|
|
do_domain_error_radix:
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = DOMAIN_ERROR_RADIX;
|
2004-02-13 18:39:29 +00:00
|
|
|
goto do_default_error;
|
|
|
|
do_consistency_error:
|
|
|
|
default:
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = CONSISTENCY_ERROR;
|
2004-02-13 18:39:29 +00:00
|
|
|
do_default_error:
|
|
|
|
if (tnum <= 8)
|
|
|
|
targs = NULL;
|
|
|
|
if (IsAtomTerm(tail)) {
|
|
|
|
fstr = NULL;
|
|
|
|
}
|
2004-10-07 02:42:46 +01:00
|
|
|
{
|
|
|
|
Term ta[2];
|
|
|
|
ta[0] = otail;
|
|
|
|
ta[1] = oargs;
|
2008-12-23 01:53:52 +00:00
|
|
|
Yap_Error(Yap_Error_TYPE, Yap_MkApplTerm(Yap_MkFunctor(AtomFormat,2),2,ta), "format/2");
|
2004-10-07 02:42:46 +01:00
|
|
|
}
|
2005-10-28 18:38:50 +01:00
|
|
|
format_clean_up(finfo.format_base, fstr, targs);
|
2004-10-07 02:42:46 +01:00
|
|
|
Yap_Error_TYPE = YAP_NO_ERROR;
|
2004-02-13 18:39:29 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
/* ok, now we should have a command */
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
} else {
|
2004-07-06 19:24:40 +01:00
|
|
|
f_putc(sno, ch);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2002-10-10 06:58:49 +01:00
|
|
|
}
|
2004-07-06 19:24:40 +01:00
|
|
|
if (has_tabs) {
|
2005-10-28 18:38:50 +01:00
|
|
|
for (fptr = finfo.format_base; fptr < finfo.format_ptr; fptr++) {
|
2004-07-06 19:24:40 +01:00
|
|
|
Stream[sno].stream_putc(sno, *fptr);
|
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
}
|
|
|
|
if (IsAtomTerm(tail)) {
|
|
|
|
fstr = NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2004-02-13 18:39:29 +00:00
|
|
|
if (tnum <= 8)
|
|
|
|
targs = NULL;
|
2005-10-28 18:38:50 +01:00
|
|
|
format_clean_up(finfo.format_base, fstr, targs);
|
2001-04-09 20:54:03 +01:00
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_format(void)
|
2004-07-22 22:32:23 +01:00
|
|
|
{ /* 'format'(Control,Args) */
|
2004-02-05 16:57:02 +00:00
|
|
|
Int res;
|
|
|
|
res = format(Deref(ARG1),Deref(ARG2), Yap_c_output_stream);
|
|
|
|
return res;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2010-12-17 00:11:05 +00:00
|
|
|
format2(UInt stream_flag)
|
|
|
|
{
|
2002-11-18 18:18:05 +00:00
|
|
|
int old_c_stream = Yap_c_output_stream;
|
2001-04-09 20:54:03 +01:00
|
|
|
Int out;
|
2008-07-23 00:34:50 +01:00
|
|
|
Term tin = Deref(ARG1);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2008-07-23 00:34:50 +01:00
|
|
|
if (IsVarTerm(tin)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR,tin,"format/3");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2011-02-12 18:42:44 +00:00
|
|
|
/* needs to change Yap_c_output_stream for write */
|
|
|
|
Yap_c_output_stream = CheckStream (ARG1, Output_Stream_f|stream_flag, "format/3");
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[Yap_c_output_stream].streamlock);
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_c_output_stream == -1) {
|
|
|
|
Yap_c_output_stream = old_c_stream;
|
2008-07-23 00:34:50 +01:00
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
out = format(Deref(ARG2),Deref(ARG3),Yap_c_output_stream);
|
2011-02-13 01:03:08 +00:00
|
|
|
{
|
2008-07-23 00:34:50 +01:00
|
|
|
Yap_c_output_stream = old_c_stream;
|
|
|
|
}
|
|
|
|
return out;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2010-12-17 00:11:05 +00:00
|
|
|
static Int
|
|
|
|
p_format2(void)
|
|
|
|
{ /* 'format'(Stream,Control,Args) */
|
|
|
|
return format2(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_swi_format(void)
|
|
|
|
{ /* 'format'(Stream,Control,Args) */
|
|
|
|
return format2(SWI_Stream_f);
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
static Int
|
|
|
|
p_skip (void)
|
|
|
|
{ /* '$skip'(Stream,N) */
|
|
|
|
int sno = CheckStream (ARG1, Input_Stream_f, "skip/2");
|
2006-11-27 17:42:03 +00:00
|
|
|
Int n = IntOfTerm (Deref (ARG2));
|
2007-01-28 14:26:37 +00:00
|
|
|
int ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
if (sno < 0)
|
|
|
|
return (FALSE);
|
2006-04-28 16:48:33 +01:00
|
|
|
if (n < 0 || n > 127) {
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
2006-04-28 16:48:33 +01:00
|
|
|
}
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2010-08-04 11:37:12 +01:00
|
|
|
while ((ch = Stream[sno].stream_wgetc(sno)) != n && ch != -1);
|
2001-04-09 20:54:03 +01:00
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
2008-07-11 18:02:10 +01:00
|
|
|
void Yap_FlushStreams(void)
|
|
|
|
{
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#if HAVE_SELECT
|
|
|
|
/* stream_select(+Streams,+TimeOut,-Result) */
|
|
|
|
static Int
|
|
|
|
p_stream_select(void)
|
|
|
|
{
|
|
|
|
Term t1 = Deref(ARG1), t2;
|
|
|
|
fd_set readfds, writefds, exceptfds;
|
|
|
|
struct timeval timeout, *ptime;
|
|
|
|
|
|
|
|
#if _MSC_VER
|
|
|
|
u_int fdmax=0;
|
|
|
|
#else
|
|
|
|
int fdmax=0;
|
|
|
|
#endif
|
|
|
|
Term tout = TermNil, ti, Head;
|
|
|
|
|
|
|
|
if (IsVarTerm(t1)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR,t1,"stream_select/3");
|
2008-07-23 00:34:50 +01:00
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
if (!IsPairTerm(t1)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(TYPE_ERROR_LIST,t1,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
FD_ZERO(&readfds);
|
|
|
|
FD_ZERO(&writefds);
|
|
|
|
FD_ZERO(&exceptfds);
|
|
|
|
ti = t1;
|
|
|
|
while (ti != TermNil) {
|
|
|
|
#if _MSC_VER
|
|
|
|
u_int fd;
|
|
|
|
#else
|
|
|
|
int fd;
|
|
|
|
#endif
|
|
|
|
int sno;
|
|
|
|
|
|
|
|
Head = HeadOfTerm(ti);
|
|
|
|
sno = CheckStream(Head, Input_Stream_f, "stream_select/3");
|
|
|
|
if (sno < 0)
|
|
|
|
return(FALSE);
|
|
|
|
fd = GetStreamFd(sno);
|
|
|
|
FD_SET(fd, &readfds);
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2001-04-09 20:54:03 +01:00
|
|
|
if (fd > fdmax)
|
|
|
|
fdmax = fd;
|
|
|
|
ti = TailOfTerm(ti);
|
|
|
|
}
|
|
|
|
t2 = Deref(ARG2);
|
|
|
|
if (IsVarTerm(t2)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
if (IsAtomTerm(t2)) {
|
2008-12-23 01:53:52 +00:00
|
|
|
if (t2 == MkAtomTerm(AtomOff)) {
|
2001-04-09 20:54:03 +01:00
|
|
|
/* wait indefinitely */
|
|
|
|
ptime = NULL;
|
|
|
|
} else {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t1,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Term t21, t22;
|
|
|
|
|
|
|
|
if (!IsApplTerm(t2) || FunctorOfTerm(t2) != FunctorModule) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
t21 = ArgOfTerm(1, t2);
|
|
|
|
if (IsVarTerm(t21)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
if (!IsIntegerTerm(t21)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
timeout.tv_sec = IntegerOfTerm(t21);
|
|
|
|
if (timeout.tv_sec < 0) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
t22 = ArgOfTerm(2, t2);
|
|
|
|
if (IsVarTerm(t22)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
if (!IsIntegerTerm(t22)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
timeout.tv_usec = IntegerOfTerm(t22);
|
|
|
|
if (timeout.tv_usec < 0) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(DOMAIN_ERROR_TIMEOUT_SPEC,t2,"stream_select/3");
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
ptime = &timeout;
|
|
|
|
}
|
|
|
|
/* do the real work */
|
|
|
|
if (select(fdmax+1, &readfds, &writefds, &exceptfds, ptime) < 0) {
|
|
|
|
#if HAVE_STRERROR
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
2001-04-09 20:54:03 +01:00
|
|
|
"stream_select/3 (select: %s)", strerror(errno));
|
|
|
|
#else
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
2001-04-09 20:54:03 +01:00
|
|
|
"stream_select/3 (select)");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
while (t1 != TermNil) {
|
|
|
|
int fd;
|
|
|
|
int sno;
|
|
|
|
|
|
|
|
Head = HeadOfTerm(t1);
|
|
|
|
sno = CheckStream(Head, Input_Stream_f, "stream_select/3");
|
|
|
|
fd = GetStreamFd(sno);
|
|
|
|
if (FD_ISSET(fd, &readfds))
|
|
|
|
tout = MkPairTerm(Head,tout);
|
|
|
|
else
|
|
|
|
tout = MkPairTerm(TermNil,tout);
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2001-04-09 20:54:03 +01:00
|
|
|
t1 = TailOfTerm(t1);
|
|
|
|
}
|
|
|
|
/* we're done, just pass the info back */
|
2002-11-18 18:18:05 +00:00
|
|
|
return(Yap_unify(ARG3,tout));
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_write_depth (void)
|
|
|
|
{ /* write_depth(Old,New) */
|
|
|
|
Term t1 = Deref (ARG1);
|
|
|
|
Term t2 = Deref (ARG2);
|
2005-12-05 17:16:12 +00:00
|
|
|
Term t3 = Deref (ARG3);
|
|
|
|
|
|
|
|
if (!IsVarTerm (t1) && !IsIntegerTerm (t1)) {
|
|
|
|
Yap_Error(TYPE_ERROR_INTEGER,t1,"write_depth/3");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (!IsVarTerm (t2) && !IsIntegerTerm (t2)) {
|
|
|
|
Yap_Error(TYPE_ERROR_INTEGER,t2,"write_depth/3");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (!IsVarTerm (t3) && !IsIntegerTerm (t3)) {
|
|
|
|
Yap_Error(TYPE_ERROR_INTEGER,t3,"write_depth/3");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
if (IsVarTerm (t1))
|
|
|
|
{
|
2005-12-05 17:16:12 +00:00
|
|
|
Term t = MkIntegerTerm (max_depth);
|
|
|
|
if (!Yap_unify_constant(t1, t))
|
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
else
|
2005-12-05 17:16:12 +00:00
|
|
|
max_depth = IntegerOfTerm (t1);
|
|
|
|
if (IsVarTerm (t2))
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2005-12-05 17:16:12 +00:00
|
|
|
Term t = MkIntegerTerm (max_list);
|
|
|
|
if (!Yap_unify_constant (t2, t))
|
|
|
|
return FALSE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
else
|
2005-12-05 17:16:12 +00:00
|
|
|
max_list = IntegerOfTerm (t2);
|
|
|
|
if (IsVarTerm (t3))
|
|
|
|
{
|
|
|
|
Term t = MkIntegerTerm (max_write_args);
|
|
|
|
if (!Yap_unify_constant (t3, t))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
max_write_args = IntegerOfTerm (t3);
|
|
|
|
return TRUE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_change_type_of_char (void)
|
|
|
|
{ /* change_type_of_char(+char,+type) */
|
|
|
|
Term t1 = Deref (ARG1);
|
|
|
|
Term t2 = Deref (ARG2);
|
2007-12-29 12:26:41 +00:00
|
|
|
if (!IsVarTerm (t1) && !IsIntegerTerm (t1))
|
|
|
|
return FALSE;
|
|
|
|
if (!IsVarTerm(t2) && !IsIntegerTerm(t2))
|
|
|
|
return FALSE;
|
|
|
|
Yap_chtype[IntegerOfTerm(t1)] = IntegerOfTerm(t2);
|
|
|
|
return TRUE;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_type_of_char (void)
|
|
|
|
{ /* type_of_char(+char,-type) */
|
|
|
|
Term t;
|
|
|
|
|
|
|
|
Term t1 = Deref (ARG1);
|
2007-12-29 12:26:41 +00:00
|
|
|
if (!IsVarTerm (t1) && !IsIntegerTerm (t1))
|
|
|
|
return FALSE;
|
|
|
|
t = MkIntTerm(Yap_chtype[IntegerOfTerm (t1)]);
|
|
|
|
return Yap_unify(t,ARG2);
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_force_char_conversion(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* don't actually enable it until someone tries to add a conversion */
|
|
|
|
if (CharConversionTable2 == NULL)
|
|
|
|
return(TRUE);
|
|
|
|
for (i = 0; i < MaxStreams; i++) {
|
|
|
|
if (!(Stream[i].status & Free_Stream_f))
|
2006-11-27 17:42:03 +00:00
|
|
|
Stream[i].stream_wgetc_for_read = ISOWGetc;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
CharConversionTable = CharConversionTable2;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_disable_char_conversion(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < MaxStreams; i++) {
|
|
|
|
if (!(Stream[i].status & Free_Stream_f))
|
2006-11-27 17:42:03 +00:00
|
|
|
Stream[i].stream_wgetc_for_read = Stream[i].stream_wgetc;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
CharConversionTable = NULL;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_char_conversion(void)
|
|
|
|
{
|
|
|
|
Term t0 = Deref(ARG1), t1 = Deref(ARG2);
|
|
|
|
char *s0, *s1;
|
|
|
|
|
|
|
|
if (IsVarTerm(t0)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR, t0, "char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
if (!IsAtomTerm(t0)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t0, "char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
s0 = RepAtom(AtomOfTerm(t0))->StrOfAE;
|
|
|
|
if (s0[1] != '\0') {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t0, "char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
if (IsVarTerm(t1)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR, t1, "char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
if (!IsAtomTerm(t1)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t1, "char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
s1 = RepAtom(AtomOfTerm(t1))->StrOfAE;
|
|
|
|
if (s1[1] != '\0') {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t1, "char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
/* check if we do have a table for converting characters */
|
|
|
|
if (CharConversionTable2 == NULL) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* don't create a table if we don't need to */
|
|
|
|
if (s0[0] == s1[0])
|
|
|
|
return(TRUE);
|
2002-11-18 18:18:05 +00:00
|
|
|
CharConversionTable2 = Yap_AllocCodeSpace(NUMBER_OF_CHARS*sizeof(char));
|
2001-04-09 20:54:03 +01:00
|
|
|
while (CharConversionTable2 == NULL) {
|
2004-01-23 02:23:51 +00:00
|
|
|
if (!Yap_growheap(FALSE, NUMBER_OF_CHARS*sizeof(char), NULL)) {
|
2004-11-19 22:08:43 +00:00
|
|
|
Yap_Error(OUT_OF_HEAP_ERROR, TermNil, Yap_ErrorMessage);
|
2001-04-09 20:54:03 +01:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (yap_flags[CHAR_CONVERSION_FLAG] != 0) {
|
|
|
|
if (p_force_char_conversion() == FALSE)
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
for (i = 0; i < NUMBER_OF_CHARS; i++)
|
2010-02-26 09:12:06 +00:00
|
|
|
CharConversionTable2[i] = i;
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
/* just add the new entry */
|
2010-02-26 09:12:06 +00:00
|
|
|
CharConversionTable2[(int)s0[0]] = s1[0];
|
2001-04-09 20:54:03 +01:00
|
|
|
/* done */
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_current_char_conversion(void)
|
|
|
|
{
|
|
|
|
Term t0, t1;
|
|
|
|
char *s0, *s1;
|
|
|
|
|
|
|
|
if (CharConversionTable == NULL) {
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
t0 = Deref(ARG1);
|
|
|
|
if (IsVarTerm(t0)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(INSTANTIATION_ERROR, t0, "current_char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
if (!IsAtomTerm(t0)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t0, "current_char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
s0 = RepAtom(AtomOfTerm(t0))->StrOfAE;
|
|
|
|
if (s0[1] != '\0') {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t0, "current_char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
t1 = Deref(ARG2);
|
|
|
|
if (IsVarTerm(t1)) {
|
|
|
|
char out[2];
|
|
|
|
if (CharConversionTable[(int)s0[0]] == '\0') return(FALSE);
|
|
|
|
out[0] = CharConversionTable[(int)s0[0]];
|
|
|
|
out[1] = '\0';
|
2002-11-18 18:18:05 +00:00
|
|
|
return(Yap_unify(ARG2,MkAtomTerm(Yap_LookupAtom(out))));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
if (!IsAtomTerm(t1)) {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t1, "current_char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
s1 = RepAtom(AtomOfTerm(t1))->StrOfAE;
|
|
|
|
if (s1[1] != '\0') {
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER, t1, "current_char_conversion/2");
|
2001-04-09 20:54:03 +01:00
|
|
|
return (FALSE);
|
|
|
|
} else {
|
|
|
|
return (CharConversionTable[(int)s0[0]] == '\0' &&
|
|
|
|
CharConversionTable[(int)s0[0]] == s1[0] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_all_char_conversions(void)
|
|
|
|
{
|
|
|
|
Term out = TermNil;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (CharConversionTable == NULL) {
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
for (i = NUMBER_OF_CHARS; i > 0; ) {
|
|
|
|
i--;
|
|
|
|
if (CharConversionTable[i] != '\0') {
|
|
|
|
Term t1, t2;
|
|
|
|
char s[2];
|
|
|
|
s[1] = '\0';
|
|
|
|
s[0] = CharConversionTable[i];
|
2002-11-18 18:18:05 +00:00
|
|
|
t1 = MkAtomTerm(Yap_LookupAtom(s));
|
2001-04-09 20:54:03 +01:00
|
|
|
out = MkPairTerm(t1,out);
|
|
|
|
s[0] = i;
|
2002-11-18 18:18:05 +00:00
|
|
|
t2 = MkAtomTerm(Yap_LookupAtom(s));
|
2001-04-09 20:54:03 +01:00
|
|
|
out = MkPairTerm(t2,out);
|
|
|
|
}
|
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
return(Yap_unify(ARG1,out));
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
|
2010-05-06 15:00:44 +01:00
|
|
|
Int
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_StreamToFileNo(Term t)
|
2001-05-21 21:00:05 +01:00
|
|
|
{
|
|
|
|
int sno =
|
|
|
|
CheckStream(t, (Input_Stream_f|Output_Stream_f), "StreamToFileNo");
|
2011-02-12 23:42:15 +00:00
|
|
|
{
|
2006-04-28 16:48:33 +01:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2001-05-21 21:00:05 +01:00
|
|
|
return(YP_fileno(Stream[sno].u.file.file));
|
|
|
|
}
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2001-05-22 21:41:52 +01:00
|
|
|
static Int
|
|
|
|
p_stream(void)
|
2001-05-22 17:14:30 +01:00
|
|
|
{
|
|
|
|
Term in = Deref(ARG1);
|
|
|
|
if (IsVarTerm(in))
|
|
|
|
return(FALSE);
|
|
|
|
if (IsApplTerm(in))
|
|
|
|
return(FunctorOfTerm(in) == FunctorStream);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
2002-05-24 05:45:05 +01:00
|
|
|
static Int
|
|
|
|
p_same_file(void) {
|
|
|
|
char *f1 = RepAtom(AtomOfTerm(Deref(ARG1)))->StrOfAE;
|
|
|
|
char *f2 = RepAtom(AtomOfTerm(Deref(ARG2)))->StrOfAE;
|
2009-05-02 16:54:09 +01:00
|
|
|
|
2002-05-24 05:45:05 +01:00
|
|
|
if (strcmp(f1,f2) == 0)
|
2006-11-27 17:42:03 +00:00
|
|
|
return TRUE;
|
2002-05-24 05:45:05 +01:00
|
|
|
#if HAVE_LSTAT
|
|
|
|
{
|
2009-05-13 23:12:12 +01:00
|
|
|
int out;
|
2006-11-27 17:42:03 +00:00
|
|
|
struct stat *b1, *b2;
|
|
|
|
while ((char *)H+sizeof(struct stat)*2 > (char *)(ASP-1024)) {
|
2008-08-28 04:43:00 +01:00
|
|
|
if (!Yap_gcl(2*sizeof(struct stat), 2, ENV, gc_P(P,CP))) {
|
2006-11-27 17:42:03 +00:00
|
|
|
Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
b1 = (struct stat *)H;
|
|
|
|
b2 = b1+1;
|
2002-05-24 05:45:05 +01:00
|
|
|
if (strcmp(f1,"user_input") == 0) {
|
2006-11-27 17:42:03 +00:00
|
|
|
if (fstat(fileno(Stream[0].u.file.file), b1) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-11-27 17:42:03 +00:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
|
|
|
} else if (strcmp(f1,"user_output") == 0) {
|
2006-11-27 17:42:03 +00:00
|
|
|
if (fstat(fileno(Stream[1].u.file.file), b1) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-11-27 17:42:03 +00:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
|
|
|
} else if (strcmp(f1,"user_error") == 0) {
|
2006-11-27 17:42:03 +00:00
|
|
|
if (fstat(fileno(Stream[2].u.file.file), b1) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-11-27 17:42:03 +00:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
} else if (stat(f1, b1) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-11-27 17:42:03 +00:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
|
|
|
if (strcmp(f2,"user_input") == 0) {
|
2006-11-27 17:42:03 +00:00
|
|
|
if (fstat(fileno(Stream[0].u.file.file), b2) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-11-27 17:42:03 +00:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
|
|
|
} else if (strcmp(f2,"user_output") == 0) {
|
2006-11-27 17:42:03 +00:00
|
|
|
if (fstat(fileno(Stream[1].u.file.file), b2) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-11-27 17:42:03 +00:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
|
|
|
} else if (strcmp(f2,"user_error") == 0) {
|
2006-11-27 17:42:03 +00:00
|
|
|
if (fstat(fileno(Stream[2].u.file.file), b2) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-11-27 17:42:03 +00:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
} else if (stat(f2, b2) == -1) {
|
2002-05-24 05:45:05 +01:00
|
|
|
/* file does not exist, but was opened? Return -1 */
|
2006-08-02 19:18:31 +01:00
|
|
|
return FALSE;
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
2009-05-02 16:54:09 +01:00
|
|
|
out = (b1->st_ino == b2->st_ino
|
2002-12-06 20:03:26 +00:00
|
|
|
#ifdef __LCC__
|
2006-11-27 17:42:03 +00:00
|
|
|
&& memcmp((const void *)&(b1->st_dev),(const void *)&(b2->st_dev),sizeof(buf1.st_dev)) == 0
|
2002-12-06 20:03:26 +00:00
|
|
|
#else
|
2006-11-27 17:42:03 +00:00
|
|
|
&& b1->st_dev == b2->st_dev
|
2002-05-24 05:45:05 +01:00
|
|
|
#endif
|
2002-12-06 20:03:26 +00:00
|
|
|
);
|
2006-11-27 17:42:03 +00:00
|
|
|
return out;
|
2002-12-06 20:03:26 +00:00
|
|
|
}
|
|
|
|
#else
|
2002-05-24 05:45:05 +01:00
|
|
|
return(FALSE);
|
2002-12-06 20:03:26 +00:00
|
|
|
#endif
|
2002-05-24 05:45:05 +01:00
|
|
|
}
|
|
|
|
|
2006-01-02 02:16:19 +00:00
|
|
|
static Int
|
|
|
|
p_float_format(void)
|
|
|
|
{
|
|
|
|
Term in = Deref(ARG1);
|
|
|
|
if (IsVarTerm(in))
|
2008-12-23 01:53:52 +00:00
|
|
|
return Yap_unify(ARG1, MkAtomTerm(AtomFloatFormat));
|
|
|
|
AtomFloatFormat = AtomOfTerm(in);
|
2006-01-02 02:16:19 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
static Int
|
|
|
|
p_get_default_encoding(void)
|
|
|
|
{
|
|
|
|
Term out = MkIntegerTerm(DefaultEncoding());
|
|
|
|
return Yap_unify(ARG1, out);
|
|
|
|
}
|
|
|
|
|
2007-12-29 12:26:41 +00:00
|
|
|
static Int
|
|
|
|
p_toupper(void)
|
|
|
|
{
|
|
|
|
Int out = IntegerOfTerm(Deref(ARG1)), uout;
|
|
|
|
if (out < 0) {
|
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER_CODE, ARG1, "toupper");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (out < 128)
|
|
|
|
uout = toupper(out);
|
|
|
|
else
|
|
|
|
uout = towupper(out);
|
|
|
|
return Yap_unify(ARG2, MkIntegerTerm(uout));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
|
|
|
p_tolower(void)
|
|
|
|
{
|
|
|
|
Int out = IntegerOfTerm(Deref(ARG1)), uout;
|
|
|
|
if (out < 0) {
|
|
|
|
Yap_Error(REPRESENTATION_ERROR_CHARACTER_CODE, ARG1, "tolower");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (out < 128)
|
|
|
|
uout = tolower(out);
|
|
|
|
else
|
|
|
|
uout = towlower(out);
|
|
|
|
return Yap_unify(ARG2, MkIntegerTerm(uout));
|
|
|
|
}
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
static Int
|
2007-04-03 16:03:11 +01:00
|
|
|
p_encoding (void)
|
|
|
|
{ /* '$encoding'(Stream,N) */
|
2006-11-27 17:42:03 +00:00
|
|
|
int sno = CheckStream (ARG1, Input_Stream_f|Output_Stream_f, "encoding/2");
|
2007-04-03 16:03:11 +01:00
|
|
|
Term t = Deref(ARG2);
|
2006-11-27 17:42:03 +00:00
|
|
|
if (sno < 0)
|
|
|
|
return FALSE;
|
2007-04-03 16:03:11 +01:00
|
|
|
if (IsVarTerm(t)) {
|
2008-01-28 12:47:45 +00:00
|
|
|
UNLOCK(Stream[sno].streamlock);
|
2007-04-03 16:03:11 +01:00
|
|
|
return Yap_unify(ARG2, MkIntegerTerm(Stream[sno].encoding));
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
Stream[sno].encoding = IntegerOfTerm(Deref(ARG2));
|
|
|
|
UNLOCK(Stream[sno].streamlock);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2004-05-14 17:33:47 +01:00
|
|
|
|
2004-05-14 18:56:47 +01:00
|
|
|
|
2009-04-22 22:41:41 +01:00
|
|
|
FILE *
|
|
|
|
Yap_FileDescriptorFromStream(Term t)
|
|
|
|
{
|
2009-04-25 16:59:05 +01:00
|
|
|
int sno = CheckStream (t, Input_Stream_f|Output_Stream_f, "FileDescriptorFromStream");
|
2009-04-22 22:41:41 +01:00
|
|
|
if (sno < 0)
|
2009-04-25 16:59:05 +01:00
|
|
|
return NULL;
|
2011-02-12 23:45:19 +00:00
|
|
|
if (Stream[sno].status & (Free_Stream_f))
|
2009-04-22 22:41:41 +01:00
|
|
|
return NULL;
|
|
|
|
return Stream[sno].u.file.file;
|
|
|
|
}
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitBackIO (void)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2002-12-06 20:03:26 +00:00
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitIOPreds(void)
|
2001-04-09 20:54:03 +01:00
|
|
|
{
|
2004-05-13 21:54:58 +01:00
|
|
|
Term cm = CurrentModule;
|
2002-11-11 17:38:10 +00:00
|
|
|
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_stdin = stdin;
|
|
|
|
Yap_stdout = stdout;
|
|
|
|
Yap_stderr = stderr;
|
2004-09-27 21:45:04 +01:00
|
|
|
if (!Stream)
|
|
|
|
Stream = (StreamDesc *)Yap_AllocCodeSpace(sizeof(StreamDesc)*MaxStreams);
|
2001-04-09 20:54:03 +01:00
|
|
|
/* here the Input/Output predicates */
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$close", 1, p_close, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$get0_line_codes", 2, p_get0_line_codes, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2007-09-27 16:25:34 +01:00
|
|
|
Yap_InitCPred ("$access", 1, p_access, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2010-02-11 18:07:08 +00:00
|
|
|
Yap_InitCPred ("exists_directory", 1, p_exists_directory, SafePredFlag|SyncPredFlag);
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$file_expansion", 2, p_file_expansion, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$set_read_error_handler", 1, p_set_read_error_handler, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$get_read_error_handler", 1, p_get_read_error_handler, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2011-02-12 14:14:12 +00:00
|
|
|
Yap_InitCPred ("$read", 6, p_read, SyncPredFlag|HiddenPredFlag|UserCPredFlag);
|
|
|
|
Yap_InitCPred ("$read", 7, p_read2, SyncPredFlag|HiddenPredFlag|UserCPredFlag);
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$skip", 2, p_skip, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$write", 2, p_write, SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$write", 3, p_write2, SyncPredFlag|HiddenPredFlag);
|
2009-05-22 19:24:27 +01:00
|
|
|
Yap_InitCPred ("$write_with_prio", 3, p_write_prio, SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$write_with_prio", 4, p_write2_prio, SyncPredFlag|HiddenPredFlag);
|
2004-07-22 22:32:23 +01:00
|
|
|
Yap_InitCPred ("format", 2, p_format, SyncPredFlag);
|
|
|
|
Yap_InitCPred ("format", 3, p_format2, SyncPredFlag);
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$start_line", 1, p_startline, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitCPred ("$user_file_name", 2, p_user_file_name, SafePredFlag|SyncPredFlag),
|
|
|
|
Yap_InitCPred ("$past_eof", 1, p_past_eof, SafePredFlag|SyncPredFlag),
|
2007-04-03 00:04:48 +01:00
|
|
|
Yap_InitCPred ("$has_bom", 1, p_has_bom, SafePredFlag);
|
2007-04-03 16:03:11 +01:00
|
|
|
Yap_InitCPred ("$stream_representation_error", 2, p_representation_error, SafePredFlag|SyncPredFlag);
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$is_same_tty", 2, p_is_same_tty, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitCPred ("always_prompt_user", 0, p_always_prompt_user, SafePredFlag|SyncPredFlag);
|
2005-12-05 17:16:12 +00:00
|
|
|
Yap_InitCPred ("write_depth", 3, p_write_depth, SafePredFlag|SyncPredFlag);
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$change_type_of_char", 2, p_change_type_of_char, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$type_of_char", 2, p_type_of_char, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitCPred ("char_conversion", 2, p_char_conversion, SyncPredFlag);
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$current_char_conversion", 2, p_current_char_conversion, SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$all_char_conversions", 1, p_all_char_conversions, SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$force_char_conversion", 0, p_force_char_conversion, SyncPredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$disable_char_conversion", 0, p_disable_char_conversion, SyncPredFlag|HiddenPredFlag);
|
2006-11-27 17:42:03 +00:00
|
|
|
Yap_InitCPred ("$stream", 1, p_stream, SafePredFlag|TestPredFlag);
|
|
|
|
Yap_InitCPred ("$get_default_encoding", 1, p_get_default_encoding, SafePredFlag|TestPredFlag);
|
2007-04-03 16:03:11 +01:00
|
|
|
Yap_InitCPred ("$encoding", 2, p_encoding, SafePredFlag|SyncPredFlag),
|
2001-04-09 20:54:03 +01:00
|
|
|
#if HAVE_SELECT
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_InitCPred ("stream_select", 3, p_stream_select, SafePredFlag|SyncPredFlag);
|
2001-04-09 20:54:03 +01:00
|
|
|
#endif
|
2004-11-18 22:32:40 +00:00
|
|
|
Yap_InitCPred ("$same_file", 2, p_same_file, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2006-01-02 02:16:19 +00:00
|
|
|
Yap_InitCPred ("$float_format", 1, p_float_format, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
2007-08-02 18:22:00 +01:00
|
|
|
Yap_InitCPred ("$has_readline", 0, p_has_readline, SafePredFlag|HiddenPredFlag);
|
2007-12-29 12:26:41 +00:00
|
|
|
Yap_InitCPred ("$toupper", 2, p_toupper, SafePredFlag|HiddenPredFlag);
|
|
|
|
Yap_InitCPred ("$tolower", 2, p_tolower, SafePredFlag|HiddenPredFlag);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2010-12-17 00:11:05 +00:00
|
|
|
CurrentModule = SYSTEM_MODULE;
|
|
|
|
Yap_InitCPred ("swi_format", 3, p_swi_format, SyncPredFlag);
|
|
|
|
CurrentModule = cm;
|
|
|
|
|
2006-08-02 19:18:31 +01:00
|
|
|
Yap_InitReadUtil ();
|
2001-04-09 20:54:03 +01:00
|
|
|
InitPlIO ();
|
2009-06-15 20:59:50 +01:00
|
|
|
#if HAVE_LIBREADLINE && HAVE_READLINE_READLINE_H
|
2001-04-09 20:54:03 +01:00
|
|
|
InitReadline();
|
|
|
|
#endif
|
|
|
|
}
|