Sun Feb 21 17:16:00 2021 UTC ()
cgram: WARNS=6, use int for all coordinates

Eliminate some frequently occurring subexpressions during substitution.

No functional change, assuming that fortune(6) always spits out less
than 2 gigacharacters of text.


(rillig)
diff -r1.2 -r1.3 src/games/cgram/Makefile
diff -r1.8 -r1.9 src/games/cgram/cgram.c

cvs diff -r1.2 -r1.3 src/games/cgram/Makefile (expand / switch to unified diff)

--- src/games/cgram/Makefile 2021/02/21 16:05:44 1.2
+++ src/games/cgram/Makefile 2021/02/21 17:16:00 1.3
@@ -1,11 +1,12 @@ @@ -1,11 +1,12 @@
1# $NetBSD: Makefile,v 1.2 2021/02/21 16:05:44 rillig Exp $ 1# $NetBSD: Makefile,v 1.3 2021/02/21 17:16:00 rillig Exp $
2 2
3PROG= cgram 3PROG= cgram
4DPADD= ${LIBCURSES} ${LIBTERMINFO} 4DPADD= ${LIBCURSES} ${LIBTERMINFO}
5LDADD= -lcurses -lterminfo 5LDADD= -lcurses -lterminfo
6SRCS= cgram.c 6SRCS= cgram.c
7MAN= cgram.6 7MAN= cgram.6
8HIDEGAME= hidegame 8HIDEGAME= hidegame
9LINTFLAGS+= -T 9LINTFLAGS+= -T
 10WARNS= 6
10 11
11.include <bsd.prog.mk> 12.include <bsd.prog.mk>

cvs diff -r1.8 -r1.9 src/games/cgram/cgram.c (expand / switch to unified diff)

