Patch 7.4.1729
Problem:    The Perl interface cannot use 'print' operator for writing
            directly in standard IO.
Solution:   Add a minimal implementation of PerlIO Layer feature and try to
            use it for STDOUT/STDERR. (Damien)
Files:      src/if_perl.xs, src/testdir/test_perl.vim


*** ../vim-7.4.1728/src/if_perl.xs      2016-04-02 14:17:55.621482124 +0200
--- src/if_perl.xs      2016-04-14 14:08:34.696507168 +0200
***************
*** 57,63 ****
  #include <EXTERN.h>
  #include <perl.h>
  #include <XSUB.h>
! 
  
  /*
   * Work around clashes between Perl and Vim namespace.        proto.h doesn't
--- 57,65 ----
  #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
***************
*** 293,298 ****
--- 295,304 ----
  # define Perl_av_fetch dll_Perl_av_fetch
  # define Perl_av_len dll_Perl_av_len
  # define Perl_sv_2nv_flags dll_Perl_sv_2nv_flags
+ # 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.
***************
*** 445,450 ****
--- 451,460 ----
  static SV** (*Perl_av_fetch)(pTHX_ AV *, SSize_t, I32);
  static SSize_t (*Perl_av_len)(pTHX_ AV *);
  static NV (*Perl_sv_2nv_flags)(pTHX_ SV *const, const I32);
+ #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.
***************
*** 584,589 ****
--- 594,603 ----
      {"Perl_av_fetch", (PERL_PROC*)&Perl_av_fetch},
      {"Perl_av_len", (PERL_PROC*)&Perl_av_len},
      {"Perl_sv_2nv_flags", (PERL_PROC*)&Perl_sv_2nv_flags},
+ #if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
+     {"PerlIOBase_pushed", (PERL_PROC*)&PerlIOBase_pushed},
+     {"PerlIO_define_layer", (PERL_PROC*)&PerlIO_define_layer},
+ #endif
      {"", NULL},
  };
  
***************
*** 646,651 ****
--- 660,669 ----
  }
  #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,
***************
*** 671,676 ****
--- 689,696 ----
      sfdisc(PerlIO_stderr(), sfdcnewvim());
      sfsetbuf(PerlIO_stdout(), NULL, 0);
      sfsetbuf(PerlIO_stderr(), NULL, 0);
+ #elif defined(PERLIO_LAYERS)
+     vim_IOLayer_init();
  #endif
  }
  
***************
*** 1307,1312 ****
--- 1327,1408 ----
      }
  }
  
+ #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((char_u *)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_u *)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,
+     NULL,             /* seek */
+     NULL,             /* tell */
+     NULL,             /* close */
+     NULL,             /* flush */
+     NULL,             /* fill */
+     NULL,             /* eof */
+     NULL,             /* error */
+     NULL,             /* clearerr */
+     NULL,             /* setlinebuf */
+     NULL,             /* get_base */
+     NULL,             /* get_bufsiz */
+     NULL,             /* get_ptr */
+     NULL,             /* get_cnt */
+     NULL              /* set_ptrcnt */
+ };
+ 
+ /* 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)
*** ../vim-7.4.1728/src/testdir/test_perl.vim   2016-01-17 22:05:09.286375447 
+0100
--- src/testdir/test_perl.vim   2016-04-14 14:07:16.657322496 +0200
***************
*** 92,94 ****
--- 92,105 ----
    perl VIM::SetOption('et')
    call assert_true(&et)
  endf
+ 
+ function Test_stdio()
+   redir =>l:out
+   perl <<EOF
+     VIM::Msg("&VIM::Msg");
+     print "STDOUT";
+     print STDERR "STDERR";
+ EOF
+   redir END
+   call assert_equal(['&VIM::Msg', 'STDOUT', 'STDERR'], split(l:out, "\n"))
+ endf
*** ../vim-7.4.1728/src/version.c       2016-04-14 13:51:16.215410861 +0200
--- src/version.c       2016-04-14 14:07:04.181453459 +0200
***************
*** 750,751 ****
--- 750,753 ----
  {   /* Add new patch number below this line */
+ /**/
+     1729,
  /**/

-- 
Ten bugs in the hand is better than one as yet undetected.

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
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.

Raspunde prin e-mail lui