GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/vi/build/../common/screen.c Lines: 0 85 0.0 %
Date: 2017-11-13 Branches: 0 74 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: screen.c,v 1.14 2017/04/18 01:45:35 deraadt Exp $	*/
2
3
/*-
4
 * Copyright (c) 1993, 1994
5
 *	The Regents of the University of California.  All rights reserved.
6
 * Copyright (c) 1993, 1994, 1995, 1996
7
 *	Keith Bostic.  All rights reserved.
8
 *
9
 * See the LICENSE file for redistribution information.
10
 */
11
12
#include "config.h"
13
14
#include <sys/types.h>
15
#include <sys/queue.h>
16
#include <sys/time.h>
17
18
#include <bitstring.h>
19
#include <errno.h>
20
#include <limits.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <unistd.h>
25
26
#include "common.h"
27
#include "../vi/vi.h"
28
29
/*
30
 * screen_init --
31
 *	Do the default initialization of an SCR structure.
32
 *
33
 * PUBLIC: int screen_init(GS *, SCR *, SCR **);
34
 */
35
int
36
screen_init(GS *gp, SCR *orig, SCR **spp)
37
{
38
	SCR *sp;
39
	size_t len;
40
41
	*spp = NULL;
42
	CALLOC_RET(orig, sp, 1, sizeof(SCR));
43
	*spp = sp;
44
45
/* INITIALIZED AT SCREEN CREATE. */
46
	sp->id = ++gp->id;
47
	sp->refcnt = 1;
48
49
	sp->gp = gp;				/* All ref the GS structure. */
50
51
	sp->ccnt = 2;				/* Anything > 1 */
52
53
	/*
54
	 * XXX
55
	 * sp->defscroll is initialized by the opts_init() code because
56
	 * we don't have the option information yet.
57
	 */
58
59
	TAILQ_INIT(&sp->tiq);
60
61
/* PARTIALLY OR COMPLETELY COPIED FROM PREVIOUS SCREEN. */
62
	if (orig == NULL) {
63
		sp->searchdir = NOTSET;
64
	} else {
65
		/* Alternate file name. */
66
		if (orig->alt_name != NULL &&
67
		    (sp->alt_name = strdup(orig->alt_name)) == NULL)
68
			goto mem;
69
70
		/* Last executed at buffer. */
71
		if (F_ISSET(orig, SC_AT_SET)) {
72
			F_SET(sp, SC_AT_SET);
73
			sp->at_lbuf = orig->at_lbuf;
74
		}
75
76
		/* Retain searching/substitution information. */
77
		sp->searchdir = orig->searchdir == NOTSET ? NOTSET : FORWARD;
78
		if (orig->re != NULL && (sp->re =
79
		    v_strdup(sp, orig->re, orig->re_len)) == NULL)
80
			goto mem;
81
		sp->re_len = orig->re_len;
82
		if (orig->subre != NULL && (sp->subre =
83
		    v_strdup(sp, orig->subre, orig->subre_len)) == NULL)
84
			goto mem;
85
		sp->subre_len = orig->subre_len;
86
		if (orig->repl != NULL && (sp->repl =
87
		    v_strdup(sp, orig->repl, orig->repl_len)) == NULL)
88
			goto mem;
89
		sp->repl_len = orig->repl_len;
90
		if (orig->newl_len) {
91
			len = orig->newl_len * sizeof(size_t);
92
			MALLOC(sp, sp->newl, len);
93
			if (sp->newl == NULL) {
94
mem:				msgq(orig, M_SYSERR, NULL);
95
				goto err;
96
			}
97
			sp->newl_len = orig->newl_len;
98
			sp->newl_cnt = orig->newl_cnt;
99
			memcpy(sp->newl, orig->newl, len);
100
		}
101
102
		if (opts_copy(orig, sp))
103
			goto err;
104
105
		F_SET(sp, F_ISSET(orig, SC_EX | SC_VI));
106
	}
107
108
	if (ex_screen_copy(orig, sp))		/* Ex. */
109
		goto err;
110
	if (v_screen_copy(orig, sp))		/* Vi. */
111
		goto err;
112
113
	*spp = sp;
114
	return (0);
115
116
err:	screen_end(sp);
117
	return (1);
118
}
119
120
/*
121
 * screen_end --
122
 *	Release a screen, no matter what had (and had not) been
123
 *	initialized.
124
 *
125
 * PUBLIC: int screen_end(SCR *);
126
 */
127
int
128
screen_end(SCR *sp)
129
{
130
	int rval;
131
	SCR *tsp;
132
133
	/* If multiply referenced, just decrement the count and return. */
134
	 if (--sp->refcnt != 0)
135
		 return (0);
136
137
	/*
138
	 * Remove the screen from the displayed and hidden queues.
139
	 *
140
	 * If a created screen failed during initialization, it may not
141
	 * be linked into a queue.
142
	 */
143
	TAILQ_FOREACH(tsp, &sp->gp->dq, q) {
144
		if (tsp == sp) {
145
			TAILQ_REMOVE(&sp->gp->dq, sp, q);
146
			break;
147
		}
148
	}
149
	TAILQ_FOREACH(tsp, &sp->gp->hq, q) {
150
		if (tsp == sp) {
151
			TAILQ_REMOVE(&sp->gp->hq, sp, q);
152
			break;
153
		}
154
	}
155
156
	/* The screen is no longer real. */
157
	F_CLR(sp, SC_SCR_EX | SC_SCR_VI);
158
159
	rval = 0;
160
	if (v_screen_end(sp))			/* End vi. */
161
		rval = 1;
162
	if (ex_screen_end(sp))			/* End ex. */
163
		rval = 1;
164
165
	/* Free file names. */
166
	{ char **ap;
167
		if (!F_ISSET(sp, SC_ARGNOFREE) && sp->argv != NULL) {
168
			for (ap = sp->argv; *ap != NULL; ++ap)
169
				free(*ap);
170
			free(sp->argv);
171
		}
172
	}
173
174
	/* Free any text input. */
175
	if (TAILQ_FIRST(&sp->tiq) != NULL)
176
		text_lfree(&sp->tiq);
177
178
	/* Free alternate file name. */
179
	free(sp->alt_name);
180
181
	/* Free up search information. */
182
	free(sp->re);
183
	if (F_ISSET(sp, SC_RE_SEARCH))
184
		regfree(&sp->re_c);
185
	free(sp->subre);
186
	if (F_ISSET(sp, SC_RE_SUBST))
187
		regfree(&sp->subre_c);
188
	free(sp->repl);
189
	free(sp->newl);
190
191
	/* Free all the options */
192
	opts_free(sp);
193
194
	/* Free the screen itself. */
195
	free(sp);
196
197
	return (rval);
198
}
199
200
/*
201
 * screen_next --
202
 *	Return the next screen in the queue.
203
 *
204
 * PUBLIC: SCR *screen_next(SCR *);
205
 */
206
SCR *
207
screen_next(SCR *sp)
208
{
209
	GS *gp;
210
	SCR *next;
211
212
	/* Try the display queue, without returning the current screen. */
213
	gp = sp->gp;
214
	TAILQ_FOREACH(next, &gp->dq, q)
215
		if (next != sp)
216
			return (next);
217
218
	/* Try the hidden queue; if found, move screen to the display queue. */
219
	if (!TAILQ_EMPTY(&gp->hq)) {
220
		next = TAILQ_FIRST(&gp->hq);
221
		TAILQ_REMOVE(&gp->hq, next, q);
222
		TAILQ_INSERT_HEAD(&gp->dq, next, q);
223
		return (next);
224
	}
225
	return (NULL);
226
}