fix mess with memory streams

This commit is contained in:
Vitor Santos Costa 2016-09-27 19:32:27 -05:00
parent b0ce23f131
commit a1ee3b30d3
7 changed files with 449 additions and 219 deletions

View File

@ -6,6 +6,7 @@ set (YAPOS_SOURCES
chartypes.c chartypes.c
console.c console.c
files.c files.c
fmem.c
fmemopen.c fmemopen.c
format.c format.c
iopreds.c iopreds.c

View File

@ -112,7 +112,7 @@ Int Yap_peek(int sno) {
return ch; return ch;
} }
#endif #endif
#if !MAY_READ #if !HAVE_FMEMOPEN
if (s->status & InMemory_Stream_f ) { if (s->status & InMemory_Stream_f ) {
return Yap_MemPeekc( sno ); return Yap_MemPeekc( sno );
} }

332
os/fmem.c Normal file
View File

@ -0,0 +1,332 @@
/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: mem.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 socket related IO.
*
*/
#include "sysbits.h"
#include "format.h"
#if HAVE_FMEMOPEN
bool format_synch(int sno, int sno0, format_info *fg) {
int (*f_putc)(int, int);
const char *s;
int n;
if (sno == sno0) {
#if MAY_WRITE
fflush(GLOBAL_Stream[sno].file);
#endif
return true;
}
f_putc = GLOBAL_Stream[sno0].stream_putc;
#if MAY_WRITE
if (fflush(GLOBAL_Stream[sno].file) == 0) {
s = GLOBAL_Stream[sno].nbuf;
n = ftell(GLOBAL_Stream[sno].file);
fwrite(s, n, 1, GLOBAL_Stream[sno0].file);
rewind(GLOBAL_Stream[sno].file);
fflush(GLOBAL_Stream[sno0].file);
} else
return false;
#else
s = GLOBAL_Stream[sno].u.mem_string.buf;
n = GLOBAL_Stream[sno].u.mem_string.pos;
#endif
#if MAY_WRITE
#else
while (n--) {
f_putc(sno0, *s++);
}
GLOBAL_Stream[sno].u.mem_string.pos = 0;
#endif
GLOBAL_Stream[sno].linecount = 1;
GLOBAL_Stream[sno].linepos = 0;
GLOBAL_Stream[sno].charcount = 0;
fg->lstart = 0;
fg->phys_start = 0;
fg->gapi = 0;
return true;
}
bool fill_pads(int sno, int sno0, int total, format_info *fg USES_REGS)
// uses directly the buffer in the memory stream.
{
int nfillers, fill_space, lfill_space, nchars;
int (*f_putc)(int, int);
const char *buf;
int phys_end;
f_putc = GLOBAL_Stream[sno0].stream_putc;
if (fflush(GLOBAL_Stream[sno].file) == 0) {
buf = GLOBAL_Stream[sno].nbuf;
phys_end = ftell(GLOBAL_Stream[sno].file);
} else
return false;
if (fg->gapi == 0) {
fg->gap[0].phys = phys_end;
fg->gap[0].filler = ' ';
fg->gapi = 1;
}
nchars = total - GLOBAL_Stream[sno].linepos;
if (nchars < 0)
nchars = 0; /* ignore */
nfillers = fg->gapi;
fill_space = nchars / nfillers;
lfill_space = nchars % nfillers;
int i = fg->phys_start;
gap_t *padi = fg->gap;
while (i < phys_end) {
if (i == padi->phys) {
int j;
for (j = 0; j < fill_space; j++)
f_putc(sno0, padi->filler);
padi++;
/* last gap??*/
if (padi - fg->gap == fg->gapi) {
for (j = 0; j < fill_space; j++)
f_putc(sno0, (padi - 1)->filler);
}
}
f_putc(sno0, buf[i++]);
}
// final gap
if (i == padi->phys) {
int j;
for (j = 0; j < fill_space + lfill_space; j++)
f_putc(sno0, padi->filler);
};
rewind(GLOBAL_Stream[sno].file);
fflush(GLOBAL_Stream[sno0].file);
GLOBAL_Stream[sno].linecount = 1;
GLOBAL_Stream[sno].linepos += nchars;
GLOBAL_Stream[sno].charcount = 0;
fg->phys_start = 0;
fg->lstart = GLOBAL_Stream[sno].linepos;
fg->gapi = 0;
return true;
}
bool Yap_set_stream_to_buf(StreamDesc *st, const char *buf, size_t nchars) {
FILE *f;
stream_flags_t flags;
// like any file stream.
st->file = f = fmemopen((void *)buf, nchars, "r");
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
Yap_DefaultStreamOps(st);
return true;
}
int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp,
memBufSource src) {
CACHE_REGS
int sno;
StreamDesc *st;
FILE *f;
encoding_t encoding;
stream_flags_t flags;
sno = GetFreeStreamD();
if (sno < 0)
return (PlIOError(RESOURCE_ERROR_MAX_STREAMS, TermNil,
"new stream not available for open_mem_read_stream/1"));
st = GLOBAL_Stream + sno;
if (encp)
encoding = *encp;
else
encoding = LOCAL_encoding;
// like any file stream.
f = st->file = fmemopen((void *)buf, nchars, "r");
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead);
// like any file stream.
Yap_DefaultStreamOps(st);
UNLOCK(st->streamlock);
return sno;
}
static Int
open_mem_read_stream(USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */
{
Term t, ti;
int sno;
char buf0[YAP_FILENAME_MAX + 1];
const char *buf;
ti = Deref(ARG1);
buf = Yap_TextTermToText(ti, buf0, 0, LOCAL_encoding);
if (!buf) {
return false;
}
sno = Yap_open_buf_read_stream(buf, strlen(buf) + 1, &LOCAL_encoding,
MEM_BUF_MALLOC);
t = Yap_MkStream(sno);
return Yap_unify(ARG2, t);
}
// open a buffer for writing, currently just ignores buf and nchars.
int Yap_open_buf_write_stream(encoding_t enc, memBufSource src) {
CACHE_REGS
int sno;
StreamDesc *st;
sno = GetFreeStreamD();
if (sno < 0)
return -1;
st = GLOBAL_Stream + sno;
st->status = Output_Stream_f | InMemory_Stream_f | FreeOnClose_Stream_f;
st->linepos = 0;
st->charcount = 0;
st->linecount = 1;
st->encoding = enc;
Yap_DefaultStreamOps(st);
#if HAVE_OPEN_MEMSTREAM
st->file = open_memstream(&st->nbuf, &st->nsize);
// setbuf(st->file, NULL);
st->status |= Seekable_Stream_f;
#else
st->file = fmemopen((void *)buf, nchars, "w");
st->nsize = nchars;
st->nbuf = buf;
if (!st->nbuf) {
return -1;
}
#endif
UNLOCK(st->streamlock);
return sno;
}
int Yap_OpenBufWriteStream(USES_REGS1) {
return Yap_open_buf_write_stream(
GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
}
static Int
open_mem_write_stream(USES_REGS1) /* $open_mem_write_stream(-Stream) */
{
Term t;
int sno;
sno = Yap_OpenBufWriteStream(PASS_REGS1);
if (sno == -1)
return (PlIOError(SYSTEM_ERROR_INTERNAL, TermNil,
"new stream not available for open_mem_read_stream/1"));
t = Yap_MkStream(sno);
GLOBAL_Stream[sno].status |= InMemory_Stream_f;
return (Yap_unify(ARG1, t));
}
/**
* Yap_PeekMemwriteStream() shows the current buffer for a memory stream.
*
* @param sno, the in-memory stream
*
* @return temporary buffer, discarded by close and may be moved away
* by other writes..
*/
char *Yap_MemExportStreamPtr(int sno) {
char *s;
if (fflush(GLOBAL_Stream[sno].file) == 0) {
s = GLOBAL_Stream[sno].nbuf;
// s[fseek(GLOBAL_Stream[sno].file, 0, SEEK_END)] = '\0';
return s;
}
return NULL;
}
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");
Int i;
Term tf = ARG2;
CELL *HI;
const char *ptr;
if (sno < 0)
return (FALSE);
restart:
HI = HR;
if (fflush(GLOBAL_Stream[sno].file) == 0) {
i = fseek(GLOBAL_Stream[sno].file, 0, SEEK_END);
ptr = GLOBAL_Stream[sno].nbuf;
}
while (i > 0) {
--i;
tf = MkPairTerm(MkIntTerm(ptr[i]), tf);
if (HR + 1024 >= ASP) {
UNLOCK(GLOBAL_Stream[sno].streamlock);
HR = HI;
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);
}
i = GLOBAL_Stream[sno].u.mem_string.pos;
tf = ARG2;
LOCK(GLOBAL_Stream[sno].streamlock);
goto restart;
}
}
UNLOCK(GLOBAL_Stream[sno].streamlock);
return (Yap_unify(ARG3, tf));
}
void Yap_MemOps(StreamDesc *st) {
st->stream_putc = FilePutc;
st->stream_getc = PlGetc;
}
bool Yap_CloseMemoryStream(int sno) {
if ((GLOBAL_Stream[sno].status & Output_Stream_f)) {
fflush(GLOBAL_Stream[sno].file);
fclose(GLOBAL_Stream[sno].file);
if (GLOBAL_Stream[sno].status & FreeOnClose_Stream_f)
free(GLOBAL_Stream[sno].nbuf);
} else {
fclose(GLOBAL_Stream[sno].file);
if (GLOBAL_Stream[sno].status & FreeOnClose_Stream_f)
free(GLOBAL_Stream[sno].nbuf);
}
return true;
}
void Yap_InitMems(void) {
CACHE_REGS
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);
}
#endif

