Bug Summary

File:src/games/tetris/tetris.c
Warning:line 208, column 2
Value stored to 'argv' 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 tetris.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/games/tetris/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/games/tetris/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/games/tetris/tetris.c
1/* $OpenBSD: tetris.c,v 1.35 2021/07/12 15:09:18 beck Exp $ */
2/* $NetBSD: tetris.c,v 1.2 1995/04/22 07:42:47 cgd Exp $ */
3
4/*-
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Chris Torek and Darren F. Provine.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * @(#)tetris.c 8.1 (Berkeley) 5/31/93
36 */
37
38/*
39 * Tetris (or however it is spelled).
40 */
41
42#include <err.h>
43#include <errno(*__errno()).h>
44#include <limits.h>
45#include <signal.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <unistd.h>
50
51#include "input.h"
52#include "scores.h"
53#include "screen.h"
54#include "tetris.h"
55
56#define NUMKEYS6 6
57
58cell board[B_SIZE(23 * 12)];
59int Rows, Cols;
60const struct shape *curshape;
61const struct shape *nextshape;
62long fallrate;
63int score;
64char key_msg[100];
65char scorepath[PATH_MAX1024];
66int showpreview, classic;
67
68static void elide(void);
69void onintr(int);
70const struct shape *randshape(void);
71static void setup_board(void);
72__dead__attribute__((__noreturn__)) void usage(void);
73
74/*
75 * Set up the initial board. The bottom display row is completely set,
76 * along with another (hidden) row underneath that. Also, the left and
77 * right edges are set.
78 */
79static void
80setup_board(void)
81{
82 int i;
83 cell *p;
84
85 p = board;
86 for (i = B_SIZE(23 * 12); i; i--)
87 *p++ = i <= (2 * B_COLS12) || (i % B_COLS12) < 2;
88}
89
90/*
91 * Elide any full active rows.
92 */
93static void
94elide(void)
95{
96 int rows = 0;
97 int i, j, base;
98 cell *p;
99
100 for (i = A_FIRST1; i < A_LAST21; i++) {
101 base = i * B_COLS12 + 1;
102 p = &board[base];
103 for (j = B_COLS12 - 2; *p++ != 0;) {
104 if (--j <= 0) {
105 /* this row is to be elided */
106 rows++;
107 memset(&board[base], 0, B_COLS12 - 2);
108 scr_update();
109 tsleep();
110 while (--base != 0)
111 board[base + B_COLS12] = board[base];
112 memset(&board[1], 0, B_COLS12 - 2);
113 scr_update();
114 tsleep();
115 break;
116 }
117 }
118 }
119 switch (rows) {
120 case 1:
121 score += 10;
122 break;
123 case 2:
124 score += 30;
125 break;
126 case 3:
127 score += 70;
128 break;
129 case 4:
130 score += 150;
131 break;
132 default:
133 break;
134 }
135}
136
137const struct shape *
138randshape(void)
139{
140 const struct shape *tmp;
141 int i, j;
142
143 tmp = &shapes[arc4random_uniform(7)];
144 j = arc4random_uniform(4);
145 for (i = 0; i < j; i++)
146 tmp = &shapes[classic? tmp->rotc : tmp->rot];
147 return (tmp);
148}
149
150int
151main(int argc, char *argv[])
152{
153 int pos, c;
154 char *keys;
155 int level = 2, ret;
156 char key_write[NUMKEYS6][10];
157 char *home;
158 const char *errstr;
159 int ch, i, j;
160
161 home = getenv("HOME");
162 if (home == NULL((void *)0) || *home == '\0')
163 err(1, "getenv");
164
165 ret = snprintf(scorepath, sizeof(scorepath), "%s/%s", home,
166 ".tetris.scores");
167 if (ret < 0 || ret >= PATH_MAX1024)
168 errc(1, ENAMETOOLONG63, "%s/%s", home, ".tetris.scores");
169
170 if (pledge("stdio rpath wpath cpath tty unveil", NULL((void *)0)) == -1)
171 err(1, "pledge");
172
173 keys = "jkl pq";
174
175 classic = showpreview = 0;
176 while ((ch = getopt(argc, argv, "ck:l:ps")) != -1)
177 switch(ch) {
178 case 'c':
179 /*
180 * this means:
181 * - rotate the other way;
182 * - no reverse video.
183 */
184 classic = 1;
185 break;
186 case 'k':
187 if (strlen(keys = optarg) != NUMKEYS6)
188 usage();
189 break;
190 case 'l':
191 level = (int)strtonum(optarg, MINLEVEL1, MAXLEVEL9,
192 &errstr);
193 if (errstr)
194 errx(1, "level must be from %d to %d",
195 MINLEVEL1, MAXLEVEL9);
196 break;
197 case 'p':
198 showpreview = 1;
199 break;
200 case 's':
201 showscores(0);
202 return 0;
203 default:
204 usage();
205 }
206
207 argc -= optind;
208 argv += optind;
Value stored to 'argv' is never read
209
210 if (argc)
211 usage();
212
213 fallrate = 1000000000L / level;
214
215 for (i = 0; i < NUMKEYS6; i++) {
216 for (j = i+1; j < NUMKEYS6; j++) {
217 if (keys[i] == keys[j])
218 errx(1, "duplicate command keys specified.");
219 }
220 if (keys[i] == ' ')
221 strlcpy(key_write[i], "<space>", sizeof key_write[i]);
222 else {
223 key_write[i][0] = keys[i];
224 key_write[i][1] = '\0';
225 }
226 }
227
228 snprintf(key_msg, sizeof key_msg,
229"%s - left %s - rotate %s - right %s - drop %s - pause %s - quit",
230 key_write[0], key_write[1], key_write[2], key_write[3],
231 key_write[4], key_write[5]);
232
233 (void)signal(SIGINT2, onintr);
234 scr_init();
235
236 if (unveil(scorepath, "rwc") == -1)
237 err(1, "unveil %s", scorepath);
238
239 if (pledge("stdio rpath wpath cpath tty", NULL((void *)0)) == -1)
240 err(1, "pledge");
241
242 setup_board();
243
244 scr_set();
245
246 pos = A_FIRST1*B_COLS12 + (B_COLS12/2)-1;
247 nextshape = randshape();
248 curshape = randshape();
249
250 scr_msg(key_msg, 1);
251
252 for (;;) {
253 place(curshape, pos, 1);
254 scr_update();
255 place(curshape, pos, 0);
256 c = tgetchar();
257 if (c < 0) {
258 /*
259 * Timeout. Move down if possible.
260 */
261 if (fits_in(curshape, pos + B_COLS12)) {
262 pos += B_COLS12;
263 continue;
264 }
265
266 /*
267 * Put up the current shape `permanently',
268 * bump score, and elide any full rows.
269 */
270 place(curshape, pos, 1);
271 score++;
272 elide();
273
274 /*
275 * Choose a new shape. If it does not fit,
276 * the game is over.
277 */
278 curshape = nextshape;
279 nextshape = randshape();
280 pos = A_FIRST1*B_COLS12 + (B_COLS12/2)-1;
281 if (!fits_in(curshape, pos))
282 break;
283 continue;
284 }
285
286 /*
287 * Handle command keys.
288 */
289 if (c == keys[5]) {
290 /* quit */
291 break;
292 }
293 if (c == keys[4]) {
294 static char msg[] =
295 "paused - press RETURN to continue";
296
297 place(curshape, pos, 1);
298 do {
299 scr_update();
300 scr_msg(key_msg, 0);
301 scr_msg(msg, 1);
302 (void) fflush(stdout(&__sF[1]));
303 } while (rwait(NULL((void *)0)) == -1);
304 scr_msg(msg, 0);
305 scr_msg(key_msg, 1);
306 place(curshape, pos, 0);
307 continue;
308 }
309 if (c == keys[0]) {
310 /* move left */
311 if (fits_in(curshape, pos - 1))
312 pos--;
313 continue;
314 }
315 if (c == keys[1]) {
316 /* turn */
317 const struct shape *new = &shapes[
318 classic? curshape->rotc : curshape->rot];
319
320 if (fits_in(new, pos))
321 curshape = new;
322 continue;
323 }
324 if (c == keys[2]) {
325 /* move right */
326 if (fits_in(curshape, pos + 1))
327 pos++;
328 continue;
329 }
330 if (c == keys[3]) {
331 /* move to bottom */
332 while (fits_in(curshape, pos + B_COLS12)) {
333 pos += B_COLS12;
334 score++;
335 }
336 continue;
337 }
338 if (c == '\f') {
339 scr_clear();
340 scr_msg(key_msg, 1);
341 }
342 }
343
344 scr_clear();
345 scr_end();
346
347 if (showpreview == 0)
348 (void)printf("Your score: %d point%s x level %d = %d\n",
349 score, score == 1 ? "" : "s", level, score * level);
350 else {
351 (void)printf("Your score: %d point%s x level %d x preview penalty %0.3f = %d\n",
352 score, score == 1 ? "" : "s", level, (double)PRE_PENALTY0.75,
353 (int)(score * level * PRE_PENALTY0.75));
354 score = score * PRE_PENALTY0.75;
355 }
356 savescore(level);
357
358 printf("\nHit RETURN to see high scores, ^C to skip.\n");
359
360 while ((i = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget(
(&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc)
((&__sF[0])))
) != '\n')
361 if (i == EOF(-1))
362 break;
363
364 showscores(level);
365
366 return 0;
367}
368
369void
370onintr(int signo)
371{
372 scr_clear(); /* XXX signal race */
373 scr_end(); /* XXX signal race */
374 _exit(0);
375}
376
377void
378usage(void)
379{
380 (void)fprintf(stderr(&__sF[2]), "usage: %s [-cps] [-k keys] "
381 "[-l level]\n", getprogname());
382 exit(1);
383}