Hello everybody,

trying to build a better Swank interface for VIM I found that it's relatively
hard to return values from a perl function.

To solve that problem I'm providing two patches:
 * The first allows setting and getting variables from embedded perl scripts.
   This one is simple; I think it's safe to use it.
 * The second is the bigger one; it defines a new perleval() function that
   calls an arbitrary perl function in array context with up to 18 parameters,
   and returns the results.
   Here I would like to get feedback, and/or fixes for the perl interface.


Regards,

Phil

-- 
Versioning your /etc, /home or even your whole installation?
             Try fsvs (fsvs.tigris.org)!

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff -r bfade53bcafb src/auto/config.mk
--- a/src/auto/config.mk	Fri Dec 17 20:24:01 2010 +0100
+++ b/src/auto/config.mk	Fri Dec 17 21:34:26 2010 +0100
@@ -1,5 +1,169 @@
-the first targets to make vim are: scratch config myself
-srcdir = .
-VIMNAME = vim
-EXNAME = ex
-VIEWNAME = view
+#
+# config.mk.in -- autoconf template for Vim on Unix		vim:ts=8:sw=8:
+#
+# DO NOT EDIT config.mk!!  It will be overwritten by configure.
+# Edit Makefile and run "make" or run ./configure with other arguments.
+#
+# Configure does not edit the makefile directly. This method is not the
+# standard use of GNU autoconf, but it has two advantages:
+#   a) The user can override every choice made by configure.
+#   b) Modifications to the makefile are not lost when configure is run.
+#
+# I hope this is worth being nonstandard. jw.
+
+
+
+VIMNAME		= vim
+EXNAME		= ex
+VIEWNAME	= view
+
+CC		= gcc
+DEFS		= -DHAVE_CONFIG_H
+CFLAGS		= -g -O2 -D_FORTIFY_SOURCE=1
+CPPFLAGS	= 
+srcdir		= .
+
+LDFLAGS		=  -Wl,-E   -Wl,--as-needed
+LIBS		= -lm -lncurses -lnsl 
+TAGPRG		= ctags -I INIT+ --fields=+S
+
+CPP		= gcc -E
+CPP_MM		= M
+DEPEND_CFLAGS_FILTER = | sed 's+-I */+-isystem /+g'
+LINK_AS_NEEDED	= yes
+X_CFLAGS	=  
+X_LIBS_DIR	=  
+X_PRE_LIBS	=  -lSM -lICE
+X_EXTRA_LIBS	=  -lXdmcp -lSM -lICE
+X_LIBS		= -lXt -lX11
+
+LUA_LIBS	= 
+LUA_SRC		= 
+LUA_OBJ		= 
+LUA_CFLAGS	= 
+LUA_PRO		= 
+
+MZSCHEME_LIBS	= 
+MZSCHEME_SRC	= 
+MZSCHEME_OBJ	= 
+MZSCHEME_CFLAGS	= 
+MZSCHEME_PRO	= 
+MZSCHEME_EXTRA  = 
+MZSCHEME_MZC	= 
+
+PERL		= /usr/bin/perl
+PERLLIB		= /usr/share/perl/5.10
+PERL_LIBS	= -Wl,-E  -fstack-protector -L/usr/local/lib  -L/usr/lib/perl/5.10/CORE -lperl -ldl -lm -lpthread -lcrypt
+SHRPENV		= 
+PERL_SRC	= auto/if_perl.c if_perlsfio.c
+PERL_OBJ	= objects/if_perl.o objects/if_perlsfio.o
+PERL_PRO	= if_perl.pro if_perlsfio.pro
+PERL_CFLAGS	=  -D_REENTRANT -D_GNU_SOURCE -DDEBIAN  -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -I/usr/lib/perl/5.10/CORE 
+
+PYTHON_SRC	= 
+PYTHON_OBJ	= 
+PYTHON_CFLAGS	= 
+PYTHON_LIBS	= 
+PYTHON_CONFDIR	= 
+PYTHON_GETPATH_CFLAGS = 
+
+PYTHON3_SRC	= 
+PYTHON3_OBJ	= 
+PYTHON3_CFLAGS	= 
+PYTHON3_LIBS	= 
+PYTHON3_CONFDIR	= 
+
+TCL		= 
+TCL_SRC		= 
+TCL_OBJ		= 
+TCL_PRO		= 
+TCL_CFLAGS	= 
+TCL_LIBS	= 
+
+HANGULIN_SRC	= 
+HANGULIN_OBJ	= 
+
+WORKSHOP_SRC	= 
+WORKSHOP_OBJ	= 
+
+NETBEANS_SRC	= netbeans.c
+NETBEANS_OBJ	= objects/netbeans.o
+
+RUBY		= 
+RUBY_SRC	= 
+RUBY_OBJ	= 
+RUBY_PRO	= 
+RUBY_CFLAGS	= 
+RUBY_LIBS	= 
+
+SNIFF_SRC	= 
+SNIFF_OBJ	= 
+
+AWK		= gawk
+
+STRIP		= strip
+
+EXEEXT		= 
+
+COMPILEDBY	= 
+
+INSTALLVIMDIFF	= installvimdiff
+INSTALLGVIMDIFF	= installgvimdiff
+INSTALL_LANGS	= install-languages
+INSTALL_TOOL_LANGS	= install-tool-languages
+
+### sed command to fix quotes while creating pathdef.c
+QUOTESED        = sed -e 's/[\\"]/\\&/g' -e 's/\\"/"/' -e 's/\\";$$/";/'
+
+### Line break character as octal number for "tr"
+NL		= "\\012"
+
+### Top directory for everything
+prefix		= /usr/local
+
+### Top directory for the binary
+exec_prefix	= ${prefix}
+
+### Prefix for location of data files
+BINDIR		= ${exec_prefix}/bin
+
+### For autoconf 2.60 and later (avoid a warning)
+datarootdir	= ${prefix}/share
+
+### Prefix for location of data files
+DATADIR		= ${datarootdir}
+
+### Prefix for location of man pages
+MANDIR		= ${datarootdir}/man
+
+### Do we have a GUI
+GUI_INC_LOC	= -pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  
+GUI_LIB_LOC	=  
+GUI_SRC		= $(GTK_SRC)
+GUI_OBJ		= $(GTK_OBJ)
+GUI_DEFS	= $(GTK_DEFS)
+GUI_IPATH	= $(GTK_IPATH)
+GUI_LIBS_DIR	= $(GTK_LIBS_DIR)
+GUI_LIBS1	= $(GTK_LIBS1)
+GUI_LIBS2	= $(GTK_LIBS2)
+GUI_INSTALL	= $(GTK_INSTALL)
+GUI_TARGETS	= $(GTK_TARGETS)
+GUI_MAN_TARGETS	= $(GTK_MAN_TARGETS)
+GUI_TESTTARGET	= $(GTK_TESTTARGET)
+GUI_TESTARG	= $(GTK_TESTARG)
+GUI_BUNDLE	= $(GTK_BUNDLE)
+NARROW_PROTO	= 
+GUI_X_LIBS	= 
+MOTIF_LIBNAME	= 
+GTK_LIBNAME	= -pthread -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lpangoft2-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lcairo -lgio-2.0 -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0  
+
+### Any OS dependent extra source and object file
+OS_EXTRA_SRC	= 
+OS_EXTRA_OBJ	= 
+
+### If the *.po files are to be translated to *.mo files.
+MAKEMO		= yes
+
+# Make sure that "make first" will run "make all" once configure has done its
+# work.  This is needed when using the Makefile in the top directory.
+first: all
diff -r bfade53bcafb src/if_perl.xs
--- a/src/if_perl.xs	Fri Dec 17 20:24:01 2010 +0100
+++ b/src/if_perl.xs	Fri Dec 17 21:34:26 2010 +0100
@@ -959,6 +959,27 @@
     update_screen(NOT_VALID);
 
 void
