diff --git a/include/YapDefs.h b/include/YapDefs.h index d253c9108..fe615a65a 100755 --- a/include/YapDefs.h +++ b/include/YapDefs.h @@ -370,7 +370,8 @@ typedef enum stream_f { RepError_Prolog_f = 0x400000, /**< handle representation error as Prolog terms */ RepError_Xml_f = 0x800000, /**< handle representation error as XML objects */ DoNotCloseOnAbort_Stream_f= 0x1000000, /**< do not close the stream after an abort event */ - Readline_Stream_f= 0x2000000 /**< the stream is a readline stream */ + Readline_Stream_f= 0x2000000, /**< the stream is a readline stream */ + FreeOnClose_Stream_f= 0x4000000 /**< the stream buffer should be releaed on close */ } estream_f; typedef uint64_t stream_flags_t; diff --git a/os/mem.c b/os/mem.c index 290975725..0da22fad9 100644 --- a/os/mem.c +++ b/os/mem.c @@ -64,6 +64,11 @@ FILE * open_memstream (char **buf, size_t *len); #define MAY_WRITE 1 #endif +#if _WIN32 +#undef MAY_WRITE +#undef MAY_READ +#endif + #if !MAY_READ static int MemGetc( int); @@ -253,13 +258,15 @@ Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp, memBufSou sno = GetFreeStreamD(); if (sno < 0) return -1; - if (!buf) { + st = GLOBAL_Stream+sno; + st->status = Output_Stream_f | InMemory_Stream_f; + if (!buf) { if (!nchars) { - nchars = Yap_page_size; + nchars = Yap_page_size; } buf = malloc( nchars ); + st->status |= FreeOnClose_Stream_f; } - st = GLOBAL_Stream+sno; st->nbuf = buf; if(!st->nbuf) { return -1; @@ -275,12 +282,11 @@ Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp, memBufSou Yap_DefaultStreamOps( st ); #if MAY_WRITE st->file = open_memstream(&st->nbuf, &st->nsize); - st->status = Output_Stream_f | InMemory_Stream_f|Seekable_Stream_f; + st->status |= Seekable_Stream_f; #else st->u.mem_string.pos = 0; - st->u.mem_string.buf = nbuf; + st->u.mem_string.buf = st->nbuf; st->u.mem_string.max_size = nchars; - st->status = Output_Stream_f | InMemory_Stream_f; #endif Yap_MemOps( st ); UNLOCK(st->streamlock); @@ -327,8 +333,8 @@ open_mem_write_stream (USES_REGS1) /* $open_mem_write_stream(-Stream) */ char * Yap_MemExportStreamPtr( int sno ) { - char *s; #if MAY_WRITE + char *s; if (fflush(GLOBAL_Stream[sno].file) == 0) { s = GLOBAL_Stream[sno].nbuf; @@ -336,7 +342,7 @@ Yap_MemExportStreamPtr( int sno ) } return NULL; #else - return &GLOBAL_Stream[sno].u.mem_string; + return GLOBAL_Stream[sno].u.mem_string.buf; #endif } @@ -360,7 +366,6 @@ peek_mem_write_stream ( USES_REGS1 ) i = GLOBAL_Stream[sno].nsize; } #else - size_t pos; ptr = GLOBAL_Stream[sno].u.mem_string.buf; i = GLOBAL_Stream[sno].u.mem_string.pos; #endif @@ -401,6 +406,35 @@ void #endif } +bool Yap_CloseMemoryStream( int sno ) +{ + if (!(GLOBAL_Stream[sno].status & Output_Stream_f) ) { +#if MAY_WRITE + 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_CODE) + Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf); + 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); + Yap_FreeAtomSpace(GLOBAL_Stream[sno].nbuf); +#else + if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_CODE) + Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf); + else if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) { + free(GLOBAL_Stream[sno].u.mem_string.buf); + } +#endif + } + return true; +} + void Yap_InitMems( void ) {