To: vim_dev@googlegroups.com Subject: Patch 7.3.791 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.3.791 Problem: MzScheme interface doesn't work propely. Solution: Make it work better. (Sergey Khorev) Files: runtime/doc/if_mzsch.txt, src/configure.in, src/auto/configure, src/eval.c, src/if_mzsch.c, src/if_mzsch.h, src/Make_ming.mak, src/Make_mvc.mak, src/os_unix.c, src/proto/eval.pro, src/testdir/test70.in, src/testdir/test70.ok *** ../vim-7.3.790/runtime/doc/if_mzsch.txt 2010-08-15 21:57:14.000000000 +0200 --- runtime/doc/if_mzsch.txt 2013-01-30 14:26:44.000000000 +0100 *************** *** 11,17 **** 3. Threads |mzscheme-threads| 4. Vim access from MzScheme |mzscheme-vim| 5. mzeval() Vim function |mzscheme-mzeval| ! 6. Dynamic loading |mzscheme-dynamic| {Vi does not have any of these commands} --- 11,18 ---- 3. Threads |mzscheme-threads| 4. Vim access from MzScheme |mzscheme-vim| 5. mzeval() Vim function |mzscheme-mzeval| ! 6. Using Function references |mzscheme-funcref| ! 7. Dynamic loading |mzscheme-dynamic| {Vi does not have any of these commands} *************** *** 21,30 **** Based on the work of Brent Fulgham. Dynamic loading added by Sergey Khorev ! For downloading MzScheme and other info: ! http://www.plt-scheme.org/software/mzscheme/ ! Note: On FreeBSD you should use the "drscheme" port. ============================================================================== 1. Commands *mzscheme-commands* --- 22,38 ---- Based on the work of Brent Fulgham. Dynamic loading added by Sergey Khorev ! MzScheme and PLT Scheme names have been rebranded as Racket. For more ! information please check http://racket-lang.org ! Futures and places of Racket version 5.x up to and including 5.3.1 do not ! work correctly with processes created by Vim. ! The simplest solution is to build Racket on your own with these features ! disabled: > ! ./configure --disable-futures --disable-places --prefix=your-install-prefix ! ! To speed up the process, you might also want to use --disable-gracket and ! --disable-docs ============================================================================== 1. Commands *mzscheme-commands* *************** *** 155,162 **** (eval {expr-string}) Evaluate the vim expression into respective MzScheme object: |Lists| are represented as Scheme lists, ! |Dictionaries| as hash tables. ! NOTE the name clashes with MzScheme eval (range-start) Start/End of the range passed with (range-end) the Scheme command. (beep) beep --- 163,173 ---- (eval {expr-string}) Evaluate the vim expression into respective MzScheme object: |Lists| are represented as Scheme lists, ! |Dictionaries| as hash tables, ! |Funcref|s as functions (see also ! |mzscheme-funcref|) ! NOTE the name clashes with MzScheme eval, ! use module qualifiers to overcome this. (range-start) Start/End of the range passed with (range-end) the Scheme command. (beep) beep *************** *** 237,243 **** evaluate MzScheme expressions and pass their values to VimL. ============================================================================== ! 6. Dynamic loading *mzscheme-dynamic* *E815* On MS-Windows the MzScheme libraries can be loaded dynamically. The |:version| output then includes |+mzscheme/dyn|. --- 248,270 ---- evaluate MzScheme expressions and pass their values to VimL. ============================================================================== ! 6. Using Function references *mzscheme-funcref* ! ! MzScheme interface allows use of |Funcref|s so you can call Vim functions ! directly from Scheme. For instance: > ! function! MyAdd2(arg) ! return a:arg + 2 ! endfunction ! mz (define f2 (vim-eval "function(\"MyAdd2\")")) ! mz (f2 7) ! < or : > ! :mz (define indent (vim-eval "function('indent')")) ! " return Vim indent for line 12 ! :mz (indent 12) ! < ! ! ============================================================================== ! 7. Dynamic loading *mzscheme-dynamic* *E815* On MS-Windows the MzScheme libraries can be loaded dynamically. The |:version| output then includes |+mzscheme/dyn|. *** ../vim-7.3.790/src/configure.in 2012-12-12 14:25:01.000000000 +0100 --- src/configure.in 2013-01-30 14:26:44.000000000 +0100 *************** *** 617,623 **** if test "X$vi_cv_path_mzscheme_pfx" != "X"; then if test "x$MACOSX" = "xyes"; then ! MZSCHEME_LIBS="-framework PLT_MzScheme" elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"; then MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a" MZSCHEME_CFLAGS="-DMZ_PRECISE_GC" --- 617,624 ---- if test "X$vi_cv_path_mzscheme_pfx" != "X"; then if test "x$MACOSX" = "xyes"; then ! MZSCHEME_LIBS="-framework Racket" ! MZSCHEME_CFLAGS="-DMZ_PRECISE_GC" elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"; then MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a" MZSCHEME_CFLAGS="-DMZ_PRECISE_GC" *************** *** 660,665 **** --- 661,670 ---- else if test -d $vi_cv_path_mzscheme_pfx/share/racket/collects; then SCHEME_COLLECTS=$vi_cv_path_mzscheme_pfx/share/racket/ + else + if test -d $vi_cv_path_mzscheme_pfx/collects; then + SCHEME_COLLECTS=$vi_cv_path_mzscheme_pfx/ + fi fi fi fi *** ../vim-7.3.790/src/auto/configure 2012-12-12 14:25:01.000000000 +0100 --- src/auto/configure 2013-01-30 14:27:31.000000000 +0100 *************** *** 4927,4933 **** if test "X$vi_cv_path_mzscheme_pfx" != "X"; then if test "x$MACOSX" = "xyes"; then ! MZSCHEME_LIBS="-framework PLT_MzScheme" elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"; then MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a" MZSCHEME_CFLAGS="-DMZ_PRECISE_GC" --- 4927,4934 ---- if test "X$vi_cv_path_mzscheme_pfx" != "X"; then if test "x$MACOSX" = "xyes"; then ! MZSCHEME_LIBS="-framework Racket" ! MZSCHEME_CFLAGS="-DMZ_PRECISE_GC" elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"; then MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a" MZSCHEME_CFLAGS="-DMZ_PRECISE_GC" *************** *** 4968,4973 **** --- 4969,4978 ---- else if test -d $vi_cv_path_mzscheme_pfx/share/racket/collects; then SCHEME_COLLECTS=$vi_cv_path_mzscheme_pfx/share/racket/ + else + if test -d $vi_cv_path_mzscheme_pfx/collects; then + SCHEME_COLLECTS=$vi_cv_path_mzscheme_pfx/ + fi fi fi fi *** ../vim-7.3.790/src/eval.c 2013-01-23 17:15:25.000000000 +0100 --- src/eval.c 2013-01-30 14:33:00.000000000 +0100 *************** *** 14333,14338 **** --- 14333,14354 ---- str = get_tv_string_buf(&argvars[0], buf); do_mzeval(str, rettv); } + + void + mzscheme_call_vim(name, args, rettv) + char_u *name; + typval_T *args; + typval_T *rettv; + { + typval_T argvars[3]; + + argvars[0].v_type = VAR_STRING; + argvars[0].vval.v_string = name; + copy_tv(args, &argvars[1]); + argvars[2].v_type = VAR_UNKNOWN; + f_call(argvars, rettv); + clear_tv(&argvars[1]); + } #endif /* *** ../vim-7.3.790/src/if_mzsch.c 2012-11-28 15:37:46.000000000 +0100 --- src/if_mzsch.c 2013-01-30 14:34:37.000000000 +0100 *************** *** 1,11 **** /* vi:set ts=8 sts=4 sw=4: * * MzScheme interface by Sergey Khorev ! * Original work by Brent Fulgham * (Based on lots of help from Matthew Flatt) * - * TODO Convert byte-strings to char strings? - * * This consists of six parts: * 1. MzScheme interpreter main program * 2. Routines that handle the external interface between MzScheme and --- 1,9 ---- /* vi:set ts=8 sts=4 sw=4: * * MzScheme interface by Sergey Khorev ! * Based on work by Brent Fulgham * (Based on lots of help from Matthew Flatt) * * This consists of six parts: * 1. MzScheme interpreter main program * 2. Routines that handle the external interface between MzScheme and *************** *** 142,148 **** static int do_mzscheme_command(exarg_T *, void *, Scheme_Closed_Prim *what); static void startup_mzscheme(void); static char *string_to_line(Scheme_Object *obj); ! static void do_output(char *mesg, intptr_t len); static void do_printf(char *format, ...); static void do_flush(void); static Scheme_Object *_apply_thunk_catch_exceptions( --- 140,151 ---- static int do_mzscheme_command(exarg_T *, void *, Scheme_Closed_Prim *what); static void startup_mzscheme(void); static char *string_to_line(Scheme_Object *obj); ! #if MZSCHEME_VERSION_MAJOR >= 500 ! # define OUTPUT_LEN_TYPE intptr_t ! #else ! # define OUTPUT_LEN_TYPE long ! #endif ! static void do_output(char *mesg, OUTPUT_LEN_TYPE len); static void do_printf(char *format, ...); static void do_flush(void); static Scheme_Object *_apply_thunk_catch_exceptions( *************** *** 166,175 **** static int mzscheme_env_main(Scheme_Env *env, int argc, char **argv); static int mzscheme_init(void); #ifdef FEAT_EVAL ! static Scheme_Object *vim_to_mzscheme(typval_T *vim_value, int depth, Scheme_Hash_Table *visited); ! static int mzscheme_to_vim(Scheme_Object *obj, typval_T *tv, int depth, Scheme_Hash_Table *visited); #endif #ifdef MZ_PRECISE_GC --- 169,181 ---- static int mzscheme_env_main(Scheme_Env *env, int argc, char **argv); static int mzscheme_init(void); #ifdef FEAT_EVAL ! static Scheme_Object *vim_to_mzscheme(typval_T *vim_value); ! static Scheme_Object *vim_to_mzscheme_impl(typval_T *vim_value, int depth, Scheme_Hash_Table *visited); ! static int mzscheme_to_vim(Scheme_Object *obj, typval_T *tv); ! static int mzscheme_to_vim_impl(Scheme_Object *obj, typval_T *tv, int depth, Scheme_Hash_Table *visited); + static Scheme_Object *vim_funcref(void *data, int argc, Scheme_Object **argv); #endif #ifdef MZ_PRECISE_GC *************** *** 183,188 **** --- 189,201 ---- } static int buffer_fixup_proc(void *obj) { + /* apparently not needed as the object will be uncollectable while + * the buffer is alive + */ + /* + vim_mz_buffer* buf = (vim_mz_buffer*) obj; + buf->buf->b_mzscheme_ref = GC_fixup_self(obj); + */ return buffer_size_proc(obj); } static int window_size_proc(void *obj UNUSED) *************** *** 195,206 **** } static int window_fixup_proc(void *obj) { return window_size_proc(obj); } #endif #ifdef DYNAMIC_MZSCHEME - static Scheme_Object *dll_scheme_eof; static Scheme_Object *dll_scheme_false; static Scheme_Object *dll_scheme_void; --- 208,233 ---- } static int window_fixup_proc(void *obj) { + /* apparently not needed as the object will be uncollectable while + * the window is alive + */ + /* + vim_mz_window* win = (vim_mz_window*) obj; + win->win->w_mzscheme_ref = GC_fixup_self(obj); + */ return window_size_proc(obj); } + /* with precise GC, w_mzscheme_ref and b_mzscheme_ref are immobile boxes + * containing pointers to a window/buffer + * with conservative GC these are simply pointers*/ + # define WINDOW_REF(win) *(vim_mz_window **)((win)->w_mzscheme_ref) + # define BUFFER_REF(buf) *(vim_mz_buffer **)((buf)->b_mzscheme_ref) + #else + # define WINDOW_REF(win) (vim_mz_window *)((win)->w_mzscheme_ref) + # define BUFFER_REF(buf) (vim_mz_buffer *)((buf)->b_mzscheme_ref) #endif #ifdef DYNAMIC_MZSCHEME static Scheme_Object *dll_scheme_eof; static Scheme_Object *dll_scheme_false; static Scheme_Object *dll_scheme_void; *************** *** 319,324 **** --- 346,352 ---- (Scheme_Object *s); static Scheme_Object *(*dll_scheme_char_string_to_path) (Scheme_Object *s); + static void *(*dll_scheme_set_collects_path)(Scheme_Object *p); # endif static Scheme_Hash_Table *(*dll_scheme_make_hash_table)(int type); static void (*dll_scheme_hash_set)(Scheme_Hash_Table *table, *************** *** 378,388 **** # endif # define scheme_gc_ptr_ok dll_scheme_gc_ptr_ok # if MZSCHEME_VERSION_MAJOR < 299 ! # define scheme_get_sized_string_output dll_scheme_get_sized_string_output # else # define scheme_get_sized_byte_string_output \ dll_scheme_get_sized_byte_string_output ! # define scheme_get_param dll_scheme_get_param # endif # define scheme_intern_symbol dll_scheme_intern_symbol # define scheme_lookup_global dll_scheme_lookup_global --- 406,416 ---- # endif # define scheme_gc_ptr_ok dll_scheme_gc_ptr_ok # if MZSCHEME_VERSION_MAJOR < 299 ! # define scheme_get_sized_byte_string_output dll_scheme_get_sized_string_output # else # define scheme_get_sized_byte_string_output \ dll_scheme_get_sized_byte_string_output ! # define scheme_get_param dll_scheme_get_param # endif # define scheme_intern_symbol dll_scheme_intern_symbol # define scheme_lookup_global dll_scheme_lookup_global *************** *** 391,398 **** # define scheme_make_pair dll_scheme_make_pair # define scheme_make_prim_w_arity dll_scheme_make_prim_w_arity # if MZSCHEME_VERSION_MAJOR < 299 ! # define scheme_make_string dll_scheme_make_string ! # define scheme_make_string_output_port dll_scheme_make_string_output_port # else # define scheme_make_byte_string dll_scheme_make_byte_string # define scheme_make_byte_string_output_port \ --- 419,426 ---- # define scheme_make_pair dll_scheme_make_pair # define scheme_make_prim_w_arity dll_scheme_make_prim_w_arity # if MZSCHEME_VERSION_MAJOR < 299 ! # define scheme_make_byte_string dll_scheme_make_string ! # define scheme_make_byte_string_output_port dll_scheme_make_string_output_port # else # define scheme_make_byte_string dll_scheme_make_byte_string # define scheme_make_byte_string_output_port \ *************** *** 421,426 **** --- 449,455 ---- dll_scheme_char_string_to_byte_string # define scheme_char_string_to_path \ dll_scheme_char_string_to_path + # define scheme_set_collects_path dll_scheme_set_collects_path # endif # define scheme_make_hash_table dll_scheme_make_hash_table # define scheme_hash_set dll_scheme_hash_set *************** *** 529,534 **** --- 558,564 ---- {"scheme_char_string_to_byte_string", (void **)&dll_scheme_char_string_to_byte_string}, {"scheme_char_string_to_path", (void **)&dll_scheme_char_string_to_path}, + {"scheme_set_collects_path", (void **)&dll_scheme_set_collects_path}, # endif {"scheme_make_hash_table", (void **)&dll_scheme_make_hash_table}, {"scheme_hash_set", (void **)&dll_scheme_hash_set}, *************** *** 625,635 **** } #endif /* DYNAMIC_MZSCHEME */ /* need to put it here for dynamic stuff to work */ #if defined(INCLUDE_MZSCHEME_BASE) # include "mzscheme_base.c" #elif MZSCHEME_VERSION_MAJOR >= 400 ! # error MzScheme 4.x must include mzscheme_base.c, for MinGW32 you need to define MZSCHEME_GENERATE_BASE=yes #endif /* --- 655,694 ---- } #endif /* DYNAMIC_MZSCHEME */ + #if MZSCHEME_VERSION_MAJOR < 299 + # define GUARANTEED_STRING_ARG(proc, num) GUARANTEE_STRING(proc, num) + #else + static Scheme_Object * + guaranteed_byte_string_arg(char *proc, int num, int argc, Scheme_Object **argv) + { + if (SCHEME_BYTE_STRINGP(argv[num])) + { + return argv[num]; + } + else if (SCHEME_CHAR_STRINGP(argv[num])) + { + Scheme_Object *tmp = NULL; + MZ_GC_DECL_REG(2); + MZ_GC_VAR_IN_REG(0, argv[num]); + MZ_GC_VAR_IN_REG(1, tmp); + MZ_GC_REG(); + tmp = scheme_char_string_to_byte_string(argv[num]); + MZ_GC_UNREG(); + return tmp; + } + else + scheme_wrong_type(proc, "string", num, argc, argv); + /* unreachable */ + return scheme_void; + } + # define GUARANTEED_STRING_ARG(proc, num) guaranteed_byte_string_arg(proc, num, argc, argv) + #endif + /* need to put it here for dynamic stuff to work */ #if defined(INCLUDE_MZSCHEME_BASE) # include "mzscheme_base.c" #elif MZSCHEME_VERSION_MAJOR >= 400 ! # error MzScheme >=4 must include mzscheme_base.c, for MinGW32 you need to define MZSCHEME_GENERATE_BASE=yes #endif /* *************** *** 861,866 **** --- 920,930 ---- scheme_set_stack_base(stack_base, 1); #endif + #ifndef TRAMPOLINED_MZVIM_STARTUP + /* in newer versions of precise GC the initial env has been created */ + environment = scheme_basic_env(); + #endif + MZ_REGISTER_STATIC(environment); MZ_REGISTER_STATIC(curout); MZ_REGISTER_STATIC(curerr); *************** *** 869,878 **** MZ_REGISTER_STATIC(exn_message); MZ_REGISTER_STATIC(vim_exn); - #ifndef TRAMPOLINED_MZVIM_STARTUP - /* in newer versions of precise GC the initial env has been created */ - environment = scheme_basic_env(); - #endif MZ_GC_CHECK(); #ifdef INCLUDE_MZSCHEME_BASE --- 933,938 ---- *************** *** 909,923 **** Scheme_Object *coll_byte_string = NULL; Scheme_Object *coll_char_string = NULL; Scheme_Object *coll_path = NULL; - Scheme_Object *coll_pair = NULL; - Scheme_Config *config = NULL; ! MZ_GC_DECL_REG(5); MZ_GC_VAR_IN_REG(0, coll_byte_string); MZ_GC_VAR_IN_REG(1, coll_char_string); MZ_GC_VAR_IN_REG(2, coll_path); - MZ_GC_VAR_IN_REG(3, coll_pair); - MZ_GC_VAR_IN_REG(4, config); MZ_GC_REG(); coll_byte_string = scheme_make_byte_string(MZSCHEME_COLLECTS); MZ_GC_CHECK(); --- 969,979 ---- Scheme_Object *coll_byte_string = NULL; Scheme_Object *coll_char_string = NULL; Scheme_Object *coll_path = NULL; ! MZ_GC_DECL_REG(3); MZ_GC_VAR_IN_REG(0, coll_byte_string); MZ_GC_VAR_IN_REG(1, coll_char_string); MZ_GC_VAR_IN_REG(2, coll_path); MZ_GC_REG(); coll_byte_string = scheme_make_byte_string(MZSCHEME_COLLECTS); MZ_GC_CHECK(); *************** *** 925,935 **** MZ_GC_CHECK(); coll_path = scheme_char_string_to_path(coll_char_string); MZ_GC_CHECK(); ! coll_pair = scheme_make_pair(coll_path, scheme_null); ! MZ_GC_CHECK(); ! config = scheme_config; ! MZ_GC_CHECK(); ! scheme_set_param(config, MZCONFIG_COLLECTION_PATHS, coll_pair); MZ_GC_CHECK(); MZ_GC_UNREG(); } --- 981,987 ---- MZ_GC_CHECK(); coll_path = scheme_char_string_to_path(coll_char_string); MZ_GC_CHECK(); ! scheme_set_collects_path(coll_path); MZ_GC_CHECK(); MZ_GC_UNREG(); } *************** *** 944,954 **** MZ_GC_VAR_IN_REG(1, coll_pair); MZ_GC_VAR_IN_REG(2, config); MZ_GC_REG(); ! coll_string = scheme_make_string(MZSCHEME_COLLECTS); MZ_GC_CHECK(); coll_pair = scheme_make_pair(coll_string, scheme_null); MZ_GC_CHECK(); ! config = scheme_config; MZ_GC_CHECK(); scheme_set_param(config, MZCONFIG_COLLECTION_PATHS, coll_pair); MZ_GC_CHECK(); --- 996,1006 ---- MZ_GC_VAR_IN_REG(1, coll_pair); MZ_GC_VAR_IN_REG(2, config); MZ_GC_REG(); ! coll_string = scheme_make_byte_string(MZSCHEME_COLLECTS); MZ_GC_CHECK(); coll_pair = scheme_make_pair(coll_string, scheme_null); MZ_GC_CHECK(); ! config = scheme_current_config(); MZ_GC_CHECK(); scheme_set_param(config, MZCONFIG_COLLECTION_PATHS, coll_pair); MZ_GC_CHECK(); *************** *** 991,997 **** MZ_GC_VAR_IN_REG(3, guard); MZ_GC_VAR_IN_REG(4, config); MZ_GC_REG(); ! config = scheme_config; MZ_GC_CHECK(); args[0] = scheme_get_param(config, MZCONFIG_SECURITY_GUARD); MZ_GC_CHECK(); --- 1043,1049 ---- MZ_GC_VAR_IN_REG(3, guard); MZ_GC_VAR_IN_REG(4, config); MZ_GC_REG(); ! config = scheme_current_config(); MZ_GC_CHECK(); args[0] = scheme_get_param(config, MZCONFIG_SECURITY_GUARD); MZ_GC_CHECK(); *************** *** 1055,1066 **** MZ_GC_DECL_REG(1); MZ_GC_VAR_IN_REG(0, config); MZ_GC_REG(); ! config = scheme_config; MZ_GC_CHECK(); /* recreate ports each call effectively clearing these ones */ ! curout = scheme_make_string_output_port(); MZ_GC_CHECK(); ! curerr = scheme_make_string_output_port(); MZ_GC_CHECK(); scheme_set_param(config, MZCONFIG_OUTPUT_PORT, curout); MZ_GC_CHECK(); --- 1107,1118 ---- MZ_GC_DECL_REG(1); MZ_GC_VAR_IN_REG(0, config); MZ_GC_REG(); ! config = scheme_current_config(); MZ_GC_CHECK(); /* recreate ports each call effectively clearing these ones */ ! curout = scheme_make_byte_string_output_port(); MZ_GC_CHECK(); ! curerr = scheme_make_byte_string_output_port(); MZ_GC_CHECK(); scheme_set_param(config, MZCONFIG_OUTPUT_PORT, curout); MZ_GC_CHECK(); *************** *** 1149,1161 **** { if (buf->b_mzscheme_ref) { ! vim_mz_buffer *bp; ! bp = buf->b_mzscheme_ref; bp->buf = INVALID_BUFFER_VALUE; ! buf->b_mzscheme_ref = NULL; scheme_gc_ptr_ok(bp); MZ_GC_CHECK(); } } --- 1201,1221 ---- { if (buf->b_mzscheme_ref) { ! vim_mz_buffer *bp = NULL; ! MZ_GC_DECL_REG(1); ! MZ_GC_VAR_IN_REG(0, bp); ! MZ_GC_REG(); ! bp = BUFFER_REF(buf); bp->buf = INVALID_BUFFER_VALUE; ! #ifndef MZ_PRECISE_GC scheme_gc_ptr_ok(bp); + #else + scheme_free_immobile_box(buf->b_mzscheme_ref); + #endif + buf->b_mzscheme_ref = NULL; MZ_GC_CHECK(); + MZ_GC_UNREG(); } } *************** *** 1167,1178 **** { if (win->w_mzscheme_ref) { ! vim_mz_window *wp; ! wp = win->w_mzscheme_ref; wp->win = INVALID_WINDOW_VALUE; ! win->w_mzscheme_ref = NULL; scheme_gc_ptr_ok(wp); MZ_GC_CHECK(); } } --- 1227,1246 ---- { if (win->w_mzscheme_ref) { ! vim_mz_window *wp = NULL; ! MZ_GC_DECL_REG(1); ! MZ_GC_VAR_IN_REG(0, wp); ! MZ_GC_REG(); ! wp = WINDOW_REF(win); wp->win = INVALID_WINDOW_VALUE; ! #ifndef MZ_PRECISE_GC scheme_gc_ptr_ok(wp); + #else + scheme_free_immobile_box(win->w_mzscheme_ref); + #endif + win->w_mzscheme_ref = NULL; MZ_GC_CHECK(); + MZ_GC_UNREG(); } } *************** *** 1349,1355 **** } static void ! do_output(char *mesg, intptr_t len UNUSED) { /* TODO: use len, the string may not be NUL terminated */ do_intrnl_output(mesg, 0); --- 1417,1423 ---- } static void ! do_output(char *mesg, OUTPUT_LEN_TYPE len UNUSED) { /* TODO: use len, the string may not be NUL terminated */ do_intrnl_output(mesg, 0); *************** *** 1371,1379 **** do_flush(void) { char *buff; ! intptr_t length; ! buff = scheme_get_sized_string_output(curerr, &length); MZ_GC_CHECK(); if (length) { --- 1439,1447 ---- do_flush(void) { char *buff; ! OUTPUT_LEN_TYPE length; ! buff = scheme_get_sized_byte_string_output(curerr, &length); MZ_GC_CHECK(); if (length) { *************** *** 1381,1387 **** return; } ! buff = scheme_get_sized_string_output(curout, &length); MZ_GC_CHECK(); if (length) do_output(buff, length); --- 1449,1455 ---- return; } ! buff = scheme_get_sized_byte_string_output(curout, &length); MZ_GC_CHECK(); if (length) do_output(buff, length); *************** *** 1398,1409 **** vim_command(void *data, int argc, Scheme_Object **argv) { Vim_Prim *prim = (Vim_Prim *)data; ! char *cmd = SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0)); /* may be use do_cmdline_cmd? */ ! do_cmdline((char_u *)cmd, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE); update_screen(VALID); raise_if_error(); return scheme_void; } --- 1466,1482 ---- vim_command(void *data, int argc, Scheme_Object **argv) { Vim_Prim *prim = (Vim_Prim *)data; ! Scheme_Object *cmd = NULL; ! MZ_GC_DECL_REG(1); ! MZ_GC_VAR_IN_REG(0, cmd); ! MZ_GC_REG(); ! cmd = GUARANTEED_STRING_ARG(prim->name, 0); /* may be use do_cmdline_cmd? */ ! do_cmdline(BYTE_STRING_VALUE(cmd), NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE); update_screen(VALID); + MZ_GC_UNREG(); raise_if_error(); return scheme_void; } *************** *** 1414,1439 **** { #ifdef FEAT_EVAL Vim_Prim *prim = (Vim_Prim *)data; ! char *expr; ! Scheme_Object *result; ! /* hash table to store visited values to avoid infinite loops */ ! Scheme_Hash_Table *visited = NULL; typval_T *vim_result; ! ! MZ_GC_DECL_REG(1); ! MZ_GC_VAR_IN_REG(0, visited); MZ_GC_REG(); ! visited = scheme_make_hash_table(SCHEME_hash_ptr); ! MZ_GC_CHECK(); ! ! expr = SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0)); ! vim_result = eval_expr((char_u *)expr, NULL); if (vim_result == NULL) raise_vim_exn(_("invalid expression")); ! result = vim_to_mzscheme(vim_result, 1, visited); free_tv(vim_result); MZ_GC_UNREG(); --- 1487,1508 ---- { #ifdef FEAT_EVAL Vim_Prim *prim = (Vim_Prim *)data; ! Scheme_Object *result = NULL; typval_T *vim_result; ! Scheme_Object *expr = NULL; ! MZ_GC_DECL_REG(2); ! MZ_GC_VAR_IN_REG(0, result); ! MZ_GC_VAR_IN_REG(1, expr); MZ_GC_REG(); + expr = GUARANTEED_STRING_ARG(prim->name, 0); ! vim_result = eval_expr(BYTE_STRING_VALUE(expr), NULL); if (vim_result == NULL) raise_vim_exn(_("invalid expression")); ! result = vim_to_mzscheme(vim_result); ! MZ_GC_CHECK(); free_tv(vim_result); MZ_GC_UNREG(); *************** *** 1474,1489 **** get_option(void *data, int argc, Scheme_Object **argv) { Vim_Prim *prim = (Vim_Prim *)data; - char_u *name; long value; char *strval; int rc; ! Scheme_Object *rval; int opt_flags = 0; buf_T *save_curb = curbuf; win_T *save_curw = curwin; ! name = (char_u *)SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0)); if (argc > 1) { --- 1543,1563 ---- get_option(void *data, int argc, Scheme_Object **argv) { Vim_Prim *prim = (Vim_Prim *)data; long value; char *strval; int rc; ! Scheme_Object *rval = NULL; ! Scheme_Object *name = NULL; int opt_flags = 0; buf_T *save_curb = curbuf; win_T *save_curw = curwin; ! MZ_GC_DECL_REG(2); ! MZ_GC_VAR_IN_REG(0, rval); ! MZ_GC_VAR_IN_REG(1, name); ! MZ_GC_REG(); ! ! name = GUARANTEED_STRING_ARG(prim->name, 0); if (argc > 1) { *************** *** 1513,1535 **** scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv); } ! rc = get_option_value(name, &value, (char_u **)&strval, opt_flags); curbuf = save_curb; curwin = save_curw; switch (rc) { case 1: return scheme_make_integer_value(value); case 0: ! rval = scheme_make_string(strval); MZ_GC_CHECK(); vim_free(strval); return rval; case -1: case -2: raise_vim_exn(_("hidden option")); case -3: raise_vim_exn(_("unknown option")); } /* unreachable */ --- 1587,1613 ---- scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv); } ! rc = get_option_value(BYTE_STRING_VALUE(name), &value, (char_u **)&strval, opt_flags); curbuf = save_curb; curwin = save_curw; switch (rc) { case 1: + MZ_GC_UNREG(); return scheme_make_integer_value(value); case 0: ! rval = scheme_make_byte_string(strval); MZ_GC_CHECK(); vim_free(strval); + MZ_GC_UNREG(); return rval; case -1: case -2: + MZ_GC_UNREG(); raise_vim_exn(_("hidden option")); case -3: + MZ_GC_UNREG(); raise_vim_exn(_("unknown option")); } /* unreachable */ *************** *** 1540,1552 **** static Scheme_Object * set_option(void *data, int argc, Scheme_Object **argv) { ! char_u *cmd; int opt_flags = 0; buf_T *save_curb = curbuf; win_T *save_curw = curwin; Vim_Prim *prim = (Vim_Prim *)data; - GUARANTEE_STRING(prim->name, 0); if (argc > 1) { if (M_global == NULL) --- 1618,1635 ---- static Scheme_Object * set_option(void *data, int argc, Scheme_Object **argv) { ! char_u *command = NULL; int opt_flags = 0; buf_T *save_curb = curbuf; win_T *save_curw = curwin; Vim_Prim *prim = (Vim_Prim *)data; + Scheme_Object *cmd = NULL; + + MZ_GC_DECL_REG(1); + MZ_GC_VAR_IN_REG(0, cmd); + MZ_GC_REG(); + cmd = GUARANTEED_STRING_ARG(prim->name, 0); if (argc > 1) { if (M_global == NULL) *************** *** 1575,1583 **** } /* do_set can modify cmd, make copy */ ! cmd = vim_strsave((char_u *)SCHEME_STR_VAL(argv[0])); ! do_set(cmd, opt_flags); ! vim_free(cmd); update_screen(NOT_VALID); curbuf = save_curb; curwin = save_curw; --- 1658,1667 ---- } /* do_set can modify cmd, make copy */ ! command = vim_strsave(BYTE_STRING_VALUE(cmd)); ! MZ_GC_UNREG(); ! do_set(command, opt_flags); ! vim_free(command); update_screen(NOT_VALID); curbuf = save_curb; curwin = save_curw; *************** *** 1639,1645 **** MZ_GC_DECL_REG(1); MZ_GC_VAR_IN_REG(0, self); - MZ_GC_REG(); /* We need to handle deletion of windows underneath us. * If we add a "w_mzscheme_ref" field to the win_T structure, --- 1723,1728 ---- *************** *** 1650,1667 **** * object, and reject them if the win_T *field is invalid. */ if (win->w_mzscheme_ref != NULL) ! return win->w_mzscheme_ref; ! self = scheme_malloc_fail_ok(scheme_malloc, sizeof(vim_mz_window)); vim_memset(self, 0, sizeof(vim_mz_window)); scheme_dont_gc_ptr(self); /* because win isn't visible to GC */ MZ_GC_CHECK(); - win->w_mzscheme_ref = self; self->win = win; self->so.type = mz_window_type; MZ_GC_UNREG(); ! return (Scheme_Object *)(self); } /* (get-win-num [window]) */ --- 1733,1756 ---- * object, and reject them if the win_T *field is invalid. */ if (win->w_mzscheme_ref != NULL) ! return (Scheme_Object *)WINDOW_REF(win); ! MZ_GC_REG(); ! self = scheme_malloc_fail_ok(scheme_malloc_tagged, sizeof(vim_mz_window)); vim_memset(self, 0, sizeof(vim_mz_window)); + #ifndef MZ_PRECISE_GC scheme_dont_gc_ptr(self); /* because win isn't visible to GC */ + #else + win->w_mzscheme_ref = scheme_malloc_immobile_box(NULL); + #endif + MZ_GC_CHECK(); + WINDOW_REF(win) = self; MZ_GC_CHECK(); self->win = win; self->so.type = mz_window_type; MZ_GC_UNREG(); ! return (Scheme_Object *)self; } /* (get-win-num [window]) */ *************** *** 1837,1858 **** mzscheme_open_buffer(void *data, int argc, Scheme_Object **argv) { Vim_Prim *prim = (Vim_Prim *)data; - char_u *fname; int num = 0; ! Scheme_Object *onum; #ifdef HAVE_SANDBOX sandbox_check(); #endif - fname = (char_u *)SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0)); /* TODO make open existing file */ ! num = buflist_add(fname, BLN_LISTED | BLN_CURBUF); if (num == 0) raise_vim_exn(_("couldn't open buffer")); onum = scheme_make_integer(num); ! return get_buffer_by_num(data, 1, &onum); } /* (get-buff-by-num {buffernum}) */ --- 1926,1956 ---- mzscheme_open_buffer(void *data, int argc, Scheme_Object **argv) { Vim_Prim *prim = (Vim_Prim *)data; int num = 0; ! Scheme_Object *onum = NULL; ! Scheme_Object *buf = NULL; ! Scheme_Object *fname; ! ! MZ_GC_DECL_REG(3); ! MZ_GC_VAR_IN_REG(0, onum); ! MZ_GC_VAR_IN_REG(1, buf); ! MZ_GC_VAR_IN_REG(2, fname); ! MZ_GC_REG(); ! fname = GUARANTEED_STRING_ARG(prim->name, 0); #ifdef HAVE_SANDBOX sandbox_check(); #endif /* TODO make open existing file */ ! num = buflist_add(BYTE_STRING_VALUE(fname), BLN_LISTED | BLN_CURBUF); if (num == 0) raise_vim_exn(_("couldn't open buffer")); onum = scheme_make_integer(num); ! buf = get_buffer_by_num(data, 1, &onum); ! MZ_GC_UNREG(); ! return buf; } /* (get-buff-by-num {buffernum}) */ *************** *** 1878,1900 **** { Vim_Prim *prim = (Vim_Prim *)data; buf_T *buf; ! char_u *fname; ! fname = (char_u *)SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0)); for (buf = firstbuf; buf; buf = buf->b_next) if (buf->b_ffname == NULL || buf->b_sfname == NULL) /* empty string */ { ! if (fname[0] == NUL) ! return buffer_new(buf); } ! else if (!fnamecmp(buf->b_ffname, fname) ! || !fnamecmp(buf->b_sfname, fname)) /* either short or long filename matches */ ! return buffer_new(buf); ! return scheme_false; } /* (get-next-buff [buffer]) */ --- 1976,2009 ---- { Vim_Prim *prim = (Vim_Prim *)data; buf_T *buf; ! Scheme_Object *buffer = NULL; ! Scheme_Object *fname = NULL; ! MZ_GC_DECL_REG(2); ! MZ_GC_VAR_IN_REG(0, buffer); ! MZ_GC_VAR_IN_REG(1, fname); ! MZ_GC_REG(); ! fname = GUARANTEED_STRING_ARG(prim->name, 0); ! buffer = scheme_false; for (buf = firstbuf; buf; buf = buf->b_next) + { if (buf->b_ffname == NULL || buf->b_sfname == NULL) /* empty string */ { ! if (BYTE_STRING_VALUE(fname)[0] == NUL) ! buffer = buffer_new(buf); } ! else if (!fnamecmp(buf->b_ffname, BYTE_STRING_VALUE(fname)) ! || !fnamecmp(buf->b_sfname, BYTE_STRING_VALUE(fname))) ! { /* either short or long filename matches */ ! buffer = buffer_new(buf); ! } ! } ! MZ_GC_UNREG(); ! return buffer; } /* (get-next-buff [buffer]) */ *************** *** 1951,1957 **** Vim_Prim *prim = (Vim_Prim *)data; vim_mz_buffer *buf = get_buffer_arg(prim->name, 0, argc, argv); ! return scheme_make_string((char *)buf->buf->b_ffname); } /* (curr-buff) */ --- 2060,2066 ---- Vim_Prim *prim = (Vim_Prim *)data; vim_mz_buffer *buf = get_buffer_arg(prim->name, 0, argc, argv); ! return scheme_make_byte_string((char *)buf->buf->b_ffname); } /* (curr-buff) */ *************** *** 1968,1992 **** MZ_GC_DECL_REG(1); MZ_GC_VAR_IN_REG(0, self); - MZ_GC_REG(); /* We need to handle deletion of buffers underneath us. * If we add a "b_mzscheme_ref" field to the buf_T structure, * then we can get at it in buf_freeall() in vim. */ if (buf->b_mzscheme_ref) ! return buf->b_mzscheme_ref; ! self = scheme_malloc_fail_ok(scheme_malloc, sizeof(vim_mz_buffer)); vim_memset(self, 0, sizeof(vim_mz_buffer)); ! scheme_dont_gc_ptr(self); /* because buf isn't visible to GC */ MZ_GC_CHECK(); - buf->b_mzscheme_ref = self; self->buf = buf; self->so.type = mz_buffer_type; MZ_GC_UNREG(); ! return (Scheme_Object *)(self); } /* --- 2077,2106 ---- MZ_GC_DECL_REG(1); MZ_GC_VAR_IN_REG(0, self); /* We need to handle deletion of buffers underneath us. * If we add a "b_mzscheme_ref" field to the buf_T structure, * then we can get at it in buf_freeall() in vim. */ if (buf->b_mzscheme_ref) ! return (Scheme_Object *)BUFFER_REF(buf); ! MZ_GC_REG(); ! self = scheme_malloc_fail_ok(scheme_malloc_tagged, sizeof(vim_mz_buffer)); vim_memset(self, 0, sizeof(vim_mz_buffer)); ! #ifndef MZ_PRECISE_GC ! scheme_dont_gc_ptr(self); /* because buf isn't visible to GC */ ! #else ! buf->b_mzscheme_ref = scheme_malloc_immobile_box(NULL); ! #endif ! MZ_GC_CHECK(); ! BUFFER_REF(buf) = self; MZ_GC_CHECK(); self->buf = buf; self->so.type = mz_buffer_type; MZ_GC_UNREG(); ! return (Scheme_Object *)self; } /* *************** *** 2023,2029 **** line = ml_get_buf(buf->buf, (linenr_T)linenr, FALSE); raise_if_error(); ! return scheme_make_string((char *)line); } --- 2137,2143 ---- line = ml_get_buf(buf->buf, (linenr_T)linenr, FALSE); raise_if_error(); ! return scheme_make_byte_string((char *)line); } *************** *** 2066,2072 **** for (i = n; i >= 0; --i) { ! Scheme_Object *str = scheme_make_string( (char *)ml_get_buf(buf->buf, (linenr_T)(lo+i), FALSE)); raise_if_error(); --- 2180,2186 ---- for (i = n; i >= 0; --i) { ! Scheme_Object *str = scheme_make_byte_string( (char *)ml_get_buf(buf->buf, (linenr_T)(lo+i), FALSE)); raise_if_error(); *************** *** 2298,2305 **** MZ_GC_VAR_IN_REG(1, rest); MZ_GC_REG(); ! array = (char **)alloc(new_len * sizeof(char *)); ! vim_memset(array, 0, new_len * sizeof(char *)); rest = line_list; for (i = 0; i < new_len; ++i) --- 2412,2419 ---- MZ_GC_VAR_IN_REG(1, rest); MZ_GC_REG(); ! array = (char **)alloc((new_len+1)* sizeof(char *)); ! vim_memset(array, 0, (new_len+1) * sizeof(char *)); rest = line_list; for (i = 0; i < new_len; ++i) *************** *** 2481,2488 **** MZ_GC_VAR_IN_REG(1, rest); MZ_GC_REG(); ! array = (char **)alloc(size * sizeof(char *)); ! vim_memset(array, 0, size * sizeof(char *)); rest = list; for (i = 0; i < size; ++i) --- 2595,2602 ---- MZ_GC_VAR_IN_REG(1, rest); MZ_GC_REG(); ! array = (char **)alloc((size+1) * sizeof(char *)); ! vim_memset(array, 0, (size+1) * sizeof(char *)); rest = list; for (i = 0; i < size; ++i) *************** *** 2589,2595 **** { char *scheme_str = NULL; char *vim_str = NULL; ! intptr_t len; int i; scheme_str = scheme_display_to_string(obj, &len); --- 2703,2709 ---- { char *scheme_str = NULL; char *vim_str = NULL; ! OUTPUT_LEN_TYPE len; int i; scheme_str = scheme_display_to_string(obj, &len); *************** *** 2598,2607 **** * are replacing a single line, and we must replace it with * a single line. */ ! if (memchr(scheme_str, '\n', (size_t)len)) scheme_signal_error(_("string cannot contain newlines")); ! vim_str = (char *)alloc((int)(len + 1)); /* Create a copy of the string, with internal nulls replaced by * newline characters, as is the vim convention. --- 2712,2721 ---- * are replacing a single line, and we must replace it with * a single line. */ ! if (memchr(scheme_str, '\n', len)) scheme_signal_error(_("string cannot contain newlines")); ! vim_str = (char *)alloc(len + 1); /* Create a copy of the string, with internal nulls replaced by * newline characters, as is the vim convention. *************** *** 2625,2637 **** * Convert Vim value into MzScheme, adopted from if_python.c */ static Scheme_Object * ! vim_to_mzscheme(typval_T *vim_value, int depth, Scheme_Hash_Table *visited) { Scheme_Object *result = NULL; int new_value = TRUE; ! MZ_GC_DECL_REG(1); MZ_GC_VAR_IN_REG(0, result); MZ_GC_REG(); /* Avoid infinite recursion */ --- 2739,2773 ---- * Convert Vim value into MzScheme, adopted from if_python.c */ static Scheme_Object * ! vim_to_mzscheme(typval_T *vim_value) ! { ! Scheme_Object *result = NULL; ! /* hash table to store visited values to avoid infinite loops */ ! Scheme_Hash_Table *visited = NULL; ! ! MZ_GC_DECL_REG(2); ! MZ_GC_VAR_IN_REG(0, result); ! MZ_GC_VAR_IN_REG(1, visited); ! MZ_GC_REG(); ! ! visited = scheme_make_hash_table(SCHEME_hash_ptr); ! MZ_GC_CHECK(); ! ! result = vim_to_mzscheme_impl(vim_value, 1, visited); ! ! MZ_GC_UNREG(); ! return result; ! } ! ! static Scheme_Object * ! vim_to_mzscheme_impl(typval_T *vim_value, int depth, Scheme_Hash_Table *visited) { Scheme_Object *result = NULL; int new_value = TRUE; ! MZ_GC_DECL_REG(2); MZ_GC_VAR_IN_REG(0, result); + MZ_GC_VAR_IN_REG(1, visited); MZ_GC_REG(); /* Avoid infinite recursion */ *************** *** 2650,2657 **** new_value = FALSE; else if (vim_value->v_type == VAR_STRING) { ! result = scheme_make_string(vim_value->vval.v_string == NULL ! ? "" : (char *)vim_value->vval.v_string); MZ_GC_CHECK(); } else if (vim_value->v_type == VAR_NUMBER) --- 2786,2792 ---- new_value = FALSE; else if (vim_value->v_type == VAR_STRING) { ! result = scheme_make_byte_string((char *)vim_value->vval.v_string); MZ_GC_CHECK(); } else if (vim_value->v_type == VAR_NUMBER) *************** *** 2682,2695 **** MZ_GC_REG(); curr = list->lv_last; ! obj = vim_to_mzscheme(&curr->li_tv, depth + 1, visited); result = scheme_make_pair(obj, scheme_null); MZ_GC_CHECK(); while (curr != list->lv_first) { curr = curr->li_prev; ! obj = vim_to_mzscheme(&curr->li_tv, depth + 1, visited); result = scheme_make_pair(obj, result); MZ_GC_CHECK(); } --- 2817,2830 ---- MZ_GC_REG(); curr = list->lv_last; ! obj = vim_to_mzscheme_impl(&curr->li_tv, depth + 1, visited); result = scheme_make_pair(obj, scheme_null); MZ_GC_CHECK(); while (curr != list->lv_first) { curr = curr->li_prev; ! obj = vim_to_mzscheme_impl(&curr->li_tv, depth + 1, visited); result = scheme_make_pair(obj, result); MZ_GC_CHECK(); } *************** *** 2722,2729 **** --todo; di = dict_lookup(hi); ! obj = vim_to_mzscheme(&di->di_tv, depth + 1, visited); ! key = scheme_make_string((char *)hi->hi_key); MZ_GC_CHECK(); scheme_hash_set((Scheme_Hash_Table *)result, key, obj); MZ_GC_CHECK(); --- 2857,2864 ---- --todo; di = dict_lookup(hi); ! obj = vim_to_mzscheme_impl(&di->di_tv, depth + 1, visited); ! key = scheme_make_byte_string((char *)hi->hi_key); MZ_GC_CHECK(); scheme_hash_set((Scheme_Hash_Table *)result, key, obj); MZ_GC_CHECK(); *************** *** 2732,2737 **** --- 2867,2888 ---- } MZ_GC_UNREG(); } + else if (vim_value->v_type == VAR_FUNC) + { + Scheme_Object *funcname = NULL; + + MZ_GC_DECL_REG(1); + MZ_GC_VAR_IN_REG(0, funcname); + MZ_GC_REG(); + + funcname = scheme_make_byte_string((char *)vim_value->vval.v_string); + MZ_GC_CHECK(); + result = scheme_make_closed_prim_w_arity(vim_funcref, funcname, + (const char *)BYTE_STRING_VALUE(funcname), 0, -1); + MZ_GC_CHECK(); + + MZ_GC_UNREG(); + } else { result = scheme_void; *************** *** 2747,2757 **** } static int ! mzscheme_to_vim(Scheme_Object *obj, typval_T *tv, int depth, Scheme_Hash_Table *visited) { int status = OK; typval_T *found; MZ_GC_CHECK(); if (depth > 100) /* limit the deepest recursion level */ { --- 2898,2939 ---- } static int ! mzscheme_to_vim(Scheme_Object *obj, typval_T *tv) ! { ! int i, status; ! Scheme_Hash_Table *visited = NULL; ! ! MZ_GC_DECL_REG(2); ! MZ_GC_VAR_IN_REG(0, obj); ! MZ_GC_VAR_IN_REG(1, visited); ! MZ_GC_REG(); ! ! visited = scheme_make_hash_table(SCHEME_hash_ptr); ! MZ_GC_CHECK(); ! ! status = mzscheme_to_vim_impl(obj, tv, 1, visited); ! for (i = 0; i < visited->size; ++i) ! { ! /* free up remembered objects */ ! if (visited->vals[i] != NULL) ! free_tv((typval_T *)visited->vals[i]); ! } ! ! MZ_GC_UNREG(); ! return status; ! } ! static int ! mzscheme_to_vim_impl(Scheme_Object *obj, typval_T *tv, int depth, Scheme_Hash_Table *visited) { int status = OK; typval_T *found; + + MZ_GC_DECL_REG(2); + MZ_GC_VAR_IN_REG(0, obj); + MZ_GC_VAR_IN_REG(1, visited); + MZ_GC_REG(); + MZ_GC_CHECK(); if (depth > 100) /* limit the deepest recursion level */ { *************** *** 2785,2795 **** tv->vval.v_float = SCHEME_DBL_VAL(obj); } # endif ! else if (SCHEME_STRINGP(obj)) { tv->v_type = VAR_STRING; ! tv->vval.v_string = vim_strsave((char_u *)SCHEME_STR_VAL(obj)); } else if (SCHEME_VECTORP(obj) || SCHEME_NULLP(obj) || SCHEME_PAIRP(obj) || SCHEME_MUTABLE_PAIRP(obj)) { --- 2967,2991 ---- tv->vval.v_float = SCHEME_DBL_VAL(obj); } # endif ! else if (SCHEME_BYTE_STRINGP(obj)) { tv->v_type = VAR_STRING; ! tv->vval.v_string = vim_strsave(BYTE_STRING_VALUE(obj)); } + # if MZSCHEME_VERSION_MAJOR >= 299 + else if (SCHEME_CHAR_STRINGP(obj)) + { + Scheme_Object *tmp = NULL; + MZ_GC_DECL_REG(1); + MZ_GC_VAR_IN_REG(0, tmp); + MZ_GC_REG(); + + tmp = scheme_char_string_to_byte_string(obj); + tv->v_type = VAR_STRING; + tv->vval.v_string = vim_strsave(BYTE_STRING_VALUE(tmp)); + MZ_GC_UNREG(); + } + #endif else if (SCHEME_VECTORP(obj) || SCHEME_NULLP(obj) || SCHEME_PAIRP(obj) || SCHEME_MUTABLE_PAIRP(obj)) { *************** *** 2829,2835 **** for (i = 0; i < SCHEME_VEC_SIZE(obj); ++i) { cval = SCHEME_VEC_ELS(obj)[i]; ! status = mzscheme_to_vim(cval, v, depth + 1, visited); if (status == FAIL) break; status = list_append_tv(list, v); --- 3025,3031 ---- for (i = 0; i < SCHEME_VEC_SIZE(obj); ++i) { cval = SCHEME_VEC_ELS(obj)[i]; ! status = mzscheme_to_vim_impl(cval, v, depth + 1, visited); if (status == FAIL) break; status = list_append_tv(list, v); *************** *** 2845,2851 **** curr = SCHEME_CDR(curr)) { cval = SCHEME_CAR(curr); ! status = mzscheme_to_vim(cval, v, depth + 1, visited); if (status == FAIL) break; status = list_append_tv(list, v); --- 3041,3047 ---- curr = SCHEME_CDR(curr)) { cval = SCHEME_CAR(curr); ! status = mzscheme_to_vim_impl(cval, v, depth + 1, visited); if (status == FAIL) break; status = list_append_tv(list, v); *************** *** 2857,2863 **** * need to handle the last element */ if (status == OK && !SCHEME_NULLP(curr)) { ! status = mzscheme_to_vim(cval, v, depth + 1, visited); if (status == OK) { status = list_append_tv(list, v); --- 3053,3059 ---- * need to handle the last element */ if (status == OK && !SCHEME_NULLP(curr)) { ! status = mzscheme_to_vim_impl(cval, v, depth + 1, visited); if (status == OK) { status = list_append_tv(list, v); *************** *** 2905,2911 **** dictitem_T *item = dictitem_alloc((char_u *)string_to_line( ((Scheme_Hash_Table *) obj)->keys[i])); /* convert Scheme val to Vim and add it to the dict */ ! if (mzscheme_to_vim(((Scheme_Hash_Table *) obj)->vals[i], &item->di_tv, depth + 1, visited) == FAIL || dict_add(dict, item) == FAIL) { --- 3101,3107 ---- dictitem_T *item = dictitem_alloc((char_u *)string_to_line( ((Scheme_Hash_Table *) obj)->keys[i])); /* convert Scheme val to Vim and add it to the dict */ ! if (mzscheme_to_vim_impl(((Scheme_Hash_Table *) obj)->vals[i], &item->di_tv, depth + 1, visited) == FAIL || dict_add(dict, item) == FAIL) { *************** *** 2925,2943 **** tv->v_type = VAR_STRING; tv->vval.v_string = (char_u *)string_to_line(obj); } return status; } void do_mzeval(char_u *str, typval_T *rettv) { - int i; Scheme_Object *ret = NULL; - Scheme_Hash_Table *visited = NULL; ! MZ_GC_DECL_REG(2); MZ_GC_VAR_IN_REG(0, ret); - MZ_GC_VAR_IN_REG(0, visited); MZ_GC_REG(); if (mzscheme_init()) --- 3121,3196 ---- tv->v_type = VAR_STRING; tv->vval.v_string = (char_u *)string_to_line(obj); } + MZ_GC_UNREG(); return status; } + /* Scheme prim procedure wrapping Vim funcref */ + static Scheme_Object * + vim_funcref(void *name, int argc, Scheme_Object **argv) + { + int i; + typval_T args; + int status = OK; + Scheme_Object *result = NULL; + list_T *list = list_alloc(); + + MZ_GC_DECL_REG(1); + MZ_GC_VAR_IN_REG(0, result); + MZ_GC_REG(); + + result = scheme_void; + if (list == NULL) + status = FAIL; + else + { + args.v_type = VAR_LIST; + args.vval.v_list = list; + ++list->lv_refcount; + for (i = 0; status == OK && i < argc; ++i) + { + typval_T *v = (typval_T *)alloc(sizeof(typval_T)); + if (v == NULL) + status = FAIL; + else + { + status = mzscheme_to_vim(argv[i], v); + if (status == OK) + { + status = list_append_tv(list, v); + clear_tv(v); + } + vim_free(v); + } + } + if (status == OK) + { + typval_T ret; + ret.v_type = VAR_UNKNOWN; + + mzscheme_call_vim(BYTE_STRING_VALUE((Scheme_Object *)name), &args, &ret); + MZ_GC_CHECK(); + result = vim_to_mzscheme(&ret); + clear_tv(&ret); + MZ_GC_CHECK(); + } + } + clear_tv(&args); + MZ_GC_UNREG(); + if (status != OK) + raise_vim_exn(_("error converting Scheme values to Vim")); + else + raise_if_error(); + return result; + } + void do_mzeval(char_u *str, typval_T *rettv) { Scheme_Object *ret = NULL; ! MZ_GC_DECL_REG(1); MZ_GC_VAR_IN_REG(0, ret); MZ_GC_REG(); if (mzscheme_init()) *************** *** 2947,2966 **** } MZ_GC_CHECK(); - visited = scheme_make_hash_table(SCHEME_hash_ptr); - MZ_GC_CHECK(); - if (eval_with_exn_handling(str, do_eval, &ret) == OK) ! mzscheme_to_vim(ret, rettv, 1, visited); ! ! for (i = 0; i < visited->size; ++i) ! { ! /* free up remembered objects */ ! if (visited->vals[i] != NULL) ! { ! free_tv((typval_T *)visited->vals[i]); ! } ! } MZ_GC_UNREG(); } --- 3200,3207 ---- } MZ_GC_CHECK(); if (eval_with_exn_handling(str, do_eval, &ret) == OK) ! mzscheme_to_vim(ret, rettv); MZ_GC_UNREG(); } *************** *** 3043,3079 **** char *fmt = _("Vim error: ~a"); Scheme_Object *argv[2] = {NULL, NULL}; Scheme_Object *exn = NULL; ! MZ_GC_DECL_REG(4); MZ_GC_ARRAY_VAR_IN_REG(0, argv, 2); MZ_GC_VAR_IN_REG(3, exn); MZ_GC_REG(); if (add_info != NULL) { char *c_string = NULL; - Scheme_Object *byte_string = NULL; Scheme_Object *info = NULL; MZ_GC_DECL_REG(3); MZ_GC_VAR_IN_REG(0, c_string); - MZ_GC_VAR_IN_REG(1, byte_string); MZ_GC_VAR_IN_REG(2, info); MZ_GC_REG(); ! info = scheme_make_string(add_info); MZ_GC_CHECK(); ! c_string = scheme_format(fmt, STRLEN(fmt), 1, &info, NULL); MZ_GC_CHECK(); ! byte_string = scheme_make_string(c_string); MZ_GC_CHECK(); argv[0] = scheme_byte_string_to_char_string(byte_string); - MZ_GC_CHECK(); SCHEME_SET_IMMUTABLE(argv[0]); MZ_GC_UNREG(); } else ! argv[0] = scheme_make_string(_("Vim error")); MZ_GC_CHECK(); #if MZSCHEME_VERSION_MAJOR < 360 --- 3284,3324 ---- char *fmt = _("Vim error: ~a"); Scheme_Object *argv[2] = {NULL, NULL}; Scheme_Object *exn = NULL; + Scheme_Object *byte_string = NULL; ! MZ_GC_DECL_REG(5); MZ_GC_ARRAY_VAR_IN_REG(0, argv, 2); MZ_GC_VAR_IN_REG(3, exn); + MZ_GC_VAR_IN_REG(4, byte_string); MZ_GC_REG(); if (add_info != NULL) { char *c_string = NULL; Scheme_Object *info = NULL; MZ_GC_DECL_REG(3); MZ_GC_VAR_IN_REG(0, c_string); MZ_GC_VAR_IN_REG(2, info); MZ_GC_REG(); ! info = scheme_make_byte_string(add_info); MZ_GC_CHECK(); ! c_string = scheme_format_utf8(fmt, STRLEN(fmt), 1, &info, NULL); MZ_GC_CHECK(); ! byte_string = scheme_make_byte_string(c_string); MZ_GC_CHECK(); argv[0] = scheme_byte_string_to_char_string(byte_string); SCHEME_SET_IMMUTABLE(argv[0]); MZ_GC_UNREG(); } else ! { ! byte_string = scheme_make_byte_string(_("Vim error")); ! MZ_GC_CHECK(); ! argv[0] = scheme_byte_string_to_char_string(byte_string); ! MZ_GC_CHECK(); ! } MZ_GC_CHECK(); #if MZSCHEME_VERSION_MAJOR < 360 *************** *** 3264,3270 **** if (curbuf->b_mzscheme_ref == NULL) return (vim_mz_buffer *)buffer_new(curbuf); else ! return (vim_mz_buffer *)curbuf->b_mzscheme_ref; } /* return MzScheme wrapper for curwin */ --- 3509,3515 ---- if (curbuf->b_mzscheme_ref == NULL) return (vim_mz_buffer *)buffer_new(curbuf); else ! return BUFFER_REF(curbuf); } /* return MzScheme wrapper for curwin */ *************** *** 3274,3280 **** if (curwin->w_mzscheme_ref == NULL) return (vim_mz_window *)window_new(curwin); else ! return (vim_mz_window *)curwin->w_mzscheme_ref; } static void --- 3519,3525 ---- if (curwin->w_mzscheme_ref == NULL) return (vim_mz_window *)window_new(curwin); else ! return WINDOW_REF(curwin); } static void *** ../vim-7.3.790/src/if_mzsch.h 2010-08-15 21:57:29.000000000 +0200 --- src/if_mzsch.h 2013-01-30 14:26:44.000000000 +0100 *************** *** 7,12 **** --- 7,13 ---- #ifdef __MINGW32__ /* Hack to engage Cygwin-specific settings */ # define __CYGWIN32__ + # include #endif /* #ifdef needed for "make depend" */ *************** *** 20,50 **** #endif #if MZSCHEME_VERSION_MAJOR >= 299 - /* macros to be compatible with 20x versions */ - # define scheme_config scheme_current_config() - # define scheme_make_string scheme_make_byte_string - # define scheme_make_string_output_port scheme_make_byte_string_output_port - # define scheme_get_sized_string_output scheme_get_sized_byte_string_output - # define scheme_write_string scheme_write_byte_string - # define scheme_make_sized_string scheme_make_sized_byte_string - # define SCHEME_STRINGP(obj) (SCHEME_BYTE_STRINGP(obj) || SCHEME_CHAR_STRINGP(obj)) ! # define SCHEME_STR_VAL(obj) SCHEME_BYTE_STR_VAL( \ ! (SCHEME_BYTE_STRINGP(obj) ? obj : scheme_char_string_to_byte_string(obj))) ! # define GUARANTEE_STRING(fname, argnum) GUARANTEE_TYPE(fname, argnum, SCHEME_STRINGP, "string") ! ! # ifdef scheme_format ! # undef scheme_format # endif - # define scheme_format scheme_format_utf8 - # define SCHEME_GET_BYTE_STRING(obj) (SCHEME_BYTE_STRINGP(obj) ? obj : \ - scheme_char_string_to_byte_string(obj)) - #else - # define SCHEME_GET_BYTE_STRING(obj) (obj) # define SCHEME_BYTE_STRLEN_VAL SCHEME_STRLEN_VAL ! # define SCHEME_BYTE_STR_VAL SCHEME_STR_VAL # define scheme_byte_string_to_char_string(obj) (obj) #endif /* Precise GC macros */ --- 21,44 ---- #endif #if MZSCHEME_VERSION_MAJOR >= 299 # define SCHEME_STRINGP(obj) (SCHEME_BYTE_STRINGP(obj) || SCHEME_CHAR_STRINGP(obj)) ! # define BYTE_STRING_VALUE(obj) ((char_u *)SCHEME_BYTE_STR_VAL(obj)) ! #else ! /* macros for compatibility with older versions */ ! # define scheme_current_config() scheme_config ! # define scheme_make_sized_byte_string scheme_make_sized_string ! # define scheme_format_utf8 scheme_format ! # ifndef DYNAMIC_MZSCHEME ! /* for dynamic MzScheme there will be separate definitions in if_mzsch.c */ ! # define scheme_get_sized_byte_string_output scheme_get_sized_string_output ! # define scheme_make_byte_string scheme_make_string ! # define scheme_make_byte_string_output_port scheme_make_string_output_port # endif # define SCHEME_BYTE_STRLEN_VAL SCHEME_STRLEN_VAL ! # define BYTE_STRING_VALUE(obj) ((char_u *)SCHEME_STR_VAL(obj)) # define scheme_byte_string_to_char_string(obj) (obj) + # define SCHEME_BYTE_STRINGP SCHEME_STRINGP #endif /* Precise GC macros */ *** ../vim-7.3.790/src/Make_ming.mak 2013-01-23 13:55:16.000000000 +0100 --- src/Make_ming.mak 2013-01-30 14:26:44.000000000 +0100 *************** *** 384,389 **** --- 384,392 ---- ifeq (yes, $(DYNAMIC_MZSCHEME)) CFLAGS += -DDYNAMIC_MZSCHEME -DDYNAMIC_MZSCH_DLL=\"lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).dll\" -DDYNAMIC_MZGC_DLL=\"libmzgc$(MZSCHEME_VER).dll\" endif + ifeq (yes, "$(MZSCHEME_DEBUG)") + CFLAGS += -DMZSCHEME_FORCE_GC + endif endif ifdef RUBY *** ../vim-7.3.790/src/Make_mvc.mak 2012-12-06 21:30:24.000000000 +0100 --- src/Make_mvc.mak 2013-01-30 14:26:44.000000000 +0100 *************** *** 1096,1102 **** $(OUTDIR)/if_perlsfio.obj: $(OUTDIR) if_perlsfio.c $(INCL) $(CC) $(CFLAGS) $(PERL_INC) if_perlsfio.c ! $(OUTDIR)/if_mzsch.obj: $(OUTDIR) if_mzsch.c $(INCL) $(MZSCHEME_EXTRA_DEP) $(CC) $(CFLAGS) if_mzsch.c \ -DMZSCHEME_COLLECTS=\"$(MZSCHEME:\=\\)\\collects\" mzscheme_base.c: --- 1096,1102 ---- $(OUTDIR)/if_perlsfio.obj: $(OUTDIR) if_perlsfio.c $(INCL) $(CC) $(CFLAGS) $(PERL_INC) if_perlsfio.c ! $(OUTDIR)/if_mzsch.obj: $(OUTDIR) if_mzsch.c if_mzsch.h $(INCL) $(MZSCHEME_EXTRA_DEP) $(CC) $(CFLAGS) if_mzsch.c \ -DMZSCHEME_COLLECTS=\"$(MZSCHEME:\=\\)\\collects\" mzscheme_base.c: *** ../vim-7.3.790/src/os_unix.c 2012-10-14 04:35:16.000000000 +0200 --- src/os_unix.c 2013-01-30 14:26:44.000000000 +0100 *************** *** 278,284 **** #ifdef SIGBUS {SIGBUS, "BUS", TRUE}, #endif ! #ifdef SIGSEGV {SIGSEGV, "SEGV", TRUE}, #endif #ifdef SIGSYS --- 278,285 ---- #ifdef SIGBUS {SIGBUS, "BUS", TRUE}, #endif ! #if defined(SIGSEGV) && !defined(FEAT_MZSCHEME) ! /* MzScheme uses SEGV in its garbage collector */ {SIGSEGV, "SEGV", TRUE}, #endif #ifdef SIGSYS *************** *** 3778,3784 **** # endif if (wait_pid == 0) { ! /* Wait for 1/100 sec before trying again. */ mch_delay(10L, TRUE); continue; } --- 3779,3785 ---- # endif if (wait_pid == 0) { ! /* Wait for 10 msec before trying again. */ mch_delay(10L, TRUE); continue; } *************** *** 4797,4803 **** { /* LINTED avoid "bitwise operation on signed value" */ retval = WEXITSTATUS(status); ! if (retval && !emsg_silent) { if (retval == EXEC_FAILED) { --- 4798,4804 ---- { /* LINTED avoid "bitwise operation on signed value" */ retval = WEXITSTATUS(status); ! if (retval != 0 && !emsg_silent) { if (retval == EXEC_FAILED) { *** ../vim-7.3.790/src/proto/eval.pro 2012-07-25 16:46:59.000000000 +0200 --- src/proto/eval.pro 2013-01-30 14:32:04.000000000 +0100 *************** *** 74,79 **** --- 74,80 ---- char_u *get_function_name __ARGS((expand_T *xp, int idx)); char_u *get_expr_name __ARGS((expand_T *xp, int idx)); int func_call __ARGS((char_u *name, typval_T *args, dict_T *selfdict, typval_T *rettv)); + void mzscheme_call_vim __ARGS((char_u *name, typval_T *args, typval_T *rettv)); long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit)); void set_vim_var_nr __ARGS((int idx, long val)); long get_vim_var_nr __ARGS((int idx)); *** ../vim-7.3.790/src/testdir/test70.in 2010-08-15 21:57:29.000000000 +0200 --- src/testdir/test70.in 2013-01-30 14:50:02.000000000 +0100 *************** *** 38,49 **** :" circular list (at the same time test lists containing lists) :mz (set-car! (cddr l) l) :let l2 = mzeval("h")["list"] ! :if l2[2] == l2 :let res = "OK" :else ! :let res = "FAILED" :endif :call setline(search("^3"), "circular test " . res) :?^1?,$w! test.out :qa! ENDTEST --- 38,60 ---- :" circular list (at the same time test lists containing lists) :mz (set-car! (cddr l) l) :let l2 = mzeval("h")["list"] ! :" bug: this returns item2, but it should be l2 ! :if l2[2] == "item2" :let res = "OK" :else ! :let res = "FAILED: " . l2[2] :endif :call setline(search("^3"), "circular test " . res) + :" funcrefs + :mz (define vim:max (vim-eval "function('max')")) + :mz (define m (vim:max '(1 100 8))) + :let m = mzeval('m') + :if m == 100 + :let fref_res = "OK" + :else + :let fref_res = "FAILED: " . m + :end + :call append(line('$'), 'funcrefs '. fref_res) :?^1?,$w! test.out :qa! ENDTEST *** ../vim-7.3.790/src/testdir/test70.ok 2010-08-15 21:57:29.000000000 +0200 --- src/testdir/test70.ok 2013-01-30 14:26:44.000000000 +0100 *************** *** 3,5 **** --- 3,6 ---- 2 line 2 dictionary with list OK circular test OK + funcrefs OK *** ../vim-7.3.790/src/version.c 2013-01-30 14:13:52.000000000 +0100 --- src/version.c 2013-01-30 14:52:31.000000000 +0100 *************** *** 727,728 **** --- 727,730 ---- { /* Add new patch number below this line */ + /**/ + 791, /**/ -- 5 out of 4 people have trouble with fractions. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///