+SetVar(name, val)
+    char *name;
+    char *val;
+
+    PPCODE:
+    if (name != NULL)
+	set_internal_string_var(name, val);
+    update_screen(NOT_VALID);
+
+
+void
+GetVar(name)
+    char *name;
+
+    PPCODE:
+    if (name != NULL)
+	XPUSHs(sv_2mortal(newSVpv((char *)get_var_value(name), 0)));
+    update_screen(NOT_VALID);
+
+
+void
 DoCommand(line)
     char *line;
 
diff -r bfade53bcafb src/Makefile
--- a/src/Makefile	Fri Dec 17 20:24:01 2010 +0100
+++ b/src/Makefile	Fri Dec 17 23:04:19 2010 +0100
@@ -2367,8 +2367,9 @@
 
 auto/if_perl.c: if_perl.xs
 	$(PERL) -e 'unless ( $$] >= 5.005 ) { for (qw(na defgv errgv)) { print "#define PL_$$_ $$_\n" }}' > $@
-	$(PERL) $(PERLLIB)/ExtUtils/xsubpp -prototypes -typemap \
-	    $(PERLLIB)/ExtUtils/typemap if_perl.xs >> $@
+	$(PERL) $(PERLLIB)/ExtUtils/xsubpp -prototypes \
+		-typemap $(PERLLIB)/ExtUtils/typemap  \
+		-typemap if_perl_typemap if_perl.xs >> $@
 
 auto/osdef.h: auto/config.h osdef.sh osdef1.h.in osdef2.h.in
 	CC="$(CC) $(OSDEF_CFLAGS)" srcdir=$(srcdir) sh $(srcdir)/osdef.sh
