diff options
author | Justus Winter <[email protected]> | 2016-03-31 11:49:56 +0000 |
---|---|---|
committer | Justus Winter <[email protected]> | 2016-06-17 09:38:00 +0000 |
commit | 56c36f2932fe2baf8e46efdea4315cf33f3c0338 (patch) | |
tree | 4d7bbf6ad0c7660c836b94aded9cc1af7e366a69 /tests/gpgscm/scheme.c | |
parent | tests/gpgscm: Dynamically allocate string buffer. (diff) | |
download | gnupg-56c36f2932fe2baf8e46efdea4315cf33f3c0338.tar.gz gnupg-56c36f2932fe2baf8e46efdea4315cf33f3c0338.zip |
tests/gpgscm: Foreign objects support for TinySCHEME.
* tests/gpgscm/scheme-private.h (struct cell): Add 'foreign_object'.
(is_foreign_object): New prototype.
(get_foreign_object_{vtable,data}): Likewise.
* tests/gpgscm/scheme.c (enum scheme_types): New type.
(is_foreign_object): New function.
(get_foreign_object_{vtable,data}): Likewise.
(mk_foreign_object): Likewise.
(finalize_cell): Free foreign objects.
(atom2str): Pretty-print foreign objects.
(vtbl): Add new functions.
* tests/gpgscm/scheme.h (struct foreign_object_vtable): New type.
(mk_foreign_object): New prototype.
(struct scheme_interface): Add new functions.
Patch from Thomas Munro,
https://sourceforge.net/p/tinyscheme/patches/13/
Signed-off-by: Justus Winter <[email protected]>
Diffstat (limited to 'tests/gpgscm/scheme.c')
-rw-r--r-- | tests/gpgscm/scheme.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c index 1f40bb2fd..748a02210 100644 --- a/tests/gpgscm/scheme.c +++ b/tests/gpgscm/scheme.c @@ -125,7 +125,8 @@ enum scheme_types { T_MACRO=12, T_PROMISE=13, T_ENVIRONMENT=14, - T_LAST_SYSTEM_TYPE=14 + T_FOREIGN_OBJECT=15, + T_LAST_SYSTEM_TYPE=15 }; /* ADJ is enough slack to align cells in a TYPE_BITS-bit boundary */ @@ -235,6 +236,14 @@ INTERFACE INLINE pointer closure_env(pointer p) { return cdr(p); } INTERFACE INLINE int is_continuation(pointer p) { return (type(p)==T_CONTINUATION); } #define cont_dump(p) cdr(p) +INTERFACE INLINE int is_foreign_object(pointer p) { return (type(p)==T_FOREIGN_OBJECT); } +INTERFACE const foreign_object_vtable *get_foreign_object_vtable(pointer p) { + return p->_object._foreign_object._vtable; +} +INTERFACE void *get_foreign_object_data(pointer p) { + return p->_object._foreign_object._data; +} + /* To do: promise should be forced ONCE only */ INTERFACE INLINE int is_promise(pointer p) { return (type(p)==T_PROMISE); } @@ -930,6 +939,15 @@ pointer mk_foreign_func(scheme *sc, foreign_func f) { return (x); } +pointer mk_foreign_object(scheme *sc, const foreign_object_vtable *vtable, void *data) { + pointer x = get_cell(sc, sc->NIL, sc->NIL); + + typeflag(x) = (T_FOREIGN_OBJECT | T_ATOM); + x->_object._foreign_object._vtable=vtable; + x->_object._foreign_object._data = data; + return (x); +} + INTERFACE pointer mk_character(scheme *sc, int c) { pointer x = get_cell(sc,sc->NIL, sc->NIL); @@ -1341,6 +1359,8 @@ static void finalize_cell(scheme *sc, pointer a) { port_close(sc,a,port_input|port_output); } sc->free(a->_object._port); + } else if(is_foreign_object(a)) { + a->_object._foreign_object._vtable->finalize(sc, a->_object._foreign_object._data); } } @@ -2047,6 +2067,9 @@ static void atom2str(scheme *sc, pointer l, int f, char **pp, int *plen) { snprintf(p,STRBUFFSIZE,"#<FOREIGN PROCEDURE %ld>", procnum(l)); } else if (is_continuation(l)) { p = "#<CONTINUATION>"; + } else if (is_foreign_object(l)) { + p = sc->strbuff; + l->_object._foreign_object._vtable->to_string(sc, p, STRBUFFSIZE, l->_object._foreign_object._data); } else { p = "#<ERROR>"; } @@ -4591,6 +4614,9 @@ static struct scheme_interface vtbl ={ mk_character, mk_vector, mk_foreign_func, + mk_foreign_object, + get_foreign_object_vtable, + get_foreign_object_data, putstr, putcharacter, |