Bug Summary

File:src/usr.bin/vi/build/../ex/ex_args.c
Warning:line 259, column 8
Although the value stored to 'len' is used in the enclosing expression, the value is never actually read from 'len'

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 ex_args.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/../ex/ex_args.c
1/* $OpenBSD: ex_args.c,v 1.12 2016/01/06 22:28:52 millert Exp $ */
2
3/*-
4 * Copyright (c) 1991, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1991, 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/vi.h"
27
28static int ex_N_next(SCR *, EXCMD *);
29
30/*
31 * ex_next -- :next [+cmd] [files]
32 * Edit the next file, optionally setting the list of files.
33 *
34 * !!!
35 * The :next command behaved differently from the :rewind command in
36 * historic vi. See nvi/docs/autowrite for details, but the basic
37 * idea was that it ignored the force flag if the autowrite flag was
38 * set. This implementation handles them all identically.
39 *
40 * PUBLIC: int ex_next(SCR *, EXCMD *);
41 */
42int
43ex_next(SCR *sp, EXCMD *cmdp)
44{
45 ARGS **argv;
46 FREF *frp;
47 int noargs;
48 char **ap;
49
50 /* Check for file to move to. */
51 if (cmdp->argc == 0 && (sp->cargv == NULL((void *)0) || sp->cargv[1] == NULL((void *)0))) {
52 msgq(sp, M_ERR, "No more files to edit");
53 return (1);
54 }
55
56 if (F_ISSET(cmdp, E_NEWSCREEN)(((cmdp)->flags) & ((0x00000100)))) {
57 /* By default, edit the next file in the old argument list. */
58 if (cmdp->argc == 0) {
59 if (argv_exp0(sp,
60 cmdp, sp->cargv[1], strlen(sp->cargv[1])))
61 return (1);
62 return (ex_edit(sp, cmdp));
63 }
64 return (ex_N_next(sp, cmdp));
65 }
66
67 /* Check modification. */
68 if (file_m1(sp,
69 FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)), FS_ALL0x001 | FS_POSSIBLE0x010))
70 return (1);
71
72 /* Any arguments are a replacement file list. */
73 if (cmdp->argc) {
74 /* Free the current list. */
75 if (!F_ISSET(sp, SC_ARGNOFREE)(((sp)->flags) & ((0x00002000))) && sp->argv != NULL((void *)0)) {
76 for (ap = sp->argv; *ap != NULL((void *)0); ++ap)
77 free(*ap);
78 free(sp->argv);
79 }
80 F_CLR(sp, SC_ARGNOFREE | SC_ARGRECOVER)(((sp)->flags) &= ~((0x00002000 | 0x00004000)));
81 sp->cargv = NULL((void *)0);
82
83 /* Create a new list. */
84 CALLOC_RET(sp,{ if (((sp->argv) = calloc((cmdp->argc + 1), (sizeof(char
*)))) == ((void *)0)) { msgq((sp), M_SYSERR, ((void *)0)); return
(1); } }
85 sp->argv, cmdp->argc + 1, sizeof(char *)){ if (((sp->argv) = calloc((cmdp->argc + 1), (sizeof(char
*)))) == ((void *)0)) { msgq((sp), M_SYSERR, ((void *)0)); return
(1); } }
;
86 for (ap = sp->argv,
87 argv = cmdp->argv; argv[0]->len != 0; ++ap, ++argv)
88 if ((*ap =
89 v_strdup(sp, argv[0]->bp, argv[0]->len)) == NULL((void *)0))
90 return (1);
91 *ap = NULL((void *)0);
92
93 /* Switch to the first file. */
94 sp->cargv = sp->argv;
95 if ((frp = file_add(sp, *sp->cargv)) == NULL((void *)0))
96 return (1);
97 noargs = 0;
98
99 /* Display a file count with the welcome message. */
100 F_SET(sp, SC_STATUS_CNT)(((sp)->flags) |= ((0x04000000)));
101 } else {
102 if ((frp = file_add(sp, sp->cargv[1])) == NULL((void *)0))
103 return (1);
104 if (F_ISSET(sp, SC_ARGRECOVER)(((sp)->flags) & ((0x00004000))))
105 F_SET(frp, FR_RECOVER)(((frp)->flags) |= ((0x0020)));
106 noargs = 1;
107 }
108
109 if (file_init(sp, frp, NULL((void *)0), FS_SETALT0x020 |
110 (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0)))
111 return (1);
112 if (noargs)
113 ++sp->cargv;
114
115 F_SET(sp, SC_FSWITCH)(((sp)->flags) |= ((0x00000800)));
116 return (0);
117}
118
119/*
120 * ex_N_next --
121 * New screen version of ex_next.
122 */
123static int
124ex_N_next(SCR *sp, EXCMD *cmdp)
125{
126 SCR *new;
127 FREF *frp;
128
129 /* Get a new screen. */
130 if (screen_init(sp->gp, sp, &new))
131 return (1);
132 if (vs_split(sp, new, 0)) {
133 (void)screen_end(new);
134 return (1);
135 }
136
137 /* Get a backing file. */
138 if ((frp = file_add(new, cmdp->argv[0]->bp)) == NULL((void *)0) ||
139 file_init(new, frp, NULL((void *)0),
140 (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0))) {
141 (void)vs_discard(new, NULL((void *)0));
142 (void)screen_end(new);
143 return (1);
144 }
145
146 /* The arguments are a replacement file list. */
147 new->cargv = new->argv = ex_buildargv(sp, cmdp, NULL((void *)0));
148
149 /* Display a file count with the welcome message. */
150 F_SET(new, SC_STATUS_CNT)(((new)->flags) |= ((0x04000000)));
151
152 /* Set up the switch. */
153 sp->nextdisp = new;
154 F_SET(sp, SC_SSWITCH)(((sp)->flags) |= ((0x00001000)));
155
156 return (0);
157}
158
159/*
160 * ex_prev -- :prev
161 * Edit the previous file.
162 *
163 * PUBLIC: int ex_prev(SCR *, EXCMD *);
164 */
165int
166ex_prev(SCR *sp, EXCMD *cmdp)
167{
168 FREF *frp;
169
170 if (sp->cargv == sp->argv) {
171 msgq(sp, M_ERR, "No previous files to edit");
172 return (1);
173 }
174
175 if (F_ISSET(cmdp, E_NEWSCREEN)(((cmdp)->flags) & ((0x00000100)))) {
176 if (argv_exp0(sp, cmdp, sp->cargv[-1], strlen(sp->cargv[-1])))
177 return (1);
178 return (ex_edit(sp, cmdp));
179 }
180
181 if (file_m1(sp,
182 FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)), FS_ALL0x001 | FS_POSSIBLE0x010))
183 return (1);
184
185 if ((frp = file_add(sp, sp->cargv[-1])) == NULL((void *)0))
186 return (1);
187
188 if (file_init(sp, frp, NULL((void *)0), FS_SETALT0x020 |
189 (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0)))
190 return (1);
191 --sp->cargv;
192
193 F_SET(sp, SC_FSWITCH)(((sp)->flags) |= ((0x00000800)));
194 return (0);
195}
196
197/*
198 * ex_rew -- :rew
199 * Re-edit the list of files.
200 *
201 * !!!
202 * Historic practice was that all files would start editing at the beginning
203 * of the file. We don't get this right because we may have multiple screens
204 * and we can't clear the FR_CURSORSET bit for a single screen. I don't see
205 * anyone noticing, but if they do, we'll have to put information into the SCR
206 * structure so we can keep track of it.
207 *
208 * PUBLIC: int ex_rew(SCR *, EXCMD *);
209 */
210int
211ex_rew(SCR *sp, EXCMD *cmdp)
212{
213 FREF *frp;
214
215 /*
216 * !!!
217 * Historic practice -- you can rewind to the current file.
218 */
219 if (sp->argv == NULL((void *)0)) {
220 msgq(sp, M_ERR, "No previous files to rewind");
221 return (1);
222 }
223
224 if (file_m1(sp,
225 FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)), FS_ALL0x001 | FS_POSSIBLE0x010))
226 return (1);
227
228 /* Switch to the first one. */
229 sp->cargv = sp->argv;
230 if ((frp = file_add(sp, *sp->cargv)) == NULL((void *)0))
231 return (1);
232 if (file_init(sp, frp, NULL((void *)0), FS_SETALT0x020 |
233 (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0)))
234 return (1);
235
236 /* Switch and display a file count with the welcome message. */
237 F_SET(sp, SC_FSWITCH | SC_STATUS_CNT)(((sp)->flags) |= ((0x00000800 | 0x04000000)));
238
239 return (0);
240}
241
242/*
243 * ex_args -- :args
244 * Display the list of files.
245 *
246 * PUBLIC: int ex_args(SCR *, EXCMD *);
247 */
248int
249ex_args(SCR *sp, EXCMD *cmdp)
250{
251 int cnt, col, len, sep;
252 char **ap;
253
254 if (sp->argv == NULL((void *)0)) {
255 (void)msgq(sp, M_ERR, "No file list to display");
256 return (0);
257 }
258
259 col = len = sep = 0;
Although the value stored to 'len' is used in the enclosing expression, the value is never actually read from 'len'
260 for (cnt = 1, ap = sp->argv; *ap != NULL((void *)0); ++ap) {
261 col += len = strlen(*ap) + sep + (ap == sp->cargv ? 2 : 0);
262 if (col >= sp->cols - 1) {
263 col = len;
264 sep = 0;
265 (void)ex_puts(sp, "\n");
266 } else if (cnt != 1) {
267 sep = 1;
268 (void)ex_puts(sp, " ");
269 }
270 ++cnt;
271
272 (void)ex_printf(sp, "%s%s%s", ap == sp->cargv ? "[" : "",
273 *ap, ap == sp->cargv ? "]" : "");
274 if (INTERRUPTED(sp)(((((sp)->gp)->flags) & ((0x0004))) || (!v_event_get
((sp), ((void *)0), 0, 0x001) && ((((sp)->gp)->
flags) & ((0x0004)))))
)
275 break;
276 }
277 (void)ex_puts(sp, "\n");
278 return (0);
279}
280
281/*
282 * ex_buildargv --
283 * Build a new file argument list.
284 *
285 * PUBLIC: char **ex_buildargv(SCR *, EXCMD *, char *);
286 */
287char **
288ex_buildargv(SCR *sp, EXCMD *cmdp, char *name)
289{
290 ARGS **argv;
291 int argc;
292 char **ap, **s_argv;
293
294 argc = cmdp == NULL((void *)0) ? 1 : cmdp->argc;
295 CALLOC(sp, s_argv, argc + 1, sizeof(char *)){ if (((s_argv) = calloc((argc + 1), (sizeof(char *)))) == ((
void *)0)) msgq((sp), M_SYSERR, ((void *)0)); }
;
296 if ((ap = s_argv) == NULL((void *)0))
297 return (NULL((void *)0));
298
299 if (cmdp == NULL((void *)0)) {
300 if ((*ap = v_strdup(sp, name, strlen(name))) == NULL((void *)0)) {
301 free(s_argv);
302 return (NULL((void *)0));
303 }
304 ++ap;
305 } else
306 for (argv = cmdp->argv; argv[0]->len != 0; ++ap, ++argv)
307 if ((*ap =
308 v_strdup(sp, argv[0]->bp, argv[0]->len)) == NULL((void *)0)) {
309 while (--ap >= s_argv)
310 free(*ap);
311 free(s_argv);
312 return (NULL((void *)0));
313 }
314 *ap = NULL((void *)0);
315 return (s_argv);
316}