119304Speter/*- 219304Speter * Copyright (c) 1992, 1993, 1994 319304Speter * The Regents of the University of California. All rights reserved. 419304Speter * Copyright (c) 1992, 1993, 1994, 1995, 1996 519304Speter * Keith Bostic. All rights reserved. 619304Speter * Copyright (c) 1995 719304Speter * George V. Neville-Neil. All rights reserved. 819304Speter * Copyright (c) 1996 919304Speter * Sven Verdoolaege. All rights reserved. 1019304Speter * 1119304Speter * See the LICENSE file for redistribution information. 1269474Ssheldonh * 1369474Ssheldonh * $FreeBSD$ 1419304Speter */ 1519304Speter 1619304Speter#include "config.h" 1719304Speter 1819304Speter#ifndef lint 1919304Speterstatic const char sccsid[] = "@(#)perl.xs 8.27 (Berkeley) 10/16/96"; 2019304Speter#endif /* not lint */ 2119304Speter 2219304Speter#include <sys/types.h> 2341839Speter#include <sys/param.h> 2419304Speter#include <sys/queue.h> 2519304Speter#include <sys/time.h> 2619304Speter 2719304Speter#include <bitstring.h> 2819304Speter#include <ctype.h> 2919304Speter#include <limits.h> 3019304Speter#include <signal.h> 3119304Speter#include <stdio.h> 3219304Speter#include <stdlib.h> 3319304Speter#include <string.h> 3419304Speter#include <termios.h> 3519304Speter#include <unistd.h> 3641839Speter#include <errno.h> 3719304Speter 3819304Speter#include "../common/common.h" 3919304Speter 4019304Speter#include <EXTERN.h> 4119304Speter#include <perl.h> 4219304Speter#include <XSUB.h> 4319304Speter 4419304Speter#include "perl_extern.h" 4519304Speter 4619304Speterstatic void msghandler __P((SCR *, mtype_t, char *, size_t)); 4719304Speter 4819304Speterextern GS *__global_list; /* XXX */ 4919304Speter 5019304Speterstatic char *errmsg = 0; 5119304Speter 5219304Speter/* 5319304Speter * INITMESSAGE -- 5419304Speter * Macros to point messages at the Perl message handler. 5519304Speter */ 5619304Speter#define INITMESSAGE \ 5719304Speter scr_msg = __global_list->scr_msg; \ 5819304Speter __global_list->scr_msg = msghandler; 5919304Speter#define ENDMESSAGE \ 6019304Speter __global_list->scr_msg = scr_msg; \ 6119304Speter if (rval) croak(errmsg); 6219304Speter 6319304Speterstatic void xs_init __P((void)); 6419304Speter 6519304Speter/* 6619304Speter * perl_end -- 6719304Speter * Clean up perl interpreter 6819304Speter * 6919304Speter * PUBLIC: int perl_end __P((GS *)); 7019304Speter */ 7119304Speterint 7219304Speterperl_end(gp) 7319304Speter GS *gp; 7419304Speter{ 7519304Speter /* 7619304Speter * Call perl_run and perl_destuct to call END blocks and DESTROY 7719304Speter * methods. 7819304Speter */ 7919304Speter if (gp->perl_interp) { 8019304Speter /*Irestartop = 0; / * XXX */ 8119304Speter perl_run(gp->perl_interp); 8219304Speter perl_destruct(gp->perl_interp); 8319304Speter#if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY) 8419304Speter perl_free(gp->perl_interp); 8519304Speter#endif 8619304Speter } 8719304Speter} 8819304Speter 8919304Speter/* 9019304Speter * perl_eval 9119304Speter * Evaluate a string 9219304Speter * We don't use mortal SVs because no one will clean up after us 9319304Speter */ 9419304Speterstatic void 9519304Speterperl_eval(string) 9619304Speter char *string; 9719304Speter{ 9819304Speter#ifdef HAVE_PERL_5_003_01 9919304Speter SV* sv = newSVpv(string, 0); 10019304Speter 10119304Speter perl_eval_sv(sv, G_DISCARD | G_NOARGS); 10219304Speter SvREFCNT_dec(sv); 10319304Speter#else 10419304Speter char *argv[2]; 10519304Speter 10619304Speter argv[0] = string; 10719304Speter argv[1] = NULL; 10819304Speter perl_call_argv("_eval_", G_EVAL | G_DISCARD | G_KEEPERR, argv); 10919304Speter#endif 11019304Speter} 11119304Speter 11219304Speter/* 11319304Speter * perl_init -- 11419304Speter * Create the perl commands used by nvi. 11519304Speter * 11619304Speter * PUBLIC: int perl_init __P((SCR *)); 11719304Speter */ 11819304Speterint 11919304Speterperl_init(scrp) 12019304Speter SCR *scrp; 12119304Speter{ 12219304Speter AV * av; 12319304Speter GS *gp; 12419304Speter char *bootargs[] = { "VI", NULL }; 12519304Speter#ifndef USE_SFIO 12619304Speter SV *svcurscr; 12719304Speter#endif 12819304Speter 12919304Speter#ifndef HAVE_PERL_5_003_01 13019304Speter static char *args[] = { "", "-e", "sub _eval_ { eval $_[0] }" }; 13119304Speter#else 13219304Speter static char *args[] = { "", "-e", "" }; 13319304Speter#endif 13419304Speter STRLEN length; 13519304Speter char *file = __FILE__; 13619304Speter 13719304Speter gp = scrp->gp; 13819304Speter gp->perl_interp = perl_alloc(); 13919304Speter perl_construct(gp->perl_interp); 14019304Speter if (perl_parse(gp->perl_interp, xs_init, 3, args, 0)) { 14119304Speter perl_destruct(gp->perl_interp); 14219304Speter perl_free(gp->perl_interp); 14319304Speter gp->perl_interp = NULL; 14419304Speter return 1; 14519304Speter } 14619304Speter perl_call_argv("VI::bootstrap", G_DISCARD, bootargs); 14719304Speter perl_eval("$SIG{__WARN__}='VI::Warn'"); 14819304Speter 14941839Speter av_unshift(av = GvAVn(PL_incgv), 1); 15019304Speter av_store(av, 0, newSVpv(_PATH_PERLSCRIPTS, 15119304Speter sizeof(_PATH_PERLSCRIPTS)-1)); 15219304Speter 15319304Speter#ifdef USE_SFIO 15419304Speter sfdisc(PerlIO_stdout(), sfdcnewnvi(scrp)); 15519304Speter sfdisc(PerlIO_stderr(), sfdcnewnvi(scrp)); 15619304Speter#else 15719304Speter svcurscr = perl_get_sv("curscr", TRUE); 15819304Speter sv_magic((SV *)gv_fetchpv("STDOUT",TRUE, SVt_PVIO), svcurscr, 15919304Speter 'q', Nullch, 0); 16019304Speter sv_magic((SV *)gv_fetchpv("STDERR",TRUE, SVt_PVIO), svcurscr, 16119304Speter 'q', Nullch, 0); 16219304Speter#endif /* USE_SFIO */ 16319304Speter return (0); 16419304Speter} 16519304Speter 16619304Speter/* 16719304Speter * perl_screen_end 16819304Speter * Remove all refences to the screen to be destroyed 16919304Speter * 17019304Speter * PUBLIC: int perl_screen_end __P((SCR*)); 17119304Speter */ 17219304Speterint 17319304Speterperl_screen_end(scrp) 17419304Speter SCR *scrp; 17519304Speter{ 17619304Speter if (scrp->perl_private) { 17719304Speter sv_setiv((SV*) scrp->perl_private, 0); 17819304Speter } 17919304Speter return 0; 18019304Speter} 18119304Speter 18219304Speterstatic void 18319304Spetermy_sighandler(i) 18419304Speter int i; 18519304Speter{ 18619304Speter croak("Perl command interrupted by SIGINT"); 18719304Speter} 18819304Speter 18919304Speter/* Create a new reference to an SV pointing to the SCR structure 19019304Speter * The perl_private part of the SCR structure points to the SV, 19119304Speter * so there can only be one such SV for a particular SCR structure. 19219304Speter * When the last reference has gone (DESTROY is called), 19319304Speter * perl_private is reset; When the screen goes away before 19419304Speter * all references are gone, the value of the SV is reset; 19519304Speter * any subsequent use of any of those reference will produce 19619304Speter * a warning. (see typemap) 19719304Speter */ 19819304Speterstatic SV * 19919304SpeternewVIrv(rv, screen) 20019304Speter SV *rv; 20119304Speter SCR *screen; 20219304Speter{ 20319304Speter sv_upgrade(rv, SVt_RV); 20419304Speter if (!screen->perl_private) { 20519304Speter screen->perl_private = newSV(0); 20619304Speter sv_setiv(screen->perl_private, (IV) screen); 20719304Speter } 20819304Speter else SvREFCNT_inc(screen->perl_private); 20919304Speter SvRV(rv) = screen->perl_private; 21019304Speter SvROK_on(rv); 21119304Speter return sv_bless(rv, gv_stashpv("VI", TRUE)); 21219304Speter} 21319304Speter 21419304Speter 21519304Speter/* 21619304Speter * perl_ex_perl -- :[line [,line]] perl [command] 21719304Speter * Run a command through the perl interpreter. 21819304Speter * 21919304Speter * PUBLIC: int perl_ex_perl __P((SCR*, CHAR_T *, size_t, recno_t, recno_t)); 22019304Speter */ 22119304Speterint 22219304Speterperl_ex_perl(scrp, cmdp, cmdlen, f_lno, t_lno) 22319304Speter SCR *scrp; 22419304Speter CHAR_T *cmdp; 22519304Speter size_t cmdlen; 22619304Speter recno_t f_lno, t_lno; 22719304Speter{ 22819304Speter static SV *svcurscr = 0, *svstart, *svstop, *svid; 22919304Speter GS *gp; 23019304Speter STRLEN length; 23119304Speter size_t len; 23219304Speter char *err; 23319304Speter Signal_t (*istat)(); 23419304Speter 23519304Speter /* Initialize the interpreter. */ 23619304Speter gp = scrp->gp; 23719304Speter if (!svcurscr) { 23819304Speter if (gp->perl_interp == NULL && perl_init(scrp)) 23919304Speter return (1); 24019304Speter SvREADONLY_on(svcurscr = perl_get_sv("curscr", TRUE)); 24119304Speter SvREADONLY_on(svstart = perl_get_sv("VI::StartLine", TRUE)); 24219304Speter SvREADONLY_on(svstop = perl_get_sv("VI::StopLine", TRUE)); 24319304Speter SvREADONLY_on(svid = perl_get_sv("VI::ScreenId", TRUE)); 24419304Speter } 24519304Speter 24619304Speter sv_setiv(svstart, f_lno); 24719304Speter sv_setiv(svstop, t_lno); 24819304Speter newVIrv(svcurscr, scrp); 24919304Speter /* Backwards compatibility. */ 25019304Speter newVIrv(svid, scrp); 25119304Speter 25219304Speter istat = signal(SIGINT, my_sighandler); 25319304Speter perl_eval(cmdp); 25419304Speter signal(SIGINT, istat); 25519304Speter 25619304Speter SvREFCNT_dec(SvRV(svcurscr)); 25719304Speter SvROK_off(svcurscr); 25819304Speter SvREFCNT_dec(SvRV(svid)); 25919304Speter SvROK_off(svid); 26019304Speter 26169474Ssheldonh err = SvPV(GvSV(PL_errgv), length); 26219304Speter if (!length) 26319304Speter return (0); 26419304Speter 26519304Speter err[length - 1] = '\0'; 26619304Speter msgq(scrp, M_ERR, "perl: %s", err); 26719304Speter return (1); 26819304Speter} 26919304Speter 27019304Speter/* 27119304Speter * replace_line 27219304Speter * replace a line with the contents of the perl variable $_ 27319304Speter * lines are split at '\n's 27419304Speter * if $_ is undef, the line is deleted 27519304Speter * returns possibly adjusted linenumber 27619304Speter */ 27719304Speterstatic int 27819304Speterreplace_line(scrp, line, t_lno) 27919304Speter SCR *scrp; 28019304Speter recno_t line, *t_lno; 28119304Speter{ 28219304Speter char *str, *next; 28319304Speter size_t len; 28419304Speter 28569474Ssheldonh if (SvOK(GvSV(PL_defgv))) { 28669474Ssheldonh str = SvPV(GvSV(PL_defgv),len); 28719304Speter next = memchr(str, '\n', len); 28819304Speter api_sline(scrp, line, str, next ? (next - str) : len); 28919304Speter while (next++) { 29019304Speter len -= next - str; 29119304Speter next = memchr(str = next, '\n', len); 29219304Speter api_iline(scrp, ++line, str, next ? (next - str) : len); 29319304Speter (*t_lno)++; 29419304Speter } 29519304Speter } else { 29619304Speter api_dline(scrp, line--); 29719304Speter (*t_lno)--; 29819304Speter } 29919304Speter return line; 30019304Speter} 30119304Speter 30219304Speter/* 30319304Speter * perl_ex_perldo -- :[line [,line]] perl [command] 30419304Speter * Run a set of lines through the perl interpreter. 30519304Speter * 30619304Speter * PUBLIC: int perl_ex_perldo __P((SCR*, CHAR_T *, size_t, recno_t, recno_t)); 30719304Speter */ 30819304Speterint 30919304Speterperl_ex_perldo(scrp, cmdp, cmdlen, f_lno, t_lno) 31019304Speter SCR *scrp; 31119304Speter CHAR_T *cmdp; 31219304Speter size_t cmdlen; 31319304Speter recno_t f_lno, t_lno; 31419304Speter{ 31519304Speter static SV *svcurscr = 0, *svstart, *svstop, *svid; 31619304Speter CHAR_T *p; 31719304Speter GS *gp; 31819304Speter STRLEN length; 31919304Speter size_t len; 32019304Speter recno_t i; 32119304Speter char *str; 32219304Speter#ifndef HAVE_PERL_5_003_01 32319304Speter char *argv[2]; 32419304Speter#else 32519304Speter SV* sv; 32619304Speter#endif 32719304Speter dSP; 32819304Speter 32919304Speter /* Initialize the interpreter. */ 33019304Speter gp = scrp->gp; 33119304Speter if (!svcurscr) { 33219304Speter if (gp->perl_interp == NULL && perl_init(scrp)) 33319304Speter return (1); 33419304Speter SPAGAIN; 33519304Speter SvREADONLY_on(svcurscr = perl_get_sv("curscr", TRUE)); 33619304Speter SvREADONLY_on(svstart = perl_get_sv("VI::StartLine", TRUE)); 33719304Speter SvREADONLY_on(svstop = perl_get_sv("VI::StopLine", TRUE)); 33819304Speter SvREADONLY_on(svid = perl_get_sv("VI::ScreenId", TRUE)); 33919304Speter } 34019304Speter 34119304Speter#ifndef HAVE_PERL_5_003_01 34219304Speter argv[0] = cmdp; 34319304Speter argv[1] = NULL; 34419304Speter#else 34519304Speter length = strlen(cmdp); 34619304Speter sv = newSV(length + sizeof("sub VI::perldo {")-1 + 1 /* } */); 34719304Speter sv_setpvn(sv, "sub VI::perldo {", sizeof("sub VI::perldo {")-1); 34819304Speter sv_catpvn(sv, cmdp, length); 34919304Speter sv_catpvn(sv, "}", 1); 35019304Speter perl_eval_sv(sv, G_DISCARD | G_NOARGS); 35119304Speter SvREFCNT_dec(sv); 35269474Ssheldonh str = SvPV(GvSV(PL_errgv),length); 35319304Speter if (length) 35419304Speter goto err; 35519304Speter#endif 35619304Speter 35719304Speter newVIrv(svcurscr, scrp); 35819304Speter /* Backwards compatibility. */ 35919304Speter newVIrv(svid, scrp); 36019304Speter 36119304Speter ENTER; 36219304Speter SAVETMPS; 36319304Speter for (i = f_lno; i <= t_lno && !api_gline(scrp, i, &str, &len); i++) { 36469474Ssheldonh sv_setpvn(GvSV(PL_defgv),str,len); 36519304Speter sv_setiv(svstart, i); 36619304Speter sv_setiv(svstop, i); 36719304Speter#ifndef HAVE_PERL_5_003_01 36819304Speter perl_call_argv("_eval_", G_SCALAR | G_EVAL | G_KEEPERR, argv); 36919304Speter#else 37019304Speter PUSHMARK(sp); 37119304Speter perl_call_pv("VI::perldo", G_SCALAR | G_EVAL); 37219304Speter#endif 37369474Ssheldonh str = SvPV(GvSV(PL_errgv), length); 37419304Speter if (length) break; 37519304Speter SPAGAIN; 37619304Speter if(SvTRUEx(POPs)) 37719304Speter i = replace_line(scrp, i, &t_lno); 37819304Speter PUTBACK; 37919304Speter } 38019304Speter FREETMPS; 38119304Speter LEAVE; 38219304Speter 38319304Speter SvREFCNT_dec(SvRV(svcurscr)); 38419304Speter SvROK_off(svcurscr); 38519304Speter SvREFCNT_dec(SvRV(svid)); 38619304Speter SvROK_off(svid); 38719304Speter 38819304Speter if (!length) 38919304Speter return (0); 39019304Speter 39119304Spetererr: str[length - 1] = '\0'; 39219304Speter msgq(scrp, M_ERR, "perl: %s", str); 39319304Speter return (1); 39419304Speter} 39519304Speter 39619304Speter/* 39719304Speter * msghandler -- 39819304Speter * Perl message routine so that error messages are processed in 39919304Speter * Perl, not in nvi. 40019304Speter */ 40119304Speterstatic void 40219304Spetermsghandler(sp, mtype, msg, len) 40319304Speter SCR *sp; 40419304Speter mtype_t mtype; 40519304Speter char *msg; 40619304Speter size_t len; 40719304Speter{ 40819304Speter /* Replace the trailing <newline> with an EOS. */ 40919304Speter /* Let's do that later instead */ 41019304Speter if (errmsg) free (errmsg); 41119304Speter errmsg = malloc(len + 1); 41219304Speter memcpy(errmsg, msg, len); 41319304Speter errmsg[len] = '\0'; 41419304Speter} 41519304Speter 41619304Speter/* Register any extra external extensions */ 41719304Speter 41819304Speterextern void boot_DynaLoader _((CV* cv)); 41919304Speterextern void boot_VI _((CV* cv)); 42019304Speter 42119304Speterstatic void 42219304Speterxs_init() 42319304Speter{ 42441839Speter char *file = __FILE__; 42541839Speter 42619304Speter#ifdef HAVE_PERL_5_003_01 42769474Ssheldonh dXSUB_SYS 42819304Speter#endif 42919304Speter newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); 43019304Speter newXS("VI::bootstrap", boot_VI, file); 43119304Speter} 43219304Speter 43319304Spetertypedef SCR * VI; 43419304Spetertypedef SCR * VI__OPT; 43519304Spetertypedef SCR * VI__MAP; 43619304Spetertypedef SCR * VI__MARK; 43719304Spetertypedef AV * AVREF; 43819304Speter 43919304SpeterMODULE = VI PACKAGE = VI 44019304Speter 44119304Speter# msg -- 44219304Speter# Set the message line to text. 44319304Speter# 44419304Speter# Perl Command: VI::Msg 44519304Speter# Usage: VI::Msg screenId text 44619304Speter 44719304Spetervoid 44819304SpeterMsg(screen, text) 44919304Speter VI screen 45019304Speter char * text 45119304Speter 45219304Speter ALIAS: 45319304Speter PRINT = 1 45419304Speter 45519304Speter CODE: 45619304Speter api_imessage(screen, text); 45719304Speter 45819304Speter# XS_VI_escreen -- 45919304Speter# End a screen. 46019304Speter# 46119304Speter# Perl Command: VI::EndScreen 46219304Speter# Usage: VI::EndScreen screenId 46319304Speter 46419304Spetervoid 46519304SpeterEndScreen(screen) 46619304Speter VI screen 46719304Speter 46819304Speter PREINIT: 46919304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 47019304Speter int rval; 47119304Speter 47219304Speter CODE: 47319304Speter INITMESSAGE; 47419304Speter rval = api_escreen(screen); 47519304Speter ENDMESSAGE; 47619304Speter 47719304Speter# XS_VI_iscreen -- 47819304Speter# Create a new screen. If a filename is specified then the screen 47919304Speter# is opened with that file. 48019304Speter# 48119304Speter# Perl Command: VI::NewScreen 48219304Speter# Usage: VI::NewScreen screenId [file] 48319304Speter 48419304SpeterVI 48519304SpeterEdit(screen, ...) 48619304Speter VI screen 48719304Speter 48819304Speter ALIAS: 48919304Speter NewScreen = 1 49019304Speter 49119304Speter PROTOTYPE: $;$ 49219304Speter PREINIT: 49319304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 49419304Speter int rval; 49519304Speter char *file; 49619304Speter SCR *nsp; 49719304Speter 49819304Speter CODE: 49969474Ssheldonh file = (items == 1) ? NULL : (char *)SvPV(ST(1),PL_na); 50019304Speter INITMESSAGE; 50119304Speter rval = api_edit(screen, file, &nsp, ix); 50219304Speter ENDMESSAGE; 50319304Speter 50419304Speter RETVAL = ix ? nsp : screen; 50519304Speter 50619304Speter OUTPUT: 50719304Speter RETVAL 50819304Speter 50919304Speter# XS_VI_fscreen -- 51019304Speter# Return the screen id associated with file name. 51119304Speter# 51219304Speter# Perl Command: VI::FindScreen 51319304Speter# Usage: VI::FindScreen file 51419304Speter 51519304SpeterVI 51619304SpeterFindScreen(file) 51719304Speter char *file 51819304Speter 51919304Speter PREINIT: 52019304Speter SCR *fsp; 52119304Speter CODE: 52219304Speter RETVAL = api_fscreen(0, file); 52319304Speter 52419304Speter# XS_VI_aline -- 52519304Speter# -- Append the string text after the line in lineNumber. 52619304Speter# 52719304Speter# Perl Command: VI::AppendLine 52819304Speter# Usage: VI::AppendLine screenId lineNumber text 52919304Speter 53019304Spetervoid 53119304SpeterAppendLine(screen, linenumber, text) 53219304Speter VI screen 53319304Speter int linenumber 53419304Speter char *text 53519304Speter 53619304Speter PREINIT: 53719304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 53819304Speter int rval; 53919304Speter STRLEN length; 54019304Speter 54119304Speter CODE: 54219304Speter SvPV(ST(2), length); 54319304Speter INITMESSAGE; 54419304Speter rval = api_aline(screen, linenumber, text, length); 54519304Speter ENDMESSAGE; 54619304Speter 54719304Speter# XS_VI_dline -- 54819304Speter# Delete lineNum. 54919304Speter# 55019304Speter# Perl Command: VI::DelLine 55119304Speter# Usage: VI::DelLine screenId lineNum 55219304Speter 55319304Spetervoid 55419304SpeterDelLine(screen, linenumber) 55519304Speter VI screen 55619304Speter int linenumber 55719304Speter 55819304Speter PREINIT: 55919304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 56019304Speter int rval; 56119304Speter 56219304Speter CODE: 56319304Speter INITMESSAGE; 56419304Speter rval = api_dline(screen, (recno_t)linenumber); 56519304Speter ENDMESSAGE; 56619304Speter 56719304Speter# XS_VI_gline -- 56819304Speter# Return lineNumber. 56919304Speter# 57019304Speter# Perl Command: VI::GetLine 57119304Speter# Usage: VI::GetLine screenId lineNumber 57219304Speter 57319304Speterchar * 57419304SpeterGetLine(screen, linenumber) 57519304Speter VI screen 57619304Speter int linenumber 57719304Speter 57819304Speter PREINIT: 57919304Speter size_t len; 58019304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 58119304Speter int rval; 58219304Speter char *line, *p; 58319304Speter 58419304Speter PPCODE: 58519304Speter INITMESSAGE; 58619304Speter rval = api_gline(screen, (recno_t)linenumber, &p, &len); 58719304Speter ENDMESSAGE; 58819304Speter 58919304Speter EXTEND(sp,1); 59019304Speter PUSHs(sv_2mortal(newSVpv(p, len))); 59119304Speter 59219304Speter# XS_VI_sline -- 59319304Speter# Set lineNumber to the text supplied. 59419304Speter# 59519304Speter# Perl Command: VI::SetLine 59619304Speter# Usage: VI::SetLine screenId lineNumber text 59719304Speter 59819304Spetervoid 59919304SpeterSetLine(screen, linenumber, text) 60019304Speter VI screen 60119304Speter int linenumber 60219304Speter char *text 60319304Speter 60419304Speter PREINIT: 60519304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 60619304Speter int rval; 60719304Speter STRLEN length; 60819304Speter 60919304Speter CODE: 61019304Speter SvPV(ST(2), length); 61119304Speter INITMESSAGE; 61219304Speter rval = api_sline(screen, linenumber, text, length); 61319304Speter ENDMESSAGE; 61419304Speter 61519304Speter# XS_VI_iline -- 61619304Speter# Insert the string text before the line in lineNumber. 61719304Speter# 61819304Speter# Perl Command: VI::InsertLine 61919304Speter# Usage: VI::InsertLine screenId lineNumber text 62019304Speter 62119304Spetervoid 62219304SpeterInsertLine(screen, linenumber, text) 62319304Speter VI screen 62419304Speter int linenumber 62519304Speter char *text 62619304Speter 62719304Speter PREINIT: 62819304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 62919304Speter int rval; 63019304Speter STRLEN length; 63119304Speter 63219304Speter CODE: 63319304Speter SvPV(ST(2), length); 63419304Speter INITMESSAGE; 63519304Speter rval = api_iline(screen, linenumber, text, length); 63619304Speter ENDMESSAGE; 63719304Speter 63819304Speter# XS_VI_lline -- 63919304Speter# Return the last line in the screen. 64019304Speter# 64119304Speter# Perl Command: VI::LastLine 64219304Speter# Usage: VI::LastLine screenId 64319304Speter 64419304Speterint 64519304SpeterLastLine(screen) 64619304Speter VI screen 64719304Speter 64819304Speter PREINIT: 64919304Speter recno_t last; 65019304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 65119304Speter int rval; 65219304Speter 65319304Speter CODE: 65419304Speter INITMESSAGE; 65519304Speter rval = api_lline(screen, &last); 65619304Speter ENDMESSAGE; 65719304Speter RETVAL=last; 65819304Speter 65919304Speter OUTPUT: 66019304Speter RETVAL 66119304Speter 66219304Speter# XS_VI_getmark -- 66319304Speter# Return the mark's cursor position as a list with two elements. 66419304Speter# {line, column}. 66519304Speter# 66619304Speter# Perl Command: VI::GetMark 66719304Speter# Usage: VI::GetMark screenId mark 66819304Speter 66919304Spetervoid 67019304SpeterGetMark(screen, mark) 67119304Speter VI screen 67219304Speter char mark 67319304Speter 67419304Speter PREINIT: 67519304Speter struct _mark cursor; 67619304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 67719304Speter int rval; 67819304Speter 67919304Speter PPCODE: 68019304Speter INITMESSAGE; 68119304Speter rval = api_getmark(screen, (int)mark, &cursor); 68219304Speter ENDMESSAGE; 68319304Speter 68419304Speter EXTEND(sp,2); 68519304Speter PUSHs(sv_2mortal(newSViv(cursor.lno))); 68619304Speter PUSHs(sv_2mortal(newSViv(cursor.cno))); 68719304Speter 68819304Speter# XS_VI_setmark -- 68919304Speter# Set the mark to the line and column numbers supplied. 69019304Speter# 69119304Speter# Perl Command: VI::SetMark 69219304Speter# Usage: VI::SetMark screenId mark line column 69319304Speter 69419304Spetervoid 69519304SpeterSetMark(screen, mark, line, column) 69619304Speter VI screen 69719304Speter char mark 69819304Speter int line 69919304Speter int column 70019304Speter 70119304Speter PREINIT: 70219304Speter struct _mark cursor; 70319304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 70419304Speter int rval; 70519304Speter 70619304Speter CODE: 70719304Speter INITMESSAGE; 70819304Speter cursor.lno = line; 70919304Speter cursor.cno = column; 71019304Speter rval = api_setmark(screen, (int)mark, &cursor); 71119304Speter ENDMESSAGE; 71219304Speter 71319304Speter# XS_VI_getcursor -- 71419304Speter# Return the current cursor position as a list with two elements. 71519304Speter# {line, column}. 71619304Speter# 71719304Speter# Perl Command: VI::GetCursor 71819304Speter# Usage: VI::GetCursor screenId 71919304Speter 72019304Spetervoid 72119304SpeterGetCursor(screen) 72219304Speter VI screen 72319304Speter 72419304Speter PREINIT: 72519304Speter struct _mark cursor; 72619304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 72719304Speter int rval; 72819304Speter 72919304Speter PPCODE: 73019304Speter INITMESSAGE; 73119304Speter rval = api_getcursor(screen, &cursor); 73219304Speter ENDMESSAGE; 73319304Speter 73419304Speter EXTEND(sp,2); 73519304Speter PUSHs(sv_2mortal(newSViv(cursor.lno))); 73619304Speter PUSHs(sv_2mortal(newSViv(cursor.cno))); 73719304Speter 73819304Speter# XS_VI_setcursor -- 73919304Speter# Set the cursor to the line and column numbers supplied. 74019304Speter# 74119304Speter# Perl Command: VI::SetCursor 74219304Speter# Usage: VI::SetCursor screenId line column 74319304Speter 74419304Spetervoid 74519304SpeterSetCursor(screen, line, column) 74619304Speter VI screen 74719304Speter int line 74819304Speter int column 74919304Speter 75019304Speter PREINIT: 75119304Speter struct _mark cursor; 75219304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 75319304Speter int rval; 75419304Speter 75519304Speter CODE: 75619304Speter INITMESSAGE; 75719304Speter cursor.lno = line; 75819304Speter cursor.cno = column; 75919304Speter rval = api_setcursor(screen, &cursor); 76019304Speter ENDMESSAGE; 76119304Speter 76219304Speter# XS_VI_swscreen -- 76319304Speter# Change the current focus to screen. 76419304Speter# 76519304Speter# Perl Command: VI::SwitchScreen 76619304Speter# Usage: VI::SwitchScreen screenId screenId 76719304Speter 76819304Spetervoid 76919304SpeterSwitchScreen(screenFrom, screenTo) 77019304Speter VI screenFrom 77119304Speter VI screenTo 77219304Speter 77319304Speter PREINIT: 77419304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 77519304Speter int rval; 77619304Speter 77719304Speter CODE: 77819304Speter INITMESSAGE; 77919304Speter rval = api_swscreen(screenFrom, screenTo); 78019304Speter ENDMESSAGE; 78119304Speter 78219304Speter# XS_VI_map -- 78319304Speter# Associate a key with a perl procedure. 78419304Speter# 78519304Speter# Perl Command: VI::MapKey 78619304Speter# Usage: VI::MapKey screenId key perlproc 78719304Speter 78819304Spetervoid 78919304SpeterMapKey(screen, key, perlproc) 79019304Speter VI screen 79119304Speter char *key 79219304Speter SV *perlproc 79319304Speter 79419304Speter PREINIT: 79519304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 79619304Speter int rval; 79719304Speter int length; 79819304Speter char *command; 79919304Speter SV *svc; 80019304Speter 80119304Speter CODE: 80219304Speter INITMESSAGE; 80319304Speter svc = sv_2mortal(newSVpv(":perl ", 6)); 80419304Speter sv_catsv(svc, perlproc); 80519304Speter command = SvPV(svc, length); 80619304Speter rval = api_map(screen, key, command, length); 80719304Speter ENDMESSAGE; 80819304Speter 80919304Speter# XS_VI_unmap -- 81019304Speter# Unmap a key. 81119304Speter# 81219304Speter# Perl Command: VI::UnmapKey 81319304Speter# Usage: VI::UnmmapKey screenId key 81419304Speter 81519304Spetervoid 81619304SpeterUnmapKey(screen, key) 81719304Speter VI screen 81819304Speter char *key 81919304Speter 82019304Speter PREINIT: 82119304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 82219304Speter int rval; 82319304Speter 82419304Speter CODE: 82519304Speter INITMESSAGE; 82619304Speter rval = api_unmap(screen, key); 82719304Speter ENDMESSAGE; 82819304Speter 82919304Speter# XS_VI_opts_set -- 83019304Speter# Set an option. 83119304Speter# 83219304Speter# Perl Command: VI::SetOpt 83319304Speter# Usage: VI::SetOpt screenId setting 83419304Speter 83519304Spetervoid 83619304SpeterSetOpt(screen, setting) 83719304Speter VI screen 83819304Speter char *setting 83919304Speter 84019304Speter PREINIT: 84119304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 84219304Speter int rval; 84319304Speter SV *svc; 84419304Speter 84519304Speter CODE: 84619304Speter INITMESSAGE; 84719304Speter svc = sv_2mortal(newSVpv(":set ", 5)); 84819304Speter sv_catpv(svc, setting); 84969474Ssheldonh rval = api_run_str(screen, SvPV(svc, PL_na)); 85019304Speter ENDMESSAGE; 85119304Speter 85219304Speter# XS_VI_opts_get -- 85319304Speter# Return the value of an option. 85419304Speter# 85519304Speter# Perl Command: VI::GetOpt 85619304Speter# Usage: VI::GetOpt screenId option 85719304Speter 85819304Spetervoid 85919304SpeterGetOpt(screen, option) 86019304Speter VI screen 86119304Speter char *option 86219304Speter 86319304Speter PREINIT: 86419304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 86519304Speter int rval; 86619304Speter char *value; 86719304Speter 86819304Speter PPCODE: 86919304Speter INITMESSAGE; 87019304Speter rval = api_opts_get(screen, option, &value, NULL); 87119304Speter ENDMESSAGE; 87219304Speter 87319304Speter EXTEND(SP,1); 87419304Speter PUSHs(sv_2mortal(newSVpv(value, 0))); 87519304Speter free(value); 87619304Speter 87719304Speter# XS_VI_run -- 87819304Speter# Run the ex command cmd. 87919304Speter# 88019304Speter# Perl Command: VI::Run 88119304Speter# Usage: VI::Run screenId cmd 88219304Speter 88319304Spetervoid 88419304SpeterRun(screen, command) 88519304Speter VI screen 88619304Speter char *command; 88719304Speter 88819304Speter PREINIT: 88919304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 89019304Speter int rval; 89119304Speter 89219304Speter CODE: 89319304Speter INITMESSAGE; 89419304Speter rval = api_run_str(screen, command); 89519304Speter ENDMESSAGE; 89619304Speter 89719304Spetervoid 89819304SpeterDESTROY(screen) 89919304Speter VI screen 90019304Speter 90119304Speter CODE: 90219304Speter screen->perl_private = 0; 90319304Speter 90419304Spetervoid 90519304SpeterWarn(warning) 90619304Speter char *warning; 90719304Speter 90819304Speter PREINIT: 90919304Speter int i; 91019304Speter CODE: 91169474Ssheldonh sv_catpv(GvSV(PL_errgv),warning); 91219304Speter 91319304Speter#define TIED(package) \ 91419304Speter sv_magic((SV *) (hv = \ 91519304Speter (HV *)sv_2mortal((SV *)newHV())), \ 91619304Speter sv_setref_pv(sv_newmortal(), package, \ 91719304Speter newVIrv(newSV(0), screen)),\ 91819304Speter 'P', Nullch, 0);\ 91919304Speter RETVAL = newRV((SV *)hv) 92019304Speter 92119304SpeterSV * 92219304SpeterOpt(screen) 92319304Speter VI screen; 92419304Speter PREINIT: 92519304Speter HV *hv; 92619304Speter CODE: 92719304Speter TIED("VI::OPT"); 92819304Speter OUTPUT: 92919304Speter RETVAL 93019304Speter 93119304SpeterSV * 93219304SpeterMap(screen) 93319304Speter VI screen; 93419304Speter PREINIT: 93519304Speter HV *hv; 93619304Speter CODE: 93719304Speter TIED("VI::MAP"); 93819304Speter OUTPUT: 93919304Speter RETVAL 94019304Speter 94119304SpeterSV * 94219304SpeterMark(screen) 94319304Speter VI screen 94419304Speter PREINIT: 94519304Speter HV *hv; 94619304Speter CODE: 94719304Speter TIED("VI::MARK"); 94819304Speter OUTPUT: 94919304Speter RETVAL 95019304Speter 95119304SpeterMODULE = VI PACKAGE = VI::OPT 95219304Speter 95319304Spetervoid 95419304SpeterDESTROY(screen) 95519304Speter VI::OPT screen 95619304Speter 95719304Speter CODE: 95819304Speter # typemap did all the checking 95919304Speter SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0)))); 96019304Speter 96119304Spetervoid 96219304SpeterFETCH(screen, key) 96319304Speter VI::OPT screen 96419304Speter char *key 96519304Speter 96619304Speter PREINIT: 96719304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 96819304Speter int rval; 96919304Speter char *value; 97019304Speter int boolvalue; 97119304Speter 97219304Speter PPCODE: 97319304Speter INITMESSAGE; 97419304Speter rval = api_opts_get(screen, key, &value, &boolvalue); 97519304Speter if (!rval) { 97619304Speter EXTEND(SP,1); 97719304Speter PUSHs(sv_2mortal((boolvalue == -1) ? newSVpv(value, 0) 97819304Speter : newSViv(boolvalue))); 97919304Speter free(value); 98069474Ssheldonh } else ST(0) = &PL_sv_undef; 98119304Speter rval = 0; 98219304Speter ENDMESSAGE; 98319304Speter 98419304Spetervoid 98519304SpeterSTORE(screen, key, value) 98619304Speter VI::OPT screen 98719304Speter char *key 98819304Speter SV *value 98919304Speter 99019304Speter PREINIT: 99119304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 99219304Speter int rval; 99319304Speter 99419304Speter CODE: 99519304Speter INITMESSAGE; 99669474Ssheldonh rval = api_opts_set(screen, key, SvPV(value, PL_na), SvIV(value), 99719304Speter SvTRUEx(value)); 99819304Speter ENDMESSAGE; 99919304Speter 100019304SpeterMODULE = VI PACKAGE = VI::MAP 100119304Speter 100219304Spetervoid 100319304SpeterDESTROY(screen) 100419304Speter VI::MAP screen 100519304Speter 100619304Speter CODE: 100719304Speter # typemap did all the checking 100819304Speter SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0)))); 100919304Speter 101019304Spetervoid 101119304SpeterSTORE(screen, key, perlproc) 101219304Speter VI::MAP screen 101319304Speter char *key 101419304Speter SV *perlproc 101519304Speter 101619304Speter PREINIT: 101719304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 101819304Speter int rval; 101919304Speter int length; 102019304Speter char *command; 102119304Speter SV *svc; 102219304Speter 102319304Speter CODE: 102419304Speter INITMESSAGE; 102519304Speter svc = sv_2mortal(newSVpv(":perl ", 6)); 102619304Speter sv_catsv(svc, perlproc); 102719304Speter command = SvPV(svc, length); 102819304Speter rval = api_map(screen, key, command, length); 102919304Speter ENDMESSAGE; 103019304Speter 103119304Spetervoid 103219304SpeterDELETE(screen, key) 103319304Speter VI::MAP screen 103419304Speter char *key 103519304Speter 103619304Speter PREINIT: 103719304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 103819304Speter int rval; 103919304Speter 104019304Speter CODE: 104119304Speter INITMESSAGE; 104219304Speter rval = api_unmap(screen, key); 104319304Speter ENDMESSAGE; 104419304Speter 104519304SpeterMODULE = VI PACKAGE = VI::MARK 104619304Speter 104719304Spetervoid 104819304SpeterDESTROY(screen) 104919304Speter VI::MARK screen 105019304Speter 105119304Speter CODE: 105219304Speter # typemap did all the checking 105319304Speter SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0)))); 105419304Speter 105519304SpeterAV * 105619304SpeterFETCH(screen, mark) 105719304Speter VI::MARK screen 105819304Speter char mark 105919304Speter 106019304Speter PREINIT: 106119304Speter struct _mark cursor; 106219304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 106319304Speter int rval; 106419304Speter 106519304Speter CODE: 106619304Speter INITMESSAGE; 106719304Speter rval = api_getmark(screen, (int)mark, &cursor); 106819304Speter ENDMESSAGE; 106919304Speter RETVAL = newAV(); 107019304Speter av_push(RETVAL, newSViv(cursor.lno)); 107119304Speter av_push(RETVAL, newSViv(cursor.cno)); 107219304Speter 107319304Speter OUTPUT: 107419304Speter RETVAL 107519304Speter 107619304Spetervoid 107719304SpeterSTORE(screen, mark, pos) 107819304Speter VI::MARK screen 107919304Speter char mark 108019304Speter AVREF pos 108119304Speter 108219304Speter PREINIT: 108319304Speter struct _mark cursor; 108419304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 108519304Speter int rval; 108619304Speter 108719304Speter CODE: 108819304Speter if (av_len(pos) < 1) 108919304Speter croak("cursor position needs 2 elements"); 109019304Speter INITMESSAGE; 109119304Speter cursor.lno = SvIV(*av_fetch(pos, 0, 0)); 109219304Speter cursor.cno = SvIV(*av_fetch(pos, 1, 0)); 109319304Speter rval = api_setmark(screen, (int)mark, &cursor); 109419304Speter ENDMESSAGE; 109519304Speter 109619304Spetervoid 109719304SpeterFIRSTKEY(screen, ...) 109819304Speter VI::MARK screen 109919304Speter 110019304Speter ALIAS: 110119304Speter NEXTKEY = 1 110219304Speter 110319304Speter PROTOTYPE: $;$ 110419304Speter 110519304Speter PREINIT: 110619304Speter struct _mark cursor; 110719304Speter void (*scr_msg) __P((SCR *, mtype_t, char *, size_t)); 110819304Speter int next; 110919304Speter char key[] = {0, 0}; 111019304Speter 111119304Speter PPCODE: 111219304Speter if (items == 2) { 111319304Speter next = 1; 111469474Ssheldonh *key = *(char *)SvPV(ST(1),PL_na); 111519304Speter } else next = 0; 111619304Speter if (api_nextmark(screen, next, key) != 1) { 111719304Speter EXTEND(sp, 1); 111819304Speter PUSHs(sv_2mortal(newSVpv(key, 1))); 111969474Ssheldonh } else ST(0) = &PL_sv_undef; 1120