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