2016-02-28 19:32:55 +00:00
|
|
|
/*************************************************************************
|
2015-06-18 01:32:33 +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 *
|
|
|
|
* *
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
2016-04-05 02:53:39 +01:00
|
|
|
* File: sockets.c *
|
2015-06-18 01:32:33 +01:00
|
|
|
* 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 socket related IO.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Yap.h"
|
|
|
|
#include "YapHeap.h"
|
2016-04-05 02:53:39 +01:00
|
|
|
#include "Yatom.h"
|
2015-06-18 01:32:33 +01:00
|
|
|
#include "yapio.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#if HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#if HAVE_STDARG_H
|
|
|
|
#include <stdarg.h>
|
|
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
|
|
#if HAVE_IO_H
|
|
|
|
/* Windows */
|
|
|
|
#include <io.h>
|
2016-04-05 02:53:39 +01:00
|
|
|
#endif
|
2015-06-18 01:32:33 +01:00
|
|
|
#if HAVE_SOCKET
|
|
|
|
#include <winsock2.h>
|
|
|
|
#endif
|
|
|
|
#include <windows.h>
|
|
|
|
#ifndef S_ISDIR
|
2016-04-05 02:53:39 +01:00
|
|
|
#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
|
2015-06-18 01:32:33 +01:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#include "iopreds.h"
|
|
|
|
#if __APPLE__
|
|
|
|
#include "fmemopen.h"
|
|
|
|
#define HAVE_FMEMOPEN 1
|
|
|
|
#define HAVE_OPEN_MEMSTREAM 1
|
2016-04-05 02:53:39 +01:00
|
|
|
FILE *open_memstream(char **buf, size_t *len);
|
2015-06-18 01:32:33 +01:00
|
|
|
#endif
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
#if __ANDROID__
|
|
|
|
#undef HAVE_FMEMOPEN
|
|
|
|
#undef HAVE_OPEN_MEMSTREAM
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if HAVE_FMEMOPEN
|
2015-06-18 01:32:33 +01:00
|
|
|
#define MAY_READ 1
|
|
|
|
#endif
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
#if HAVE_OPEN_MEMSTREAM
|
2015-06-18 01:32:33 +01:00
|
|
|
#define MAY_READ 1
|
|
|
|
#define MAY_WRITE 1
|
|
|
|
#endif
|
|
|
|
|
2016-01-31 10:02:11 +00:00
|
|
|
#if _WIN32
|
|
|
|
#undef MAY_WRITE
|
|
|
|
#undef MAY_READ
|
|
|
|
#endif
|
|
|
|
|
2015-06-18 01:32:33 +01:00
|
|
|
#if !MAY_READ
|
2016-04-05 02:53:39 +01:00
|
|
|
static int MemGetc(int);
|
2015-06-18 01:32:33 +01:00
|
|
|
|
|
|
|
/* read from memory */
|
2016-04-05 02:53:39 +01:00
|
|
|
static int MemGetc(int sno) {
|
|
|
|
register StreamDesc *s = &GLOBAL_Stream[sno];
|
|
|
|
Int ch;
|
|
|
|
int spos;
|
|
|
|
|
|
|
|
spos = s->u.mem_string.pos;
|
|
|
|
if (spos == s->u.mem_string.max_size) {
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
ch = s->u.mem_string.buf[spos];
|
|
|
|
s->u.mem_string.pos = ++spos;
|
|
|
|
}
|
|
|
|
return ch;
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !MAY_WRITE
|
2016-04-05 02:53:39 +01:00
|
|
|
static int MemPutc(int, int);
|
2015-06-18 01:32:33 +01:00
|
|
|
|
|
|
|
/* static */
|
2016-04-05 02:53:39 +01:00
|
|
|
static int MemPutc(int sno, int ch) {
|
2015-06-18 01:32:33 +01:00
|
|
|
StreamDesc *s = &GLOBAL_Stream[sno];
|
|
|
|
#if MAC || _MSC_VER
|
2016-04-05 02:53:39 +01:00
|
|
|
if (ch == 10) {
|
|
|
|
ch = '\n';
|
|
|
|
}
|
2015-06-18 01:32:33 +01:00
|
|
|
#endif
|
|
|
|
s->u.mem_string.buf[s->u.mem_string.pos++] = ch;
|
2016-04-05 02:53:39 +01:00
|
|
|
if (s->u.mem_string.pos >= s->u.mem_string.max_size - 8) {
|
2015-06-18 01:32:33 +01:00
|
|
|
int old_src = s->u.mem_string.src, new_src;
|
|
|
|
|
|
|
|
/* oops, we have reached an overflow */
|
|
|
|
Int new_max_size = s->u.mem_string.max_size + Yap_page_size;
|
|
|
|
char *newbuf;
|
|
|
|
|
|
|
|
if (old_src == MEM_BUF_CODE &&
|
2016-04-05 02:53:39 +01:00
|
|
|
(newbuf = Yap_AllocAtomSpace(new_max_size * sizeof(char))) != NULL) {
|
2015-06-18 01:32:33 +01:00
|
|
|
new_src = MEM_BUF_CODE;
|
|
|
|
#if HAVE_MEMMOVE
|
2016-04-05 02:53:39 +01:00
|
|
|
memmove((void *)newbuf, (void *)s->u.mem_string.buf,
|
|
|
|
(size_t)((s->u.mem_string.pos) * sizeof(char)));
|
2015-06-18 01:32:33 +01:00
|
|
|
#else
|
2016-04-05 02:53:39 +01:00
|
|
|
{
|
|
|
|
Int n = s->u.mem_string.pos;
|
|
|
|
char *to = newbuf;
|
|
|
|
char *from = s->u.mem_string.buf;
|
|
|
|
while (n-- >= 0) {
|
|
|
|
*to++ = *from++;
|
|
|
|
}
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
Yap_FreeAtomSpace(s->u.mem_string.buf);
|
|
|
|
#if !HAVE_SYSTEM_MALLOC
|
2016-04-05 02:53:39 +01:00
|
|
|
} else if ((newbuf = (ADDR)realloc(s->u.mem_string.buf,
|
|
|
|
new_max_size * sizeof(char))) != NULL) {
|
2015-06-18 01:32:33 +01:00
|
|
|
new_src = MEM_BUF_MALLOC;
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
if (GLOBAL_Stream[sno].u.mem_string.error_handler) {
|
2016-04-05 02:53:39 +01:00
|
|
|
CACHE_REGS
|
|
|
|
LOCAL_Error_Size = new_max_size * sizeof(char);
|
|
|
|
save_machine_regs();
|
|
|
|
longjmp(*(jmp_buf *)GLOBAL_Stream[sno].u.mem_string.error_handler, 1);
|
2015-06-18 01:32:33 +01:00
|
|
|
} else {
|
2016-04-05 02:53:39 +01:00
|
|
|
Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
|
|
|
|
"YAP could not grow heap for writing to string");
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2016-04-05 02:53:39 +01:00
|
|
|
if (old_src == MEM_BUF_CODE) {
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
s->u.mem_string.buf = newbuf;
|
|
|
|
s->u.mem_string.max_size = new_max_size;
|
|
|
|
s->u.mem_string.src = new_src;
|
|
|
|
}
|
2016-04-05 02:53:39 +01:00
|
|
|
count_output_char(ch, s);
|
|
|
|
return ((int)ch);
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
int Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp,
|
|
|
|
memBufSource src) {
|
2015-10-08 02:23:45 +01:00
|
|
|
CACHE_REGS
|
2015-06-18 01:32:33 +01:00
|
|
|
int sno;
|
|
|
|
StreamDesc *st;
|
2016-01-04 14:11:09 +00:00
|
|
|
FILE *f;
|
|
|
|
encoding_t encoding;
|
|
|
|
stream_flags_t flags;
|
2016-04-05 02:53:39 +01:00
|
|
|
|
2015-06-18 01:32:33 +01:00
|
|
|
sno = GetFreeStreamD();
|
|
|
|
if (sno < 0)
|
2016-04-05 02:53:39 +01:00
|
|
|
return (PlIOError(RESOURCE_ERROR_MAX_STREAMS, TermNil,
|
|
|
|
"new stream not available for open_mem_read_stream/1"));
|
|
|
|
st = GLOBAL_Stream + sno;
|
2016-01-04 14:11:09 +00:00
|
|
|
if (encp)
|
|
|
|
encoding = *encp;
|
|
|
|
else
|
|
|
|
encoding = LOCAL_encoding;
|
2015-06-18 01:32:33 +01:00
|
|
|
#if MAY_READ
|
|
|
|
// like any file stream.
|
2016-04-05 02:53:39 +01:00
|
|
|
f = fmemopen((void *)nbuf, nchars, "r");
|
2016-01-04 14:11:09 +00:00
|
|
|
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
|
2015-06-18 01:32:33 +01:00
|
|
|
#else
|
2016-01-04 14:11:09 +00:00
|
|
|
f = NULL;
|
|
|
|
flags = Input_Stream_f | InMemory_Stream_f;
|
|
|
|
#endif
|
2016-04-05 02:53:39 +01:00
|
|
|
Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead);
|
|
|
|
// like any file stream.
|
2016-01-04 14:11:09 +00:00
|
|
|
#if !MAY_READ
|
2015-06-18 01:32:33 +01:00
|
|
|
/* currently these streams are not seekable */
|
|
|
|
st->status = Input_Stream_f | InMemory_Stream_f;
|
|
|
|
st->u.mem_string.pos = 0;
|
|
|
|
st->u.mem_string.buf = (char *)nbuf;
|
|
|
|
st->u.mem_string.max_size = nchars;
|
|
|
|
st->u.mem_string.error_handler = NULL;
|
|
|
|
st->u.mem_string.src = src;
|
|
|
|
#endif
|
2016-04-05 02:53:39 +01:00
|
|
|
Yap_MemOps(st);
|
2015-06-18 01:32:33 +01:00
|
|
|
UNLOCK(st->streamlock);
|
|
|
|
return sno;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2016-04-05 02:53:39 +01:00
|
|
|
open_mem_read_stream(USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */
|
2015-06-18 01:32:33 +01:00
|
|
|
{
|
|
|
|
Term t, ti;
|
|
|
|
int sno;
|
|
|
|
Int sl = 0, nchars = 0;
|
|
|
|
char *nbuf;
|
|
|
|
|
|
|
|
ti = Deref(ARG1);
|
|
|
|
while (ti != TermNil) {
|
|
|
|
if (IsVarTerm(ti)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, ti, "open_mem_read_stream");
|
|
|
|
return (FALSE);
|
|
|
|
} else if (!IsPairTerm(ti)) {
|
|
|
|
Yap_Error(TYPE_ERROR_LIST, ti, "open_mem_read_stream");
|
|
|
|
return (FALSE);
|
|
|
|
} else {
|
|
|
|
sl++;
|
|
|
|
ti = TailOfTerm(ti);
|
|
|
|
}
|
|
|
|
}
|
2016-04-05 02:53:39 +01:00
|
|
|
while ((nbuf = (char *)Yap_AllocAtomSpace((sl + 1) * sizeof(char))) == NULL) {
|
|
|
|
if (!Yap_growheap(FALSE, (sl + 1) * sizeof(char), NULL)) {
|
|
|
|
Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
|
|
|
|
return (FALSE);
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ti = Deref(ARG1);
|
|
|
|
while (ti != TermNil) {
|
|
|
|
Term ts = HeadOfTerm(ti);
|
|
|
|
|
|
|
|
if (IsVarTerm(ts)) {
|
|
|
|
Yap_Error(INSTANTIATION_ERROR, ARG1, "open_mem_read_stream");
|
|
|
|
return (FALSE);
|
|
|
|
} else if (!IsIntTerm(ts)) {
|
|
|
|
Yap_Error(TYPE_ERROR_INTEGER, ARG1, "open_mem_read_stream");
|
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
nbuf[nchars++] = IntOfTerm(ts);
|
|
|
|
ti = TailOfTerm(ti);
|
|
|
|
}
|
|
|
|
nbuf[nchars] = '\0';
|
2015-10-08 02:23:45 +01:00
|
|
|
sno = Yap_open_buf_read_stream(nbuf, nchars, &LOCAL_encoding, MEM_BUF_CODE);
|
2016-04-05 02:53:39 +01:00
|
|
|
t = Yap_MkStream(sno);
|
|
|
|
return (Yap_unify(ARG2, t));
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
int Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp,
|
|
|
|
memBufSource sr) {
|
2015-10-08 02:23:45 +01:00
|
|
|
CACHE_REGS
|
2016-04-05 02:53:39 +01:00
|
|
|
int sno;
|
|
|
|
StreamDesc *st;
|
2015-08-07 22:57:53 +01:00
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
sno = GetFreeStreamD();
|
|
|
|
if (sno < 0)
|
|
|
|
return -1;
|
|
|
|
st = GLOBAL_Stream + sno;
|
|
|
|
st->status = Output_Stream_f | InMemory_Stream_f;
|
|
|
|
if (!buf) {
|
|
|
|
if (!nchars) {
|
|
|
|
nchars = Yap_page_size;
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
2016-04-05 02:53:39 +01:00
|
|
|
buf = malloc(nchars);
|
|
|
|
st->status |= FreeOnClose_Stream_f;
|
|
|
|
}
|
|
|
|
st->nbuf = buf;
|
|
|
|
if (!st->nbuf) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
st->nsize = nchars;
|
|
|
|
st->linepos = 0;
|
|
|
|
st->charcount = 0;
|
|
|
|
st->linecount = 1;
|
|
|
|
if (encp)
|
|
|
|
st->encoding = *encp;
|
|
|
|
else
|
|
|
|
st->encoding = LOCAL_encoding;
|
|
|
|
Yap_DefaultStreamOps(st);
|
2015-06-18 01:32:33 +01:00
|
|
|
#if MAY_WRITE
|
2016-04-05 02:53:39 +01:00
|
|
|
st->file = open_memstream(&st->nbuf, &st->nsize);
|
|
|
|
st->status |= Seekable_Stream_f;
|
2015-06-18 01:32:33 +01:00
|
|
|
#else
|
2016-04-05 02:53:39 +01:00
|
|
|
st->u.mem_string.pos = 0;
|
|
|
|
st->u.mem_string.buf = st->nbuf;
|
|
|
|
st->u.mem_string.max_size = nchars;
|
|
|
|
#endif
|
|
|
|
Yap_MemOps(st);
|
|
|
|
UNLOCK(st->streamlock);
|
|
|
|
return sno;
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
int Yap_OpenBufWriteStream(USES_REGS1) {
|
2015-06-18 01:32:33 +01:00
|
|
|
char *nbuf;
|
2016-04-05 02:53:39 +01:00
|
|
|
size_t sz = Yap_page_size;
|
2015-06-18 01:32:33 +01:00
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
while ((nbuf = (char *)Yap_AllocAtomSpace(Yap_page_size * sizeof(char))) ==
|
|
|
|
NULL) {
|
|
|
|
if (!Yap_growheap(FALSE, Yap_page_size * sizeof(char), NULL)) {
|
|
|
|
Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
|
2015-06-18 01:32:33 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2016-04-05 02:53:39 +01:00
|
|
|
return Yap_open_buf_write_stream(
|
|
|
|
nbuf, sz, &GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2016-04-05 02:53:39 +01:00
|
|
|
open_mem_write_stream(USES_REGS1) /* $open_mem_write_stream(-Stream) */
|
2015-06-18 01:32:33 +01:00
|
|
|
{
|
|
|
|
Term t;
|
|
|
|
int sno;
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
sno = Yap_OpenBufWriteStream(PASS_REGS1);
|
2015-06-18 01:32:33 +01:00
|
|
|
if (sno == -1)
|
2016-04-05 02:53:39 +01:00
|
|
|
return (PlIOError(SYSTEM_ERROR_INTERNAL, TermNil,
|
|
|
|
"new stream not available for open_mem_read_stream/1"));
|
|
|
|
t = Yap_MkStream(sno);
|
|
|
|
return (Yap_unify(ARG1, t));
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
/**
|
2015-06-18 01:32:33 +01:00
|
|
|
* Yap_PeekMemwriteStream() shows the current buffer for a memory stream.
|
2016-04-05 02:53:39 +01:00
|
|
|
*
|
2015-06-18 01:32:33 +01:00
|
|
|
* @param sno, the in-memory stream
|
2016-04-05 02:53:39 +01:00
|
|
|
*
|
2015-06-18 01:32:33 +01:00
|
|
|
* @return temporary buffer, discarded by close and may be moved away
|
|
|
|
* by other writes..
|
|
|
|
*/
|
2016-04-05 02:53:39 +01:00
|
|
|
char *Yap_MemExportStreamPtr(int sno) {
|
2015-07-23 01:33:30 +01:00
|
|
|
#if MAY_WRITE
|
2016-01-31 10:02:11 +00:00
|
|
|
char *s;
|
2016-04-05 02:53:39 +01:00
|
|
|
if (fflush(GLOBAL_Stream[sno].file) == 0) {
|
|
|
|
s = GLOBAL_Stream[sno].nbuf;
|
2015-08-07 22:57:53 +01:00
|
|
|
return s;
|
|
|
|
}
|
2015-07-23 01:33:30 +01:00
|
|
|
return NULL;
|
|
|
|
#else
|
2016-01-31 10:02:11 +00:00
|
|
|
return GLOBAL_Stream[sno].u.mem_string.buf;
|
2015-07-23 01:33:30 +01:00
|
|
|
#endif
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
static Int peek_mem_write_stream(
|
|
|
|
USES_REGS1) { /* '$peek_mem_write_stream'(+GLOBAL_Stream,?S0,?S) */
|
|
|
|
Int sno =
|
|
|
|
Yap_CheckStream(ARG1, (Output_Stream_f | InMemory_Stream_f), "close/2");
|
2015-07-23 01:33:30 +01:00
|
|
|
Int i;
|
2015-06-18 01:32:33 +01:00
|
|
|
Term tf = ARG2;
|
|
|
|
CELL *HI;
|
2015-07-23 01:33:30 +01:00
|
|
|
const char *ptr;
|
2015-06-18 01:32:33 +01:00
|
|
|
|
|
|
|
if (sno < 0)
|
|
|
|
return (FALSE);
|
2016-04-05 02:53:39 +01:00
|
|
|
restart:
|
2015-06-18 01:32:33 +01:00
|
|
|
HI = HR;
|
2015-07-23 01:33:30 +01:00
|
|
|
#if MAY_WRITE
|
|
|
|
if (fflush(GLOBAL_Stream[sno].file) == 0) {
|
2016-04-05 02:53:39 +01:00
|
|
|
ptr = GLOBAL_Stream[sno].nbuf;
|
|
|
|
i = GLOBAL_Stream[sno].nsize;
|
|
|
|
}
|
2015-07-23 01:33:30 +01:00
|
|
|
#else
|
2016-04-05 02:53:39 +01:00
|
|
|
ptr = GLOBAL_Stream[sno].u.mem_string.buf;
|
|
|
|
i = GLOBAL_Stream[sno].u.mem_string.pos;
|
2015-07-23 01:33:30 +01:00
|
|
|
#endif
|
2015-06-18 01:32:33 +01:00
|
|
|
while (i > 0) {
|
|
|
|
--i;
|
2016-04-05 02:53:39 +01:00
|
|
|
tf = MkPairTerm(MkIntTerm(ptr[i]), tf);
|
2015-06-18 01:32:33 +01:00
|
|
|
if (HR + 1024 >= ASP) {
|
|
|
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
|
|
|
HR = HI;
|
2016-04-05 02:53:39 +01:00
|
|
|
if (!Yap_gcl((ASP - HI) * sizeof(CELL), 3, ENV, Yap_gcP())) {
|
|
|
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
|
|
|
Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
|
|
|
|
return (FALSE);
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
i = GLOBAL_Stream[sno].u.mem_string.pos;
|
|
|
|
tf = ARG2;
|
|
|
|
LOCK(GLOBAL_Stream[sno].streamlock);
|
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
2016-04-05 02:53:39 +01:00
|
|
|
return (Yap_unify(ARG3, tf));
|
2015-06-18 01:32:33 +01:00
|
|
|
}
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
void Yap_MemOps(StreamDesc *st) {
|
2015-06-18 01:32:33 +01:00
|
|
|
#if MAY_WRITE
|
|
|
|
st->stream_putc = FilePutc;
|
|
|
|
#else
|
2016-04-05 02:53:39 +01:00
|
|
|
st->stream_putc = MemPutc;
|
2015-06-18 01:32:33 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if MAY_READ
|
|
|
|
st->stream_getc = PlGetc;
|
|
|
|
#else
|
|
|
|
st->stream_getc = MemGetc;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
bool Yap_CloseMemoryStream(int sno) {
|
|
|
|
if (!(GLOBAL_Stream[sno].status & Output_Stream_f)) {
|
2016-01-31 10:02:11 +00:00
|
|
|
#if MAY_WRITE
|
2016-04-05 02:53:39 +01:00
|
|
|
fclose(GLOBAL_Stream[sno].file);
|
|
|
|
if (GLOBAL_Stream[sno].status & FreeOnClose_Stream_f)
|
|
|
|
free(GLOBAL_Stream[sno].nbuf);
|
|
|
|
#else
|
|
|
|
if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_CODE)
|
2016-01-31 10:02:11 +00:00
|
|
|
Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf);
|
|
|
|
else if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) {
|
|
|
|
free(GLOBAL_Stream[sno].u.mem_string.buf);
|
|
|
|
}
|
2016-04-05 02:53:39 +01:00
|
|
|
#endif
|
|
|
|
} else {
|
2016-01-31 10:02:11 +00:00
|
|
|
#if MAY_READ
|
2016-04-05 02:53:39 +01:00
|
|
|
fclose(GLOBAL_Stream[sno].file);
|
|
|
|
Yap_FreeAtomSpace(GLOBAL_Stream[sno].nbuf);
|
2016-01-31 10:02:11 +00:00
|
|
|
#else
|
2016-04-05 02:53:39 +01:00
|
|
|
if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_CODE)
|
2016-01-31 10:02:11 +00:00
|
|
|
Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf);
|
|
|
|
else if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) {
|
|
|
|
free(GLOBAL_Stream[sno].u.mem_string.buf);
|
|
|
|
}
|
2016-04-05 02:53:39 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return true;
|
2016-01-31 10:02:11 +00:00
|
|
|
}
|
|
|
|
|
2016-04-05 02:53:39 +01:00
|
|
|
void Yap_InitMems(void) {
|
|
|
|
CACHE_REGS
|
2015-06-18 01:32:33 +01:00
|
|
|
Term cm = CurrentModule;
|
|
|
|
CurrentModule = CHARSIO_MODULE;
|
2016-04-05 02:53:39 +01:00
|
|
|
Yap_InitCPred("open_mem_read_stream", 2, open_mem_read_stream, SyncPredFlag);
|
|
|
|
Yap_InitCPred("open_mem_write_stream", 1, open_mem_write_stream,
|
|
|
|
SyncPredFlag);
|
|
|
|
Yap_InitCPred("peek_mem_write_stream", 3, peek_mem_write_stream,
|
|
|
|
SyncPredFlag);
|
2015-06-18 01:32:33 +01:00
|
|
|
CurrentModule = cm;
|
|
|
|
}
|