fix mess with memory streams
This commit is contained in:
parent
b0ce23f131
commit
a1ee3b30d3
@ -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
|
||||||
|
@ -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
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 "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
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"
|
#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
|
10
os/stream.h
10
os/stream.h
@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user