diff -r bfade53bcafb src/eval.c
--- a/src/eval.c	Fri Dec 17 20:24:01 2010 +0100
+++ b/src/eval.c	Fri Dec 17 23:04:19 2010 +0100
@@ -645,6 +645,9 @@
 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv));
+#ifdef FEAT_PERL
+void f_perleval __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
 #ifdef FEAT_FLOAT
 static void f_pow __ARGS((typval_T *argvars, typval_T *rettv));
 #endif
@@ -7839,6 +7843,9 @@
     {"nextnonblank",	1, 1, f_nextnonblank},
     {"nr2char",		1, 1, f_nr2char},
     {"pathshorten",	1, 1, f_pathshorten},
+#ifdef FEAT_PERL
+    {"perleval",	1, 19, f_perleval},
+#endif
 #ifdef FEAT_FLOAT
     {"pow",		2, 2, f_pow},
 #endif
diff -r bfade53bcafb src/if_perl.xs
--- a/src/if_perl.xs	Fri Dec 17 20:24:01 2010 +0100
+++ b/src/if_perl.xs	Fri Dec 17 23:04:19 2010 +0100
@@ -886,6 +887,135 @@
     }
 }
 
+
+void
+f_perleval(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*cmd;
+    char_u	buf[NUMBUFLEN];
+    int         count, i;
+    STRLEN	len;
+    SV		*sv;
+    list_T	*retlist;
+    I32		ax;
+    typval_T	*v;
+    char	*cp;
+
+    if (perl_interp == NULL)
+    {
+#ifdef DYNAMIC_PERL
+	if (!perl_enabled(TRUE))
+	{
+	    EMSG(_(e_noperl));
+	    return;
+	}
+#endif
+	perl_init();
+    }
+
+    dSP;
+
+    ENTER;
+    SAVETMPS;
+
+    PUSHMARK(SP);
+    EXTEND(SP, 20);
+    if (argvars[0].v_type != VAR_STRING) {
+	return;
+    }
+
+    cmd = argvars[0].vval.v_string;
+
+    for(i=1; i<20; i++)
+    {
+	sv = NULL;
+	// see perlcall
+	switch(argvars[i].v_type)
+	{
+	    case VAR_NUMBER:
+		sv = newSViv(argvars[i].vval.v_number);
+		break;
+	    case VAR_STRING:
+		sv = newSVpv(argvars[i].vval.v_string,
+			argvars[i].vval.v_string ?
+			strlen(argvars[i].vval.v_string) : 0);
+		break;
+	    case VAR_FLOAT:
+		sv = newSVnv(argvars[i].vval.v_float);
+		break;
+
+	    case VAR_LIST:
+	    case VAR_DICT:
+		/* These two could be supported, I think. */
+		break;
+
+	    case VAR_FUNC:
+		break;
+	    default:
+	    case VAR_UNKNOWN:
+		break;
+	}
+
+	if (!sv)
+	    break;
+
+	XPUSHs(sv_2mortal(sv));
+    }
+
+    PUTBACK;
+
+    count = call_pv(cmd, G_ARRAY | G_EVAL);
+
+    SPAGAIN;
+
+    SP -= count;
+    ax = (SP - PL_stack_base) + 1;
+
+
+    retlist = list_alloc();
+    if (retlist == NULL)
+	return;
+    retlist->lv_refcount = 1;
+
+
+    v = (typval_T *)alloc(sizeof(typval_T));
+    if (v == NULL)
+	return;
+    v->v_lock = VAR_LOCKED; // Is this correct ???
+
+    for(i=0; i<count; i++) {
+	// See perlguts
+	if (SvIOK(ST(i))) {
+	    v->v_type = VAR_NUMBER;
+	    v->vval.v_number = SvIV(ST(i));
+	} else if (SvNOK(ST(i))) {
+	    v->v_type = VAR_FLOAT;
+	    v->vval.v_float = SvNV(ST(i));
+	} else if (SvPOK(ST(i))) {
+	    v->v_type = VAR_STRING;
+	    cp = SvPV(ST(i), len);
+	    v->vval.v_string = vim_strnsave(cp, len);
+	} else
+	    continue;
+
+	list_append_tv(retlist, v);
+	clear_tv(v);
+    }
+
+    rettv->v_type = VAR_LIST;
+    rettv->v_lock = 0;
+    rettv->vval.v_list = retlist;
+
+
+    PUTBACK;
+
+    FREETMPS;
+    LEAVE;
+}
+
+
 #ifndef FEAT_WINDOWS
 int win_valid(win_T *w) { return TRUE; }
 int win_count() { return 1; }

Raspunde prin e-mail lui