2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * George V. Neville-Neil. All rights reserved.
9 * Sven Verdoolaege. All rights reserved.
11 * See the LICENSE file for redistribution information.
17 static const char sccsid[] = "$Id: perl.xs,v 8.36 2000/07/07 22:28:18 skimo Exp $ (Berkeley) $Date: 2000/07/07 22:28:18 $";
20 #include <sys/types.h>
21 #include <sys/queue.h>
24 #include <bitstring.h>
38 /* perl redefines them
41 #undef USE_DYNAMIC_LOADING
49 #include "../common/common.h"
50 #include "../perl_api/extern.h"
53 #define DEFSV GvSV(defgv)
56 #define ERRSV GvSV(errgv)
64 static void msghandler __P((SCR *, mtype_t, char *, size_t));
66 static char *errmsg = 0;
68 typedef struct _perl_data {
69 PerlInterpreter* interp;
70 SV *svcurscr, *svstart, *svstop, *svid;
75 * Macros to point messages at the Perl message handler.
77 #define INITMESSAGE(sp) \
78 scr_msg = sp->gp->scr_msg; \
79 sp->gp->scr_msg = msghandler;
80 #define ENDMESSAGE(sp) \
81 sp->gp->scr_msg = scr_msg; \
82 if (rval) croak(errmsg);
84 void xs_init __P((void));
88 * Clean up perl interpreter
90 * PUBLIC: int perl_end __P((GS *));
97 * Call perl_run and perl_destuct to call END blocks and DESTROY
100 if (gp->perl_interp) {
101 perl_run(gp->perl_interp);
102 perl_destruct(gp->perl_interp);
103 #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
104 perl_free(gp->perl_interp);
106 /* XXX rather make sure only one thread calls perl_end */
114 * We don't use mortal SVs because no one will clean up after us
122 SV* sv = newSVpv(string, 0);
124 /* G_KEEPERR to catch syntax error; better way ? */
126 perl_eval_sv(sv, G_DISCARD | G_NOARGS | G_KEEPERR);
132 * Create the perl commands used by nvi.
134 * PUBLIC: int perl_init __P((SCR *));
143 char *bootargs[] = { "VI", NULL };
149 static char *args[] = { "", "-e", "" };
151 char *file = __FILE__;
156 if (gp->perl_interp == NULL) {
157 gp->perl_interp = perl_alloc();
158 perl_construct(gp->perl_interp);
159 if (perl_parse(gp->perl_interp, xs_init, 3, args, 0)) {
160 perl_destruct(gp->perl_interp);
161 perl_free(gp->perl_interp);
162 gp->perl_interp = NULL;
168 perl_call_argv("VI::bootstrap", G_DISCARD, bootargs);
169 perl_eval("$SIG{__WARN__}='VI::Warn'");
171 av_unshift(av = GvAVn(PL_incgv), 1);
172 av_store(av, 0, newSVpv(_PATH_PERLSCRIPTS,
173 sizeof(_PATH_PERLSCRIPTS)-1));
176 sfdisc(PerlIO_stdout(), sfdcnewnvi(scrp));
177 sfdisc(PerlIO_stderr(), sfdcnewnvi(scrp));
179 svcurscr = perl_get_sv("curscr", TRUE);
180 sv_magic((SV *)gv_fetchpv("STDOUT",TRUE, SVt_PVIO), svcurscr,
182 sv_magic((SV *)gv_fetchpv("STDERR",TRUE, SVt_PVIO), svcurscr,
184 #endif /* USE_SFIO */
187 MALLOC(scrp, pp, perl_data_t *, sizeof(perl_data_t));
188 wp->perl_private = pp;
190 pp->interp = perl_clone(gp->perl_interp, 0);
191 if (1) { /* hack for bug fixed in perl-current (5.6.1) */
193 if (PL_scopestack_ix == 0) {
198 pp->interp = gp->perl_interp;
203 SvREADONLY_on(pp->svcurscr = perl_get_sv("curscr", TRUE));
204 SvREADONLY_on(pp->svstart = perl_get_sv("VI::StartLine", TRUE));
205 SvREADONLY_on(pp->svstop = perl_get_sv("VI::StopLine", TRUE));
206 SvREADONLY_on(pp->svid = perl_get_sv("VI::ScreenId", TRUE));
213 * Remove all refences to the screen to be destroyed
215 * PUBLIC: int perl_screen_end __P((SCR*));
218 perl_screen_end(scrp)
223 if (scrp->perl_private) {
224 sv_setiv((SV*) scrp->perl_private, 0);
233 croak("Perl command interrupted by SIGINT");
236 /* Create a new reference to an SV pointing to the SCR structure
237 * The perl_private part of the SCR structure points to the SV,
238 * so there can only be one such SV for a particular SCR structure.
239 * When the last reference has gone (DESTROY is called),
240 * perl_private is reset; When the screen goes away before
241 * all references are gone, the value of the SV is reset;
242 * any subsequent use of any of those reference will produce
243 * a warning. (see typemap)
252 if (!screen) return sv_setsv(rv, &PL_sv_undef), rv;
253 sv_upgrade(rv, SVt_RV);
254 if (!screen->perl_private) {
255 screen->perl_private = newSV(0);
256 sv_setiv(screen->perl_private, (IV) screen);
258 else SvREFCNT_inc(screen->perl_private);
259 SvRV(rv) = screen->perl_private;
261 return sv_bless(rv, gv_stashpv("VI", TRUE));
266 * perl_ex_perl -- :[line [,line]] perl [command]
267 * Run a command through the perl interpreter.
269 * PUBLIC: int perl_ex_perl __P((SCR*, CHAR_T *, size_t, db_recno_t, db_recno_t));
272 perl_ex_perl(scrp, cmdp, cmdlen, f_lno, t_lno)
276 db_recno_t f_lno, t_lno;
285 /* Initialize the interpreter. */
286 if (scrp->wp->perl_private == NULL && perl_init(scrp))
288 pp = scrp->wp->perl_private;
293 sv_setiv(pp->svstart, f_lno);
294 sv_setiv(pp->svstop, t_lno);
295 newVIrv(pp->svcurscr, scrp);
296 /* Backwards compatibility. */
297 newVIrv(pp->svid, scrp);
299 istat = signal(SIGINT, my_sighandler);
301 signal(SIGINT, istat);
303 SvREFCNT_dec(SvRV(pp->svcurscr));
304 SvROK_off(pp->svcurscr);
305 SvREFCNT_dec(SvRV(pp->svid));
308 err = SvPV(ERRSV, length);
312 err[length - 1] = '\0';
313 msgq(scrp, M_ERR, "perl: %s", err);
320 * replace a line with the contents of the perl variable $_
321 * lines are split at '\n's
322 * if $_ is undef, the line is deleted
323 * returns possibly adjusted linenumber
326 replace_line(scrp, line, t_lno, defsv)
328 db_recno_t line, *t_lno;
336 str = SvPV(defsv,len);
337 next = memchr(str, '\n', len);
338 api_sline(scrp, line, str, next ? (next - str) : len);
341 next = memchr(str = next, '\n', len);
342 api_iline(scrp, ++line, str, next ? (next - str) : len);
346 api_dline(scrp, line--);
353 * perl_ex_perldo -- :[line [,line]] perl [command]
354 * Run a set of lines through the perl interpreter.
356 * PUBLIC: int perl_ex_perldo __P((SCR*, CHAR_T *, size_t, db_recno_t, db_recno_t));
359 perl_ex_perldo(scrp, cmdp, cmdlen, f_lno, t_lno)
363 db_recno_t f_lno, t_lno;
375 /* Initialize the interpreter. */
376 if (scrp->wp->perl_private == NULL && perl_init(scrp))
378 pp = scrp->wp->perl_private;
383 newVIrv(pp->svcurscr, scrp);
384 /* Backwards compatibility. */
385 newVIrv(pp->svid, scrp);
387 if (!(command = malloc(length = strlen(cmdp) + sizeof("sub {}"))))
389 snprintf(command, length, "sub {%s}", cmdp);
394 cv = perl_eval_pv(command, FALSE);
397 str = SvPV(ERRSV,length);
401 for (i = f_lno; i <= t_lno && !api_gline(scrp, i, &str, &len); i++) {
402 sv_setpvn(DEFSV,str,len);
403 sv_setiv(pp->svstart, i);
404 sv_setiv(pp->svstop, i);
406 perl_call_sv(cv, G_SCALAR | G_EVAL);
407 str = SvPV(ERRSV, length);
411 i = replace_line(scrp, i, &t_lno, DEFSV);
417 SvREFCNT_dec(SvRV(pp->svcurscr));
418 SvROK_off(pp->svcurscr);
419 SvREFCNT_dec(SvRV(pp->svid));
425 err: str[length - 1] = '\0';
426 msgq(scrp, M_ERR, "perl: %s", str);
433 * Perl message routine so that error messages are processed in
437 msghandler(sp, mtype, msg, len)
443 /* Replace the trailing <newline> with an EOS. */
444 /* Let's do that later instead */
445 if (errmsg) free (errmsg);
446 errmsg = malloc(len + 1);
447 memcpy(errmsg, msg, len);
453 typedef SCR * VI__OPT;
454 typedef SCR * VI__MAP;
455 typedef SCR * VI__MARK;
456 typedef SCR * VI__LINE;
464 typedef perl_tagq * VI__TAGQ;
465 typedef perl_tagq * VI__TAGQ2;
467 MODULE = VI PACKAGE = VI
470 # Set the message line to text.
472 # Perl Command: VI::Msg
473 # Usage: VI::Msg screenId text
484 api_imessage(screen, text);
489 # Perl Command: VI::EndScreen
490 # Usage: VI::EndScreen screenId
497 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
502 rval = api_escreen(screen);
506 # Create a new screen. If a filename is specified then the screen
507 # is opened with that file.
509 # Perl Command: VI::NewScreen
510 # Usage: VI::NewScreen screenId [file]
521 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
527 file = (items == 1) ? NULL : (char *)SvPV(ST(1),PL_na);
529 rval = api_edit(screen, file, &nsp, ix);
532 RETVAL = ix ? nsp : screen;
538 # Return the screen id associated with file name.
540 # Perl Command: VI::FindScreen
541 # Usage: VI::FindScreen file
550 RETVAL = api_fscreen(0, file);
555 # XS_VI_GetFileName --
556 # Return the file name of the screen
558 # Perl Command: VI::GetFileName
559 # Usage: VI::GetFileName screenId
567 PUSHs(sv_2mortal(newSVpv(screen->frp->name, 0)));
570 # -- Append the string text after the line in lineNumber.
572 # Perl Command: VI::AppendLine
573 # Usage: VI::AppendLine screenId lineNumber text
576 AppendLine(screen, linenumber, text)
582 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
589 rval = api_aline(screen, linenumber, text, length);
595 # Perl Command: VI::DelLine
596 # Usage: VI::DelLine screenId lineNum
599 DelLine(screen, linenumber)
604 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
609 rval = api_dline(screen, (db_recno_t)linenumber);
615 # Perl Command: VI::GetLine
616 # Usage: VI::GetLine screenId lineNumber
619 GetLine(screen, linenumber)
625 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
632 rval = api_gline(screen, (db_recno_t)linenumber, &p, &len);
636 PUSHs(sv_2mortal(newSVpv(len ? (char *)p : "", len)));
639 # Set lineNumber to the text supplied.
641 # Perl Command: VI::SetLine
642 # Usage: VI::SetLine screenId lineNumber text
645 SetLine(screen, linenumber, text)
651 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
658 rval = api_sline(screen, linenumber, text, length);
662 # Insert the string text before the line in lineNumber.
664 # Perl Command: VI::InsertLine
665 # Usage: VI::InsertLine screenId lineNumber text
668 InsertLine(screen, linenumber, text)
674 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
681 rval = api_iline(screen, linenumber, text, length);
685 # Return the last line in the screen.
687 # Perl Command: VI::LastLine
688 # Usage: VI::LastLine screenId
696 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
701 rval = api_lline(screen, &last);
709 # Return the mark's cursor position as a list with two elements.
712 # Perl Command: VI::GetMark
713 # Usage: VI::GetMark screenId mark
716 GetMark(screen, mark)
722 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
727 rval = api_getmark(screen, (int)mark, &cursor);
731 PUSHs(sv_2mortal(newSViv(cursor.lno)));
732 PUSHs(sv_2mortal(newSViv(cursor.cno)));
735 # Set the mark to the line and column numbers supplied.
737 # Perl Command: VI::SetMark
738 # Usage: VI::SetMark screenId mark line column
741 SetMark(screen, mark, line, column)
749 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
756 rval = api_setmark(screen, (int)mark, &cursor);
760 # Return the current cursor position as a list with two elements.
763 # Perl Command: VI::GetCursor
764 # Usage: VI::GetCursor screenId
772 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
777 rval = api_getcursor(screen, &cursor);
781 PUSHs(sv_2mortal(newSViv(cursor.lno)));
782 PUSHs(sv_2mortal(newSViv(cursor.cno)));
785 # Set the cursor to the line and column numbers supplied.
787 # Perl Command: VI::SetCursor
788 # Usage: VI::SetCursor screenId line column
791 SetCursor(screen, line, column)
798 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
805 rval = api_setcursor(screen, &cursor);
809 # Change the current focus to screen.
811 # Perl Command: VI::SwitchScreen
812 # Usage: VI::SwitchScreen screenId screenId
815 SwitchScreen(screenFrom, screenTo)
820 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
824 INITMESSAGE(screenFrom);
825 rval = api_swscreen(screenFrom, screenTo);
826 ENDMESSAGE(screenFrom);
829 # Associate a key with a perl procedure.
831 # Perl Command: VI::MapKey
832 # Usage: VI::MapKey screenId key perlproc
835 MapKey(screen, key, perlproc)
841 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
850 svc = sv_2mortal(newSVpv(":perl ", 6));
851 sv_catsv(svc, perlproc);
852 svn = sv_2mortal(newSVpv("
\r", 1));
854 command = SvPV(svc, length);
855 rval = api_map(screen, key, command, length);
861 # Perl Command: VI::UnmapKey
862 # Usage: VI::UnmmapKey screenId key
865 UnmapKey(screen, key)
870 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
875 rval = api_unmap(screen, key);
881 # Perl Command: VI::SetOpt
882 # Usage: VI::SetOpt screenId setting
885 SetOpt(screen, setting)
890 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
896 svc = sv_2mortal(newSVpv(":set ", 5));
897 sv_catpv(svc, setting);
898 rval = api_run_str(screen, SvPV(svc, PL_na));
902 # Return the value of an option.
904 # Perl Command: VI::GetOpt
905 # Usage: VI::GetOpt screenId option
908 GetOpt(screen, option)
913 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
919 rval = api_opts_get(screen, option, &value, NULL);
923 PUSHs(sv_2mortal(newSVpv(value, 0)));
927 # Run the ex command cmd.
929 # Perl Command: VI::Run
930 # Usage: VI::Run screenId cmd
938 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
943 rval = api_run_str(screen, command);
954 if (sv_isa(screensv, "VI")) {
955 IV tmp = SvIV((SV*)SvRV(screensv));
956 screen = (SCR *) tmp;
959 croak("screen is not of type VI");
962 screen->perl_private = 0;
969 sv_catpv(ERRSV,warning);
971 #define TIED(kind,package) \
972 sv_magic((SV *) (var = \
973 (##kind##V *)sv_2mortal((SV *)new##kind##V())), \
974 sv_setref_pv(sv_newmortal(), package, \
975 newVIrv(newSV(0), screen)),\
977 RETVAL = newRV((SV *)var)
1028 if ((ptag = malloc(sizeof(perl_tagq))) == NULL)
1031 ptag->sprv = newVIrv(newSV(0), screen);
1032 ptag->tqp = api_tagq_new(screen, tag);
1033 if (ptag->tqp != NULL) {
1035 PUSHs(sv_2mortal(sv_setref_pv(newSV(0), "VI::TAGQ", ptag)));
1038 ST(0) = &PL_sv_undef;
1042 MODULE = VI PACKAGE = VI::OPT
1049 # typemap did all the checking
1050 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1058 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1064 INITMESSAGE(screen);
1065 rval = api_opts_get(screen, key, &value, &boolvalue);
1068 PUSHs(sv_2mortal((boolvalue == -1) ? newSVpv(value, 0)
1069 : newSViv(boolvalue)));
1071 } else ST(0) = &PL_sv_undef;
1076 STORE(screen, key, value)
1082 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1086 INITMESSAGE(screen);
1087 rval = api_opts_set(screen, key, SvPV(value, PL_na), SvIV(value),
1091 MODULE = VI PACKAGE = VI::MAP
1098 # typemap did all the checking
1099 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1102 STORE(screen, key, perlproc)
1108 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1116 INITMESSAGE(screen);
1117 svc = sv_2mortal(newSVpv(":perl ", 6));
1118 sv_catsv(svc, perlproc);
1119 svn = sv_2mortal(newSVpv("
\r", 1));
1121 command = SvPV(svc, length);
1122 rval = api_map(screen, key, command, length);
1131 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1135 INITMESSAGE(screen);
1136 rval = api_unmap(screen, key);
1139 MODULE = VI PACKAGE = VI::MARK
1146 # typemap did all the checking
1147 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1155 struct _mark cursor;
1156 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1160 INITMESSAGE(screen);
1161 rval = api_getmark(screen, (int)mark, &cursor);
1164 av_push(RETVAL, newSViv(cursor.lno));
1165 av_push(RETVAL, newSViv(cursor.cno));
1171 STORE(screen, mark, pos)
1177 struct _mark cursor;
1178 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1182 if (av_len(pos) < 1)
1183 croak("cursor position needs 2 elements");
1184 INITMESSAGE(screen);
1185 cursor.lno = SvIV(*av_fetch(pos, 0, 0));
1186 cursor.cno = SvIV(*av_fetch(pos, 1, 0));
1187 rval = api_setmark(screen, (int)mark, &cursor);
1191 FIRSTKEY(screen, ...)
1201 char key[] = {0, 0};
1206 *key = *(char *)SvPV(ST(1),PL_na);
1208 if (api_nextmark(screen, next, key) != 1) {
1210 PUSHs(sv_2mortal(newSVpv(key, 1)));
1211 } else ST(0) = &PL_sv_undef;
1213 MODULE = VI PACKAGE = VI::LINE
1220 # typemap did all the checking
1221 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1223 # similar to SetLine
1226 STORE(screen, linenumber, text)
1232 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1238 ++linenumber; /* vi 1 based ; perl 0 based */
1239 SvPV(ST(2), length);
1240 INITMESSAGE(screen);
1241 rval = api_lline(screen, &last);
1243 if (linenumber > last)
1244 rval = api_extend(screen, linenumber);
1246 rval = api_sline(screen, linenumber, text, length);
1250 # similar to GetLine
1253 FETCH(screen, linenumber)
1259 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1265 ++linenumber; /* vi 1 based ; perl 0 based */
1266 INITMESSAGE(screen);
1267 rval = api_gline(screen, (db_recno_t)linenumber, &p, &len);
1271 PUSHs(sv_2mortal(newSVpv(len ? (char*)p : "", len)));
1273 # similar to LastLine
1281 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1285 INITMESSAGE(screen);
1286 rval = api_lline(screen, &last);
1294 STORESIZE(screen, count)
1300 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1304 INITMESSAGE(screen);
1305 rval = api_lline(screen, &last);
1308 rval = api_extend(screen, count);
1309 else while(last && last > count) {
1310 rval = api_dline(screen, last--);
1317 EXTEND(screen, count)
1329 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1333 INITMESSAGE(screen);
1334 rval = api_lline(screen, &last);
1337 rval = api_dline(screen, last--);
1349 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1354 INITMESSAGE(screen);
1355 rval = api_lline(screen, &last);
1358 for (i = 1; i < items; ++i) {
1359 line = SvPV(ST(i), len);
1360 if ((rval = api_aline(screen, last++, line, len)))
1371 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1376 INITMESSAGE(screen);
1377 rval = api_lline(screen, &last);
1378 if (rval || last < 1)
1379 ST(0) = &PL_sv_undef;
1381 rval = api_gline(screen, last, &line, &len) ||
1382 api_dline(screen, last);
1384 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1394 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1399 INITMESSAGE(screen);
1400 rval = api_lline(screen, &last);
1401 if (rval || last < 1)
1402 ST(0) = &PL_sv_undef;
1404 rval = api_gline(screen, (db_recno_t)1, &line, &len) ||
1405 api_dline(screen, (db_recno_t)1);
1407 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1412 UNSHIFT(screen, ...)
1416 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1421 INITMESSAGE(screen);
1422 while (--items != 0) {
1423 line = SvPV(ST(items), len);
1424 if ((rval = api_iline(screen, (db_recno_t)1, line, len)))
1434 db_recno_t last, db_offset;
1435 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1436 int rval, length, common, len, i, offset;
1440 INITMESSAGE(screen);
1441 rval = api_lline(screen, &last);
1442 offset = items > 1 ? (int)SvIV(ST(1)) : 0;
1443 if (offset < 0) offset += last;
1446 croak("Invalid offset");
1448 length = items > 2 ? (int)SvIV(ST(2)) : last - offset;
1449 if (length > last - offset)
1450 length = last - offset;
1451 db_offset = offset + 1; /* 1 based */
1453 for (common = MIN(length, items - 3), i = 3; common > 0;
1454 --common, ++db_offset, --length, ++i) {
1455 rval |= api_gline(screen, db_offset, &line, &len);
1456 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1457 line = SvPV(ST(i), len);
1458 rval |= api_sline(screen, db_offset, line, len);
1460 for (; length; --length) {
1461 rval |= api_gline(screen, db_offset, &line, &len);
1462 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1463 rval |= api_dline(screen, db_offset);
1465 for (; i < items; ++i) {
1466 line = SvPV(ST(i), len);
1467 rval |= api_iline(screen, db_offset, line, len);
1471 MODULE = VI PACKAGE = VI::TAGQ
1474 Add(tagq, filename, search, msg)
1484 sp = (SCR *)SvIV((SV*)SvRV(tagq->sprv));
1486 croak("screen no longer exists");
1487 api_tagq_add(sp, tagq->tqp, filename, search, msg);
1497 sp = (SCR *)SvIV((SV*)SvRV(tagq->sprv));
1499 croak("screen no longer exists");
1500 api_tagq_push(sp, &tagq->tqp);
1504 # Can already be invalidated by push
1511 sp = (SCR *)SvIV((SV*)SvRV(tagq->sprv));
1513 api_tagq_free(sp, tagq->tqp);
1514 SvREFCNT_dec(tagq->sprv);