Hi list,
Actually, Perl users cannot use 'print' operator for wrinting
directly in standard IO witch embed perl interpreter.
The attached patch add a minimal implementation of PerlIO Layer
feature and try to use it for STDOUT/STDERR.
Please check it.
Regards,
Damien
--
--
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
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/if_perl.xs b/src/if_perl.xs
--- a/src/if_perl.xs
+++ b/src/if_perl.xs
@@ -52,7 +52,9 @@
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
-
+#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
+# include <perliol.h>
+#endif
/*
* Work around clashes between Perl and Vim namespace. proto.h doesn't
@@ -279,6 +281,10 @@
# define PL_thr_key *dll_PL_thr_key
# endif
# endif
+# if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
+# define PerlIOBase_pushed dll_PerlIOBase_pushed
+# define PerlIO_define_layer dll_PerlIO_define_layer
+# endif
/*
* Declare HANDLE for perl.dll and function pointers.
@@ -422,6 +428,10 @@
static perl_key* (*Perl_Gthr_key_ptr)_((pTHX));
#endif
static void (*boot_DynaLoader)_((pTHX_ CV*));
+#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
+static IV (*PerlIOBase_pushed)(pTHX_ PerlIO *, const char *, SV *, PerlIO_funcs *);
+static void (*PerlIO_define_layer)(pTHX_ PerlIO_funcs *);
+#endif
/*
* Table of name to function pointer of perl.
@@ -554,6 +564,10 @@
{"Perl_Gthr_key_ptr", (PERL_PROC*)&Perl_Gthr_key_ptr},
#endif
{"boot_DynaLoader", (PERL_PROC*)&boot_DynaLoader},
+#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
+ {"PerlIOBase_pushed", (PERL_PROC*)&PerlIOBase_pushed},
+ {"PerlIO_define_layer", (PERL_PROC*)&PerlIO_define_layer},
+#endif
{"", NULL},
};
@@ -620,6 +634,10 @@
}
#endif /* DYNAMIC_PERL */
+#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
+static void vim_IOLayer_init(void);
+#endif
+
/*
* perl_init(): initialize perl interpreter
* We have to call perl_parse to initialize some structures,
@@ -645,6 +663,8 @@
sfdisc(PerlIO_stderr(), sfdcnewvim());
sfsetbuf(PerlIO_stdout(), NULL, 0);
sfsetbuf(PerlIO_stderr(), NULL, 0);
+#elif defined(PERLIO_LAYERS)
+ vim_IOLayer_init();
#endif
}
@@ -1038,6 +1058,70 @@
}
}
+#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
+typedef struct {
+ struct _PerlIO base;
+ int attr;
+} PerlIOVim;
+
+ static IV
+PerlIOVim_pushed(pTHX_ PerlIO *f, const char *mode,
+ SV *arg, PerlIO_funcs *tab
+ )
+{
+ PerlIOVim *s = PerlIOSelf(f, PerlIOVim);
+ s->attr = 0;
+ if (arg && SvPOK(arg)) {
+ int id = syn_name2id(SvPV_nolen(arg));
+ if (id != 0)
+ s->attr = syn_id2attr(id);
+ }
+ return PerlIOBase_pushed(aTHX_ f, mode, (SV *)NULL, tab);
+}
+
+ static SSize_t
+PerlIOVim_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
+{
+ char_u *str;
+ PerlIOVim * s = PerlIOSelf(f, PerlIOVim);
+
+ str = vim_strnsave((char_u *)vbuf, count);
+ if (str == NULL)
+ return 0;
+ msg_split((char *)str, s->attr);
+ vim_free(str);
+
+ return count;
+}
+
+static PERLIO_FUNCS_DECL(PerlIO_Vim) = {
+ sizeof(PerlIO_funcs),
+ "Vim",
+ sizeof(PerlIOVim),
+ PERLIO_K_DUMMY, /* flags */
+ PerlIOVim_pushed,
+ NULL, /* popped */
+ NULL, /* open */
+ NULL, /* binmode */
+ NULL, /* arg */
+ NULL, /* fileno */
+ NULL, /* dup */
+ NULL, /* read */
+ NULL, /* unread */
+ PerlIOVim_write,
+ /* ... */
+};
+
+/* Use Vim routine for print operator */
+ static void
+vim_IOLayer_init(void)
+{
+ PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_Vim));
+ (void)eval_pv( "binmode(STDOUT, ':Vim')"
+ " && binmode(STDERR, ':Vim(ErrorMsg)');", 0);
+}
+#endif /* PERLIO_LAYERS && !USE_SFIO */
+
#ifndef FEAT_WINDOWS
int win_valid(win_T *w) { return TRUE; }
int win_count() { return 1; }