Bug Summary

File:src/games/hack/hack.read.c
Warning:line 453, column 11
The right operand of '*' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hack.read.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/hack/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I . -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/games/hack/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/games/hack/hack.read.c
1/* $OpenBSD: hack.read.c,v 1.9 2016/01/09 18:33:15 mestre Exp $ */
2
3/*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37/*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64#include <stdlib.h>
65
66#include "hack.h"
67
68static boolean monstersym(char);
69
70int
71doread(void)
72{
73 struct obj *scroll;
74 boolean confused = (Confusionu.uprops[(19 +2)].p_flgs != 0);
1
Assuming field 'p_flgs' is not equal to 0
75 boolean known = FALSE0;
76
77 scroll = getobj("?", "read");
78 if(!scroll) return(0);
2
Assuming 'scroll' is non-null
79 if(!scroll->dknown && Blindu.uprops[(19 +7)].p_flgs) {
3
Assuming field 'dknown' is not equal to 0
80 pline("Being blind, you cannot read the formula on the scroll.");
81 return(0);
82 }
83 if(Blindu.uprops[(19 +7)].p_flgs)
4
Assuming field 'p_flgs' is 0
5
Taking false branch
84 pline("As you pronounce the formula on it, the scroll disappears.");
85 else
86 pline("As you read the scroll, it disappears.");
87 if(confused
5.1
'confused' is 1
)
6
Taking true branch
88 pline("Being confused, you mispronounce the magic words ... ");
89
90 switch(scroll->otyp) {
7
Control jumps to 'case 149:' at line 435
91#ifdef MAIL
92 case SCR_MAIL130:
93 readmail(/* scroll */);
94 break;
95#endif /* MAIL */
96 case SCR_ENCHANT_ARMOR131:
97 { struct obj *otmp = some_armor();
98 if(!otmp) {
99 strange_feeling(scroll,"Your skin glows then fades.");
100 return(1);
101 }
102 if(confused) {
103 pline("Your %s glows silver for a moment.",
104 objects[otmp->otyp].oc_name);
105 otmp->rustfree = 1;
106 break;
107 }
108 if(otmp->spe > 3 && rn2(otmp->spe)) {
109 pline("Your %s glows violently green for a while, then evaporates.",
110 objects[otmp->otyp].oc_name);
111 useup(otmp);
112 break;
113 }
114 pline("Your %s glows green for a moment.",
115 objects[otmp->otyp].oc_name);
116 otmp->cursed = 0;
117 otmp->spe++;
118 break;
119 }
120 case SCR_DESTROY_ARMOR132:
121 if(confused) {
122 struct obj *otmp = some_armor();
123 if(!otmp) {
124 strange_feeling(scroll,"Your bones itch.");
125 return(1);
126 }
127 pline("Your %s glows purple for a moment.",
128 objects[otmp->otyp].oc_name);
129 otmp->rustfree = 0;
130 break;
131 }
132 if(uarm) {
133 pline("Your armor turns to dust and falls to the floor!");
134 useup(uarm);
135 } else if(uarmh) {
136 pline("Your helmet turns to dust and is blown away!");
137 useup(uarmh);
138 } else if(uarmg) {
139 pline("Your gloves vanish!");
140 useup(uarmg);
141 selftouch("You");
142 } else {
143 strange_feeling(scroll,"Your skin itches.");
144 return(1);
145 }
146 break;
147 case SCR_CONFUSE_MONSTER133:
148 if(confused) {
149 pline("Your hands begin to glow purple.");
150 Confusionu.uprops[(19 +2)].p_flgs += rnd(100);
151 } else {
152 pline("Your hands begin to glow blue.");
153 u.umconf = 1;
154 }
155 break;
156 case SCR_SCARE_MONSTER134:
157 { int ct = 0;
158 struct monst *mtmp;
159
160 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
161 if(cansee(mtmp->mx,mtmp->my)) {
162 if(confused)
163 mtmp->mflee = mtmp->mfroz =
164 mtmp->msleep = 0;
165 else
166 mtmp->mflee = 1;
167 ct++;
168 }
169 if(!ct) {
170 if(confused)
171 pline("You hear sad wailing in the distance.");
172 else
173 pline("You hear maniacal laughter in the distance.");
174 }
175 break;
176 }
177 case SCR_BLANK_PAPER135:
178 if(confused)
179 pline("You see strange patterns on this scroll.");
180 else
181 pline("This scroll seems to be blank.");
182 break;
183 case SCR_REMOVE_CURSE136:
184 { struct obj *obj;
185 if(confused)
186 pline("You feel like you need some help.");
187 else
188 pline("You feel like someone is helping you.");
189 for(obj = invent; obj ; obj = obj->nobj)
190 if(obj->owornmask)
191 obj->cursed = confused;
192 if(Punishedu.uprops[(19 +5)].p_flgs && !confused) {
193 Punishedu.uprops[(19 +5)].p_flgs = 0;
194 freeobj(uchain);
195 unpobj(uchain);
196 free(uchain);
197 uball->spe = 0;
198 uball->owornmask &= ~W_BALL02000L;
199 uchain = uball = (struct obj *) 0;
200 }
201 break;
202 }
203 case SCR_CREATE_MONSTER139:
204 { int cnt = 1;
205
206 if(!rn2(73)) cnt += rnd(4);
207 if(confused) cnt += 12;
208 while(cnt--)
209 (void) makemon(confused ? PM_ACID_BLOB&mons[7] :
210 (struct permonst *) 0, u.ux, u.uy);
211 break;
212 }
213 case SCR_ENCHANT_WEAPON137:
214 if(uwep && confused) {
215 pline("Your %s glows silver for a moment.",
216 objects[uwep->otyp].oc_name);
217 uwep->rustfree = 1;
218 } else
219 if(!chwepon(scroll, 1)) /* tests for !uwep */
220 return(1);
221 break;
222 case SCR_DAMAGE_WEAPON138:
223 if(uwep && confused) {
224 pline("Your %s glows purple for a moment.",
225 objects[uwep->otyp].oc_name);
226 uwep->rustfree = 0;
227 } else
228 if(!chwepon(scroll, -1)) /* tests for !uwep */
229 return(1);
230 break;
231 case SCR_TAMING140:
232 { int i,j;
233 int bd = confused ? 5 : 1;
234 struct monst *mtmp;
235
236 for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
237 if ((mtmp = m_at(u.ux+i, u.uy+j)))
238 (void) tamedog(mtmp, NULL((void *)0));
239 break;
240 }
241 case SCR_GENOCIDE141:
242 { extern char genocided[], fut_geno[];
243 char buf[BUFSZ256];
244 struct monst *mtmp, *mtmp2;
245
246 pline("You have found a scroll of genocide!");
247 known = TRUE1;
248 if(confused)
249 *buf = u.usym;
250 else do {
251 pline("What monster do you want to genocide (Type the letter)? ");
252 getlin(buf);
253 } while(strlen(buf) != 1 || !monstersym(*buf));
254 if(!strchr(fut_geno, *buf))
255 charcat(fut_geno, *buf);
256 if(!strchr(genocided, *buf))
257 charcat(genocided, *buf);
258 else {
259 pline("Such monsters do not exist in this world.");
260 break;
261 }
262 for(mtmp = fmon; mtmp; mtmp = mtmp2){
263 mtmp2 = mtmp->nmon;
264 if(mtmp->data->mlet == *buf)
265 mondead(mtmp);
266 }
267 pline("Wiped out all %c's.", *buf);
268 if(*buf == u.usym) {
269 killer = "scroll of genocide";
270 u.uhp = -1;
271 }
272 break;
273 }
274 case SCR_LIGHT142:
275 if(!Blindu.uprops[(19 +7)].p_flgs) known = TRUE1;
276 litroom(!confused);
277 break;
278 case SCR_TELEPORTATION143:
279 if(confused)
280 level_tele();
281 else {
282#ifdef QUEST
283 int oux = u.ux, ouy = u.uy;
284 tele();
285 if(dist(oux, ouy) > 100) known = TRUE1;
286#else /* QUEST */
287 int uroom = inroom(u.ux, u.uy);
288 tele();
289 if(uroom != inroom(u.ux, u.uy)) known = TRUE1;
290#endif /* QUEST */
291 }
292 break;
293 case SCR_GOLD_DETECTION144:
294 /* Unfortunately this code has become slightly less elegant,
295 now that gold and traps no longer are of the same type. */
296 if(confused) {
297 struct trap *ttmp;
298
299 if(!ftrap) {
300 strange_feeling(scroll, "Your toes stop itching.");
301 return(1);
302 } else {
303 for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
304 if(ttmp->tx != u.ux || ttmp->ty != u.uy)
305 goto outtrapmap;
306 /* only under me - no separate display required */
307 pline("Your toes itch!");
308 break;
309 outtrapmap:
310 cls();
311 for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
312 at(ttmp->tx, ttmp->ty, '$');
313 prme();
314 pline("You feel very greedy!");
315 }
316 } else {
317 struct gold *gtmp;
318
319 if(!fgold) {
320 strange_feeling(scroll, "You feel materially poor.");
321 return(1);
322 } else {
323 known = TRUE1;
324 for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
325 if(gtmp->gx != u.ux || gtmp->gy != u.uy)
326 goto outgoldmap;
327 /* only under me - no separate display required */
328 pline("You notice some gold between your feet.");
329 break;
330 outgoldmap:
331 cls();
332 for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
333 at(gtmp->gx, gtmp->gy, '$');
334 prme();
335 pline("You feel very greedy, and sense gold!");
336 }
337 }
338 /* common sequel */
339 more();
340 docrt();
341 break;
342 case SCR_FOOD_DETECTION145:
343 { int ct = 0, ctu = 0;
344 struct obj *obj;
345 char foodsym = confused ? POTION_SYM'!' : FOOD_SYM'%';
346
347 for(obj = fobj; obj; obj = obj->nobj)
348 if(obj->olet == FOOD_SYM'%') {
349 if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
350 else ct++;
351 }
352 if(!ct && !ctu) {
353 strange_feeling(scroll,"Your nose twitches.");
354 return(1);
355 } else if(!ct) {
356 known = TRUE1;
357 pline("You smell %s close nearby.",
358 confused ? "something" : "food");
359
360 } else {
361 known = TRUE1;
362 cls();
363 for(obj = fobj; obj; obj = obj->nobj)
364 if(obj->olet == foodsym)
365 at(obj->ox, obj->oy, FOOD_SYM'%');
366 prme();
367 pline("Your nose tingles and you smell %s!",
368 confused ? "something" : "food");
369 more();
370 docrt();
371 }
372 break;
373 }
374 case SCR_IDENTIFY146:
375 /* known = TRUE; */
376 if(confused)
377 pline("You identify this as an identify scroll.");
378 else
379 pline("This is an identify scroll.");
380 useup(scroll);
381 objects[SCR_IDENTIFY146].oc_name_known = 1;
382 if(!confused)
383 while(
384 !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
385 && invent
386 );
387 return(1);
388 case SCR_MAGIC_MAPPING147:
389 { struct rm *lev;
390 int num, zx, zy;
391
392 known = TRUE1;
393 pline("On this scroll %s a map!",
394 confused ? "was" : "is");
395 for(zy = 0; zy < ROWNO22; zy++)
396 for(zx = 0; zx < COLNO80; zx++) {
397 if(confused && rn2(7)) continue;
398 lev = &(levl[zx][zy]);
399 if((num = lev->typ) == 0)
400 continue;
401 if(num == SCORR4) {
402 lev->typ = CORR8;
403 lev->scrsym = CORR_SYM'#';
404 } else
405 if(num == SDOOR3) {
406 lev->typ = DOOR7;
407 lev->scrsym = '+';
408 /* do sth in doors ? */
409 } else if(lev->seen) continue;
410#ifndef QUEST
411 if(num != ROOM9)
412#endif /* QUEST */
413 {
414 lev->seen = lev->new = 1;
415 if(lev->scrsym == ' ' || !lev->scrsym)
416 newsym(zx,zy);
417 else
418 on_scr(zx,zy);
419 }
420 }
421 break;
422 }
423 case SCR_AMNESIA148:
424 { int zx, zy;
425
426 known = TRUE1;
427 for(zx = 0; zx < COLNO80; zx++) for(zy = 0; zy < ROWNO22; zy++)
428 if(!confused || rn2(7))
429 if(!cansee(zx,zy))
430 levl[zx][zy].seen = 0;
431 docrt();
432 pline("Thinking of Maud you forget everything else.");
433 break;
434 }
435 case SCR_FIRE149:
436 { int num;
8
'num' declared without an initial value
437 struct monst *mtmp;
438
439 known = TRUE1;
440 if(confused
8.1
'confused' is 1
) {
9
Taking true branch
441 pline("The scroll catches fire and you burn your hands.");
442 losehp(1, "scroll of fire");
443 } else {
444 pline("The scroll erupts in a tower of flame!");
445 if(Fire_resistanceu.uprops[10].p_flgs)
446 pline("You are uninjured.");
447 else {
448 num = rnd(6);
449 u.uhpmax -= num;
450 losehp(num, "scroll of fire");
451 }
452 }
453 num = (2*num + 1)/3;
10
The right operand of '*' is a garbage value
454 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
455 if(dist(mtmp->mx,mtmp->my) < 3) {
456 mtmp->mhp -= num;
457 if(strchr("FY", mtmp->data->mlet))
458 mtmp->mhp -= 3*num; /* this might well kill 'F's */
459 if(mtmp->mhp < 1) {
460 killed(mtmp);
461 break; /* primitive */
462 }
463 }
464 }
465 break;
466 }
467 case SCR_PUNISHMENT150:
468 known = TRUE1;
469 if(confused) {
470 pline("You feel guilty.");
471 break;
472 }
473 pline("You are being punished for your misbehaviour!");
474 if(Punishedu.uprops[(19 +5)].p_flgs){
475 pline("Your iron ball gets heavier.");
476 uball->owt += 15;
477 break;
478 }
479 Punishedu.uprops[(19 +5)].p_flgs = INTRINSIC040000L;
480 setworn(mkobj_at(CHAIN_SYM'_', u.ux, u.uy), W_CHAIN04000L);
481 setworn(mkobj_at(BALL_SYM'0', u.ux, u.uy), W_BALL02000L);
482 uball->spe = 1; /* special ball (see save) */
483 break;
484 default:
485 impossible("What weird language is this written in? (%u)",
486 scroll->otyp);
487 }
488 if(!objects[scroll->otyp].oc_name_known) {
489 if(known && !confused) {
490 objects[scroll->otyp].oc_name_known = 1;
491 more_experienced(0,10);
492 } else if(!objects[scroll->otyp].oc_uname)
493 docall(scroll);
494 }
495 useup(scroll);
496 return(1);
497}
498
499/* also called by newmail() */
500int
501identify(struct obj *otmp)
502{
503 objects[otmp->otyp].oc_name_known = 1;
504 otmp->known = otmp->dknown = 1;
505 prinv(otmp);
506 return(1);
507}
508
509void
510litroom(boolean on)
511{
512 int num,zx,zy;
513
514 /* first produce the text (provided he is not blind) */
515 if(Blindu.uprops[(19 +7)].p_flgs) goto do_it;
516 if(!on) {
517 if(u.uswallow || !xdnstair ||
518 levl[(int)u.ux][(int)u.uy].typ == CORR8 ||
519 !levl[(int)u.ux][(int)u.uy].lit) {
520 pline("It seems even darker in here than before.");
521 return;
522 } else
523 pline("It suddenly becomes dark in here.");
524 } else {
525 if(u.uswallow){
526 pline("%s's stomach is lit.", Monnam(u.ustuck));
527 return;
528 }
529 if(!xdnstair){
530 pline("Nothing Happens.");
531 return;
532 }
533#ifdef QUEST
534 pline("The cave lights up around you, then fades.");
535 return;
536#else /* QUEST */
537 if (levl[(int)u.ux][(int)u.uy].typ == CORR8) {
538 pline("The corridor lights up around you, then fades.");
539 return;
540 } else if (levl[(int)u.ux][(int)u.uy].lit) {
541 pline("The light here seems better now.");
542 return;
543 } else
544 pline("The room is lit.");
545#endif /* QUEST */
546 }
547
548do_it:
549#ifdef QUEST
550 return;
551#else /* QUEST */
552 if (levl[(int)u.ux][(int)u.uy].lit == on)
553 return;
554 if (levl[(int)u.ux][(int)u.uy].typ == DOOR7) {
555 if (IS_ROOM(levl[(int)u.ux][(int)u.uy+1].typ)((levl[(int)u.ux][(int)u.uy+1].typ) >= 9))
556 zy = u.uy+1;
557 else if(IS_ROOM(levl[(int)u.ux][u.uy-1].typ)((levl[(int)u.ux][u.uy-1].typ) >= 9))
558 zy = u.uy-1;
559 else zy = u.uy;
560 if(IS_ROOM(levl[u.ux+1][(int)u.uy].typ)((levl[u.ux+1][(int)u.uy].typ) >= 9))
561 zx = u.ux+1;
562 else if(IS_ROOM(levl[u.ux-1][(int)u.uy].typ)((levl[u.ux-1][(int)u.uy].typ) >= 9))
563 zx = u.ux-1;
564 else zx = u.ux;
565 } else {
566 zx = u.ux;
567 zy = u.uy;
568 }
569 for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR8 && num != 0;
570 seelx--);
571 for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR8 && num != 0;
572 seehx++);
573 for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR8 && num != 0;
574 seely--);
575 for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR8 && num != 0;
576 seehy++);
577 for(zy = seely; zy <= seehy; zy++)
578 for(zx = seelx; zx <= seehx; zx++) {
579 levl[zx][zy].lit = on;
580 if (!Blindu.uprops[(19 +7)].p_flgs && dist(zx,zy) > 2) {
581 if(on)
582 prl(zx,zy);
583 else
584 nosee(zx,zy);
585 }
586 }
587 if(!on)
588 seehx = 0;
589#endif /* QUEST */
590}
591
592/* Test whether we may genocide all monsters with symbol ch */
593/* arnold@ucsfcgl */
594static boolean
595monstersym(char ch)
596{
597 struct permonst *mp;
598 extern struct permonst pm_eel;
599
600 /*
601 * can't genocide certain monsters
602 */
603 if (strchr("12 &:", ch))
604 return FALSE0;
605
606 if (ch == pm_eel.mlet)
607 return TRUE1;
608 for (mp = mons; mp < &mons[CMNUM55+2]; mp++)
609 if (mp->mlet == ch)
610 return TRUE1;
611 return FALSE0;
612}