xref: /minix/external/bsd/nvi/dist/common/gs.c (revision 84d9c625)
1*84d9c625SLionel Sambuc /*	$NetBSD: gs.c,v 1.4 2013/12/01 02:34:54 christos Exp $ */
2*84d9c625SLionel Sambuc /*-
3*84d9c625SLionel Sambuc  * Copyright (c) 2000
4*84d9c625SLionel Sambuc  *	Sven Verdoolaege.  All rights reserved.
5*84d9c625SLionel Sambuc  *
6*84d9c625SLionel Sambuc  * See the LICENSE file for redistribution information.
7*84d9c625SLionel Sambuc  */
8*84d9c625SLionel Sambuc 
9*84d9c625SLionel Sambuc #include "config.h"
10*84d9c625SLionel Sambuc 
11*84d9c625SLionel Sambuc #include <sys/types.h>
12*84d9c625SLionel Sambuc #include <sys/queue.h>
13*84d9c625SLionel Sambuc 
14*84d9c625SLionel Sambuc #include <bitstring.h>
15*84d9c625SLionel Sambuc #include <ctype.h>
16*84d9c625SLionel Sambuc #include <errno.h>
17*84d9c625SLionel Sambuc #include <stdio.h>
18*84d9c625SLionel Sambuc #include <stdlib.h>
19*84d9c625SLionel Sambuc #include <string.h>
20*84d9c625SLionel Sambuc #include <unistd.h>
21*84d9c625SLionel Sambuc 
22*84d9c625SLionel Sambuc #include "../common/common.h"
23*84d9c625SLionel Sambuc #ifdef USE_PERL_INTERP
24*84d9c625SLionel Sambuc #include "perl_api_extern.h"
25*84d9c625SLionel Sambuc #endif
26*84d9c625SLionel Sambuc 
27*84d9c625SLionel Sambuc __dead static void	   perr __P((char *, char *));
28*84d9c625SLionel Sambuc 
29*84d9c625SLionel Sambuc /*
30*84d9c625SLionel Sambuc  * gs_init --
31*84d9c625SLionel Sambuc  *	Create and partially initialize the GS structure.
32*84d9c625SLionel Sambuc  * PUBLIC: GS * gs_init __P((char*));
33*84d9c625SLionel Sambuc  */
34*84d9c625SLionel Sambuc GS *
gs_init(char * name)35*84d9c625SLionel Sambuc gs_init(char *name)
36*84d9c625SLionel Sambuc {
37*84d9c625SLionel Sambuc 	GS *gp;
38*84d9c625SLionel Sambuc 	char *p;
39*84d9c625SLionel Sambuc 
40*84d9c625SLionel Sambuc 	/* Figure out what our name is. */
41*84d9c625SLionel Sambuc 	if ((p = strrchr(name, '/')) != NULL)
42*84d9c625SLionel Sambuc 		name = p + 1;
43*84d9c625SLionel Sambuc 
44*84d9c625SLionel Sambuc 	/* Allocate the global structure. */
45*84d9c625SLionel Sambuc 	CALLOC_NOMSG(NULL, gp, GS *, 1, sizeof(GS));
46*84d9c625SLionel Sambuc 	if (gp == NULL)
47*84d9c625SLionel Sambuc 		perr(name, NULL);
48*84d9c625SLionel Sambuc 
49*84d9c625SLionel Sambuc 	gp->progname = name;
50*84d9c625SLionel Sambuc 
51*84d9c625SLionel Sambuc 	/* Common global structure initialization. */
52*84d9c625SLionel Sambuc 	/* others will need to be copied from main.c */
53*84d9c625SLionel Sambuc 	TAILQ_INIT(&gp->dq);
54*84d9c625SLionel Sambuc 
55*84d9c625SLionel Sambuc 	TAILQ_INIT(&gp->hq);
56*84d9c625SLionel Sambuc 	gp->noprint = DEFAULT_NOPRINT;
57*84d9c625SLionel Sambuc 
58*84d9c625SLionel Sambuc 	/* Structures shared by screens so stored in the GS structure. */
59*84d9c625SLionel Sambuc 	TAILQ_INIT(&gp->frefq);
60*84d9c625SLionel Sambuc 	TAILQ_INIT(&gp->exfq);
61*84d9c625SLionel Sambuc 	LIST_INIT(&gp->seqq);
62*84d9c625SLionel Sambuc 
63*84d9c625SLionel Sambuc 	thread_init(gp);
64*84d9c625SLionel Sambuc 
65*84d9c625SLionel Sambuc 	return (gp);
66*84d9c625SLionel Sambuc }
67*84d9c625SLionel Sambuc 
68*84d9c625SLionel Sambuc /*
69*84d9c625SLionel Sambuc  * gs_new_win
70*84d9c625SLionel Sambuc  *	Create new window
71*84d9c625SLionel Sambuc  * PUBLIC: WIN * gs_new_win __P((GS *gp));
72*84d9c625SLionel Sambuc  */
73*84d9c625SLionel Sambuc 
74*84d9c625SLionel Sambuc WIN *
gs_new_win(GS * gp)75*84d9c625SLionel Sambuc gs_new_win(GS *gp)
76*84d9c625SLionel Sambuc {
77*84d9c625SLionel Sambuc 	WIN *wp;
78*84d9c625SLionel Sambuc 
79*84d9c625SLionel Sambuc 	CALLOC_NOMSG(NULL, wp, WIN *, 1, sizeof(*wp));
80*84d9c625SLionel Sambuc 	if (!wp)
81*84d9c625SLionel Sambuc 		return NULL;
82*84d9c625SLionel Sambuc 
83*84d9c625SLionel Sambuc 	/* Common global structure initialization. */
84*84d9c625SLionel Sambuc 	LIST_INIT(&wp->ecq);
85*84d9c625SLionel Sambuc 	LIST_INSERT_HEAD(&wp->ecq, &wp->excmd, q);
86*84d9c625SLionel Sambuc 
87*84d9c625SLionel Sambuc 	TAILQ_INSERT_TAIL(&gp->dq, wp, q);
88*84d9c625SLionel Sambuc 	TAILQ_INIT(&wp->scrq);
89*84d9c625SLionel Sambuc 
90*84d9c625SLionel Sambuc 	TAILQ_INIT(&wp->dcb_store.textq);
91*84d9c625SLionel Sambuc 	LIST_INIT(&wp->cutq);
92*84d9c625SLionel Sambuc 
93*84d9c625SLionel Sambuc 	wp->gp = gp;
94*84d9c625SLionel Sambuc 
95*84d9c625SLionel Sambuc 	return wp;
96*84d9c625SLionel Sambuc }
97*84d9c625SLionel Sambuc 
98*84d9c625SLionel Sambuc /*
99*84d9c625SLionel Sambuc  * win_end --
100*84d9c625SLionel Sambuc  *	Remove window.
101*84d9c625SLionel Sambuc  *
102*84d9c625SLionel Sambuc  * PUBLIC: int win_end __P((WIN *wp));
103*84d9c625SLionel Sambuc  */
104*84d9c625SLionel Sambuc int
win_end(WIN * wp)105*84d9c625SLionel Sambuc win_end(WIN *wp)
106*84d9c625SLionel Sambuc {
107*84d9c625SLionel Sambuc 	SCR *sp;
108*84d9c625SLionel Sambuc 
109*84d9c625SLionel Sambuc 	TAILQ_REMOVE(&wp->gp->dq, wp, q);
110*84d9c625SLionel Sambuc 
111*84d9c625SLionel Sambuc 	if (wp->ccl_sp != NULL) {
112*84d9c625SLionel Sambuc 		(void)file_end(wp->ccl_sp, NULL, 1);
113*84d9c625SLionel Sambuc 		(void)screen_end(wp->ccl_sp);
114*84d9c625SLionel Sambuc 	}
115*84d9c625SLionel Sambuc 	while ((sp = TAILQ_FIRST(&wp->scrq)) != NULL)
116*84d9c625SLionel Sambuc 		(void)screen_end(sp);
117*84d9c625SLionel Sambuc 
118*84d9c625SLionel Sambuc 	/* Free key input queue. */
119*84d9c625SLionel Sambuc 	if (wp->i_event != NULL)
120*84d9c625SLionel Sambuc 		free(wp->i_event);
121*84d9c625SLionel Sambuc 
122*84d9c625SLionel Sambuc 	/* Free cut buffers. */
123*84d9c625SLionel Sambuc 	cut_close(wp);
124*84d9c625SLionel Sambuc 
125*84d9c625SLionel Sambuc 	/* Free default buffer storage. */
126*84d9c625SLionel Sambuc 	(void)text_lfree(&wp->dcb_store.textq);
127*84d9c625SLionel Sambuc 
128*84d9c625SLionel Sambuc #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
129*84d9c625SLionel Sambuc 	/* Free any temporary space. */
130*84d9c625SLionel Sambuc 	if (wp->tmp_bp != NULL)
131*84d9c625SLionel Sambuc 		free(wp->tmp_bp);
132*84d9c625SLionel Sambuc #endif
133*84d9c625SLionel Sambuc 
134*84d9c625SLionel Sambuc 	return 0;
135*84d9c625SLionel Sambuc }
136*84d9c625SLionel Sambuc 
137*84d9c625SLionel Sambuc /*
138*84d9c625SLionel Sambuc  * gs_end --
139*84d9c625SLionel Sambuc  *	End the program, discarding screens and most of the global area.
140*84d9c625SLionel Sambuc  *
141*84d9c625SLionel Sambuc  * PUBLIC: void gs_end __P((GS *));
142*84d9c625SLionel Sambuc  */
143*84d9c625SLionel Sambuc void
gs_end(GS * gp)144*84d9c625SLionel Sambuc gs_end(GS *gp)
145*84d9c625SLionel Sambuc {
146*84d9c625SLionel Sambuc 	MSGS *mp;
147*84d9c625SLionel Sambuc 	SCR *sp;
148*84d9c625SLionel Sambuc 	WIN *wp;
149*84d9c625SLionel Sambuc 
150*84d9c625SLionel Sambuc 	/* If there are any remaining screens, kill them off. */
151*84d9c625SLionel Sambuc 	while ((wp = TAILQ_FIRST(&gp->dq)) != NULL)
152*84d9c625SLionel Sambuc 		(void)win_end(wp);
153*84d9c625SLionel Sambuc 	while ((sp = TAILQ_FIRST(&gp->hq)) != NULL)
154*84d9c625SLionel Sambuc 		(void)screen_end(sp);
155*84d9c625SLionel Sambuc 
156*84d9c625SLionel Sambuc #ifdef HAVE_PERL_INTERP
157*84d9c625SLionel Sambuc 	perl_end(gp);
158*84d9c625SLionel Sambuc #endif
159*84d9c625SLionel Sambuc 
160*84d9c625SLionel Sambuc #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
161*84d9c625SLionel Sambuc 	{ FREF *frp;
162*84d9c625SLionel Sambuc 		/* Free FREF's. */
163*84d9c625SLionel Sambuc 		while ((frp = TAILQ_FIRST(&gp->frefq)) != NULL) {
164*84d9c625SLionel Sambuc 			TAILQ_REMOVE(&gp->frefq, frp, q);
165*84d9c625SLionel Sambuc 			if (frp->name != NULL)
166*84d9c625SLionel Sambuc 				free(frp->name);
167*84d9c625SLionel Sambuc 			if (frp->tname != NULL)
168*84d9c625SLionel Sambuc 				free(frp->tname);
169*84d9c625SLionel Sambuc 			free(frp);
170*84d9c625SLionel Sambuc 		}
171*84d9c625SLionel Sambuc 	}
172*84d9c625SLionel Sambuc 
173*84d9c625SLionel Sambuc 	/* Free map sequences. */
174*84d9c625SLionel Sambuc 	seq_close(gp);
175*84d9c625SLionel Sambuc 
176*84d9c625SLionel Sambuc 	/* Close message catalogs. */
177*84d9c625SLionel Sambuc 	msg_close(gp);
178*84d9c625SLionel Sambuc #endif
179*84d9c625SLionel Sambuc 
180*84d9c625SLionel Sambuc 	/* Ring the bell if scheduled. */
181*84d9c625SLionel Sambuc 	if (F_ISSET(gp, G_BELLSCHED))
182*84d9c625SLionel Sambuc 		(void)fprintf(stderr, "\07");		/* \a */
183*84d9c625SLionel Sambuc 
184*84d9c625SLionel Sambuc 	/*
185*84d9c625SLionel Sambuc 	 * Flush any remaining messages.  If a message is here, it's almost
186*84d9c625SLionel Sambuc 	 * certainly the message about the event that killed us (although
187*84d9c625SLionel Sambuc 	 * it's possible that the user is sourcing a file that exits from the
188*84d9c625SLionel Sambuc 	 * editor).
189*84d9c625SLionel Sambuc 	 */
190*84d9c625SLionel Sambuc 	while ((mp = LIST_FIRST(&gp->msgq)) != NULL) {
191*84d9c625SLionel Sambuc 		(void)fprintf(stderr, "%s%.*s",
192*84d9c625SLionel Sambuc 		    mp->mtype == M_ERR ? "ex/vi: " : "", (int)mp->len, mp->buf);
193*84d9c625SLionel Sambuc 		LIST_REMOVE(mp, q);
194*84d9c625SLionel Sambuc #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
195*84d9c625SLionel Sambuc 		free(mp->buf);
196*84d9c625SLionel Sambuc 		free(mp);
197*84d9c625SLionel Sambuc #endif
198*84d9c625SLionel Sambuc 	}
199*84d9c625SLionel Sambuc 
200*84d9c625SLionel Sambuc #if defined(TRACE)
201*84d9c625SLionel Sambuc 	/* Close tracing file descriptor. */
202*84d9c625SLionel Sambuc 	vtrace_end();
203*84d9c625SLionel Sambuc #endif
204*84d9c625SLionel Sambuc }
205*84d9c625SLionel Sambuc 
206*84d9c625SLionel Sambuc 
207*84d9c625SLionel Sambuc /*
208*84d9c625SLionel Sambuc  * perr --
209*84d9c625SLionel Sambuc  *	Print system error.
210*84d9c625SLionel Sambuc  */
211*84d9c625SLionel Sambuc static void
perr(char * name,char * msg)212*84d9c625SLionel Sambuc perr(char *name, char *msg)
213*84d9c625SLionel Sambuc {
214*84d9c625SLionel Sambuc 	(void)fprintf(stderr, "%s:", name);
215*84d9c625SLionel Sambuc 	if (msg != NULL)
216*84d9c625SLionel Sambuc 		(void)fprintf(stderr, "%s:", msg);
217*84d9c625SLionel Sambuc 	(void)fprintf(stderr, "%s\n", strerror(errno));
218*84d9c625SLionel Sambuc 	exit(1);
219*84d9c625SLionel Sambuc }
220