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.35 2000/07/06 19:32:00 skimo Exp $ (Berkeley) $Date: 2000/07/06 19:32:00 $";
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;
189 pp->interp = perl_clone(gp->perl_interp, 0);
190 if (1) { /* hack for bug fixed in perl-current (5.6.1) */
192 if (PL_scopestack_ix == 0) {
199 SvREADONLY_on(pp->svcurscr = perl_get_sv("curscr", TRUE));
200 SvREADONLY_on(pp->svstart = perl_get_sv("VI::StartLine", TRUE));
201 SvREADONLY_on(pp->svstop = perl_get_sv("VI::StopLine", TRUE));
202 SvREADONLY_on(pp->svid = perl_get_sv("VI::ScreenId", TRUE));
209 * Remove all refences to the screen to be destroyed
211 * PUBLIC: int perl_screen_end __P((SCR*));
214 perl_screen_end(scrp)
219 if (scrp->perl_private) {
220 sv_setiv((SV*) scrp->perl_private, 0);
229 croak("Perl command interrupted by SIGINT");
232 /* Create a new reference to an SV pointing to the SCR structure
233 * The perl_private part of the SCR structure points to the SV,
234 * so there can only be one such SV for a particular SCR structure.
235 * When the last reference has gone (DESTROY is called),
236 * perl_private is reset; When the screen goes away before
237 * all references are gone, the value of the SV is reset;
238 * any subsequent use of any of those reference will produce
239 * a warning. (see typemap)
248 if (!screen) return sv_setsv(rv, &PL_sv_undef), rv;
249 sv_upgrade(rv, SVt_RV);
250 if (!screen->perl_private) {
251 screen->perl_private = newSV(0);
252 sv_setiv(screen->perl_private, (IV) screen);
254 else SvREFCNT_inc(screen->perl_private);
255 SvRV(rv) = screen->perl_private;
257 return sv_bless(rv, gv_stashpv("VI", TRUE));
262 * perl_ex_perl -- :[line [,line]] perl [command]
263 * Run a command through the perl interpreter.
265 * PUBLIC: int perl_ex_perl __P((SCR*, CHAR_T *, size_t, db_recno_t, db_recno_t));
268 perl_ex_perl(scrp, cmdp, cmdlen, f_lno, t_lno)
272 db_recno_t f_lno, t_lno;
281 /* Initialize the interpreter. */
282 if (scrp->wp->perl_private == NULL && perl_init(scrp))
284 pp = scrp->wp->perl_private;
289 sv_setiv(pp->svstart, f_lno);
290 sv_setiv(pp->svstop, t_lno);
291 newVIrv(pp->svcurscr, scrp);
292 /* Backwards compatibility. */
293 newVIrv(pp->svid, scrp);
295 istat = signal(SIGINT, my_sighandler);
297 signal(SIGINT, istat);
299 SvREFCNT_dec(SvRV(pp->svcurscr));
300 SvROK_off(pp->svcurscr);
301 SvREFCNT_dec(SvRV(pp->svid));
304 err = SvPV(ERRSV, length);
308 err[length - 1] = '\0';
309 msgq(scrp, M_ERR, "perl: %s", err);
316 * replace a line with the contents of the perl variable $_
317 * lines are split at '\n's
318 * if $_ is undef, the line is deleted
319 * returns possibly adjusted linenumber
322 replace_line(scrp, line, t_lno, defsv)
324 db_recno_t line, *t_lno;
332 str = SvPV(defsv,len);
333 next = memchr(str, '\n', len);
334 api_sline(scrp, line, str, next ? (next - str) : len);
337 next = memchr(str = next, '\n', len);
338 api_iline(scrp, ++line, str, next ? (next - str) : len);
342 api_dline(scrp, line--);
349 * perl_ex_perldo -- :[line [,line]] perl [command]
350 * Run a set of lines through the perl interpreter.
352 * PUBLIC: int perl_ex_perldo __P((SCR*, CHAR_T *, size_t, db_recno_t, db_recno_t));
355 perl_ex_perldo(scrp, cmdp, cmdlen, f_lno, t_lno)
359 db_recno_t f_lno, t_lno;
371 /* Initialize the interpreter. */
372 if (scrp->wp->perl_private == NULL && perl_init(scrp))
374 pp = scrp->wp->perl_private;
379 newVIrv(pp->svcurscr, scrp);
380 /* Backwards compatibility. */
381 newVIrv(pp->svid, scrp);
383 if (!(command = malloc(length = strlen(cmdp) + sizeof("sub {}"))))
385 snprintf(command, length, "sub {%s}", cmdp);
390 cv = perl_eval_pv(command, FALSE);
393 str = SvPV(ERRSV,length);
397 for (i = f_lno; i <= t_lno && !api_gline(scrp, i, &str, &len); i++) {
398 sv_setpvn(DEFSV,str,len);
399 sv_setiv(pp->svstart, i);
400 sv_setiv(pp->svstop, i);
402 perl_call_sv(cv, G_SCALAR | G_EVAL);
403 str = SvPV(ERRSV, length);
407 i = replace_line(scrp, i, &t_lno, DEFSV);
413 SvREFCNT_dec(SvRV(pp->svcurscr));
414 SvROK_off(pp->svcurscr);
415 SvREFCNT_dec(SvRV(pp->svid));
421 err: str[length - 1] = '\0';
422 msgq(scrp, M_ERR, "perl: %s", str);
429 * Perl message routine so that error messages are processed in
433 msghandler(sp, mtype, msg, len)
439 /* Replace the trailing <newline> with an EOS. */
440 /* Let's do that later instead */
441 if (errmsg) free (errmsg);
442 errmsg = malloc(len + 1);
443 memcpy(errmsg, msg, len);
449 typedef SCR * VI__OPT;
450 typedef SCR * VI__MAP;
451 typedef SCR * VI__MARK;
452 typedef SCR * VI__LINE;
460 typedef perl_tagq * VI__TAGQ;
461 typedef perl_tagq * VI__TAGQ2;
463 MODULE = VI PACKAGE = VI
466 # Set the message line to text.
468 # Perl Command: VI::Msg
469 # Usage: VI::Msg screenId text
480 api_imessage(screen, text);
485 # Perl Command: VI::EndScreen
486 # Usage: VI::EndScreen screenId
493 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
498 rval = api_escreen(screen);
502 # Create a new screen. If a filename is specified then the screen
503 # is opened with that file.
505 # Perl Command: VI::NewScreen
506 # Usage: VI::NewScreen screenId [file]
517 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
523 file = (items == 1) ? NULL : (char *)SvPV(ST(1),PL_na);
525 rval = api_edit(screen, file, &nsp, ix);
528 RETVAL = ix ? nsp : screen;
534 # Return the screen id associated with file name.
536 # Perl Command: VI::FindScreen
537 # Usage: VI::FindScreen file
546 RETVAL = api_fscreen(0, file);
551 # XS_VI_GetFileName --
552 # Return the file name of the screen
554 # Perl Command: VI::GetFileName
555 # Usage: VI::GetFileName screenId
563 PUSHs(sv_2mortal(newSVpv(screen->frp->name, 0)));
566 # -- Append the string text after the line in lineNumber.
568 # Perl Command: VI::AppendLine
569 # Usage: VI::AppendLine screenId lineNumber text
572 AppendLine(screen, linenumber, text)
578 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
585 rval = api_aline(screen, linenumber, text, length);
591 # Perl Command: VI::DelLine
592 # Usage: VI::DelLine screenId lineNum
595 DelLine(screen, linenumber)
600 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
605 rval = api_dline(screen, (db_recno_t)linenumber);
611 # Perl Command: VI::GetLine
612 # Usage: VI::GetLine screenId lineNumber
615 GetLine(screen, linenumber)
621 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
628 rval = api_gline(screen, (db_recno_t)linenumber, &p, &len);
632 PUSHs(sv_2mortal(newSVpv(len ? (char *)p : "", len)));
635 # Set lineNumber to the text supplied.
637 # Perl Command: VI::SetLine
638 # Usage: VI::SetLine screenId lineNumber text
641 SetLine(screen, linenumber, text)
647 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
654 rval = api_sline(screen, linenumber, text, length);
658 # Insert the string text before the line in lineNumber.
660 # Perl Command: VI::InsertLine
661 # Usage: VI::InsertLine screenId lineNumber text
664 InsertLine(screen, linenumber, text)
670 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
677 rval = api_iline(screen, linenumber, text, length);
681 # Return the last line in the screen.
683 # Perl Command: VI::LastLine
684 # Usage: VI::LastLine screenId
692 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
697 rval = api_lline(screen, &last);
705 # Return the mark's cursor position as a list with two elements.
708 # Perl Command: VI::GetMark
709 # Usage: VI::GetMark screenId mark
712 GetMark(screen, mark)
718 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
723 rval = api_getmark(screen, (int)mark, &cursor);
727 PUSHs(sv_2mortal(newSViv(cursor.lno)));
728 PUSHs(sv_2mortal(newSViv(cursor.cno)));
731 # Set the mark to the line and column numbers supplied.
733 # Perl Command: VI::SetMark
734 # Usage: VI::SetMark screenId mark line column
737 SetMark(screen, mark, line, column)
745 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
752 rval = api_setmark(screen, (int)mark, &cursor);
756 # Return the current cursor position as a list with two elements.
759 # Perl Command: VI::GetCursor
760 # Usage: VI::GetCursor screenId
768 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
773 rval = api_getcursor(screen, &cursor);
777 PUSHs(sv_2mortal(newSViv(cursor.lno)));
778 PUSHs(sv_2mortal(newSViv(cursor.cno)));
781 # Set the cursor to the line and column numbers supplied.
783 # Perl Command: VI::SetCursor
784 # Usage: VI::SetCursor screenId line column
787 SetCursor(screen, line, column)
794 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
801 rval = api_setcursor(screen, &cursor);
805 # Change the current focus to screen.
807 # Perl Command: VI::SwitchScreen
808 # Usage: VI::SwitchScreen screenId screenId
811 SwitchScreen(screenFrom, screenTo)
816 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
820 INITMESSAGE(screenFrom);
821 rval = api_swscreen(screenFrom, screenTo);
822 ENDMESSAGE(screenFrom);
825 # Associate a key with a perl procedure.
827 # Perl Command: VI::MapKey
828 # Usage: VI::MapKey screenId key perlproc
831 MapKey(screen, key, perlproc)
837 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
846 svc = sv_2mortal(newSVpv(":perl ", 6));
847 sv_catsv(svc, perlproc);
848 svn = sv_2mortal(newSVpv("
\r", 1));
850 command = SvPV(svc, length);
851 rval = api_map(screen, key, command, length);
857 # Perl Command: VI::UnmapKey
858 # Usage: VI::UnmmapKey screenId key
861 UnmapKey(screen, key)
866 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
871 rval = api_unmap(screen, key);
877 # Perl Command: VI::SetOpt
878 # Usage: VI::SetOpt screenId setting
881 SetOpt(screen, setting)
886 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
892 svc = sv_2mortal(newSVpv(":set ", 5));
893 sv_catpv(svc, setting);
894 rval = api_run_str(screen, SvPV(svc, PL_na));
898 # Return the value of an option.
900 # Perl Command: VI::GetOpt
901 # Usage: VI::GetOpt screenId option
904 GetOpt(screen, option)
909 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
915 rval = api_opts_get(screen, option, &value, NULL);
919 PUSHs(sv_2mortal(newSVpv(value, 0)));
923 # Run the ex command cmd.
925 # Perl Command: VI::Run
926 # Usage: VI::Run screenId cmd
934 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
939 rval = api_run_str(screen, command);
950 if (sv_isa(screensv, "VI")) {
951 IV tmp = SvIV((SV*)SvRV(screensv));
952 screen = (SCR *) tmp;
955 croak("screen is not of type VI");
958 screen->perl_private = 0;
965 sv_catpv(ERRSV,warning);
967 #define TIED(kind,package) \
968 sv_magic((SV *) (var = \
969 (##kind##V *)sv_2mortal((SV *)new##kind##V())), \
970 sv_setref_pv(sv_newmortal(), package, \
971 newVIrv(newSV(0), screen)),\
973 RETVAL = newRV((SV *)var)
1024 if ((ptag = malloc(sizeof(perl_tagq))) == NULL)
1027 ptag->sprv = newVIrv(newSV(0), screen);
1028 ptag->tqp = api_tagq_new(screen, tag);
1029 if (ptag->tqp != NULL) {
1031 PUSHs(sv_2mortal(sv_setref_pv(newSV(0), "VI::TAGQ", ptag)));
1034 ST(0) = &PL_sv_undef;
1038 MODULE = VI PACKAGE = VI::OPT
1045 # typemap did all the checking
1046 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1054 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1060 INITMESSAGE(screen);
1061 rval = api_opts_get(screen, key, &value, &boolvalue);
1064 PUSHs(sv_2mortal((boolvalue == -1) ? newSVpv(value, 0)
1065 : newSViv(boolvalue)));
1067 } else ST(0) = &PL_sv_undef;
1072 STORE(screen, key, value)
1078 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1082 INITMESSAGE(screen);
1083 rval = api_opts_set(screen, key, SvPV(value, PL_na), SvIV(value),
1087 MODULE = VI PACKAGE = VI::MAP
1094 # typemap did all the checking
1095 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1098 STORE(screen, key, perlproc)
1104 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1112 INITMESSAGE(screen);
1113 svc = sv_2mortal(newSVpv(":perl ", 6));
1114 sv_catsv(svc, perlproc);
1115 svn = sv_2mortal(newSVpv("
\r", 1));
1117 command = SvPV(svc, length);
1118 rval = api_map(screen, key, command, length);
1127 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1131 INITMESSAGE(screen);
1132 rval = api_unmap(screen, key);
1135 MODULE = VI PACKAGE = VI::MARK
1142 # typemap did all the checking
1143 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1151 struct _mark cursor;
1152 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1156 INITMESSAGE(screen);
1157 rval = api_getmark(screen, (int)mark, &cursor);
1160 av_push(RETVAL, newSViv(cursor.lno));
1161 av_push(RETVAL, newSViv(cursor.cno));
1167 STORE(screen, mark, pos)
1173 struct _mark cursor;
1174 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1178 if (av_len(pos) < 1)
1179 croak("cursor position needs 2 elements");
1180 INITMESSAGE(screen);
1181 cursor.lno = SvIV(*av_fetch(pos, 0, 0));
1182 cursor.cno = SvIV(*av_fetch(pos, 1, 0));
1183 rval = api_setmark(screen, (int)mark, &cursor);
1187 FIRSTKEY(screen, ...)
1197 char key[] = {0, 0};
1202 *key = *(char *)SvPV(ST(1),PL_na);
1204 if (api_nextmark(screen, next, key) != 1) {
1206 PUSHs(sv_2mortal(newSVpv(key, 1)));
1207 } else ST(0) = &PL_sv_undef;
1209 MODULE = VI PACKAGE = VI::LINE
1216 # typemap did all the checking
1217 SvREFCNT_dec((SV*)SvIV((SV*)SvRV(ST(0))));
1219 # similar to SetLine
1222 STORE(screen, linenumber, text)
1228 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1234 ++linenumber; /* vi 1 based ; perl 0 based */
1235 SvPV(ST(2), length);
1236 INITMESSAGE(screen);
1237 rval = api_lline(screen, &last);
1239 if (linenumber > last)
1240 rval = api_extend(screen, linenumber);
1242 rval = api_sline(screen, linenumber, text, length);
1246 # similar to GetLine
1249 FETCH(screen, linenumber)
1255 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1261 ++linenumber; /* vi 1 based ; perl 0 based */
1262 INITMESSAGE(screen);
1263 rval = api_gline(screen, (db_recno_t)linenumber, &p, &len);
1267 PUSHs(sv_2mortal(newSVpv(len ? (char*)p : "", len)));
1269 # similar to LastLine
1277 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1281 INITMESSAGE(screen);
1282 rval = api_lline(screen, &last);
1290 STORESIZE(screen, count)
1296 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1300 INITMESSAGE(screen);
1301 rval = api_lline(screen, &last);
1304 rval = api_extend(screen, count);
1305 else while(last && last > count) {
1306 rval = api_dline(screen, last--);
1313 EXTEND(screen, count)
1325 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1329 INITMESSAGE(screen);
1330 rval = api_lline(screen, &last);
1333 rval = api_dline(screen, last--);
1345 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1350 INITMESSAGE(screen);
1351 rval = api_lline(screen, &last);
1354 for (i = 1; i < items; ++i) {
1355 line = SvPV(ST(i), len);
1356 if ((rval = api_aline(screen, last++, line, len)))
1367 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1372 INITMESSAGE(screen);
1373 rval = api_lline(screen, &last);
1374 if (rval || last < 1)
1375 ST(0) = &PL_sv_undef;
1377 rval = api_gline(screen, last, &line, &len) ||
1378 api_dline(screen, last);
1380 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1390 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1395 INITMESSAGE(screen);
1396 rval = api_lline(screen, &last);
1397 if (rval || last < 1)
1398 ST(0) = &PL_sv_undef;
1400 rval = api_gline(screen, (db_recno_t)1, &line, &len) ||
1401 api_dline(screen, (db_recno_t)1);
1403 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1408 UNSHIFT(screen, ...)
1412 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1417 INITMESSAGE(screen);
1418 while (--items != 0) {
1419 line = SvPV(ST(items), len);
1420 if ((rval = api_iline(screen, (db_recno_t)1, line, len)))
1430 db_recno_t last, db_offset;
1431 void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
1432 int rval, length, common, len, i, offset;
1436 INITMESSAGE(screen);
1437 rval = api_lline(screen, &last);
1438 offset = items > 1 ? (int)SvIV(ST(1)) : 0;
1439 if (offset < 0) offset += last;
1442 croak("Invalid offset");
1444 length = items > 2 ? (int)SvIV(ST(2)) : last - offset;
1445 if (length > last - offset)
1446 length = last - offset;
1447 db_offset = offset + 1; /* 1 based */
1449 for (common = MIN(length, items - 3), i = 3; common > 0;
1450 --common, ++db_offset, --length, ++i) {
1451 rval |= api_gline(screen, db_offset, &line, &len);
1452 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1453 line = SvPV(ST(i), len);
1454 rval |= api_sline(screen, db_offset, line, len);
1456 for (; length; --length) {
1457 rval |= api_gline(screen, db_offset, &line, &len);
1458 PUSHs(sv_2mortal(newSVpv(len ? (char *)line : "", len)));
1459 rval |= api_dline(screen, db_offset);
1461 for (; i < items; ++i) {
1462 line = SvPV(ST(i), len);
1463 rval |= api_iline(screen, db_offset, line, len);
1467 MODULE = VI PACKAGE = VI::TAGQ
1470 Add(tagq, filename, search, msg)
1480 sp = (SCR *)SvIV((SV*)SvRV(tagq->sprv));
1482 croak("screen no longer exists");
1483 api_tagq_add(sp, tagq->tqp, filename, search, msg);
1493 sp = (SCR *)SvIV((SV*)SvRV(tagq->sprv));
1495 croak("screen no longer exists");
1496 api_tagq_push(sp, &tagq->tqp);
1500 # Can already be invalidated by push
1507 sp = (SCR *)SvIV((SV*)SvRV(tagq->sprv));
1509 api_tagq_free(sp, tagq->tqp);
1510 SvREFCNT_dec(tagq->sprv);