Fixes for processing write to buffer: should b more robust, but we still may have memory leaks

This commit is contained in:
Vitor Santos Costa 2016-04-22 18:19:58 +01:00
parent cd41d373db
commit f966a5b912
9 changed files with 1102 additions and 1073 deletions

View File

@ -2116,32 +2116,33 @@ X_API Term YAP_CopyTerm(Term t) {
return tn;
}
X_API int YAP_WriteBuffer(Term t, char *buf, size_t sze, int flags) {
X_API char *YAP_WriteBuffer(Term t, char *buf, size_t sze, int flags) {
CACHE_REGS
size_t length;
char *b;
BACKUP_MACHINE_REGS();
if ((b = Yap_TermToString(t, buf, sze, &length, &LOCAL_encoding, flags)) !=
buf) {
if (b)
free(b);
if ((b = Yap_TermToString(t, &length, LOCAL_encoding, flags)) != buf) {
RECOVER_MACHINE_REGS();
return FALSE;
return b;
}
RECOVER_MACHINE_REGS();
return TRUE;
return buf;
}
X_API char *YAP_WriteDynamicBuffer(YAP_Term t, char *buf, size_t sze,
size_t *lengthp, encoding_t *encp,
int flags) {
/// write a a term to n user-provided buffer: make sure not tp
/// overflow the buffer even if the text is much larger.
X_API int YAP_WriteDynamicBuffer(YAP_Term t, char *buf, size_t sze,
size_t *lengthp, encoding_t enc, int flags) {
char *b;
BACKUP_MACHINE_REGS();
b = Yap_TermToString(t, buf, sze, lengthp, encp, flags);
b = Yap_TermToString(t, lengthp, enc, flags);
if (*lengthp >= sze)
*lengthp = sze;
strncpy(buf, b, sze);
RECOVER_MACHINE_REGS();
return b;
return true;
}
X_API char *YAP_CompileClause(Term t) {

View File

@ -404,11 +404,11 @@ writing, writing a BOM can be requested using the option
*/
#include "Yap.h"
#include "Yatom.h"
#include "YapHeap.h"
#include "yapio.h"
#include "Yatom.h"
#include "alloc.h"
#include "eval.h"
#include "yapio.h"
/* stuff we want to use in standard YAP code */
#include "YapText.h"
#if _MSC_VER || defined(__MINGW32__)
@ -458,80 +458,62 @@ char_kind_t Yap_chtype0[NUMBER_OF_CHARS + 1] = {
EF,
/* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si
*/
BS, BS, BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
/* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us
*/
BS, BS, BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
/* sp ! " # $ % & ' ( ) * + , - . / */
BS, SL, DC, SY, SY, CC, SY, QT, BK,
BK, SY, SY, BK, SY, SY, SY,
BS, SL, DC, SY, SY, CC, SY, QT, BK, BK, SY, SY, BK, SY, SY, SY,
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
NU, NU, NU, NU, NU, NU, NU, NU, NU,
NU, SY, SL, SY, SY, SY, SY,
NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, SY, SL, SY, SY, SY, SY,
/* @ A B C D E F G H I J K L M N O */
SY, UC, UC, UC, UC, UC, UC, UC, UC,
UC, UC, UC, UC, UC, UC, UC,
SY, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC,
/* P Q R S T U V W X Y Z [ \ ] ^ _ */
UC, UC, UC, UC, UC, UC, UC, UC, UC,
UC, UC, BK, SY, BK, SY, UL,
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, BK, SY, BK, SY, UL,
/* ` a b c d e f g h i j k l m n o */
SY, LC, LC, LC, LC, LC, LC, LC, LC,
LC, LC, LC, LC, LC, LC, LC,
SY, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC,
/* p q r s t u v w x y z { | } ~ del */
LC, LC, LC, LC, LC, LC, LC, LC, LC,
LC, LC, BK, BK, BK, SY, BS,
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, BK, BK, BK, SY, BS,
/* 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
*/
BS, BS, BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
/* 144 145 ’ 147 148 149 150 151 152 153 154 155 156 157 158 159
*/
BS, BS, BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS,
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
/* ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ */
BS, SY, SY, SY, SY, SY, SY, SY, SY,
SY, LC, SY, SY, SY, SY, SY,
BS, SY, SY, SY, SY, SY, SY, SY, SY, SY, LC, SY, SY, SY, SY, SY,
/* ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ */
SY, SY, LC, LC, SY, SY, SY, SY, SY,
LC, LC, SY, SY, SY, SY, SY,
SY, SY, LC, LC, SY, SY, SY, SY, SY, LC, LC, SY, SY, SY, SY, SY,
/* À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï */
UC, UC, UC, UC, UC, UC, UC, UC, UC,
UC, UC, UC, UC, UC, UC, UC,
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC,
/* Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß */
#ifdef vms
UC, UC, UC, UC, UC, UC, UC, UC, UC,
UC, UC, UC, UC, UC, UC, LC,
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, LC,
#else
UC, UC, UC, UC, UC, UC, UC, SY, UC,
UC, UC, UC, UC, UC, UC, LC,
UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, LC,
#endif
/* à á â ã ä å æ ç è é ê ë ì í î ï */
LC, LC, LC, LC, LC, LC, LC, LC, LC,
LC, LC, LC, LC, LC, LC, LC,
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC,
/* ð ñ ò ó ô õ ö ÷ ø ù ú û ü cannot write the last
* three because of lcc */
#ifdef vms
LC, LC, LC, LC, LC, LC, LC, LC, LC,
LC, LC, LC, LC, LC, LC, LC
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC
#else
LC, LC, LC, LC, LC, LC, LC, SY, LC,
LC, LC, LC, LC, LC, LC, LC
LC, LC, LC, LC, LC, LC, LC, SY, LC, LC, LC, LC, LC, LC, LC, LC
#endif
};
@ -564,7 +546,8 @@ typedef struct scanner_extra_alloc {
} ScannerExtraBlock;
#define CodeSpaceError(t, p, l) CodeSpaceError__(t, p, l PASS_REGS)
static TokEntry *CodeSpaceError__(TokEntry *t, TokEntry *p, TokEntry *l USES_REGS) {
static TokEntry *CodeSpaceError__(TokEntry *t, TokEntry *p,
TokEntry *l USES_REGS) {
LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP;
LOCAL_ErrorMessage = "Code Space Overflow";
if (t) {
@ -587,7 +570,8 @@ static TokEntry *TrailSpaceError__(TokEntry *t, TokEntry *l USES_REGS) {
}
#define AuxSpaceError(p, l, msg) AuxSpaceError__(p, l, msg PASS_REGS)
static TokEntry *AuxSpaceError__(TokEntry *p, TokEntry *l, const char *msg USES_REGS) {
static TokEntry *AuxSpaceError__(TokEntry *p, TokEntry *l,
const char *msg USES_REGS) {
/* huge atom or variable, we are in trouble */
LOCAL_ErrorMessage = (char *)msg;
LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK;
@ -1136,7 +1120,8 @@ Term Yap_scan_num(StreamDesc *inp) {
}
TokEntry *tokptr = (TokEntry *)AllocScannerMemory(sizeof(TokEntry));
tokptr->TokPos = GetCurInpPos(inp);
while((ch = getchr(inp)) == BS);
while ((ch = getchr(inp)) == BS)
;
if (ch == '-') {
sign = -1;
ch = getchr(inp);
@ -1229,8 +1214,8 @@ Term Yap_scan_num(StreamDesc *inp) {
const char *Yap_tokRep(TokEntry *tokptr, encoding_t encoding) {
CACHE_REGS
Term info = tokptr->TokInfo;
char *b, *buf = LOCAL_FileNameBuf2;
size_t length, sze = YAP_FILENAME_MAX - 1;
char *buf = LOCAL_FileNameBuf2;
size_t length;
UInt flags = 0;
switch (tokptr->Tok) {
@ -1242,11 +1227,7 @@ const char *Yap_tokRep(TokEntry *tokptr, encoding_t encoding) {
}
return RepAtom((Atom)info)->StrOfAE;
case Number_tok:
if ((b = Yap_TermToString(info, buf, sze, &length, &encoding,
flags)) != buf) {
return NULL;
}
return buf;
return Yap_TermToString(info, &length, encoding, flags);
case Var_tok: {
VarEntry *varinfo = (VarEntry *)info;
varinfo->VarAdr = TermNil;
@ -1754,6 +1735,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
mark_eof(inp_stream);
t->TokInfo = TermEof;
} else {
if (ch == '%')
continue;
t->TokInfo = TermNewLine;
}
return l;
@ -2054,7 +2037,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
}
#if DEBUG
if (GLOBAL_Option[2])
fprintf(stderr, "[Token %d %s]", Ord(kind), Yap_tokRep(t, inp_stream->encoding));
fprintf(stderr, "[Token %d %s]", Ord(kind),
Yap_tokRep(t, inp_stream->encoding));
#endif
if (LOCAL_ErrorMessage) {
/* insert an error token to inform the system of what happened */

746
C/text.c

File diff suppressed because it is too large Load Diff

View File

@ -164,7 +164,6 @@ static void protect_close_number(struct write_globs *wglb, int used_bracket) {
static void wrputn(Int n,
struct write_globs *wglb) /* writes an integer */
{
wrf stream = wglb->stream;
char s[256], *s1 = s; /* that should be enough for most integers */
@ -389,8 +388,8 @@ int Yap_FormatFloat(Float f, char **s, size_t sz) {
int sno;
char *so;
sno = Yap_open_buf_write_stream(
*s, sz, &GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
sno = Yap_open_buf_write_stream(GLOBAL_Stream[LOCAL_c_output_stream].encoding,
0);
if (sno < 0)
return FALSE;
wglb.lw = separator;
@ -1272,24 +1271,24 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags,
Yap_CloseSlots(sls);
}
char *Yap_TermToString(Term t, char *s, size_t sz, size_t *length,
encoding_t *encp, int flags) {
char *Yap_TermToString(Term t, size_t *lengthp, encoding_t enc, int flags) {
CACHE_REGS
int sno = Yap_open_buf_write_stream(s, sz, encp, flags);
int sno = Yap_open_buf_write_stream(enc, flags);
int old_output_stream = LOCAL_c_output_stream;
const char *sf;
if (sno < 0)
return NULL;
LOCAL_c_output_stream = sno;
if (encp)
GLOBAL_Stream[sno].encoding = *encp;
if (enc)
GLOBAL_Stream[sno].encoding = enc;
else
GLOBAL_Stream[sno].encoding = LOCAL_encoding;
Yap_plwrite(t, GLOBAL_Stream + sno, 0, flags, GLOBAL_MaxPriority);
s = Yap_MemExportStreamPtr(sno);
sf = Yap_MemExportStreamPtr(sno);
Yap_CloseStream(sno);
LOCAL_c_output_stream = old_output_stream;
if (Yap_HasException())
return NULL;
return s;
return (char *)sf;
}

View File

@ -8,8 +8,8 @@ extern "C" {
#include "YapInterface.h"
#include "blobs.h"
X_API char *Yap_TermToString(Term t, char *s, size_t sz, size_t *length,
encoding_t *encodingp, int flags);
X_API char *Yap_TermToString(Term t, size_t *length, encoding_t encodingp,
int flags);
X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity);
X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity,
@ -297,14 +297,14 @@ intptr_t YAPTerm::hashTerm(size_t sz, size_t depth, bool variant) {
const char *YAPTerm::text() {
CACHE_REGS
size_t sze = 4096, length;
char *os = new char[4097];
size_t length;
encoding_t enc = LOCAL_encoding;
char *os;
BACKUP_MACHINE_REGS();
if (!(os = Yap_TermToString(Yap_GetFromSlot(t), os, sze, &length, &enc, 0))) {
if (!(os = Yap_TermToString(Yap_GetFromSlot(t), &length, enc, 0))) {
RECOVER_MACHINE_REGS();
return (char *)NULL;
return nullptr;
}
RECOVER_MACHINE_REGS();
return os;

View File

@ -1902,10 +1902,10 @@ extern X_API int YAP_Reset(yap_reset_t reset);
extern X_API void YAP_Error(int myerrno, YAP_Term t, const char *buf, ...);
extern X_API int YAP_WriteBuffer(YAP_Term, char *, size_t, int);
extern X_API char *YAP_WriteBuffer(YAP_Term, char *, size_t, int);
extern X_API char *YAP_WriteDynamicBuffer(YAP_Term t, char *buf, size_t sze,
size_t *lengthp, YAP_encoding_t *encp,
extern X_API int YAP_WriteDynamicBuffer(YAP_Term t, char *buf, size_t sze,
size_t *lengthp, YAP_encoding_t enc,
int flags);
/* void YAP_Term(YAP_Term) */

View File

@ -110,7 +110,7 @@ static int MemPutc(int sno, int ch) {
#endif
int Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp,
int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp,
memBufSource src) {
CACHE_REGS
int sno;
@ -130,7 +130,7 @@ int Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp,
encoding = LOCAL_encoding;
#if MAY_READ
// like any file stream.
st->file = f = fmemopen((void *)nbuf, nchars, "r");
st->file = f = fmemopen((void *)buf, nchars, "r");
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
#else
st->file = f = NULL;
@ -142,7 +142,7 @@ int Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp,
/* 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.buf = (char *)buf;
st->u.mem_string.max_size = nchars;
st->u.mem_string.error_handler = NULL;
st->u.mem_string.src = src;
@ -158,7 +158,7 @@ static Int
Term t, ti;
int sno;
Int sl = 0, nchars = 0;
char *nbuf;
char *buf;
ti = Deref(ARG1);
while (ti != TermNil) {
@ -173,7 +173,7 @@ static Int
ti = TailOfTerm(ti);
}
}
while ((nbuf = (char *)Yap_AllocAtomSpace((sl + 1) * sizeof(char))) == NULL) {
while ((buf = (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);
@ -190,17 +190,18 @@ static Int
Yap_Error(TYPE_ERROR_INTEGER, ARG1, "open_mem_read_stream");
return (FALSE);
}
nbuf[nchars++] = IntOfTerm(ts);
buf[nchars++] = IntOfTerm(ts);
ti = TailOfTerm(ti);
}
nbuf[nchars] = '\0';
sno = Yap_open_buf_read_stream(nbuf, nchars, &LOCAL_encoding, MEM_BUF_CODE);
buf[nchars] = '\0';
sno = Yap_open_buf_read_stream(buf, nchars, &LOCAL_encoding, MEM_BUF_CODE);
t = Yap_MkStream(sno);
return (Yap_unify(ARG2, t));
}
int Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp,
memBufSource sr) {
// 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;
@ -210,55 +211,37 @@ int Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp,
return -1;
st = GLOBAL_Stream + sno;
st->status = Output_Stream_f | InMemory_Stream_f;
if (!buf) {
if (!nchars) {
nchars = Yap_page_size;
}
buf = malloc(nchars);
st->status |= FreeOnClose_Stream_f;
}
st->nsize = nchars;
st->linepos = 0;
st->charcount = 0;
st->linecount = 1;
if (encp)
st->encoding = *encp;
else
st->encoding = LOCAL_encoding;
st->encoding = enc;
Yap_DefaultStreamOps(st);
#if MAY_WRITE
#if HAVE_FMEMOPEN
st->file = fmemopen((void *)buf, nchars, "w");
#else
st->file = open_memstream(buf, &st->nsize);
#if HAVE_OPEN_MEMSTREAM
st->file = open_memstream(&st->nbuf, &st->nsize);
st->status |= Seekable_Stream_f;
#endif
#else
st->file = fmemopen((void *)buf, nchars, "w");
st->nsize = nchars;
st->nbuf = buf;
if (!st->nbuf) {
return -1;
}
st->u.mem_string.pos = 0;
st->u.mem_string.buf = st->nbuf;
st->u.mem_string.max_size = nchars;
#endif
#else
char buf[YAP_FILENAME_MAX + 1];
st->nbuf = buf;
st->u.mem_string.buf = buf;
st->u.mem_string.max_size = YAP_FILENAME_MAX;
#endif
UNLOCK(st->streamlock);
return sno;
}
int Yap_OpenBufWriteStream(USES_REGS1) {
char *nbuf;
size_t sz = Yap_page_size;
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);
return -1;
}
}
return Yap_open_buf_write_stream(
nbuf, sz, &GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
}
static Int
@ -312,7 +295,7 @@ restart:
#if MAY_WRITE
if (fflush(GLOBAL_Stream[sno].file) == 0) {
ptr = GLOBAL_Stream[sno].nbuf;
i = GLOBAL_Stream[sno].nsize;
i = fseek(GLOBAL_Stream[sno].file, SEEK_END, 0);
}
#else
ptr = GLOBAL_Stream[sno].u.mem_string.buf;
@ -356,6 +339,7 @@ void Yap_MemOps(StreamDesc *st) {
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);

View File

@ -1325,7 +1325,7 @@ static Int term_to_string(USES_REGS1) {
const char *s;
if (IsVarTerm(t2)) {
size_t length;
s = Yap_TermToString(ARG1, NULL, 0, &length, NULL,
s = Yap_TermToString(ARG1, &length, LOCAL_encoding,
Quote_illegal_f | Handle_vars_f);
if (!s || !MkStringTerm(s)) {
Yap_Error(RESOURCE_ERROR_HEAP, t1,
@ -1357,7 +1357,7 @@ static Int term_to_atom(USES_REGS1) {
Atom at;
if (IsVarTerm(t2)) {
size_t length;
char *s = Yap_TermToString(Deref(ARG1), NULL, 0, &length, NULL,
char *s = Yap_TermToString(Deref(ARG1), &length, LOCAL_encoding,
Quote_illegal_f | Handle_vars_f);
if (!s || !(at = Yap_LookupAtom(s))) {
Yap_Error(RESOURCE_ERROR_HEAP, t2,

View File

@ -79,8 +79,7 @@ int Yap_PlFGetchar(void);
int Yap_GetCharForSIGINT(void);
Int Yap_StreamToFileNo(Term);
int Yap_OpenStream(FILE *, char *, Term, int);
char *Yap_TermToString(Term t, char *s, size_t sz, size_t *length,
encoding_t *encoding, int flags);
char *Yap_TermToString(Term t, size_t *length, encoding_t encoding, int flags);
char *Yap_HandleToString(yhandle_t l, size_t sz, size_t *length,
encoding_t *encoding, int flags);
int Yap_GetFreeStreamD(void);
@ -128,10 +127,8 @@ extern X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp,
int prio, Term *bindings_p);
extern Term Yap_StringToNumberTerm(char *s, encoding_t *encp);
int Yap_FormatFloat(Float f, char **s, size_t sz);
int Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp,
memBufSource src);
int Yap_open_buf_write_stream(char *nbuf, size_t nchars, encoding_t *encp,
memBufSource src);
int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, memBufSource src);
int Yap_open_buf_write_stream(encoding_t enc, memBufSource src);
Term Yap_ReadFromAtom(Atom a, Term opts);
FILE *Yap_GetInputStream(Term t, const char *m);
FILE *Yap_GetOutputStream(Term t, const char *m);