fix mess with memory streams
This commit is contained in:
parent
b0ce23f131
commit
a1ee3b30d3
@ -6,6 +6,7 @@ set (YAPOS_SOURCES
|
||||
chartypes.c
|
||||
console.c
|
||||
files.c
|
||||
fmem.c
|
||||
fmemopen.c
|
||||
format.c
|
||||
iopreds.c
|
||||
|
@ -112,7 +112,7 @@ Int Yap_peek(int sno) {
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
#if !MAY_READ
|
||||
#if !HAVE_FMEMOPEN
|
||||
if (s->status & InMemory_Stream_f ) {
|
||||
return Yap_MemPeekc( sno );
|
||||
}
|
||||
|
332
os/fmem.c
Normal file
332
os/fmem.c
Normal 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
|
130
os/format.c
130
os/format.c
@ -265,133 +265,8 @@ output is directed to the stream used by format/2.
|
||||
|
||||
#include "eval.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,
|
||||
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;
|
||||
}
|
||||
|
||||
#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) {
|
||||
|
25
os/format.h
Normal file
25
os/format.h
Normal 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
168
os/mem.c
@ -25,8 +25,89 @@ static char SccsId[] = "%W% %G%";
|
||||
|
||||
#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 */
|
||||
static int MemGetc(int sno) {
|
||||
@ -59,9 +140,6 @@ int Yap_MemPeekc(int sno) {
|
||||
return ch;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !MAY_WRITE
|
||||
static int MemPutc(int, int);
|
||||
|
||||
/* static */
|
||||
@ -102,24 +180,15 @@ static int MemPutc(int sno, int ch) {
|
||||
return ((int)ch);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool Yap_set_stream_to_buf(StreamDesc *st, const char *buf, size_t nchars) {
|
||||
FILE *f;
|
||||
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;
|
||||
flags = Input_Stream_f | InMemory_Stream_f;
|
||||
#endif
|
||||
Yap_initStream(st - GLOBAL_Stream, f, NULL, TermNil, LOCAL_encoding, flags,
|
||||
AtomRead);
|
||||
// like any file stream.
|
||||
#if !MAY_READ
|
||||
/* currently these streams are not seekable */
|
||||
st->status = Input_Stream_f | InMemory_Stream_f;
|
||||
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.error_handler = NULL;
|
||||
// st->u.mem_string.src = src; check new assets coode
|
||||
#endif
|
||||
Yap_DefaultStreamOps(st);
|
||||
return true;
|
||||
}
|
||||
@ -150,17 +218,10 @@ int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp,
|
||||
encoding = *encp;
|
||||
else
|
||||
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;
|
||||
flags = Input_Stream_f | InMemory_Stream_f;
|
||||
#endif
|
||||
Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead);
|
||||
// like any file stream.
|
||||
#if !MAY_READ
|
||||
/* currently these streams are not seekable */
|
||||
st->status = Input_Stream_f | InMemory_Stream_f;
|
||||
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.error_handler = NULL;
|
||||
st->u.mem_string.src = src;
|
||||
#endif
|
||||
Yap_DefaultStreamOps(st);
|
||||
UNLOCK(st->streamlock);
|
||||
return sno;
|
||||
@ -210,26 +270,10 @@ int Yap_open_buf_write_stream(encoding_t enc, memBufSource src) {
|
||||
st->linecount = 1;
|
||||
st->encoding = enc;
|
||||
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->u.mem_string.src == MEM_BUF_MALLOC;
|
||||
st->u.mem_string.src = 1;
|
||||
st->u.mem_string.src = MEM_BUF_MALLOC;
|
||||
st->u.mem_string.max_size = PLGETC_BUF_SIZE - 1;
|
||||
st->u.mem_string.pos = 0;
|
||||
#endif
|
||||
UNLOCK(st->streamlock);
|
||||
return sno;
|
||||
}
|
||||
@ -264,19 +308,10 @@ open_mem_write_stream(USES_REGS1) /* $open_mem_write_stream(-Stream) */
|
||||
* by other writes..
|
||||
*/
|
||||
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] =
|
||||
'\0';
|
||||
return GLOBAL_Stream[sno].u.mem_string.buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
static Int peek_mem_write_stream(
|
||||
@ -292,15 +327,8 @@ static Int peek_mem_write_stream(
|
||||
return (FALSE);
|
||||
restart:
|
||||
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;
|
||||
i = GLOBAL_Stream[sno].u.mem_string.pos;
|
||||
#endif
|
||||
while (i > 0) {
|
||||
--i;
|
||||
tf = MkPairTerm(MkIntTerm(ptr[i]), tf);
|
||||
@ -323,41 +351,19 @@ restart:
|
||||
}
|
||||
|
||||
void Yap_MemOps(StreamDesc *st) {
|
||||
#if MAY_WRITE
|
||||
st->stream_putc = FilePutc;
|
||||
#else
|
||||
st->stream_putc = MemPutc;
|
||||
#endif
|
||||
|
||||
#if MAY_READ
|
||||
st->stream_getc = PlGetc;
|
||||
#else
|
||||
st->stream_getc = MemGetc;
|
||||
#endif
|
||||
}
|
||||
st->stream_getc = MemGetc;}
|
||||
|
||||
bool Yap_CloseMemoryStream(int sno) {
|
||||
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) {
|
||||
free(GLOBAL_Stream[sno].u.mem_string.buf);
|
||||
}
|
||||
#endif
|
||||
} 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) {
|
||||
free(GLOBAL_Stream[sno].u.mem_string.buf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -370,3 +376,5 @@ void Yap_InitMems(void) {
|
||||
Yap_InitCPred("peek_mem_write_stream", 3, peek_mem_write_stream,
|
||||
SyncPredFlag);
|
||||
}
|
||||
|
||||
#endif
|
10
os/stream.h
10
os/stream.h
@ -15,15 +15,6 @@ static char SccsId[] = "%W% %G%";
|
||||
#undef HAVE_OPEN_MEMSTREAM
|
||||
#endif
|
||||
|
||||
#if HAVE_FMEMOPEN
|
||||
#define MAY_READ 1
|
||||
#endif
|
||||
|
||||
#if HAVE_OPEN_MEMSTREAM
|
||||
#define MAY_READ 1
|
||||
#define MAY_WRITE 1
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
#undef MAY_WRITE
|
||||
#undef MAY_READ
|
||||
@ -85,3 +76,4 @@ typedef struct stream_desc {
|
||||
from above if the ISO character conversion is on */
|
||||
encoding_t encoding; /** current encoding for stream */
|
||||
} StreamDesc;
|
||||
|
||||
|
Reference in New Issue
Block a user