Bug Summary

File:src/usr.bin/vi/build/../vi/vs_split.c
Warning:line 465, column 2
Value stored to 'gp' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name vs_split.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/vi/build/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.bin/vi/build -I /usr/src/usr.bin/vi/build/../include -I . -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/vi/build/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/vi/build/../vi/vs_split.c
1/* $OpenBSD: vs_split.c,v 1.16 2016/05/27 09:18:12 martijn 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(*__errno()).h>
20#include <limits.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "../common/common.h"
26#include "vi.h"
27
28static SCR *vs_getbg(SCR *, char *);
29
30/*
31 * vs_split --
32 * Create a new screen.
33 *
34 * PUBLIC: int vs_split(SCR *, SCR *, int);
35 */
36int
37vs_split(SCR *sp, SCR *new, int ccl)
38{
39 GS *gp;
40 SMAP *smp;
41 size_t half;
42 int issmallscreen, splitup;
43
44 gp = sp->gp;
45
46 /* Check to see if it's possible. */
47 /* XXX: The IS_ONELINE fix will change this, too. */
48 if (sp->rows < 4) {
49 msgq(sp, M_ERR,
50 "Screen must be larger than %d lines to split", 4 - 1);
51 return (1);
52 }
53
54 /* Wait for any messages in the screen. */
55 vs_resolve(sp, NULL((void *)0), 1);
56
57 half = sp->rows / 2;
58 if (ccl && half > 6)
59 half = 6;
60
61 /* Get a new screen map. */
62 CALLOC(sp, _HMAP(new), SIZE_HMAP(sp), sizeof(SMAP)){ if ((((((VI_PRIVATE *)((new)->vi_private))->h_smap)) =
calloc(((((VI_PRIVATE *)((sp)->vi_private))->srows + 1
)), (sizeof(SMAP)))) == ((void *)0)) msgq((sp), M_SYSERR, ((void
*)0)); }
;
63 if (_HMAP(new)(((VI_PRIVATE *)((new)->vi_private))->h_smap) == NULL((void *)0))
64 return (1);
65 _HMAP(new)(((VI_PRIVATE *)((new)->vi_private))->h_smap)->lno = sp->lno;
66 _HMAP(new)(((VI_PRIVATE *)((new)->vi_private))->h_smap)->coff = 0;
67 _HMAP(new)(((VI_PRIVATE *)((new)->vi_private))->h_smap)->soff = 1;
68
69 /*
70 * Small screens: see vs_refresh.c section 6a. Set a flag so
71 * we know to fix the screen up later.
72 */
73 issmallscreen = IS_SMALL(sp)((sp)->t_minrows != (sp)->t_maxrows);
74
75 /* The columns in the screen don't change. */
76 new->cols = sp->cols;
77
78 /*
79 * Split the screen, and link the screens together. If creating a
80 * screen to edit the colon command line or the cursor is in the top
81 * half of the current screen, the new screen goes under the current
82 * screen. Else, it goes above the current screen.
83 *
84 * Recalculate current cursor position based on sp->lno, we're called
85 * with the cursor on the colon command line. Then split the screen
86 * in half and update the shared information.
87 */
88 splitup =
89 !ccl && (vs_sm_cursor(sp, &smp) ? 0 : (smp - HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)) + 1) >= half;
90 if (splitup) { /* Old is bottom half. */
91 new->rows = sp->rows - half; /* New. */
92 new->woff = sp->woff;
93 sp->rows = half; /* Old. */
94 sp->woff += new->rows;
95 /* Link in before old. */
96 TAILQ_INSERT_BEFORE(sp, new, q)do { (new)->q.tqe_prev = (sp)->q.tqe_prev; (new)->q.
tqe_next = (sp); *(sp)->q.tqe_prev = (new); (sp)->q.tqe_prev
= &(new)->q.tqe_next; } while (0)
;
97
98 /*
99 * If the parent is the bottom half of the screen, shift
100 * the map down to match on-screen text.
101 */
102 memmove(_HMAP(sp)(((VI_PRIVATE *)((sp)->vi_private))->h_smap), _HMAP(sp)(((VI_PRIVATE *)((sp)->vi_private))->h_smap) + new->rows,
103 (sp->t_maxrows - new->rows) * sizeof(SMAP));
104 } else { /* Old is top half. */
105 new->rows = half; /* New. */
106 sp->rows -= half; /* Old. */
107 new->woff = sp->woff + sp->rows;
108 /* Link in after old. */
109 TAILQ_INSERT_AFTER(&gp->dq, sp, new, q)do { if (((new)->q.tqe_next = (sp)->q.tqe_next) != ((void
*)0)) (new)->q.tqe_next->q.tqe_prev = &(new)->q
.tqe_next; else (&gp->dq)->tqh_last = &(new)->
q.tqe_next; (sp)->q.tqe_next = (new); (new)->q.tqe_prev
= &(sp)->q.tqe_next; } while (0)
;
110 }
111
112 /* Adjust maximum text count. */
113 sp->t_maxrows = IS_ONELINE(sp)((sp)->rows == 1) ? 1 : sp->rows - 1;
114 new->t_maxrows = IS_ONELINE(new)((new)->rows == 1) ? 1 : new->rows - 1;
115
116 /*
117 * Small screens: see vs_refresh.c, section 6a.
118 *
119 * The child may have different screen options sizes than the parent,
120 * so use them. Guarantee that text counts aren't larger than the
121 * new screen sizes.
122 */
123 if (issmallscreen) {
124 /* Fix the text line count for the parent. */
125 if (splitup)
126 sp->t_rows -= new->rows;
127
128 /* Fix the parent screen. */
129 if (sp->t_rows > sp->t_maxrows)
130 sp->t_rows = sp->t_maxrows;
131 if (sp->t_minrows > sp->t_maxrows)
132 sp->t_minrows = sp->t_maxrows;
133
134 /* Fix the child screen. */
135 new->t_minrows = new->t_rows = O_VAL(sp, O_WINDOW)((((&((sp))->opts[((O_WINDOW))])->flags) & ((0x01
))) ? ((sp))->gp->opts[((sp))->opts[((O_WINDOW))].o_cur
.val].o_cur.val : ((sp))->opts[((O_WINDOW))].o_cur.val)
;
136 if (new->t_rows > new->t_maxrows)
137 new->t_rows = new->t_maxrows;
138 if (new->t_minrows > new->t_maxrows)
139 new->t_minrows = new->t_maxrows;
140 } else {
141 sp->t_minrows = sp->t_rows = IS_ONELINE(sp)((sp)->rows == 1) ? 1 : sp->rows - 1;
142
143 /*
144 * The new screen may be a small screen, even if the parent
145 * was not. Don't complain if O_WINDOW is too large, we're
146 * splitting the screen so the screen is much smaller than
147 * normal.
148 */
149 new->t_minrows = new->t_rows = O_VAL(sp, O_WINDOW)((((&((sp))->opts[((O_WINDOW))])->flags) & ((0x01
))) ? ((sp))->gp->opts[((sp))->opts[((O_WINDOW))].o_cur
.val].o_cur.val : ((sp))->opts[((O_WINDOW))].o_cur.val)
;
150 if (new->t_rows > new->rows - 1)
151 new->t_minrows = new->t_rows =
152 IS_ONELINE(new)((new)->rows == 1) ? 1 : new->rows - 1;
153 }
154
155 /* Adjust the ends of the new and old maps. */
156 _TMAP(sp)(((VI_PRIVATE *)((sp)->vi_private))->t_smap) = IS_ONELINE(sp)((sp)->rows == 1) ?
157 _HMAP(sp)(((VI_PRIVATE *)((sp)->vi_private))->h_smap) : _HMAP(sp)(((VI_PRIVATE *)((sp)->vi_private))->h_smap) + (sp->t_rows - 1);
158 _TMAP(new)(((VI_PRIVATE *)((new)->vi_private))->t_smap) = IS_ONELINE(new)((new)->rows == 1) ?
159 _HMAP(new)(((VI_PRIVATE *)((new)->vi_private))->h_smap) : _HMAP(new)(((VI_PRIVATE *)((new)->vi_private))->h_smap) + (new->t_rows - 1);
160
161 /* Reset the length of the default scroll. */
162 if ((sp->defscroll = sp->t_maxrows / 2) == 0)
163 sp->defscroll = 1;
164 if ((new->defscroll = new->t_maxrows / 2) == 0)
165 new->defscroll = 1;
166
167 /*
168 * Initialize the screen flags:
169 *
170 * If we're in vi mode in one screen, we don't have to reinitialize.
171 * This isn't just a cosmetic fix. The path goes like this:
172 *
173 * return into vi(), SC_SSWITCH set
174 * call vs_refresh() with SC_STATUS set
175 * call vs_resolve to display the status message
176 * call vs_refresh() because the SC_SCR_VI bit isn't set
177 *
178 * Things go downhill at this point.
179 *
180 * Draw the new screen from scratch, and add a status line.
181 */
182 F_SET(new,(((new)->flags) |= ((0x00000020 | 0x02000000 | (((sp)->
flags) & ((0x00000001 | 0x00000002 | 0x00000008 | 0x00000004
))))))
183 SC_SCR_REFORMAT | SC_STATUS |(((new)->flags) |= ((0x00000020 | 0x02000000 | (((sp)->
flags) & ((0x00000001 | 0x00000002 | 0x00000008 | 0x00000004
))))))
184 F_ISSET(sp, SC_EX | SC_VI | SC_SCR_VI | SC_SCR_EX))(((new)->flags) |= ((0x00000020 | 0x02000000 | (((sp)->
flags) & ((0x00000001 | 0x00000002 | 0x00000008 | 0x00000004
))))))
;
185 return (0);
186}
187
188/*
189 * vs_discard --
190 * Discard the screen, folding the real-estate into a related screen,
191 * if one exists, and return that screen.
192 *
193 * PUBLIC: int vs_discard(SCR *, SCR **);
194 */
195int
196vs_discard(SCR *sp, SCR **spp)
197{
198 SCR *nsp;
199 dir_t dir;
200
201 /*
202 * Save the old screen's cursor information.
203 *
204 * XXX
205 * If called after file_end(), and the underlying file was a tmp
206 * file, it may have gone away.
207 */
208 if (sp->frp != NULL((void *)0)) {
209 sp->frp->lno = sp->lno;
210 sp->frp->cno = sp->cno;
211 F_SET(sp->frp, FR_CURSORSET)(((sp->frp)->flags) |= ((0x0001)));
212 }
213
214 /*
215 * Add into a previous screen and then into a subsequent screen, as
216 * they're the closest to the current screen. If that doesn't work,
217 * there was no screen to join.
218 */
219 if ((nsp = TAILQ_PREV(sp, _dqh, q)(*(((struct _dqh *)((sp)->q.tqe_prev))->tqh_last)))) {
220 nsp->rows += sp->rows;
221 sp = nsp;
222 dir = FORWARD;
223 } else if ((nsp = TAILQ_NEXT(sp, q)((sp)->q.tqe_next))) {
224 nsp->woff = sp->woff;
225 nsp->rows += sp->rows;
226 sp = nsp;
227 dir = BACKWARD;
228 } else {
229 sp = NULL((void *)0);
230 dir = 0; /* unused */
231 }
232
233 if (spp != NULL((void *)0))
234 *spp = sp;
235 if (sp == NULL((void *)0))
236 return (0);
237
238 /*
239 * Make no effort to clean up the discarded screen's information. If
240 * it's not exiting, we'll do the work when the user redisplays it.
241 *
242 * Small screens: see vs_refresh.c section 6a. Adjust text line info,
243 * unless it's a small screen.
244 *
245 * Reset the length of the default scroll.
246 */
247 if (!IS_SMALL(sp)((sp)->t_minrows != (sp)->t_maxrows))
248 sp->t_rows = sp->t_minrows = sp->rows - 1;
249 sp->t_maxrows = sp->rows - 1;
250 sp->defscroll = sp->t_maxrows / 2;
251 *(HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap) + (sp->t_rows - 1)) = *TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap);
252 TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap) = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap) + (sp->t_rows - 1);
253
254 /*
255 * Draw the new screen from scratch, and add a status line.
256 *
257 * XXX
258 * We could play games with the map, if this were ever to be a
259 * performance problem, but I wrote the code a few times and it
260 * was never clean or easy.
261 */
262 switch (dir) {
263 case FORWARD:
264 vs_sm_fill(sp, OOBLNO0, P_TOP);
265 break;
266 case BACKWARD:
267 vs_sm_fill(sp, OOBLNO0, P_BOTTOM);
268 break;
269 default:
270 abort();
271 }
272
273 F_SET(sp, SC_STATUS)(((sp)->flags) |= ((0x02000000)));
274 return (0);
275}
276
277/*
278 * vs_fg --
279 * Background the current screen, and foreground a new one.
280 *
281 * PUBLIC: int vs_fg(SCR *, SCR **, CHAR_T *, int);
282 */
283int
284vs_fg(SCR *sp, SCR **nspp, CHAR_T *name, int newscreen)
285{
286 GS *gp;
287 SCR *nsp;
288
289 gp = sp->gp;
290
291 if (newscreen)
292 /* Get the specified background screen. */
293 nsp = vs_getbg(sp, name);
294 else
295 /* Swap screens. */
296 if (vs_swap(sp, &nsp, name))
297 return (1);
298
299 if ((*nspp = nsp) == NULL((void *)0)) {
300 msgq_str(sp, M_ERR, name,
301 name == NULL((void *)0) ?
302 "There are no background screens" :
303 "There's no background screen editing a file named %s");
304 return (1);
305 }
306
307 if (newscreen) {
308 /* Remove the new screen from the background queue. */
309 TAILQ_REMOVE(&gp->hq, nsp, q)do { if (((nsp)->q.tqe_next) != ((void *)0)) (nsp)->q.tqe_next
->q.tqe_prev = (nsp)->q.tqe_prev; else (&gp->hq)
->tqh_last = (nsp)->q.tqe_prev; *(nsp)->q.tqe_prev =
(nsp)->q.tqe_next; ; ; } while (0)
;
310
311 /* Split the screen; if we fail, hook the screen back in. */
312 if (vs_split(sp, nsp, 0)) {
313 TAILQ_INSERT_TAIL(&gp->hq, nsp, q)do { (nsp)->q.tqe_next = ((void *)0); (nsp)->q.tqe_prev
= (&gp->hq)->tqh_last; *(&gp->hq)->tqh_last
= (nsp); (&gp->hq)->tqh_last = &(nsp)->q.tqe_next
; } while (0)
;
314 return (1);
315 }
316 } else {
317 /* Move the old screen to the background queue. */
318 TAILQ_REMOVE(&gp->dq, sp, q)do { if (((sp)->q.tqe_next) != ((void *)0)) (sp)->q.tqe_next
->q.tqe_prev = (sp)->q.tqe_prev; else (&gp->dq)->
tqh_last = (sp)->q.tqe_prev; *(sp)->q.tqe_prev = (sp)->
q.tqe_next; ; ; } while (0)
;
319 TAILQ_INSERT_TAIL(&gp->hq, sp, q)do { (sp)->q.tqe_next = ((void *)0); (sp)->q.tqe_prev =
(&gp->hq)->tqh_last; *(&gp->hq)->tqh_last
= (sp); (&gp->hq)->tqh_last = &(sp)->q.tqe_next
; } while (0)
;
320 }
321 return (0);
322}
323
324/*
325 * vs_bg --
326 * Background the screen, and switch to the next one.
327 *
328 * PUBLIC: int vs_bg(SCR *);
329 */
330int
331vs_bg(SCR *sp)
332{
333 GS *gp;
334 SCR *nsp;
335
336 gp = sp->gp;
337
338 /* Try and join with another screen. */
339 if (vs_discard(sp, &nsp))
340 return (1);
341 if (nsp == NULL((void *)0)) {
342 msgq(sp, M_ERR,
343 "You may not background your only displayed screen");
344 return (1);
345 }
346
347 /* Move the old screen to the background queue. */
348 TAILQ_REMOVE(&gp->dq, sp, q)do { if (((sp)->q.tqe_next) != ((void *)0)) (sp)->q.tqe_next
->q.tqe_prev = (sp)->q.tqe_prev; else (&gp->dq)->
tqh_last = (sp)->q.tqe_prev; *(sp)->q.tqe_prev = (sp)->
q.tqe_next; ; ; } while (0)
;
349 TAILQ_INSERT_TAIL(&gp->hq, sp, q)do { (sp)->q.tqe_next = ((void *)0); (sp)->q.tqe_prev =
(&gp->hq)->tqh_last; *(&gp->hq)->tqh_last
= (sp); (&gp->hq)->tqh_last = &(sp)->q.tqe_next
; } while (0)
;
350
351 /* Toss the screen map. */
352 free(_HMAP(sp)(((VI_PRIVATE *)((sp)->vi_private))->h_smap));
353 _HMAP(sp)(((VI_PRIVATE *)((sp)->vi_private))->h_smap) = NULL((void *)0);
354
355 /* Switch screens. */
356 sp->nextdisp = nsp;
357 F_SET(sp, SC_SSWITCH)(((sp)->flags) |= ((0x00001000)));
358
359 return (0);
360}
361
362/*
363 * vs_swap --
364 * Swap the current screen with a backgrounded one.
365 *
366 * PUBLIC: int vs_swap(SCR *, SCR **, char *);
367 */
368int
369vs_swap(SCR *sp, SCR **nspp, char *name)
370{
371 GS *gp;
372 SCR *nsp;
373
374 gp = sp->gp;
375
376 /* Get the specified background screen. */
377 if ((*nspp = nsp = vs_getbg(sp, name)) == NULL((void *)0))
378 return (0);
379
380 /*
381 * Save the old screen's cursor information.
382 *
383 * XXX
384 * If called after file_end(), and the underlying file was a tmp
385 * file, it may have gone away.
386 */
387 if (sp->frp != NULL((void *)0)) {
388 sp->frp->lno = sp->lno;
389 sp->frp->cno = sp->cno;
390 F_SET(sp->frp, FR_CURSORSET)(((sp->frp)->flags) |= ((0x0001)));
391 }
392
393 /* Switch screens. */
394 sp->nextdisp = nsp;
395 F_SET(sp, SC_SSWITCH)(((sp)->flags) |= ((0x00001000)));
396
397 /* Initialize terminal information. */
398 VIP(nsp)((VI_PRIVATE *)((nsp)->vi_private))->srows = VIP(sp)((VI_PRIVATE *)((sp)->vi_private))->srows;
399
400 /* Initialize screen information. */
401 nsp->cols = sp->cols;
402 nsp->rows = sp->rows; /* XXX: Only place in vi that sets rows. */
403 nsp->woff = sp->woff;
404
405 /*
406 * Small screens: see vs_refresh.c, section 6a.
407 *
408 * The new screens may have different screen options sizes than the
409 * old one, so use them. Make sure that text counts aren't larger
410 * than the new screen sizes.
411 */
412 if (IS_SMALL(nsp)((nsp)->t_minrows != (nsp)->t_maxrows)) {
413 nsp->t_minrows = nsp->t_rows = O_VAL(nsp, O_WINDOW)((((&((nsp))->opts[((O_WINDOW))])->flags) & ((0x01
))) ? ((nsp))->gp->opts[((nsp))->opts[((O_WINDOW))].
o_cur.val].o_cur.val : ((nsp))->opts[((O_WINDOW))].o_cur.val
)
;
414 if (nsp->t_rows > sp->t_maxrows)
415 nsp->t_rows = nsp->t_maxrows;
416 if (nsp->t_minrows > sp->t_maxrows)
417 nsp->t_minrows = nsp->t_maxrows;
418 } else
419 nsp->t_rows = nsp->t_maxrows = nsp->t_minrows = nsp->rows - 1;
420
421 /* Reset the length of the default scroll. */
422 nsp->defscroll = nsp->t_maxrows / 2;
423
424 /* Allocate a new screen map. */
425 CALLOC_RET(nsp, _HMAP(nsp), SIZE_HMAP(nsp), sizeof(SMAP)){ if ((((((VI_PRIVATE *)((nsp)->vi_private))->h_smap)) =
calloc(((((VI_PRIVATE *)((nsp)->vi_private))->srows + 1
)), (sizeof(SMAP)))) == ((void *)0)) { msgq((nsp), M_SYSERR, (
(void *)0)); return (1); } }
;
426 _TMAP(nsp)(((VI_PRIVATE *)((nsp)->vi_private))->t_smap) = _HMAP(nsp)(((VI_PRIVATE *)((nsp)->vi_private))->h_smap) + (nsp->t_rows - 1);
427
428 /* Fill the map. */
429 if (vs_sm_fill(nsp, nsp->lno, P_FILL))
430 return (1);
431
432 /*
433 * The new screen replaces the old screen in the parent/child list.
434 * We insert the new screen after the old one. If we're exiting,
435 * the exit will delete the old one, if we're foregrounding, the fg
436 * code will move the old one to the background queue.
437 */
438 TAILQ_REMOVE(&gp->hq, nsp, q)do { if (((nsp)->q.tqe_next) != ((void *)0)) (nsp)->q.tqe_next
->q.tqe_prev = (nsp)->q.tqe_prev; else (&gp->hq)
->tqh_last = (nsp)->q.tqe_prev; *(nsp)->q.tqe_prev =
(nsp)->q.tqe_next; ; ; } while (0)
;
439 TAILQ_INSERT_AFTER(&gp->dq, sp, nsp, q)do { if (((nsp)->q.tqe_next = (sp)->q.tqe_next) != ((void
*)0)) (nsp)->q.tqe_next->q.tqe_prev = &(nsp)->q
.tqe_next; else (&gp->dq)->tqh_last = &(nsp)->
q.tqe_next; (sp)->q.tqe_next = (nsp); (nsp)->q.tqe_prev
= &(sp)->q.tqe_next; } while (0)
;
440
441 /*
442 * Don't change the screen's cursor information other than to
443 * note that the cursor is wrong.
444 */
445 F_SET(VIP(nsp), VIP_CUR_INVALID)(((((VI_PRIVATE *)((nsp)->vi_private)))->flags) |= ((0x0001
)))
;
446
447 /* Draw the new screen from scratch, and add a status line. */
448 F_SET(nsp, SC_SCR_REDRAW | SC_STATUS)(((nsp)->flags) |= ((0x00000040 | 0x02000000)));
449 return (0);
450}
451
452/*
453 * vs_resize --
454 * Change the absolute size of the current screen.
455 *
456 * PUBLIC: int vs_resize(SCR *, long, adj_t);
457 */
458int
459vs_resize(SCR *sp, long count, adj_t adj)
460{
461 GS *gp;
462 SCR *g, *s;
463 size_t g_off, s_off;
464
465 gp = sp->gp;
Value stored to 'gp' is never read
466
467 /*
468 * Figure out which screens will grow, which will shrink, and
469 * make sure it's possible.
470 */
471 if (count == 0)
472 return (0);
473 if (adj == A_SET) {
474 if (sp->t_maxrows == count)
475 return (0);
476 if (sp->t_maxrows > count) {
477 adj = A_DECREASE;
478 count = sp->t_maxrows - count;
479 } else {
480 adj = A_INCREASE;
481 count = count - sp->t_maxrows;
482 }
483 }
484
485 g_off = s_off = 0;
486 if (adj == A_DECREASE) {
487 if (count < 0)
488 count = -count;
489 s = sp;
490 if (s->t_maxrows < MINIMUM_SCREEN_ROWS1 + count)
491 goto toosmall;
492 if ((g = TAILQ_PREV(sp, _dqh, q)(*(((struct _dqh *)((sp)->q.tqe_prev))->tqh_last))) == NULL((void *)0)) {
493 if ((g = TAILQ_NEXT(sp, q)((sp)->q.tqe_next)) == NULL((void *)0))
494 goto toobig;
495 g_off = -count;
496 } else
497 s_off = count;
498 } else {
499 g = sp;
500 if ((s = TAILQ_NEXT(sp, q)((sp)->q.tqe_next)))
501 if (s->t_maxrows < MINIMUM_SCREEN_ROWS1 + count)
502 s = NULL((void *)0);
503 else
504 s_off = count;
505 else
506 s = NULL((void *)0);
507 if (s == NULL((void *)0)) {
508 if ((s = TAILQ_PREV(sp, _dqh, q)(*(((struct _dqh *)((sp)->q.tqe_prev))->tqh_last))) == NULL((void *)0)) {
509toobig: msgq(sp, M_BERR, adj == A_DECREASE ?
510 "The screen cannot shrink" :
511 "The screen cannot grow");
512 return (1);
513 }
514 if (s->t_maxrows < MINIMUM_SCREEN_ROWS1 + count) {
515toosmall: msgq(sp, M_BERR,
516 "The screen can only shrink to %d rows",
517 MINIMUM_SCREEN_ROWS1);
518 return (1);
519 }
520 g_off = -count;
521 }
522 }
523
524 /*
525 * Fix up the screens; we could optimize the reformatting of the
526 * screen, but this isn't likely to be a common enough operation
527 * to make it worthwhile.
528 */
529 s->rows += -count;
530 s->woff += s_off;
531 g->rows += count;
532 g->woff += g_off;
533
534 g->t_rows += count;
535 if (g->t_minrows == g->t_maxrows)
536 g->t_minrows += count;
537 g->t_maxrows += count;
538 _TMAP(g)(((VI_PRIVATE *)((g)->vi_private))->t_smap) += count;
539 F_SET(g, SC_SCR_REFORMAT | SC_STATUS)(((g)->flags) |= ((0x00000020 | 0x02000000)));
540
541 s->t_rows -= count;
542 s->t_maxrows -= count;
543 if (s->t_minrows > s->t_maxrows)
544 s->t_minrows = s->t_maxrows;
545 _TMAP(s)(((VI_PRIVATE *)((s)->vi_private))->t_smap) -= count;
546 F_SET(s, SC_SCR_REFORMAT | SC_STATUS)(((s)->flags) |= ((0x00000020 | 0x02000000)));
547
548 return (0);
549}
550
551/*
552 * vs_getbg --
553 * Get the specified background screen, or, if name is NULL, the first
554 * background screen.
555 */
556static SCR *
557vs_getbg(SCR *sp, char *name)
558{
559 GS *gp;
560 SCR *nsp;
561 char *p;
562
563 gp = sp->gp;
564
565 /* If name is NULL, return the first background screen on the list. */
566 if (name == NULL((void *)0))
567 return (TAILQ_FIRST(&gp->hq)((&gp->hq)->tqh_first));
568
569 /* Search for a full match. */
570 TAILQ_FOREACH(nsp, &gp->hq, q)for((nsp) = ((&gp->hq)->tqh_first); (nsp) != ((void
*)0); (nsp) = ((nsp)->q.tqe_next))
{
571 if (!strcmp(nsp->frp->name, name))
572 return(nsp);
573 }
574
575 /* Search for a last-component match. */
576 TAILQ_FOREACH(nsp, &gp->hq, q)for((nsp) = ((&gp->hq)->tqh_first); (nsp) != ((void
*)0); (nsp) = ((nsp)->q.tqe_next))
{
577 if ((p = strrchr(nsp->frp->name, '/')) == NULL((void *)0))
578 p = nsp->frp->name;
579 else
580 ++p;
581 if (!strcmp(p, name))
582 return(nsp);
583 }
584
585 return (NULL((void *)0));
586}