View File

@ -265,133 +265,8 @@ output is directed to the stream used by format/2.
#include "eval.h" #include "eval.h"
#include "iopreds.h" #include "iopreds.h"
#include "format.h"
#define FORMAT_MAX_SIZE 1024
typedef struct {
Int filler;
/* character to dump */
int phys;
/* position in buffer */
int log; /* columnn as wide chsh */
} gap_t;
typedef struct format_status {
gap_t gap[16];
// number of octets
int phys_start;
// number of characters
int lstart;
int gapi;
} format_info;
static bool format_synch(int sno, int sno0, format_info *fg) {
int (*f_putc)(int, int);
const char *s;
int n;
if (sno == sno0) {
#if MAY_WRITE
fflush(GLOBAL_Stream[sno].file);
#endif
return true;
}
f_putc = GLOBAL_Stream[sno0].stream_putc;
#if MAY_WRITE
if (fflush(GLOBAL_Stream[sno].file) == 0) {
s = GLOBAL_Stream[sno].nbuf;
n = ftell(GLOBAL_Stream[sno].file);
fwrite(s, n, 1, GLOBAL_Stream[sno0].file);
rewind(GLOBAL_Stream[sno].file);
fflush(GLOBAL_Stream[sno0].file);
} else
return false;
#else
s = GLOBAL_Stream[sno].u.mem_string.buf;
n = GLOBAL_Stream[sno].u.mem_string.pos;
#endif
#if MAY_WRITE
#else
while (n--) {
f_putc(sno0, *s++);
}
GLOBAL_Stream[sno].u.mem_string.pos = 0;
#endif
GLOBAL_Stream[sno].linecount = 1;
GLOBAL_Stream[sno].linepos = 0;
GLOBAL_Stream[sno].charcount = 0;
fg->lstart = 0;
fg->phys_start = 0;
fg->gapi = 0;
return true;
}
// uses directly the buffer in the memory stream.
static bool fill_pads(int sno, int sno0, int total, format_info *fg USES_REGS) {
int nfillers, fill_space, lfill_space, nchars;
int (*f_putc)(int, int);
const char *buf;
int phys_end;
f_putc = GLOBAL_Stream[sno0].stream_putc;
#if MAY_WRITE
if (fflush(GLOBAL_Stream[sno].file) == 0) {
buf = GLOBAL_Stream[sno].nbuf;
phys_end = ftell(GLOBAL_Stream[sno].file);
} else
return false;
#else
buf = GLOBAL_Stream[sno].u.mem_string.buf;
phys_end = GLOBAL_Stream[sno].u.mem_string.pos;
#endif
if (fg->gapi == 0) {
fg->gap[0].phys = phys_end;
fg->gap[0].filler = ' ';
fg->gapi = 1;
}
nchars = total - GLOBAL_Stream[sno].linepos;
if (nchars < 0)
nchars = 0; /* ignore */
nfillers = fg->gapi;
fill_space = nchars / nfillers;
lfill_space = nchars % nfillers;
int i = fg->phys_start;
gap_t *padi = fg->gap;
while (i < phys_end) {
if (i == padi->phys) {
int j;
for (j = 0; j < fill_space; j++)
f_putc(sno0, padi->filler);
padi++;
/* last gap??*/
if (padi - fg->gap == fg->gapi) {
for (j = 0; j < fill_space; j++)
f_putc(sno0, (padi - 1)->filler);
}
}
f_putc(sno0, buf[i++]);
}
// final gap
if (i == padi->phys) {
int j;
for (j = 0; j < fill_space + lfill_space; j++)
f_putc(sno0, padi->filler);
};
#if MAY_WRITE
rewind(GLOBAL_Stream[sno].file);
fflush(GLOBAL_Stream[sno0].file);
#else
GLOBAL_Stream[sno].u.mem_string.pos = 0;
#endif
GLOBAL_Stream[sno].linecount = 1;
GLOBAL_Stream[sno].linepos += nchars;
GLOBAL_Stream[sno].charcount = 0;
fg->phys_start = 0;
fg->lstart = GLOBAL_Stream[sno].linepos;
fg->gapi = 0;
return true;
}
static int format_print_str(Int sno, Int size, Int has_size, Term args, static int format_print_str(Int sno, Int size, Int has_size, Term args,
int (*f_putc)(int, wchar_t)) { int (*f_putc)(int, wchar_t)) {
@ -430,9 +305,6 @@ static int format_print_str(Int sno, Int size, Int has_size, Term args,
return TRUE; return TRUE;
} }
#define FORMAT_COPY_ARGS_ERROR -1
#define FORMAT_COPY_ARGS_OVERFLOW -2
static Int format_copy_args(Term args, Term *targs, Int tsz) { static Int format_copy_args(Term args, Term *targs, Int tsz) {
Int n = 0; Int n = 0;
while (args != TermNil) { while (args != TermNil) {

25
os/format.h Normal file
View File

@ -0,0 +1,25 @@
#define FORMAT_MAX_SIZE 1024
typedef struct {
Int filler;
/* character to dump */
int phys;
/* position in buffer */
int log; /* columnn as wide chsh */
} gap_t;
typedef struct format_status {
gap_t gap[16];
// number of octets
int phys_start;
// number of characters
int lstart;
int gapi;
} format_info;
#define FORMAT_COPY_ARGS_ERROR -1
#define FORMAT_COPY_ARGS_OVERFLOW -2
extern bool format_synch(int sno, int sno0, format_info *fg);
extern bool fill_pads(int sno, int sno0, int total, format_info *fg USES_REGS);

168
os/mem.c
View File

@ -25,8 +25,89 @@ static char SccsId[] = "%W% %G%";
#include "sysbits.h" #include "sysbits.h"
#if !MAY_READ
static int MemGetc(int); #if !HAVE_FMEMOPEN || !defined(HAVE_FMEMOPEN)
#include "format.h"
bool format_synch(int sno, int sno0, format_info *fg) {
int (*f_putc)(int, int);
const char *s;
int n;
if (sno == sno0) {
return true;
}
f_putc = GLOBAL_Stream[sno0].stream_putc;
s = GLOBAL_Stream[sno].u.mem_string.buf;
n = GLOBAL_Stream[sno].u.mem_string.pos;
while (n--) {
f_putc(sno0, *s++);
}
GLOBAL_Stream[sno].u.mem_string.pos = 0;
GLOBAL_Stream[sno].linecount = 1;
GLOBAL_Stream[sno].linepos = 0;
GLOBAL_Stream[sno].charcount = 0;
fg->lstart = 0;
fg->phys_start = 0;
fg->gapi = 0;
return true;
}
// uses directly the buffer in the memory stream.
bool fill_pads(int sno, int sno0, int total, format_info *fg USES_REGS) {
int nfillers, fill_space, lfill_space, nchars;
int (*f_putc)(int, int);
const char *buf;
int phys_end;
f_putc = GLOBAL_Stream[sno0].stream_putc;
buf = GLOBAL_Stream[sno].u.mem_string.buf;
phys_end = GLOBAL_Stream[sno].u.mem_string.pos;
if (fg->gapi == 0) {
fg->gap[0].phys = phys_end;
fg->gap[0].filler = ' ';
fg->gapi = 1;
}
nchars = total - GLOBAL_Stream[sno].linepos;
if (nchars < 0)
nchars = 0; /* ignore */
nfillers = fg->gapi;
fill_space = nchars / nfillers;
lfill_space = nchars % nfillers;
int i = fg->phys_start;
gap_t *padi = fg->gap;
while (i < phys_end) {
if (i == padi->phys) {
int j;
for (j = 0; j < fill_space; j++)
f_putc(sno0, padi->filler);
padi++;
/* last gap??*/
if (padi - fg->gap == fg->gapi) {
for (j = 0; j < fill_space; j++)
f_putc(sno0, (padi - 1)->filler);
}
}
f_putc(sno0, buf[i++]);
}
// final gap
if (i == padi->phys) {
int j;
for (j = 0; j < fill_space + lfill_space; j++)
f_putc(sno0, padi->filler);
};
GLOBAL_Stream[sno].u.mem_string.pos = 0;
GLOBAL_Stream[sno].linecount = 1;
GLOBAL_Stream[sno].linepos += nchars;
GLOBAL_Stream[sno].charcount = 0;
fg->phys_start = 0;
fg->lstart = GLOBAL_Stream[sno].linepos;
fg->gapi = 0;
return true;
}
/* read from memory */ /* read from memory */
static int MemGetc(int sno) { static int MemGetc(int sno) {
@ -59,9 +140,6 @@ int Yap_MemPeekc(int sno) {
return ch; return ch;
} }
#endif
#if !MAY_WRITE
static int MemPutc(int, int); static int MemPutc(int, int);
/* static */ /* static */
@ -102,24 +180,15 @@ static int MemPutc(int sno, int ch) {
return ((int)ch); return ((int)ch);
} }
#endif
bool Yap_set_stream_to_buf(StreamDesc *st, const char *buf, size_t nchars) { bool Yap_set_stream_to_buf(StreamDesc *st, const char *buf, size_t nchars) {
FILE *f; FILE *f;
stream_flags_t flags; stream_flags_t flags;
#if MAY_READ
// like any file stream.
st->file = f = fmemopen((void *)buf, nchars, "r");
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
#else
st->file = f = NULL; st->file = f = NULL;
flags = Input_Stream_f | InMemory_Stream_f; flags = Input_Stream_f | InMemory_Stream_f;
#endif
Yap_initStream(st - GLOBAL_Stream, f, NULL, TermNil, LOCAL_encoding, flags, Yap_initStream(st - GLOBAL_Stream, f, NULL, TermNil, LOCAL_encoding, flags,
AtomRead); AtomRead);
// like any file stream. // like any file stream.
#if !MAY_READ
/* currently these streams are not seekable */ /* currently these streams are not seekable */
st->status = Input_Stream_f | InMemory_Stream_f; st->status = Input_Stream_f | InMemory_Stream_f;
st->u.mem_string.pos = 0; st->u.mem_string.pos = 0;
@ -127,7 +196,6 @@ bool Yap_set_stream_to_buf(StreamDesc *st, const char *buf, size_t nchars) {
st->u.mem_string.max_size = nchars; st->u.mem_string.max_size = nchars;
st->u.mem_string.error_handler = NULL; st->u.mem_string.error_handler = NULL;
// st->u.mem_string.src = src; check new assets coode // st->u.mem_string.src = src; check new assets coode
#endif
Yap_DefaultStreamOps(st); Yap_DefaultStreamOps(st);
return true; return true;
} }
@ -150,17 +218,10 @@ int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp,
encoding = *encp; encoding = *encp;
else else
encoding = LOCAL_encoding; encoding = LOCAL_encoding;
#if MAY_READ
// like any file stream.
f = st->file = fmemopen((void *)buf, nchars, "r");
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
#else
st->file = f = NULL; st->file = f = NULL;
flags = Input_Stream_f | InMemory_Stream_f; flags = Input_Stream_f | InMemory_Stream_f;
#endif
Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead); Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead);
// like any file stream. // like any file stream.
#if !MAY_READ
/* currently these streams are not seekable */ /* currently these streams are not seekable */
st->status = Input_Stream_f | InMemory_Stream_f; st->status = Input_Stream_f | InMemory_Stream_f;
st->u.mem_string.pos = 0; st->u.mem_string.pos = 0;
@ -168,7 +229,6 @@ int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp,
st->u.mem_string.max_size = nchars; st->u.mem_string.max_size = nchars;
st->u.mem_string.error_handler = NULL; st->u.mem_string.error_handler = NULL;
st->u.mem_string.src = src; st->u.mem_string.src = src;
#endif
Yap_DefaultStreamOps(st); Yap_DefaultStreamOps(st);
UNLOCK(st->streamlock); UNLOCK(st->streamlock);
return sno; return sno;
@ -210,26 +270,10 @@ int Yap_open_buf_write_stream(encoding_t enc, memBufSource src) {
st->linecount = 1; st->linecount = 1;
st->encoding = enc; st->encoding = enc;
Yap_DefaultStreamOps(st); Yap_DefaultStreamOps(st);
#if MAY_WRITE
#if HAVE_OPEN_MEMSTREAM
st->file = open_memstream(&st->nbuf, &st->nsize);
// setbuf(st->file, NULL);
st->status |= Seekable_Stream_f;
#else
st->file = fmemopen((void *)buf, nchars, "w");
st->nsize = nchars;
st->nbuf = buf;
if (!st->nbuf) {
return -1;
}
#endif
#else
st->nbuf = st->u.mem_string.buf = malloc(PLGETC_BUF_SIZE); st->nbuf = st->u.mem_string.buf = malloc(PLGETC_BUF_SIZE);
st->u.mem_string.src == MEM_BUF_MALLOC; st->u.mem_string.src = MEM_BUF_MALLOC;
st->u.mem_string.src = 1;
st->u.mem_string.max_size = PLGETC_BUF_SIZE - 1; st->u.mem_string.max_size = PLGETC_BUF_SIZE - 1;
st->u.mem_string.pos = 0; st->u.mem_string.pos = 0;
#endif
UNLOCK(st->streamlock); UNLOCK(st->streamlock);
return sno; return sno;
} }
@ -264,19 +308,10 @@ open_mem_write_stream(USES_REGS1) /* $open_mem_write_stream(-Stream) */
* by other writes.. * by other writes..
*/ */
char *Yap_MemExportStreamPtr(int sno) { char *Yap_MemExportStreamPtr(int sno) {
#if MAY_WRITE
char *s;
if (fflush(GLOBAL_Stream[sno].file) == 0) {
s = GLOBAL_Stream[sno].nbuf;
// s[fseek(GLOBAL_Stream[sno].file, 0, SEEK_END)] = '\0';
return s;
}
return NULL;
#else
GLOBAL_Stream[sno].u.mem_string.buf[GLOBAL_Stream[sno].u.mem_string.pos] = GLOBAL_Stream[sno].u.mem_string.buf[GLOBAL_Stream[sno].u.mem_string.pos] =
'\0'; '\0';
return GLOBAL_Stream[sno].u.mem_string.buf; return GLOBAL_Stream[sno].u.mem_string.buf;
#endif
} }
static Int peek_mem_write_stream( static Int peek_mem_write_stream(
@ -292,15 +327,8 @@ static Int peek_mem_write_stream(
return (FALSE); return (FALSE);
restart: restart:
HI = HR; HI = HR;
#if MAY_WRITE
if (fflush(GLOBAL_Stream[sno].file) == 0) {
i = fseek(GLOBAL_Stream[sno].file, 0, SEEK_END);
ptr = GLOBAL_Stream[sno].nbuf;
}
#else
ptr = GLOBAL_Stream[sno].u.mem_string.buf; ptr = GLOBAL_Stream[sno].u.mem_string.buf;
i = GLOBAL_Stream[sno].u.mem_string.pos; i = GLOBAL_Stream[sno].u.mem_string.pos;
#endif
while (i > 0) { while (i > 0) {
--i; --i;
tf = MkPairTerm(MkIntTerm(ptr[i]), tf); tf = MkPairTerm(MkIntTerm(ptr[i]), tf);
@ -323,41 +351,19 @@ restart:
} }
void Yap_MemOps(StreamDesc *st) { void Yap_MemOps(StreamDesc *st) {
#if MAY_WRITE
st->stream_putc = FilePutc;
#else
st->stream_putc = MemPutc; st->stream_putc = MemPutc;
#endif
#if MAY_READ st->stream_getc = MemGetc;}
st->stream_getc = PlGetc;
#else
st->stream_getc = MemGetc;
#endif
}
bool Yap_CloseMemoryStream(int sno) { bool Yap_CloseMemoryStream(int sno) {
if ((GLOBAL_Stream[sno].status & Output_Stream_f)) { if ((GLOBAL_Stream[sno].status & Output_Stream_f)) {
#if MAY_WRITE
fflush(GLOBAL_Stream[sno].file);
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_MALLOC) { if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) {
free(GLOBAL_Stream[sno].u.mem_string.buf); free(GLOBAL_Stream[sno].u.mem_string.buf);
} }
#endif
} else { } else {
#if MAY_READ
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_MALLOC) { if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) {
free(GLOBAL_Stream[sno].u.mem_string.buf); free(GLOBAL_Stream[sno].u.mem_string.buf);
} }
#endif
} }
return true; return true;
} }
@ -370,3 +376,5 @@ void Yap_InitMems(void) {
Yap_InitCPred("peek_mem_write_stream", 3, peek_mem_write_stream, Yap_InitCPred("peek_mem_write_stream", 3, peek_mem_write_stream,
SyncPredFlag); SyncPredFlag);
} }
#endif

View File

@ -15,15 +15,6 @@ static char SccsId[] = "%W% %G%";
#undef HAVE_OPEN_MEMSTREAM #undef HAVE_OPEN_MEMSTREAM
#endif #endif
#if HAVE_FMEMOPEN
#define MAY_READ 1
#endif
#if HAVE_OPEN_MEMSTREAM
#define MAY_READ 1
#define MAY_WRITE 1
#endif
#if _WIN32 #if _WIN32
#undef MAY_WRITE #undef MAY_WRITE
#undef MAY_READ #undef MAY_READ
@ -85,3 +76,4 @@ typedef struct stream_desc {
from above if the ISO character conversion is on */ from above if the ISO character conversion is on */
encoding_t encoding; /** current encoding for stream */ encoding_t encoding; /** current encoding for stream */
} StreamDesc; } StreamDesc;