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