1 /* $NetBSD: screen.c,v 1.8 2014/01/26 21:43:45 christos Exp $ */
3 * Copyright (c) 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1993, 1994, 1995, 1996
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
13 #include <sys/cdefs.h>
16 static const char sccsid
[] = "Id: screen.c,v 10.22 2001/06/25 15:19:12 skimo Exp (Berkeley) Date: 2001/06/25 15:19:12 ";
19 __RCSID("$NetBSD: screen.c,v 1.8 2014/01/26 21:43:45 christos Exp $");
22 #include <sys/types.h>
23 #include <sys/queue.h>
26 #include <bitstring.h>
37 static int screen_end1(SCR
*, int);
40 * Do the default initialization of an SCR structure.
42 * PUBLIC: int screen_init __P((GS *, SCR *, SCR **));
45 screen_init(GS
*gp
, SCR
*orig
, SCR
**spp
)
51 CALLOC_RET(orig
, sp
, SCR
*, 1, sizeof(SCR
));
54 /* INITIALIZED AT SCREEN CREATE. */
58 sp
->gp
= gp
; /* All ref the GS structure. */
60 sp
->ccnt
= 2; /* Anything > 1 */
64 * sp->defscroll is initialized by the opts_init() code because
65 * we don't have the option information yet.
70 /* PARTIALLY OR COMPLETELY COPIED FROM PREVIOUS SCREEN. */
72 sp
->searchdir
= NOTSET
;
76 /* Alternate file name. */
77 if (orig
->alt_name
!= NULL
&&
78 (sp
->alt_name
= strdup(orig
->alt_name
)) == NULL
)
81 /* Last executed at buffer. */
82 if (F_ISSET(orig
, SC_AT_SET
)) {
84 sp
->at_lbuf
= orig
->at_lbuf
;
87 /* Retain searching/substitution information. */
88 sp
->searchdir
= orig
->searchdir
== NOTSET
? NOTSET
: FORWARD
;
89 if (orig
->re
!= NULL
&& (sp
->re
=
90 v_wstrdup(sp
, orig
->re
, orig
->re_len
)) == NULL
)
92 sp
->re_len
= orig
->re_len
;
93 if (orig
->subre
!= NULL
&& (sp
->subre
=
94 v_wstrdup(sp
, orig
->subre
, orig
->subre_len
)) == NULL
)
96 sp
->subre_len
= orig
->subre_len
;
97 if (orig
->repl
!= NULL
&& (sp
->repl
=
98 v_wstrdup(sp
, orig
->repl
, orig
->repl_len
)) == NULL
)
100 sp
->repl_len
= orig
->repl_len
;
101 if (orig
->newl_len
) {
102 len
= orig
->newl_len
* sizeof(size_t);
103 MALLOC(sp
, sp
->newl
, size_t *, len
);
104 if (sp
->newl
== NULL
) {
105 mem
: msgq(orig
, M_SYSERR
, NULL
);
108 sp
->newl_len
= orig
->newl_len
;
109 sp
->newl_cnt
= orig
->newl_cnt
;
110 memcpy(sp
->newl
, orig
->newl
, len
);
113 if (opts_copy(orig
, sp
))
116 F_SET(sp
, F_ISSET(orig
, SC_EX
| SC_VI
));
119 if (ex_screen_copy(orig
, sp
)) /* Ex. */
121 if (v_screen_copy(orig
, sp
)) /* Vi. */
123 sp
->cl_private
= 0; /* XXX */
124 conv_init(orig
, sp
); /* XXX */
129 err
: screen_fini(sp
);
134 screen_end1(SCR
*sp
, int init
)
138 /* If multiply referenced, just decrement the count and return. */
139 if (--sp
->refcnt
!= 0)
143 * Remove the screen from the displayed queue.
145 * If a created screen failed during initialization, it may not
146 * be linked into the chain.
148 * XXX screen_end can be called multiple times, abuse the tqe_prev pointer
149 * to signal wether the tailq node is on-list.
151 if (init
&& sp
->q
.tqe_prev
) {
152 TAILQ_REMOVE(&sp
->wp
->scrq
, sp
, q
);
153 sp
->q
.tqe_prev
= NULL
;
156 /* The screen is no longer real. */
157 F_CLR(sp
, SC_SCR_EX
| SC_SCR_VI
);
160 #ifdef HAVE_PERL_INTERP
161 if (perl_screen_end(sp
)) /* End perl. */
164 if (v_screen_end(sp
)) /* End vi. */
166 if (ex_screen_end(sp
)) /* End ex. */
169 /* Free file names. */
171 if (!F_ISSET(sp
, SC_ARGNOFREE
) && sp
->argv
!= NULL
) {
172 for (ap
= sp
->argv
; *ap
!= NULL
; ++ap
)
178 /* Free any text input. */
179 if (!TAILQ_EMPTY(&sp
->tiq
))
180 text_lfree(&sp
->tiq
);
182 /* Free alternate file name. */
183 if (sp
->alt_name
!= NULL
)
186 /* Free up search information. */
189 if (F_ISSET(sp
, SC_RE_SEARCH
))
191 if (sp
->subre
!= NULL
)
193 if (F_ISSET(sp
, SC_RE_SUBST
))
194 regfree(&sp
->subre_c
);
195 if (sp
->repl
!= NULL
)
197 if (sp
->newl
!= NULL
)
200 /* Free all the options */
203 /* Free the screen itself. */
211 * Release a screen, that has not been chained to the screen queues.
213 * PUBLIC: int screen_fini __P((SCR *));
218 return screen_end1(sp
, 0);
223 * Release a screen, that has been chained to the screen queues.
225 * PUBLIC: int screen_end __P((SCR *));
230 return screen_end1(sp
, 1);
234 * Return the next screen in the queue.
236 * PUBLIC: SCR *screen_next __P((SCR *));
245 /* Try the display queue, without returning the current screen. */
248 TAILQ_FOREACH(next
, &wp
->scrq
, q
)
254 /* Try the hidden queue; if found, move screen to the display queue. */
255 if ((next
= TAILQ_FIRST(&gp
->hq
)) != NULL
) {
256 TAILQ_REMOVE(&gp
->hq
, next
, q
);
257 TAILQ_INSERT_HEAD(&wp
->scrq
, next
, q
);