Bug Summary

File:src/usr.bin/vi/build/../vi/vs_refresh.c
Warning:line 894, column 10
3rd function call argument is an uninitialized value

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_refresh.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_refresh.c
1/* $OpenBSD: vs_refresh.c,v 1.22 2016/01/30 21:31:08 martijn Exp $ */
2
3/*-
4 * Copyright (c) 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1992, 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 <ctype.h>
20#include <libgen.h>
21#include <limits.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include "../common/common.h"
27#include "vi.h"
28
29#define UPDATE_CURSOR0x01 0x01 /* Update the cursor. */
30#define UPDATE_SCREEN0x02 0x02 /* Flush to screen. */
31
32static void vs_modeline(SCR *);
33static int vs_paint(SCR *, u_int);
34
35/*
36 * v_repaint --
37 * Repaint selected lines from the screen.
38 *
39 * PUBLIC: int vs_repaint(SCR *, EVENT *);
40 */
41int
42vs_repaint(SCR *sp, EVENT *evp)
43{
44 SMAP *smp;
45
46 for (; evp->e_flno_u_event._e_mark.lno1 <= evp->e_tlno_u_event._e_mark.lno2; ++evp->e_flno_u_event._e_mark.lno1) {
47 smp = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap) + evp->e_flno_u_event._e_mark.lno1 - 1;
48 SMAP_FLUSH(smp)((smp)->c_ecsize = 0);
49 if (vs_line(sp, smp, NULL((void *)0), NULL((void *)0)))
50 return (1);
51 }
52 return (0);
53}
54
55/*
56 * vs_refresh --
57 * Refresh all screens.
58 *
59 * PUBLIC: int vs_refresh(SCR *, int);
60 */
61int
62vs_refresh(SCR *sp, int forcepaint)
63{
64 GS *gp;
65 SCR *tsp;
66 int need_refresh;
67 u_int priv_paint, pub_paint;
68
69 gp = sp->gp;
70
71 /*
72 * 1: Refresh the screen.
73 *
74 * If SC_SCR_REDRAW is set in the current screen, repaint everything
75 * that we can find, including status lines.
76 */
77 if (F_ISSET(sp, SC_SCR_REDRAW)(((sp)->flags) & ((0x00000040))))
78 TAILQ_FOREACH(tsp, &gp->dq, q)for((tsp) = ((&gp->dq)->tqh_first); (tsp) != ((void
*)0); (tsp) = ((tsp)->q.tqe_next))
79 if (tsp != sp)
80 F_SET(tsp, SC_SCR_REDRAW | SC_STATUS)(((tsp)->flags) |= ((0x00000040 | 0x02000000)));
81
82 /*
83 * 2: Related or dirtied screens, or screens with messages.
84 *
85 * If related screens share a view into a file, they may have been
86 * modified as well. Refresh any screens that aren't exiting that
87 * have paint or dirty bits set. Always update their screens, we
88 * are not likely to get another chance. Finally, if we refresh any
89 * screens other than the current one, the cursor will be trashed.
90 */
91 pub_paint = SC_SCR_REFORMAT0x00000020 | SC_SCR_REDRAW0x00000040;
92 priv_paint = VIP_CUR_INVALID0x0001 | VIP_N_REFRESH0x0010;
93 if (O_ISSET(sp, O_NUMBER)((((&(((sp)))->opts[(((O_NUMBER)))])->flags) & (
(0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_NUMBER
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_NUMBER)))]
.o_cur.val)
)
94 priv_paint |= VIP_N_RENUMBER0x0020;
95 TAILQ_FOREACH(tsp, &gp->dq, q)for((tsp) = ((&gp->dq)->tqh_first); (tsp) != ((void
*)0); (tsp) = ((tsp)->q.tqe_next))
96 if (tsp != sp && !F_ISSET(tsp, SC_EXIT | SC_EXIT_FORCE)(((tsp)->flags) & ((0x00000200 | 0x00000400))) &&
97 (F_ISSET(tsp, pub_paint)(((tsp)->flags) & ((pub_paint))) ||
98 F_ISSET(VIP(tsp), priv_paint)(((((VI_PRIVATE *)((tsp)->vi_private)))->flags) & (
(priv_paint)))
)) {
99 (void)vs_paint(tsp,
100 (F_ISSET(VIP(tsp), VIP_CUR_INVALID)(((((VI_PRIVATE *)((tsp)->vi_private)))->flags) & (
(0x0001)))
?
101 UPDATE_CURSOR0x01 : 0) | UPDATE_SCREEN0x02);
102 F_SET(VIP(sp), VIP_CUR_INVALID)(((((VI_PRIVATE *)((sp)->vi_private)))->flags) |= ((0x0001
)))
;
103 }
104
105 /*
106 * 3: Refresh the current screen.
107 *
108 * Always refresh the current screen, it may be a cursor movement.
109 * Also, always do it last -- that way, SC_SCR_REDRAW can be set
110 * in the current screen only, and the screen won't flash.
111 */
112 if (vs_paint(sp, UPDATE_CURSOR0x01 | (!forcepaint &&
113 F_ISSET(sp, SC_SCR_VI)(((sp)->flags) & ((0x00000008))) && KEYS_WAITING(sp)((sp)->gp->i_cnt != 0) ? 0 : UPDATE_SCREEN0x02)))
114 return (1);
115
116 /*
117 * 4: Paint any missing status lines.
118 *
119 * XXX
120 * This is fairly evil. Status lines are written using the vi message
121 * mechanism, since we have no idea how long they are. Since we may be
122 * painting screens other than the current one, we don't want to make
123 * the user wait. We depend heavily on there not being any other lines
124 * currently waiting to be displayed and the message truncation code in
125 * the msgq_status routine working.
126 *
127 * And, finally, if we updated any status lines, make sure the cursor
128 * gets back to where it belongs.
129 */
130 need_refresh = 0;
131 TAILQ_FOREACH(tsp, &gp->dq, q)for((tsp) = ((&gp->dq)->tqh_first); (tsp) != ((void
*)0); (tsp) = ((tsp)->q.tqe_next))
132 if (F_ISSET(tsp, SC_STATUS)(((tsp)->flags) & ((0x02000000)))) {
133 need_refresh = 1;
134 vs_resolve(tsp, sp, 0);
135 }
136 if (need_refresh)
137 (void)gp->scr_refresh(sp, 0);
138
139 /*
140 * A side-effect of refreshing the screen is that it's now ready
141 * for everything else, i.e. messages.
142 */
143 F_SET(sp, SC_SCR_VI)(((sp)->flags) |= ((0x00000008)));
144 return (0);
145}
146
147/*
148 * vs_paint --
149 * This is the guts of the vi curses screen code. The idea is that
150 * the SCR structure passed in contains the new coordinates of the
151 * screen. What makes this hard is that we don't know how big
152 * characters are, doing input can put the cursor in illegal places,
153 * and we're frantically trying to avoid repainting unless it's
154 * absolutely necessary. If you change this code, you'd better know
155 * what you're doing. It's subtle and quick to anger.
156 */
157static int
158vs_paint(SCR *sp, u_int flags)
159{
160 GS *gp;
161 SMAP *smp, tmp;
162 VI_PRIVATE *vip;
163 recno_t lastline, lcnt;
164 size_t cwtotal, cnt, len, notused, off, y;
165 int ch = 0, didpaint, isempty, leftright_warp;
166 char *p;
167
168#define LNO sp->lno /* Current file line. */
169#define OLNO vip->olno /* Remembered file line. */
170#define CNO sp->cno /* Current file column. */
171#define OCNO vip->ocno /* Remembered file column. */
172#define SCNO vip->sc_col /* Current screen column. */
173
174 gp = sp->gp;
175 vip = VIP(sp)((VI_PRIVATE *)((sp)->vi_private));
176 didpaint = leftright_warp = 0;
177
178 /*
179 * 5: Reformat the lines.
180 *
181 * If the lines themselves have changed (:set list, for example),
182 * fill in the map from scratch. Adjust the screen that's being
183 * displayed if the leftright flag is set.
184 */
185 if (F_ISSET(sp, SC_SCR_REFORMAT)(((sp)->flags) & ((0x00000020)))) {
1
Assuming the condition is false
2
Taking false branch
186 /* Invalidate the line size cache. */
187 VI_SCR_CFLUSH(vip)((vip)->ss_lno = 0);
188
189 /* Toss vs_line() cached information. */
190 if (F_ISSET(sp, SC_SCR_TOP)(((sp)->flags) & ((0x00000100)))) {
191 if (vs_sm_fill(sp, LNO, P_TOP))
192 return (1);
193 }
194 else if (F_ISSET(sp, SC_SCR_CENTER)(((sp)->flags) & ((0x00000080)))) {
195 if (vs_sm_fill(sp, LNO, P_MIDDLE))
196 return (1);
197 } else {
198 if (LNO == HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->lno || LNO == TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->lno) {
199 cnt = vs_screens(sp, LNO, &CNO);
200 if (LNO == HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->lno && cnt < HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->soff)
201 HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->soff = cnt;
202 if (LNO == TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->lno && cnt > TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->soff)
203 TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->soff = cnt;
204 }
205
206 if (vs_sm_fill(sp, OOBLNO0, P_TOP))
207 return (1);
208 }
209 F_SET(sp, SC_SCR_REDRAW)(((sp)->flags) |= ((0x00000040)));
210 }
211
212 /*
213 * 6: Line movement.
214 *
215 * Line changes can cause the top line to change as well. As
216 * before, if the movement is large, the screen is repainted.
217 *
218 * 6a: Small screens.
219 *
220 * Users can use the window, w300, w1200 and w9600 options to make
221 * the screen artificially small. The behavior of these options
222 * in the historic vi wasn't all that consistent, and, in fact, it
223 * was never documented how various screen movements affected the
224 * screen size. Generally, one of three things would happen:
225 * 1: The screen would expand in size, showing the line
226 * 2: The screen would scroll, showing the line
227 * 3: The screen would compress to its smallest size and
228 * repaint.
229 * In general, scrolling didn't cause compression (200^D was handled
230 * the same as ^D), movement to a specific line would (:N where N
231 * was 1 line below the screen caused a screen compress), and cursor
232 * movement would scroll if it was 11 lines or less, and compress if
233 * it was more than 11 lines. (And, no, I have no idea where the 11
234 * comes from.)
235 *
236 * What we do is try and figure out if the line is less than half of
237 * a full screen away. If it is, we expand the screen if there's
238 * room, and then scroll as necessary. The alternative is to compress
239 * and repaint.
240 *
241 * !!!
242 * This code is a special case from beginning to end. Unfortunately,
243 * home modems are still slow enough that it's worth having.
244 *
245 * XXX
246 * If the line a really long one, i.e. part of the line is on the
247 * screen but the column offset is not, we'll end up in the adjust
248 * code, when we should probably have compressed the screen.
249 */
250 if (IS_SMALL(sp)((sp)->t_minrows != (sp)->t_maxrows)) {
3
Assuming field 't_minrows' is equal to field 't_maxrows'
4
Taking false branch
251 if (LNO < HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->lno) {
252 lcnt = vs_sm_nlines(sp, HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap), LNO, sp->t_maxrows);
253 if (lcnt <= HALFSCREEN(sp)((sp)->t_maxrows == 1 ? 1 : (sp)->t_maxrows / 2))
254 for (; lcnt && sp->t_rows != sp->t_maxrows;
255 --lcnt, ++sp->t_rows) {
256 ++TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap);
257 if (vs_sm_1down(sp))
258 return (1);
259 }
260 else
261 goto small_fill;
262 } else if (LNO > TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->lno) {
263 lcnt = vs_sm_nlines(sp, TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap), LNO, sp->t_maxrows);
264 if (lcnt <= HALFSCREEN(sp)((sp)->t_maxrows == 1 ? 1 : (sp)->t_maxrows / 2))
265 for (; lcnt && sp->t_rows != sp->t_maxrows;
266 --lcnt, ++sp->t_rows) {
267 if (vs_sm_next(sp, TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap), TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap) + 1))
268 return (1);
269 ++TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap);
270 if (vs_line(sp, TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap), NULL((void *)0), NULL((void *)0)))
271 return (1);
272 }
273 else {
274small_fill: (void)gp->scr_move(sp, LASTLINE(sp)((sp)->t_maxrows < (sp)->rows ? (sp)->t_maxrows :
(sp)->rows - 1)
, 0);
275 (void)gp->scr_clrtoeol(sp);
276 for (; sp->t_rows > sp->t_minrows;
277 --sp->t_rows, --TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)) {
278 (void)gp->scr_move(sp, TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap) - HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap), 0);
279 (void)gp->scr_clrtoeol(sp);
280 }
281 if (vs_sm_fill(sp, LNO, P_FILL))
282 return (1);
283 F_SET(sp, SC_SCR_REDRAW)(((sp)->flags) |= ((0x00000040)));
284 goto adjust;
285 }
286 }
287 }
288
289 /*
290 * 6b: Line down, or current screen.
291 */
292 if (LNO >= HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->lno) {
5
Assuming 'LNO' is < 'HMAP->lno'
6
Taking false branch
293 /* Current screen. */
294 if (LNO <= TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->lno)
295 goto adjust;
296 if (F_ISSET(sp, SC_SCR_TOP)(((sp)->flags) & ((0x00000100))))
297 goto top;
298 if (F_ISSET(sp, SC_SCR_CENTER)(((sp)->flags) & ((0x00000080))))
299 goto middle;
300
301 /*
302 * If less than half a screen above the line, scroll down
303 * until the line is on the screen.
304 */
305 lcnt = vs_sm_nlines(sp, TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap), LNO, HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2));
306 if (lcnt < HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2)) {
307 while (lcnt--)
308 if (vs_sm_1up(sp))
309 return (1);
310 goto adjust;
311 }
312 goto bottom;
313 }
314
315 /*
316 * 6c: If not on the current screen, may request center or top.
317 */
318 if (F_ISSET(sp, SC_SCR_TOP)(((sp)->flags) & ((0x00000100))))
7
Assuming the condition is false
8
Taking false branch
319 goto top;
320 if (F_ISSET(sp, SC_SCR_CENTER)(((sp)->flags) & ((0x00000080))))
9
Assuming the condition is false
10
Taking false branch
321 goto middle;
322
323 /*
324 * 6d: Line up.
325 */
326 lcnt = vs_sm_nlines(sp, HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap), LNO, HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2));
11
Assuming field 't_rows' is not equal to 1
12
'?' condition is false
327 if (lcnt < HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2)) {
13
Assuming field 't_rows' is equal to 1
14
'?' condition is true
15
Assuming the condition is false
16
Taking false branch
328 /*
329 * If less than half a screen below the line, scroll up until
330 * the line is the first line on the screen. Special check so
331 * that if the screen has been emptied, we refill it.
332 */
333 if (db_exist(sp, HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->lno)) {
334 while (lcnt--)
335 if (vs_sm_1down(sp))
336 return (1);
337 goto adjust;
338 }
339
340 /*
341 * If less than a half screen from the bottom of the file,
342 * put the last line of the file on the bottom of the screen.
343 */
344bottom: if (db_last(sp, &lastline))
345 return (1);
346 tmp.lno = LNO;
347 tmp.coff = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->coff;
348 tmp.soff = 1;
349 lcnt = vs_sm_nlines(sp, &tmp, lastline, sp->t_rows);
350 if (lcnt < HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2)) {
351 if (vs_sm_fill(sp, lastline, P_BOTTOM))
352 return (1);
353 F_SET(sp, SC_SCR_REDRAW)(((sp)->flags) |= ((0x00000040)));
354 goto adjust;
355 }
356 /* It's not close, just put the line in the middle. */
357 goto middle;
358 }
359
360 /*
361 * If less than half a screen from the top of the file, put the first
362 * line of the file at the top of the screen. Otherwise, put the line
363 * in the middle of the screen.
364 */
365 tmp.lno = 1;
366 tmp.coff = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->coff;
367 tmp.soff = 1;
368 lcnt = vs_sm_nlines(sp, &tmp, LNO, HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2));
17
'?' condition is true
369 if (lcnt < HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2)) {
18
Assuming field 't_rows' is equal to 1
19
'?' condition is true
20
Assuming the condition is false
21
Taking false branch
370 if (vs_sm_fill(sp, 1, P_TOP))
371 return (1);
372 } else
373middle: if (vs_sm_fill(sp, LNO, P_MIDDLE))
22
Assuming the condition is false
23
Taking false branch
374 return (1);
375 if (0) {
24
Taking false branch
376top: if (vs_sm_fill(sp, LNO, P_TOP))
377 return (1);
378 }
379 F_SET(sp, SC_SCR_REDRAW)(((sp)->flags) |= ((0x00000040)));
380
381 /*
382 * At this point we know part of the line is on the screen. Since
383 * scrolling is done using logical lines, not physical, all of the
384 * line may not be on the screen. While that's not necessarily bad,
385 * if the part the cursor is on isn't there, we're going to lose.
386 * This can be tricky; if the line covers the entire screen, lno
387 * may be the same as both ends of the map, that's why we test BOTH
388 * the top and the bottom of the map. This isn't a problem for
389 * left-right scrolling, the cursor movement code handles the problem.
390 *
391 * There's a performance issue here if editing *really* long lines.
392 * This gets to the right spot by scrolling, and, in a binary, by
393 * scrolling hundreds of lines. If the adjustment looks like it's
394 * going to be a serious problem, refill the screen and repaint.
395 */
396adjust: if (!O_ISSET(sp, O_LEFTRIGHT)((((&(((sp)))->opts[(((O_LEFTRIGHT)))])->flags) &
((0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_LEFTRIGHT
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_LEFTRIGHT)
))].o_cur.val)
&&
25
Assuming the condition is false
26
'?' condition is false
27
Assuming the condition is false
397 (LNO == HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->lno || LNO == TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->lno)) {
398 cnt = vs_screens(sp, LNO, &CNO);
399 if (LNO == HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->lno && cnt < HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->soff) {
400 if ((HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->soff - cnt) > HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2)) {
401 HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->soff = cnt;
402 vs_sm_fill(sp, OOBLNO0, P_TOP);
403 F_SET(sp, SC_SCR_REDRAW)(((sp)->flags) |= ((0x00000040)));
404 } else
405 while (cnt < HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap)->soff)
406 if (vs_sm_1down(sp))
407 return (1);
408 }
409 if (LNO == TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->lno && cnt > TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->soff) {
410 if ((cnt - TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->soff) > HALFTEXT(sp)((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2)) {
411 TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->soff = cnt;
412 vs_sm_fill(sp, OOBLNO0, P_BOTTOM);
413 F_SET(sp, SC_SCR_REDRAW)(((sp)->flags) |= ((0x00000040)));
414 } else
415 while (cnt > TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap)->soff)
416 if (vs_sm_1up(sp))
417 return (1);
418 }
419 }
420
421 /*
422 * If the screen needs to be repainted, skip cursor optimization.
423 * However, in the code above we skipped leftright scrolling on
424 * the grounds that the cursor code would handle it. Make sure
425 * the right screen is up.
426 */
427 if (F_ISSET(sp, SC_SCR_REDRAW)(((sp)->flags) & ((0x00000040)))) {
28
Assuming the condition is false
29
Taking false branch
428 if (O_ISSET(sp, O_LEFTRIGHT)((((&(((sp)))->opts[(((O_LEFTRIGHT)))])->flags) &
((0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_LEFTRIGHT
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_LEFTRIGHT)
))].o_cur.val)
)
429 goto slow;
430 goto paint;
431 }
432
433 /*
434 * 7: Cursor movements (current screen only).
435 */
436 if (!LF_ISSET(UPDATE_CURSOR)((flags) & ((0x01))))
30
Assuming the condition is false
31
Taking false branch
437 goto number;
438
439 /*
440 * Decide cursor position. If the line has changed, the cursor has
441 * moved over a tab, or don't know where the cursor was, reparse the
442 * line. Otherwise, we've just moved over fixed-width characters,
443 * and can calculate the left/right scrolling and cursor movement
444 * without reparsing the line. Note that we don't know which (if any)
445 * of the characters between the old and new cursor positions changed.
446 *
447 * XXX
448 * With some work, it should be possible to handle tabs quickly, at
449 * least in obvious situations, like moving right and encountering
450 * a tab, without reparsing the whole line.
451 *
452 * If the line we're working with has changed, reread it..
453 */
454 if (F_ISSET(vip, VIP_CUR_INVALID)(((vip)->flags) & ((0x0001))) || LNO != OLNO)
32
Assuming the condition is false
33
Assuming field 'lno' is equal to field 'olno'
34
Taking false branch
455 goto slow;
456
457 /* Otherwise, if nothing's changed, ignore the cursor. */
458 if (CNO == OCNO)
35
Assuming field 'cno' is not equal to field 'ocno'
36
Taking false branch
459 goto fast;
460
461 /*
462 * Get the current line. If this fails, we either have an empty
463 * file and can just repaint, or there's a real problem. This
464 * isn't a performance issue because there aren't any ways to get
465 * here repeatedly.
466 */
467 if (db_eget(sp, LNO, &p, &len, &isempty)) {
37
Assuming the condition is false
38
Taking false branch
468 if (isempty)
469 goto slow;
470 return (1);
471 }
472
473#ifdef DEBUG
474 /* Sanity checking. */
475 if (CNO >= len && len != 0) {
476 msgq(sp, M_ERR, "Error: %s/%d: cno (%u) >= len (%u)",
477 basename(__FILE__"/usr/src/usr.bin/vi/build/../vi/vs_refresh.c"), __LINE__477, CNO, len);
478 return (1);
479 }
480#endif
481 /*
482 * The basic scheme here is to look at the characters in between
483 * the old and new positions and decide how big they are on the
484 * screen, and therefore, how many screen positions to move.
485 */
486 if (CNO < OCNO) {
39
Assuming field 'cno' is >= field 'ocno'
40
Taking false branch
487 /*
488 * 7a: Cursor moved left.
489 *
490 * Point to the old character. The old cursor position can
491 * be past EOL if, for example, we just deleted the rest of
492 * the line. In this case, since we don't know the width of
493 * the characters we traversed, we have to do it slowly.
494 */
495 p += OCNO;
496 cnt = (OCNO - CNO) + 1;
497 if (OCNO >= len)
498 goto slow;
499
500 /*
501 * Quick sanity check -- it's hard to figure out exactly when
502 * we cross a screen boundary as we do in the cursor right
503 * movement. If cnt is so large that we're going to cross the
504 * boundary no matter what, stop now.
505 */
506 if (SCNO + 1 + MAX_CHARACTER_COLUMNS4 < cnt)
507 goto slow;
508
509 /*
510 * Count up the widths of the characters. If it's a tab
511 * character, go do it the slow way.
512 */
513 for (cwtotal = 0; cnt--; cwtotal += KEY_LEN(sp, ch)((unsigned char)(ch) <= 254 ? (sp)->gp->cname[(unsigned
char)(ch)].len : v_key_len((sp), (ch)))
)
514 if ((ch = *(u_char *)p--) == '\t')
515 goto slow;
516
517 /*
518 * Decrement the screen cursor by the total width of the
519 * characters minus 1.
520 */
521 cwtotal -= 1;
522
523 /*
524 * If we're moving left, and there's a wide character in the
525 * current position, go to the end of the character.
526 */
527 if (KEY_LEN(sp, ch)((unsigned char)(ch) <= 254 ? (sp)->gp->cname[(unsigned
char)(ch)].len : v_key_len((sp), (ch)))
> 1)
528 cwtotal -= KEY_LEN(sp, ch)((unsigned char)(ch) <= 254 ? (sp)->gp->cname[(unsigned
char)(ch)].len : v_key_len((sp), (ch)))
- 1;
529
530 /*
531 * If the new column moved us off of the current logical line,
532 * calculate a new one. If doing leftright scrolling, we've
533 * moved off of the current screen, as well.
534 */
535 if (SCNO < cwtotal)
536 goto slow;
537 SCNO -= cwtotal;
538 } else {
539 /*
540 * 7b: Cursor moved right.
541 *
542 * Point to the first character to the right.
543 */
544 p += OCNO + 1;
545 cnt = CNO - OCNO;
546
547 /*
548 * Count up the widths of the characters. If it's a tab
549 * character, go do it the slow way. If we cross a
550 * screen boundary, we can quit.
551 */
552 for (cwtotal = SCNO; cnt--;) {
41
Loop condition is false. Execution continues on line 563
553 if ((ch = *(u_char *)p++) == '\t')
554 goto slow;
555 if ((cwtotal += KEY_LEN(sp, ch)((unsigned char)(ch) <= 254 ? (sp)->gp->cname[(unsigned
char)(ch)].len : v_key_len((sp), (ch)))
) >= SCREEN_COLS(sp)((((((&((((sp))))->opts[(((O_NUMBER)))])->flags) &
((0x01))) ? ((((sp))))->gp->opts[((((sp))))->opts[(
((O_NUMBER)))].o_cur.val].o_cur.val : ((((sp))))->opts[(((
O_NUMBER)))].o_cur.val) ? (sp)->cols - 8 : (sp)->cols))
)
556 break;
557 }
558
559 /*
560 * Increment the screen cursor by the total width of the
561 * characters.
562 */
563 SCNO = cwtotal;
564
565 /* See screen change comment in section 6a. */
566 if (SCNO >= SCREEN_COLS(sp)((((((&((((sp))))->opts[(((O_NUMBER)))])->flags) &
((0x01))) ? ((((sp))))->gp->opts[((((sp))))->opts[(
((O_NUMBER)))].o_cur.val].o_cur.val : ((((sp))))->opts[(((
O_NUMBER)))].o_cur.val) ? (sp)->cols - 8 : (sp)->cols))
)
42
Assuming the condition is false
43
'?' condition is false
44
Assuming the condition is false
45
'?' condition is false
46
Assuming the condition is false
47
Taking false branch
567 goto slow;
568 }
569
570 /*
571 * 7c: Fast cursor update.
572 *
573 * We have the current column, retrieve the current row.
574 */
575fast: (void)gp->scr_cursor(sp, &y, &notused);
576 goto done_cursor;
48
Control jumps to line 697
577
578 /*
579 * 7d: Slow cursor update.
580 *
581 * Walk through the map and find the current line.
582 */
583slow: for (smp = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap); smp->lno != LNO; ++smp);
584
585 /*
586 * 7e: Leftright scrolling adjustment.
587 *
588 * If doing left-right scrolling and the cursor movement has changed
589 * the displayed screen, scroll the screen left or right, unless we're
590 * updating the info line in which case we just scroll that one line.
591 * We adjust the offset up or down until we have a window that covers
592 * the current column, making sure that we adjust differently for the
593 * first screen as compared to subsequent ones.
594 */
595 if (O_ISSET(sp, O_LEFTRIGHT)((((&(((sp)))->opts[(((O_LEFTRIGHT)))])->flags) &
((0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_LEFTRIGHT
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_LEFTRIGHT)
))].o_cur.val)
) {
596 /*
597 * Get the screen column for this character, and correct
598 * for the number option offset.
599 */
600 cnt = vs_columns(sp, NULL((void *)0), LNO, &CNO, NULL((void *)0));
601 if (O_ISSET(sp, O_NUMBER)((((&(((sp)))->opts[(((O_NUMBER)))])->flags) & (
(0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_NUMBER
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_NUMBER)))]
.o_cur.val)
)
602 cnt -= O_NUMBER_LENGTH8;
603
604 /* Adjust the window towards the beginning of the line. */
605 off = smp->coff;
606 if (off >= cnt) {
607 do {
608 if (off >= O_VAL(sp, O_SIDESCROLL)((((&((sp))->opts[((O_SIDESCROLL))])->flags) & (
(0x01))) ? ((sp))->gp->opts[((sp))->opts[((O_SIDESCROLL
))].o_cur.val].o_cur.val : ((sp))->opts[((O_SIDESCROLL))].
o_cur.val)
)
609 off -= O_VAL(sp, O_SIDESCROLL)((((&((sp))->opts[((O_SIDESCROLL))])->flags) & (
(0x01))) ? ((sp))->gp->opts[((sp))->opts[((O_SIDESCROLL
))].o_cur.val].o_cur.val : ((sp))->opts[((O_SIDESCROLL))].
o_cur.val)
;
610 else {
611 off = 0;
612 break;
613 }
614 } while (off >= cnt);
615 goto shifted;
616 }
617
618 /* Adjust the window towards the end of the line. */
619 if ((off == 0 && off + SCREEN_COLS(sp)((((((&((((sp))))->opts[(((O_NUMBER)))])->flags) &
((0x01))) ? ((((sp))))->gp->opts[((((sp))))->opts[(
((O_NUMBER)))].o_cur.val].o_cur.val : ((((sp))))->opts[(((
O_NUMBER)))].o_cur.val) ? (sp)->cols - 8 : (sp)->cols))
< cnt) ||
620 (off != 0 && off + sp->cols < cnt)) {
621 do {
622 off += O_VAL(sp, O_SIDESCROLL)((((&((sp))->opts[((O_SIDESCROLL))])->flags) & (
(0x01))) ? ((sp))->gp->opts[((sp))->opts[((O_SIDESCROLL
))].o_cur.val].o_cur.val : ((sp))->opts[((O_SIDESCROLL))].
o_cur.val)
;
623 } while (off + sp->cols < cnt);
624
625shifted: /* Fill in screen map with the new offset. */
626 if (F_ISSET(sp, SC_TINPUT_INFO)(((sp)->flags) & ((0x10000000))))
627 smp->coff = off;
628 else {
629 for (smp = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap); smp <= TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap); ++smp)
630 smp->coff = off;
631 leftright_warp = 1;
632 }
633 goto paint;
634 }
635
636 /*
637 * We may have jumped here to adjust a leftright screen because
638 * redraw was set. If so, we have to paint the entire screen.
639 */
640 if (F_ISSET(sp, SC_SCR_REDRAW)(((sp)->flags) & ((0x00000040))))
641 goto paint;
642 }
643
644 /*
645 * Update the screen lines for this particular file line until we
646 * have a new screen cursor position.
647 */
648 for (y = -1,
649 vip->sc_smap = NULL((void *)0); smp <= TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap) && smp->lno == LNO; ++smp) {
650 if (vs_line(sp, smp, &y, &SCNO))
651 return (1);
652 if (y != -1) {
653 vip->sc_smap = smp;
654 break;
655 }
656 }
657 goto done_cursor;
658
659 /*
660 * 8: Repaint the entire screen.
661 *
662 * Lost big, do what you have to do. We flush the cache, since
663 * SC_SCR_REDRAW gets set when the screen isn't worth fixing, and
664 * it's simpler to repaint. So, don't trust anything that we
665 * think we know about it.
666 */
667paint: for (smp = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap); smp <= TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap); ++smp)
668 SMAP_FLUSH(smp)((smp)->c_ecsize = 0);
669 for (y = -1, vip->sc_smap = NULL((void *)0), smp = HMAP(((VI_PRIVATE *)((sp)->vi_private))->h_smap); smp <= TMAP(((VI_PRIVATE *)((sp)->vi_private))->t_smap); ++smp) {
670 if (vs_line(sp, smp, &y, &SCNO))
671 return (1);
672 if (y != -1 && vip->sc_smap == NULL((void *)0))
673 vip->sc_smap = smp;
674 }
675 /*
676 * If it's a small screen and we're redrawing, clear the unused lines,
677 * ex may have overwritten them.
678 */
679 if (F_ISSET(sp, SC_SCR_REDRAW)(((sp)->flags) & ((0x00000040))) && IS_SMALL(sp)((sp)->t_minrows != (sp)->t_maxrows))
680 for (cnt = sp->t_rows; cnt <= sp->t_maxrows; ++cnt) {
681 (void)gp->scr_move(sp, cnt, 0);
682 (void)gp->scr_clrtoeol(sp);
683 }
684
685 didpaint = 1;
686
687done_cursor:
688 /*
689 * Sanity checking. When the repainting code messes up, the usual
690 * result is we don't repaint the cursor and so sc_smap will be
691 * NULL. If we're debugging, die, otherwise restart from scratch.
692 */
693#ifdef DEBUG
694 if (vip->sc_smap == NULL((void *)0))
695 abort();
696#else
697 if (vip->sc_smap == NULL((void *)0)) {
49
Assuming field 'sc_smap' is not equal to NULL
50
Taking false branch
698 if (F_ISSET(sp, SC_SCR_REFORMAT)(((sp)->flags) & ((0x00000020))))
699 return (0);
700 F_SET(sp, SC_SCR_REFORMAT)(((sp)->flags) |= ((0x00000020)));
701 return (vs_paint(sp, flags));
702 }
703#endif
704
705 /*
706 * 9: Set the remembered cursor values.
707 */
708 OCNO = CNO;
709 OLNO = LNO;
710
711 /*
712 * 10: Repaint the line numbers.
713 *
714 * If O_NUMBER is set and the VIP_N_RENUMBER bit is set, and we
715 * didn't repaint the screen, repaint all of the line numbers,
716 * they've changed.
717 */
718number: if (O_ISSET(sp, O_NUMBER)((((&(((sp)))->opts[(((O_NUMBER)))])->flags) & (
(0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_NUMBER
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_NUMBER)))]
.o_cur.val)
&&
51
Assuming the condition is false
52
'?' condition is false
53
Assuming the condition is false
719 F_ISSET(vip, VIP_N_RENUMBER)(((vip)->flags) & ((0x0020))) && !didpaint && vs_number(sp))
720 return (1);
721
722 /*
723 * 11: Update the mode line, position the cursor, and flush changes.
724 *
725 * If we warped the screen, we have to refresh everything.
726 */
727 if (leftright_warp
53.1
'leftright_warp' is 0
)
54
Taking false branch
728 LF_SET(UPDATE_CURSOR | UPDATE_SCREEN)((flags) |= ((0x01 | 0x02)));
729
730 if (LF_ISSET(UPDATE_SCREEN)((flags) & ((0x02))) && !IS_ONELINE(sp)((sp)->rows == 1) &&
55
Assuming the condition is true
56
Assuming field 'rows' is not equal to 1
59
Taking true branch
731 !F_ISSET(vip, VIP_S_MODELINE)(((vip)->flags) & ((0x0080))) && !F_ISSET(sp, SC_TINPUT_INFO)(((sp)->flags) & ((0x10000000))))
57
Assuming the condition is true
58
Assuming the condition is true
732 vs_modeline(sp);
60
Calling 'vs_modeline'
733
734 if (LF_ISSET(UPDATE_CURSOR)((flags) & ((0x01)))) {
735 (void)gp->scr_move(sp, y, SCNO);
736
737 /*
738 * XXX
739 * If the screen shifted, we recalculate the "most favorite"
740 * cursor position. Vi won't know that we've warped the
741 * screen, so it's going to have a wrong idea about where the
742 * cursor should be. This is vi's problem, and fixing it here
743 * is a gross layering violation.
744 */
745 if (leftright_warp)
746 (void)vs_column(sp, &sp->rcm);
747 }
748
749 if (LF_ISSET(UPDATE_SCREEN)((flags) & ((0x02))))
750 (void)gp->scr_refresh(sp, F_ISSET(vip, VIP_N_EX_PAINT)(((vip)->flags) & ((0x0004))));
751
752 /* 12: Clear the flags that are handled by this routine. */
753 F_CLR(sp, SC_SCR_CENTER | SC_SCR_REDRAW | SC_SCR_REFORMAT | SC_SCR_TOP)(((sp)->flags) &= ~((0x00000080 | 0x00000040 | 0x00000020
| 0x00000100)))
;
754 F_CLR(vip, VIP_CUR_INVALID |(((vip)->flags) &= ~((0x0001 | 0x0004 | 0x0010 | 0x0020
| 0x0080)))
755 VIP_N_EX_PAINT | VIP_N_REFRESH | VIP_N_RENUMBER | VIP_S_MODELINE)(((vip)->flags) &= ~((0x0001 | 0x0004 | 0x0010 | 0x0020
| 0x0080)))
;
756
757 return (0);
758
759#undef LNO
760#undef OLNO
761#undef CNO
762#undef OCNO
763#undef SCNO
764}
765
766/*
767 * vs_modeline --
768 * Update the mode line.
769 */
770static void
771vs_modeline(SCR *sp)
772{
773 static char * const modes[] = {
774 "Append", /* SM_APPEND */
775 "Change", /* SM_CHANGE */
776 "Command", /* SM_COMMAND */
777 "Insert", /* SM_INSERT */
778 "Replace", /* SM_REPLACE */
779 };
780 GS *gp;
781 size_t cols, curcol, curlen, endpoint, len, midpoint;
61
'len' declared without an initial value
782 const char *t = NULL((void *)0);
783 int ellipsis;
784 char *p, buf[20];
785
786 /*
787 * It's possible that this routine will be called after sp->frp
788 * has been set to NULL by file_end(). We return immediately
789 * to avoid a SEGV.
790 */
791 if (sp->frp == NULL((void *)0))
62
Assuming field 'frp' is not equal to NULL
63
Taking false branch
792 return;
793
794 gp = sp->gp;
795
796 /*
797 * We put down the file name, the ruler, the mode and the dirty flag.
798 * If there's not enough room, there's not enough room, we don't play
799 * any special games. We try to put the ruler in the middle and the
800 * mode and dirty flag at the end.
801 *
802 * !!!
803 * Leave the last character blank, in case it's a really dumb terminal
804 * with hardware scroll. Second, don't paint the last character in the
805 * screen, SunOS 4.1.1 and Ultrix 4.2 curses won't let you.
806 *
807 * Move to the last line on the screen.
808 */
809 (void)gp->scr_move(sp, LASTLINE(sp)((sp)->t_maxrows < (sp)->rows ? (sp)->t_maxrows :
(sp)->rows - 1)
, 0);
64
Assuming field 't_maxrows' is >= field 'rows'
65
'?' condition is false
810
811 /* If more than one screen in the display, show the file name. */
812 curlen = 0;
813 if (IS_SPLIT(sp)((((sp))->q.tqe_next) || (*(((struct _dqh *)(((sp))->q.
tqe_prev))->tqh_last)))
) {
66
Assuming field 'tqe_next' is null
67
Assuming the condition is false
68
Taking false branch
814 for (p = sp->frp->name; *p != '\0'; ++p);
815 for (ellipsis = 0, cols = sp->cols / 2; --p > sp->frp->name;) {
816 if (*p == '/') {
817 ++p;
818 break;
819 }
820 if ((curlen += KEY_LEN(sp, *p)((unsigned char)(*p) <= 254 ? (sp)->gp->cname[(unsigned
char)(*p)].len : v_key_len((sp), (*p)))
) > cols) {
821 ellipsis = 3;
822 curlen +=
823 KEY_LEN(sp, '.')((unsigned char)('.') <= 254 ? (sp)->gp->cname[(unsigned
char)('.')].len : v_key_len((sp), ('.')))
* 3 + KEY_LEN(sp, ' ')((unsigned char)(' ') <= 254 ? (sp)->gp->cname[(unsigned
char)(' ')].len : v_key_len((sp), (' ')))
;
824 while (curlen > cols) {
825 ++p;
826 curlen -= KEY_LEN(sp, *p)((unsigned char)(*p) <= 254 ? (sp)->gp->cname[(unsigned
char)(*p)].len : v_key_len((sp), (*p)))
;
827 }
828 break;
829 }
830 }
831 if (ellipsis) {
832 while (ellipsis--)
833 (void)gp->scr_addstr(sp,
834 KEY_NAME(sp, '.')((unsigned char)('.') <= 254 ? (sp)->gp->cname[(unsigned
char)('.')].name : v_key_name((sp), ('.')))
, KEY_LEN(sp, '.')((unsigned char)('.') <= 254 ? (sp)->gp->cname[(unsigned
char)('.')].len : v_key_len((sp), ('.')))
);
835 (void)gp->scr_addstr(sp,
836 KEY_NAME(sp, ' ')((unsigned char)(' ') <= 254 ? (sp)->gp->cname[(unsigned
char)(' ')].name : v_key_name((sp), (' ')))
, KEY_LEN(sp, ' ')((unsigned char)(' ') <= 254 ? (sp)->gp->cname[(unsigned
char)(' ')].len : v_key_len((sp), (' ')))
);
837 }
838 for (; *p != '\0'; ++p)
839 (void)gp->scr_addstr(sp,
840 KEY_NAME(sp, *p)((unsigned char)(*p) <= 254 ? (sp)->gp->cname[(unsigned
char)(*p)].name : v_key_name((sp), (*p)))
, KEY_LEN(sp, *p)((unsigned char)(*p) <= 254 ? (sp)->gp->cname[(unsigned
char)(*p)].len : v_key_len((sp), (*p)))
);
841 }
842
843 /* Clear the rest of the line. */
844 (void)gp->scr_clrtoeol(sp);
845
846 /*
847 * Display the ruler. If we're not at the midpoint yet, move there.
848 * Otherwise, add in two extra spaces.
849 *
850 * Adjust the current column for the fact that the editor uses it as
851 * a zero-based number.
852 *
853 * XXX
854 * Assume that numbers, commas, and spaces only take up a single
855 * column on the screen.
856 */
857 cols = sp->cols - 1;
858 if (O_ISSET(sp, O_RULER)((((&(((sp)))->opts[(((O_RULER)))])->flags) & (
(0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_RULER
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_RULER)))].
o_cur.val)
) {
69
Assuming the condition is false
70
'?' condition is false
71
Assuming the condition is false
72
Taking false branch
859 vs_column(sp, &curcol);
860 len = snprintf(buf, sizeof(buf), "%lu,%zu",
861 (ulong)sp->lno, curcol + 1);
862
863 midpoint = (cols - ((len + 1) / 2)) / 2;
864 if (curlen < midpoint) {
865 (void)gp->scr_move(sp, LASTLINE(sp)((sp)->t_maxrows < (sp)->rows ? (sp)->t_maxrows :
(sp)->rows - 1)
, midpoint);
866 curlen += len;
867 } else if (curlen + 2 + len < cols) {
868 (void)gp->scr_addstr(sp, " ", 2);
869 curlen += 2 + len;
870 }
871 (void)gp->scr_addstr(sp, buf, len);
872 }
873
874 /*
875 * Display the mode and the modified flag, as close to the end of the
876 * line as possible, but guaranteeing at least two spaces between the
877 * ruler and the modified flag.
878 */
879#define MODESIZE9 9
880 endpoint = cols;
881 if (O_ISSET(sp, O_SHOWMODE)((((&(((sp)))->opts[(((O_SHOWMODE)))])->flags) &
((0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_SHOWMODE
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_SHOWMODE))
)].o_cur.val)
) {
73
Assuming the condition is false
74
'?' condition is false
75
Assuming the condition is false
76
Taking false branch
882 if (F_ISSET(sp->ep, F_MODIFIED)(((sp->ep)->flags) & ((0x004))))
883 --endpoint;
884 t = modes[sp->showmode];
885 endpoint -= (len = strlen(t));
886 }
887
888 if (endpoint > curlen + 2) {
77
Assuming the condition is true
78
Taking true branch
889 (void)gp->scr_move(sp, LASTLINE(sp)((sp)->t_maxrows < (sp)->rows ? (sp)->t_maxrows :
(sp)->rows - 1)
, endpoint);
79
Assuming field 't_maxrows' is >= field 'rows'
80
'?' condition is false
890 if (O_ISSET(sp, O_SHOWMODE)((((&(((sp)))->opts[(((O_SHOWMODE)))])->flags) &
((0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((O_SHOWMODE
)))].o_cur.val].o_cur.val : (((sp)))->opts[(((O_SHOWMODE))
)].o_cur.val)
) {
81
Assuming the condition is false
82
'?' condition is false
83
Assuming the condition is true
84
Taking true branch
891 if (F_ISSET(sp->ep, F_MODIFIED)(((sp->ep)->flags) & ((0x004))))
85
Assuming the condition is false
86
Taking false branch
892 (void)gp->scr_addstr(sp,
893 KEY_NAME(sp, '*')((unsigned char)('*') <= 254 ? (sp)->gp->cname[(unsigned
char)('*')].name : v_key_name((sp), ('*')))
, KEY_LEN(sp, '*')((unsigned char)('*') <= 254 ? (sp)->gp->cname[(unsigned
char)('*')].len : v_key_len((sp), ('*')))
);
894 (void)gp->scr_addstr(sp, t, len);
87
3rd function call argument is an uninitialized value
895 }
896 }
897}