--- src/games/cgram/cgram.c 2021/02/21 16:50:57 1.8
+++ src/games/cgram/cgram.c 2021/02/21 17:16:00 1.9
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD */ 1/* $NetBSD: cgram.c,v 1.9 2021/02/21 17:16:00 rillig Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by David A. Holland. 8 * by David A. Holland.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -80,27 +80,27 @@ ch_islower(char ch) @@ -80,27 +80,27 @@ ch_islower(char ch)
80 return islower((unsigned char)ch); 80 return islower((unsigned char)ch);
81} 81}
82 82
83static bool 83static bool
84ch_isupper(char ch) 84ch_isupper(char ch)
85{ 85{
86 return isupper((unsigned char)ch); 86 return isupper((unsigned char)ch);
87} 87}
88 88
89//////////////////////////////////////////////////////////// 89////////////////////////////////////////////////////////////
90 90
91struct stringarray { 91struct stringarray {
92 char **v; 92 char **v;
93 int num; 93 size_t num;
94}; 94};
95 95
96static void 96static void
97stringarray_init(struct stringarray *a) 97stringarray_init(struct stringarray *a)
98{ 98{
99 a->v = NULL; 99 a->v = NULL;
100 a->num = 0; 100 a->num = 0;
101} 101}
102 102
103static void 103static void
104stringarray_cleanup(struct stringarray *a) 104stringarray_cleanup(struct stringarray *a)
105{ 105{
106 free(a->v); 106 free(a->v);
@@ -113,27 +113,27 @@ stringarray_add(struct stringarray *a, c @@ -113,27 +113,27 @@ stringarray_add(struct stringarray *a, c
113 if (a->v == NULL) { 113 if (a->v == NULL) {
114 errx(1, "Out of memory"); 114 errx(1, "Out of memory");
115 } 115 }
116 a->v[a->num] = xstrdup(s); 116 a->v[a->num] = xstrdup(s);
117 a->num++; 117 a->num++;
118} 118}
119 119
120//////////////////////////////////////////////////////////// 120////////////////////////////////////////////////////////////
121 121
122static struct stringarray lines; 122static struct stringarray lines;
123static struct stringarray sollines; 123static struct stringarray sollines;
124static bool hinting; 124static bool hinting;
125static int scrolldown; 125static int scrolldown;
126static unsigned curx; 126static int curx;
127static int cury; 127static int cury;
128 128
129static void 129static void
130readquote(void) 130readquote(void)
131{ 131{
132 FILE *f = popen(_PATH_FORTUNE, "r"); 132 FILE *f = popen(_PATH_FORTUNE, "r");
133 if (f == NULL) { 133 if (f == NULL) {
134 err(1, "%s", _PATH_FORTUNE); 134 err(1, "%s", _PATH_FORTUNE);
135 } 135 }
136 136
137 char buf[128], buf2[8 * sizeof(buf)]; 137 char buf[128], buf2[8 * sizeof(buf)];
138 while (fgets(buf, sizeof buf, f) != NULL) { 138 while (fgets(buf, sizeof buf, f) != NULL) {
139 char *s = strrchr(buf, '\n'); 139 char *s = strrchr(buf, '\n');
@@ -157,96 +157,93 @@ readquote(void) @@ -157,96 +157,93 @@ readquote(void)
157 buf2[j] = '\0'; 157 buf2[j] = '\0';
158 158
159 stringarray_add(&lines, buf2); 159 stringarray_add(&lines, buf2);
160 stringarray_add(&sollines, buf2); 160 stringarray_add(&sollines, buf2);
161 } 161 }
162 162
163 pclose(f); 163 pclose(f);
164} 164}
165 165
166static void 166static void
167encode(void) 167encode(void)
168{ 168{
169 int key[26]; 169 int key[26];
 170
170 for (int i = 0; i < 26; i++) 171 for (int i = 0; i < 26; i++)
171 key[i] = i; 172 key[i] = i;
 173
172 for (int i = 26; i > 1; i--) { 174 for (int i = 26; i > 1; i--) {
173 int c = random() % i; 175 int c = (int)(random() % i);
174 int t = key[i - 1]; 176 int t = key[i - 1];
175 key[i - 1] = key[c]; 177 key[i - 1] = key[c];
176 key[c] = t; 178 key[c] = t;
177 } 179 }
178 180
179 for (int y = 0; y < lines.num; y++) { 181 for (int y = 0; y < (int)lines.num; y++) {
180 for (unsigned x = 0; lines.v[y][x] != '\0'; x++) { 182 for (char *p = lines.v[y]; *p != '\0'; p++) {
181 if (ch_islower(lines.v[y][x])) { 183 if (ch_islower(*p))
182 int q = lines.v[y][x] - 'a'; 184 *p = (char)('a' + key[*p - 'a']);
183 lines.v[y][x] = 'a' + key[q]; 185 if (ch_isupper(*p))
184 } 186 *p = (char)('A' + key[*p - 'A']);
185 if (ch_isupper(lines.v[y][x])) { 
186 int q = lines.v[y][x] - 'A'; 
187 lines.v[y][x] = 'A' + key[q]; 
188 } 
189 } 187 }
190 } 188 }
191} 189}
192 190
193static bool 191static bool
194substitute(int ch) 192substitute(char ch)
195{ 193{
196 assert(cury >= 0 && cury < lines.num); 194 assert(cury >= 0 && cury < (int)lines.num);
197 if (curx >= strlen(lines.v[cury])) { 195 if (curx >= (int)strlen(lines.v[cury])) {
198 beep(); 196 beep();
199 return false; 197 return false;
200 } 198 }
201 199
202 char och = lines.v[cury][curx]; 200 char och = lines.v[cury][curx];
203 if (!ch_isalpha(och)) { 201 if (!ch_isalpha(och)) {
204 beep(); 202 beep();
205 return false; 203 return false;
206 } 204 }
207 205
208 char loch = ch_tolower(och); 206 char loch = ch_tolower(och);
209 char uoch = ch_toupper(och); 207 char uoch = ch_toupper(och);
210 char lch = ch_tolower(ch); 208 char lch = ch_tolower(ch);
211 char uch = ch_toupper(ch); 209 char uch = ch_toupper(ch);
212 210
213 for (int y = 0; y < lines.num; y++) { 211 for (int y = 0; y < (int)lines.num; y++) {
214 for (unsigned x = 0; lines.v[y][x] != '\0'; x++) { 212 for (char *p = lines.v[y]; *p != '\0'; p++) {
215 if (lines.v[y][x] == loch) { 213 if (*p == loch)
216 lines.v[y][x] = lch; 214 *p = lch;
217 } else if (lines.v[y][x] == uoch) { 215 else if (*p == uoch)
218 lines.v[y][x] = uch; 216 *p = uch;
219 } else if (lines.v[y][x] == lch) { 217 else if (*p == lch)
220 lines.v[y][x] = loch; 218 *p = loch;
221 } else if (lines.v[y][x] == uch) { 219 else if (*p == uch)
222 lines.v[y][x] = uoch; 220 *p = uoch;
223 } 
224 } 221 }
225 } 222 }
226 return true; 223 return true;
227} 224}
228 225
229//////////////////////////////////////////////////////////// 226////////////////////////////////////////////////////////////
230 227
231static void 228static void
232redraw(void) 229redraw(void)
233{ 230{
234 erase(); 231 erase();
235 bool won = true; 232 bool won = true;
236 for (int i = 0; i < LINES - 1; i++) { 233 for (int i = 0; i < LINES - 1; i++) {
237 move(i, 0); 234 move(i, 0);
238 int ln = i + scrolldown; 235 int ln = i + scrolldown;
239 if (ln < lines.num) { 236 if (ln < (int)lines.num) {
240 for (unsigned j = 0; lines.v[i][j] != '\0'; j++) { 237 for (unsigned j = 0; lines.v[i][j] != '\0'; j++) {
241 char ch = lines.v[i][j]; 238 char ch = lines.v[i][j];
242 if (ch != sollines.v[i][j] && ch_isalpha(ch)) { 239 if (ch != sollines.v[i][j] && ch_isalpha(ch)) {
243 won = false; 240 won = false;
244 } 241 }
245 bool bold = false; 242 bool bold = false;
246 if (hinting && ch == sollines.v[i][j] && 243 if (hinting && ch == sollines.v[i][j] &&
247 ch_isalpha(ch)) { 244 ch_isalpha(ch)) {
248 bold = true; 245 bold = true;
249 attron(A_BOLD); 246 attron(A_BOLD);
250 } 247 }
251 addch(lines.v[i][j]); 248 addch(lines.v[i][j]);
252 if (bold) { 249 if (bold) {
@@ -294,110 +291,110 @@ loop(void) @@ -294,110 +291,110 @@ loop(void)
294 redraw(); 291 redraw();
295 int ch = getch(); 292 int ch = getch();
296 switch (ch) { 293 switch (ch) {
297 case 1: /* ^A */ 294 case 1: /* ^A */
298 case KEY_HOME: 295 case KEY_HOME:
299 curx = 0; 296 curx = 0;
300 break; 297 break;
301 case 2: /* ^B */ 298 case 2: /* ^B */
302 case KEY_LEFT: 299 case KEY_LEFT:
303 if (curx > 0) { 300 if (curx > 0) {
304 curx--; 301 curx--;
305 } else if (cury > 0) { 302 } else if (cury > 0) {
306 cury--; 303 cury--;
307 curx = strlen(lines.v[cury]); 304 curx = (int)strlen(lines.v[cury]);
308 } 305 }
309 break; 306 break;
310 case 5: /* ^E */ 307 case 5: /* ^E */
311 case KEY_END: 308 case KEY_END:
312 curx = strlen(lines.v[cury]); 309 curx = (int)strlen(lines.v[cury]);
313 break; 310 break;
314 case 6: /* ^F */ 311 case 6: /* ^F */
315 case KEY_RIGHT: 312 case KEY_RIGHT:
316 if (curx < strlen(lines.v[cury])) { 313 if (curx < (int)strlen(lines.v[cury])) {
317 curx++; 314 curx++;
318 } else if (cury < lines.num - 1) { 315 } else if (cury < (int)lines.num - 1) {
319 cury++; 316 cury++;
320 curx = 0; 317 curx = 0;
321 } 318 }
322 break; 319 break;
323 case 12: /* ^L */ 320 case 12: /* ^L */
324 clear(); 321 clear();
325 break; 322 break;
326 case 14: /* ^N */ 323 case 14: /* ^N */
327 case KEY_DOWN: 324 case KEY_DOWN:
328 if (cury < lines.num - 1) { 325 if (cury < (int)lines.num - 1) {
329 cury++; 326 cury++;
330 } 327 }
331 if (curx > strlen(lines.v[cury])) { 328 if (curx > (int)strlen(lines.v[cury])) {
332 curx = strlen(lines.v[cury]); 329 curx = (int)strlen(lines.v[cury]);
333 } 330 }
334 if (scrolldown < cury - (LINES - 2)) { 331 if (scrolldown < cury - (LINES - 2)) {
335 scrolldown = cury - (LINES - 2); 332 scrolldown = cury - (LINES - 2);
336 } 333 }
337 break; 334 break;
338 case 16: /* ^P */ 335 case 16: /* ^P */
339 case KEY_UP: 336 case KEY_UP:
340 if (cury > 0) { 337 if (cury > 0) {
341 cury--; 338 cury--;
342 } 339 }
343 if (curx > strlen(lines.v[cury])) { 340 if (curx > (int)strlen(lines.v[cury])) {
344 curx = strlen(lines.v[cury]); 341 curx = (int)strlen(lines.v[cury]);
345 } 342 }
346 if (scrolldown > cury) { 343 if (scrolldown > cury) {
347 scrolldown = cury; 344 scrolldown = cury;
348 } 345 }
349 break; 346 break;
350 case '*': 347 case '*':
351 hinting = !hinting; 348 hinting = !hinting;
352 break; 349 break;
353 case '~': 350 case '~':
354 done = true; 351 done = true;
355 break; 352 break;
356 default: 353 default:
357 if (isascii(ch) && isalpha(ch)) { 354 if (isascii(ch) && ch_isalpha((char)ch)) {
358 if (substitute(ch)) { 355 if (substitute((char)ch)) {
359 if (curx < strlen(lines.v[cury])) { 356 if (curx < (int)strlen(lines.v[cury])) {
360 curx++; 357 curx++;
361 } 358 }
362 if (curx == strlen(lines.v[cury]) && 359 if (curx == (int)strlen(lines.v[cury]) &&
363 cury < lines.num - 1) { 360 cury < (int)lines.num - 1) {
364 curx = 0; 361 curx = 0;
365 cury++; 362 cury++;
366 } 363 }
367 } 364 }
368 } else if (curx < strlen(lines.v[cury]) && 365 } else if (curx < (int)strlen(lines.v[cury]) &&
369 ch == lines.v[cury][curx]) { 366 ch == lines.v[cury][curx]) {
370 curx++; 367 curx++;
371 if (curx == strlen(lines.v[cury]) && 368 if (curx == (int)strlen(lines.v[cury]) &&
372 cury < lines.num - 1) { 369 cury < (int)lines.num - 1) {
373 curx = 0; 370 curx = 0;
374 cury++; 371 cury++;
375 } 372 }
376 } else { 373 } else {
377 beep(); 374 beep();
378 } 375 }
379 break; 376 break;
380 } 377 }
381 } 378 }
382} 379}
383 380
384//////////////////////////////////////////////////////////// 381////////////////////////////////////////////////////////////
385 382
386int 383int
387main(void) 384main(void)
388{ 385{
389 386
390 stringarray_init(&lines); 387 stringarray_init(&lines);
391 stringarray_init(&sollines); 388 stringarray_init(&sollines);
392 srandom(time(NULL)); 389 srandom((unsigned int)time(NULL));
393 readquote(); 390 readquote();
394 encode(); 391 encode();
395 opencurses(); 392 opencurses();
396 393
397 keypad(stdscr, true); 394 keypad(stdscr, true);
398 loop(); 395 loop();
399 396
400 closecurses(); 397 closecurses();
401 stringarray_cleanup(&sollines); 398 stringarray_cleanup(&sollines);
402 stringarray_cleanup(&lines); 399 stringarray_cleanup(&lines);
403} 400}