diff --git a/Makefile b/Makefile index 28e22324..13ba7e4b 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,7 @@ libcyclone.a: runtime.c include/cyclone/runtime.h include/cyclone/types.h gc.c d $(CC) $(CFLAGS) -std=gnu99 -c gc.c -o gc.o $(CC) $(CFLAGS) -c \ -DCYC_HAVE_OPEN_MEMSTREAM=$(CYC_PLATFORM_HAS_MEMSTREAM) \ + -DCYC_HAVE_FMEMOPEN=$(CYC_PLATFORM_HAS_FMEMOPEN) \ mstreams.c -o mstreams.o $(CC) $(CFLAGS) -c \ -DCYC_INSTALL_DIR=\"$(PREFIX)\" \ diff --git a/Makefile.config b/Makefile.config index 062e96c4..01e7dbb0 100644 --- a/Makefile.config +++ b/Makefile.config @@ -39,6 +39,7 @@ DESTDIR ?= # Automatically detect platform-specific flags, instead of using autoconf #CYC_PLATFORM_HAS_MEMSTREAM ?= 1 CYC_PLATFORM_HAS_MEMSTREAM := $(shell echo "main(){char *buf; int len; open_memstream(&buf, &len);}" | gcc -xc - >/dev/null 2>/dev/null && echo 1 || echo 0) +CYC_PLATFORM_HAS_FMEMOPEN := $(shell echo "main(){char *buf; fmemopen(&buf, 0, \"r\");}" | gcc -xc - >/dev/null 2>/dev/null && echo 1 || echo 0) # code from chibi's makefile to detect platform ifndef PLATFORM diff --git a/include/cyclone/runtime.h b/include/cyclone/runtime.h index ce05dc43..87d9469f 100644 --- a/include/cyclone/runtime.h +++ b/include/cyclone/runtime.h @@ -217,6 +217,7 @@ port_type Cyc_stderr(void); port_type Cyc_io_open_input_file(void *data, object str); port_type Cyc_io_open_output_file(void *data, object str); port_type *Cyc_io_open_output_string(void *data); +port_type *Cyc_io_open_input_string(void *data, object str); void Cyc_io_get_output_string(void *data, object cont, object port); object Cyc_io_close_port(void *data, object port); object Cyc_io_close_input_port(void *data, object port); diff --git a/mstreams.c b/mstreams.c index 323fc620..9cac2044 100644 --- a/mstreams.c +++ b/mstreams.c @@ -11,8 +11,6 @@ #include "cyclone/types.h" #include "cyclone/runtime.h" #include -//#include -//#include /* These macros are hardcoded here to support functions in this module. */ #define closcall1(td, clo, a1) \ @@ -34,6 +32,27 @@ if (type_is_pair_prim(clo)) { \ } object Cyc_heap_alloc_port(void *data, port_type *p); +port_type *Cyc_io_open_input_string(void *data, object str) +{ +// // Allocate port on the heap so the location of mem_buf does not change + port_type *p; + make_port(sp, NULL, 0); + + Cyc_check_str(data, str); + p = (port_type *)Cyc_heap_alloc_port(data, &sp); + errno = 0; +#if CYC_HAVE_FMEMOPEN + p->mem_buf = malloc(sizeof(char) * (string_len(str) + 1)); + p->mem_buf_len = string_len(str); + memcpy(p->mem_buf, string_str(str), string_len(str)); + p->fp = fmemopen(p->mem_buf, string_len(str) + 1, "r"); +#endif + if (p->fp == NULL){ + Cyc_rt_raise2(data, "Unable to open input memory stream", obj_int2obj(errno)); + } + return p; +} + port_type *Cyc_io_open_output_string(void *data) { // Allocate port on the heap so the location of mem_buf does not change @@ -45,7 +64,7 @@ port_type *Cyc_io_open_output_string(void *data) p->fp = open_memstream(&(p->mem_buf), &(p->mem_buf_len)); #endif if (p->fp == NULL){ - Cyc_rt_raise2(data, "Unable to open memory stream", obj_int2obj(errno)); + Cyc_rt_raise2(data, "Unable to open output memory stream", obj_int2obj(errno)); } return p; } diff --git a/scheme/base.sld b/scheme/base.sld index 2b5221a3..65467137 100644 --- a/scheme/base.sld +++ b/scheme/base.sld @@ -140,6 +140,7 @@ output-port-open? get-output-string open-output-string + open-input-string features Cyc-version any @@ -194,11 +195,6 @@ ; ; No complex or rational numbers at this time ; rationalize ; -; ; need string ports -; ; may be able to use POSIX string steams for this, see: open_memstream -; ; however there may be portability issues with that. looks like BSD and windows don't have it -; open-input-string -; ; ;; no binary/text ports yet ; binary-port? ; textual-port? @@ -1161,6 +1157,10 @@ data, k, ((p->mode == 0 && p->fp != NULL) ? boolean_t : boolean_f)); ") + (define-c open-input-string + "(void *data, int argc, closure _, object k, object str)" + " port_type *p = Cyc_io_open_input_string(data, str); + return_closcall1(data, k, p); ") (define-c open-output-string "(void *data, int argc, closure _, object k)" " port_type *p = Cyc_io_open_output_string(data);