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; 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 CACHE_REGS
size_t length; size_t length;
char *b; char *b;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
if ((b = Yap_TermToString(t, buf, sze, &length, &LOCAL_encoding, flags)) != if ((b = Yap_TermToString(t, &length, LOCAL_encoding, flags)) != buf) {
buf) {
if (b)
free(b);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return FALSE; return b;
} }
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return TRUE; return buf;
} }
X_API char *YAP_WriteDynamicBuffer(YAP_Term t, char *buf, size_t sze, /// write a a term to n user-provided buffer: make sure not tp
size_t *lengthp, encoding_t *encp, /// overflow the buffer even if the text is much larger.
int flags) { X_API int YAP_WriteDynamicBuffer(YAP_Term t, char *buf, size_t sze,
size_t *lengthp, encoding_t enc, int flags) {
char *b; char *b;
BACKUP_MACHINE_REGS(); 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(); RECOVER_MACHINE_REGS();
return b; return true;
} }
X_API char *YAP_CompileClause(Term t) { 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 "Yap.h"
#include "Yatom.h"
#include "YapHeap.h" #include "YapHeap.h"
#include "yapio.h" #include "Yatom.h"
#include "alloc.h" #include "alloc.h"
#include "eval.h" #include "eval.h"
#include "yapio.h"
/* stuff we want to use in standard YAP code */ /* stuff we want to use in standard YAP code */
#include "YapText.h" #include "YapText.h"
#if _MSC_VER || defined(__MINGW32__) #if _MSC_VER || defined(__MINGW32__)
@ -458,80 +458,62 @@ char_kind_t Yap_chtype0[NUMBER_OF_CHARS + 1] = {
EF, EF,
/* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si /* 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 /* 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 ! " # $ % & ' ( ) * + , - . / */ /* sp ! " # $ % & ' ( ) * + , - . / */
BS, SL, DC, SY, SY, CC, SY, QT, BK, BS, SL, DC, SY, SY, CC, SY, QT, BK, BK, SY, SY, BK, SY, SY, SY,
BK, SY, SY, BK, SY, SY, SY,
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, SY, SL, SY, SY, SY, SY,
NU, SY, SL, SY, SY, SY, SY,
/* @ A B C D E F G H I J K L M N O */ /* @ A B C D E F G H I J K L M N O */
SY, UC, UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, 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 [ \ ] ^ _ */ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, BK, SY, BK, SY, UL,
UC, UC, BK, SY, BK, SY, UL,
/* ` a b c d e f g h i j k l m n o */ /* ` a b c d e f g h i j k l m n o */
SY, LC, LC, LC, LC, LC, LC, LC, LC, SY, LC, LC, LC, LC, LC, LC, LC, 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 */ /* p q r s t u v w x y z { | } ~ del */
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, BK, BK, BK, SY, BS,
LC, LC, BK, BK, BK, SY, BS,
/* 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 /* 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 /* 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, BS, SY, SY, SY, SY, SY, SY, SY, SY, SY, LC, SY, SY, SY, SY, SY,
SY, LC, SY, SY, 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,
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 #ifdef vms
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, LC,
UC, UC, UC, UC, UC, UC, LC,
#else #else
UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, LC,
UC, UC, UC, UC, UC, UC, LC,
#endif #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 /* ð ñ ò ó ô õ ö ÷ ø ù ú û ü cannot write the last
* three because of lcc */ * three because of lcc */
#ifdef vms #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 #else
LC, LC, LC, LC, LC, LC, LC, SY, LC, LC, LC, LC, LC, LC, LC, LC, SY, LC, LC, LC, LC, LC, LC, LC, LC
LC, LC, LC, LC, LC, LC, LC
#endif #endif
}; };
@ -564,7 +546,8 @@ typedef struct scanner_extra_alloc {
} ScannerExtraBlock; } ScannerExtraBlock;
#define CodeSpaceError(t, p, l) CodeSpaceError__(t, p, l PASS_REGS) #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_Error_TYPE = RESOURCE_ERROR_HEAP;
LOCAL_ErrorMessage = "Code Space Overflow"; LOCAL_ErrorMessage = "Code Space Overflow";
if (t) { 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) #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 */ /* huge atom or variable, we are in trouble */
LOCAL_ErrorMessage = (char *)msg; LOCAL_ErrorMessage = (char *)msg;
LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK;
@ -1136,7 +1120,8 @@ Term Yap_scan_num(StreamDesc *inp) {
} }
TokEntry *tokptr = (TokEntry *)AllocScannerMemory(sizeof(TokEntry)); TokEntry *tokptr = (TokEntry *)AllocScannerMemory(sizeof(TokEntry));
tokptr->TokPos = GetCurInpPos(inp); tokptr->TokPos = GetCurInpPos(inp);
while((ch = getchr(inp)) == BS); while ((ch = getchr(inp)) == BS)
;
if (ch == '-') { if (ch == '-') {
sign = -1; sign = -1;
ch = getchr(inp); ch = getchr(inp);
@ -1229,8 +1214,8 @@ Term Yap_scan_num(StreamDesc *inp) {
const char *Yap_tokRep(TokEntry *tokptr, encoding_t encoding) { const char *Yap_tokRep(TokEntry *tokptr, encoding_t encoding) {
CACHE_REGS CACHE_REGS
Term info = tokptr->TokInfo; Term info = tokptr->TokInfo;
char *b, *buf = LOCAL_FileNameBuf2; char *buf = LOCAL_FileNameBuf2;
size_t length, sze = YAP_FILENAME_MAX - 1; size_t length;
UInt flags = 0; UInt flags = 0;
switch (tokptr->Tok) { switch (tokptr->Tok) {
@ -1240,13 +1225,9 @@ const char *Yap_tokRep(TokEntry *tokptr, encoding_t encoding) {
Term s = Yap_WCharsToString(wc PASS_REGS); Term s = Yap_WCharsToString(wc PASS_REGS);
return StringOfTerm(s); return StringOfTerm(s);
} }
return RepAtom((Atom)info)->StrOfAE; return RepAtom((Atom)info)->StrOfAE;
case Number_tok: case Number_tok:
if ((b = Yap_TermToString(info, buf, sze, &length, &encoding, return Yap_TermToString(info, &length, encoding, flags);
flags)) != buf) {
return NULL;
}
return buf;
case Var_tok: { case Var_tok: {
VarEntry *varinfo = (VarEntry *)info; VarEntry *varinfo = (VarEntry *)info;
varinfo->VarAdr = TermNil; varinfo->VarAdr = TermNil;
@ -1744,16 +1725,18 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
} else } else
ch = getchr(inp_stream); ch = getchr(inp_stream);
break; break;
case SY: case SY:
if (ch == '.' && (pch = Yap_peek(inp_stream - GLOBAL_Stream)) && if (ch == '.' && (pch = Yap_peek(inp_stream - GLOBAL_Stream)) &&
(chtype(pch) == BS || chtype(pch) == EF || pch == '%')) { (chtype(pch) == BS || chtype(pch) == EF || pch == '%')) {
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
// consume... // consume...
ch = getchr(inp_stream); ch = getchr(inp_stream);
if (chtype(ch) == EF) { if (chtype(ch) == EF) {
mark_eof(inp_stream); mark_eof(inp_stream);
t->TokInfo = TermEof; t->TokInfo = TermEof;
} else { } else {
if (ch == '%')
continue;
t->TokInfo = TermNewLine; t->TokInfo = TermNewLine;
} }
return l; return l;
@ -2054,7 +2037,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
} }
#if DEBUG #if DEBUG
if (GLOBAL_Option[2]) 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 #endif
if (LOCAL_ErrorMessage) { if (LOCAL_ErrorMessage) {
/* insert an error token to inform the system of what happened */ /* insert an error token to inform the system of what happened */

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

View File

@ -8,8 +8,8 @@ extern "C" {
#include "YapInterface.h" #include "YapInterface.h"
#include "blobs.h" #include "blobs.h"
X_API char *Yap_TermToString(Term t, char *s, size_t sz, size_t *length, X_API char *Yap_TermToString(Term t, size_t *length, encoding_t encodingp,
encoding_t *encodingp, int flags); int flags);
X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity);
X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_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() { const char *YAPTerm::text() {
CACHE_REGS CACHE_REGS
size_t sze = 4096, length; size_t length;
char *os = new char[4097];
encoding_t enc = LOCAL_encoding; encoding_t enc = LOCAL_encoding;
char *os;
BACKUP_MACHINE_REGS(); 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(); RECOVER_MACHINE_REGS();
return (char *)NULL; return nullptr;
} }
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return os; return os;

View File

@ -1902,11 +1902,11 @@ 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 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, extern X_API int YAP_WriteDynamicBuffer(YAP_Term t, char *buf, size_t sze,
size_t *lengthp, YAP_encoding_t *encp, size_t *lengthp, YAP_encoding_t enc,
int flags); int flags);
/* void YAP_Term(YAP_Term) */ /* void YAP_Term(YAP_Term) */
extern X_API YAP_Term YAP_CopyTerm(YAP_Term); extern X_API YAP_Term YAP_CopyTerm(YAP_Term);

View File

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

View File

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

View File

@ -79,8 +79,7 @@ int Yap_PlFGetchar(void);
int Yap_GetCharForSIGINT(void); int Yap_GetCharForSIGINT(void);
Int Yap_StreamToFileNo(Term); Int Yap_StreamToFileNo(Term);
int Yap_OpenStream(FILE *, char *, Term, int); int Yap_OpenStream(FILE *, char *, Term, int);
char *Yap_TermToString(Term t, char *s, size_t sz, size_t *length, char *Yap_TermToString(Term t, size_t *length, encoding_t encoding, int flags);
encoding_t *encoding, int flags);
char *Yap_HandleToString(yhandle_t l, size_t sz, size_t *length, char *Yap_HandleToString(yhandle_t l, size_t sz, size_t *length,
encoding_t *encoding, int flags); encoding_t *encoding, int flags);
int Yap_GetFreeStreamD(void); int Yap_GetFreeStreamD(void);
@ -125,13 +124,11 @@ typedef enum mem_buf_source {
char *Yap_MemStreamBuf(int sno); char *Yap_MemStreamBuf(int sno);
extern X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp, extern X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp,
int prio, Term *bindings_p); int prio, Term *bindings_p);
extern Term Yap_StringToNumberTerm(char *s, encoding_t *encp); extern Term Yap_StringToNumberTerm(char *s, encoding_t *encp);
int Yap_FormatFloat(Float f, char **s, size_t sz); 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, int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, memBufSource src);
memBufSource src); int Yap_open_buf_write_stream(encoding_t enc, memBufSource src);
int Yap_open_buf_write_stream(char *nbuf, size_t nchars, encoding_t *encp,
memBufSource src);
Term Yap_ReadFromAtom(Atom a, Term opts); Term Yap_ReadFromAtom(Atom a, Term opts);
FILE *Yap_GetInputStream(Term t, const char *m); FILE *Yap_GetInputStream(Term t, const char *m);
FILE *Yap_GetOutputStream(Term t, const char *m); FILE *Yap_GetOutputStream(Term t, const char *m);