magic numbers, show usage, fixed linty warnings

Show usage when using bad parameter with ./advent
Converted magic numbers to enums for BUG().  Also bug now shows
stringify'ed version of bug enumeration (not just a number).
This commit is contained in:
Bob Little 2017-06-18 19:33:21 -04:00
parent 65e2e472dd
commit 04eca720d9
10 changed files with 140 additions and 116 deletions

2
.gitignore vendored
View file

@ -5,10 +5,10 @@ dungeon
*.o *.o
*.html *.html
database.h database.h
database.c
advent.6 advent.6
*.tar.gz *.tar.gz
MANIFEST MANIFEST
*.adv *.adv
.*~
newdb.h newdb.h
newdb.c newdb.c

View file

@ -24,6 +24,8 @@
# #
# To build with save/resume disabled, pass CCFLAGS="-D ADVENT_NOSAVE" # To build with save/resume disabled, pass CCFLAGS="-D ADVENT_NOSAVE"
.PHONY: debug indent release refresh dist linty html clean
VERS=1.0 VERS=1.0
CC?=gcc CC?=gcc
@ -118,7 +120,25 @@ refresh: advent.html
dist: advent-$(VERS).tar.gz dist: advent-$(VERS).tar.gz
linty: CCFLAGS += -W -Wall -Wextra -Wundef -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wfloat-equal -Wcast-align -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-enum -Wwrite-strings -Wunreachable-code -Winit-self -Wpointer-arith -O2 linty: CCFLAGS += -W
linty: CCFLAGS += -Wall
linty: CCFLAGS += -Wextra
linty: CCFLAGS += -Wundef
linty: CCFLAGS += -Wstrict-prototypes
linty: CCFLAGS += -Wmissing-prototypes
linty: CCFLAGS += -Wmissing-declarations
linty: CCFLAGS += -Wshadow
linty: CCFLAGS += -Wfloat-equal
linty: CCFLAGS += -Wcast-align
linty: CCFLAGS += -Wwrite-strings
linty: CCFLAGS += -Waggregate-return
linty: CCFLAGS += -Wcast-qual
linty: CCFLAGS += -Wswitch-enum
linty: CCFLAGS += -Wwrite-strings
linty: CCFLAGS += -Wunreachable-code
linty: CCFLAGS += -Winit-self
linty: CCFLAGS += -Wpointer-arith
linty: CCFLAGS +=-O2
linty: advent linty: advent
debug: CCFLAGS += -O0 --coverage -g debug: CCFLAGS += -O0 --coverage -g

View file

@ -789,7 +789,7 @@ static int pour(token_t verb, token_t obj)
} }
} }
static int quit(FILE *input) static int quit(void)
/* Quit. Intransitive only. Verify intent and exit if that's what he wants. */ /* Quit. Intransitive only. Verify intent and exit if that's what he wants. */
{ {
if (YES(REALLY_QUIT, OK_MAN, OK_MAN)) if (YES(REALLY_QUIT, OK_MAN, OK_MAN))
@ -797,7 +797,7 @@ static int quit(FILE *input)
return GO_CLEAROBJ; return GO_CLEAROBJ;
} }
static int read(FILE *input, token_t verb, token_t obj) static int read(token_t verb, token_t obj)
/* Read. Print stuff based on objtxt. Oyster (?) is special case. */ /* Read. Print stuff based on objtxt. Oyster (?) is special case. */
{ {
int spk = ACTSPK[verb]; int spk = ACTSPK[verb];
@ -1100,7 +1100,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
case 16: /* TOSS */ case 16: /* TOSS */
return GO_UNKNOWN; return GO_UNKNOWN;
case 17: /* QUIT */ case 17: /* QUIT */
return quit(input); return quit();
case 18: /* FIND */ case 18: /* FIND */
return GO_UNKNOWN; return GO_UNKNOWN;
case 19: /* INVEN */ case 19: /* INVEN */
@ -1120,15 +1120,15 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
case 25: /* BRIEF */ case 25: /* BRIEF */
return brief(); return brief();
case 26: /* READ */ case 26: /* READ */
return read(input, verb, INTRANSITIVE); return read(verb, INTRANSITIVE);
case 27: /* BREAK */ case 27: /* BREAK */
return GO_UNKNOWN; return GO_UNKNOWN;
case 28: /* WAKE */ case 28: /* WAKE */
return GO_UNKNOWN; return GO_UNKNOWN;
case 29: /* SUSP */ case 29: /* SUSP */
return suspend(input); return suspend();
case 30: /* RESU */ case 30: /* RESU */
return resume(input); return resume();
case 31: /* FLY */ case 31: /* FLY */
return fly(verb, INTRANSITIVE); return fly(verb, INTRANSITIVE);
case 32: /* LISTE */ case 32: /* LISTE */
@ -1136,7 +1136,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
case 33: /* ZZZZ */ case 33: /* ZZZZ */
return reservoir(); return reservoir();
} }
BUG(23); BUG(INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST);
} }
/* FALLTHRU */ /* FALLTHRU */
case transitive: case transitive:
@ -1210,7 +1210,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
return GO_CLEAROBJ; return GO_CLEAROBJ;
} }
case 26: /* READ */ case 26: /* READ */
return read(input, verb, obj); return read(verb, obj);
case 27: /* BREAK */ case 27: /* BREAK */
return vbreak(verb, obj); return vbreak(verb, obj);
case 28: /* WAKE */ case 28: /* WAKE */
@ -1232,13 +1232,13 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
case 33: /* ZZZZ */ case 33: /* ZZZZ */
return reservoir(); return reservoir();
} }
BUG(24); BUG(TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST);
case unknown: case unknown:
/* Unknown verb, couldn't deduce object - might need hint */ /* Unknown verb, couldn't deduce object - might need hint */
SETPRM(1, WD1, WD1X); SETPRM(1, WD1, WD1X);
RSPEAK(WHAT_DO); RSPEAK(WHAT_DO);
return GO_CHECKHINT; return GO_CHECKHINT;
default: default:
BUG(99); BUG(SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN);
} }
} }

View file

@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include "common.h" #include "common.h"
@ -106,7 +107,6 @@ extern long ATDWRF(long);
extern long SETBIT(long); extern long SETBIT(long);
extern bool TSTBIT(long,int); extern bool TSTBIT(long,int);
extern long RNDVOC(long,long); extern long RNDVOC(long,long);
extern void BUG(long) __attribute__((noreturn));
extern bool MAPLIN(FILE *); extern bool MAPLIN(FILE *);
extern void DATIME(long*, long*); extern void DATIME(long*, long*);
@ -117,8 +117,8 @@ extern unsigned long get_next_lcg_value(void);
extern long randrange(long); extern long randrange(long);
extern long score(enum termination); extern long score(enum termination);
extern void terminate(enum termination) __attribute__((noreturn)); extern void terminate(enum termination) __attribute__((noreturn));
extern int suspend(FILE *); extern int suspend(void);
extern int resume(FILE *); extern int resume(void);
extern int restore(FILE *); extern int restore(FILE *);
/* /*

View file

@ -1,3 +1,5 @@
#include <stdlib.h>
#include <stdio.h>
#include "common.h" #include "common.h"
const char advent_to_ascii[] = { const char advent_to_ascii[] = {

View file

@ -1,3 +1,5 @@
#ifndef COMMON_H
#define COMMON_H
/* maximum size limits shared by dungeon compiler and runtime */ /* maximum size limits shared by dungeon compiler and runtime */
#define LOCSIZ 185 #define LOCSIZ 185
@ -6,3 +8,41 @@
extern const char advent_to_ascii[128]; extern const char advent_to_ascii[128];
extern const char ascii_to_advent[128]; extern const char ascii_to_advent[128];
enum bug_e {
MESSAGE_LINE_GT_70_CHARACTERS, // 0
NULL_LINE_IN_MESSAGE, // 1
TOO_MANY_WORDS_OF_MESSAGES, // 2
TOO_MANY_TRAVEL_OPTIONS, // 3
TOO_MANY_VOCABULARY_WORDS, // 4
REQUIRED_VOCABULARY_WORD_NOT_FOUND, // 5
TOO_MANY_RTEXT_MESSAGES, // 6
TOO_MANY_HINTS, // 7
LOCATION_HAS_CONDITION_BIT_BEING_SET_TWICE, // 8
INVALID_SECTION_NUMBER_IN_DATABASE, // 9
TOO_MANY_LOCATIONS, // 10
TOO_MANY_CLASS_OR_TURN_MESSAGES, // 11
SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST = 20, // 20
RAN_OFF_END_OF_VOCABULARY_TABLE, // 21
VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3, // 22
INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, // 23
TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, // 24
CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION, // 25
LOCATION_HAS_NO_TRAVEL_ENTRIES, // 26
HINT_NUMBER_EXCEEDS_GOTO_LIST, // 27
INVALID_MOTH_RETURNED_BY_DATA_FUNCTION, // 28
TOO_MANY_PARAMETERS_GIVEN_TO_SETPRM, // 29
SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN=99, // 99
ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH, // 100
};
static inline void bug(enum bug_e num, const char *error_string) __attribute__((__noreturn__));
static inline void bug(enum bug_e num, const char *error_string)
{
fprintf(stderr, "Fatal error %d, %s.\n", num, error_string);
exit(EXIT_FAILURE);
}
#define BUG(x) bug(x, #x)
#endif

View file

@ -3,7 +3,6 @@
* defining (mostly) invariant state. A couple of slots are messed with * defining (mostly) invariant state. A couple of slots are messed with
* at runtime. * at runtime.
*/ */
#include "common.h"
#define LINESIZE 100 #define LINESIZE 100
#define RTXSIZ 277 #define RTXSIZ 277
@ -20,6 +19,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <unistd.h> #include <unistd.h>
#include "common.h"
// Global variables for use in functions below that can gradually disappear as code is cleaned up // Global variables for use in functions below that can gradually disappear as code is cleaned up
static long LNLENG; static long LNLENG;
@ -114,38 +114,6 @@ static long GETTXT(long SKIP, long ONEWRD, long UPPER)
return (TEXT); return (TEXT);
} }
static void BUG(long NUM)
{
/* The following conditions are currently considered fatal bugs. Numbers < 20
* are detected while reading the database; the others occur at "run time".
* 0 Message line > 70 characters
* 1 Null line in message
* 2 Too many words of messages
* 3 Too many travel options
* 4 Too many vocabulary words
* 5 Required vocabulary word not found
* 6 Too many RTEXT messages
* 7 Too many hints
* 8 Location has cond bit being set twice
* 9 Invalid section number in database
* 10 Too many locations
* 11 Too many class or turn messages
* 20 Special travel (500>L>300) exceeds goto list
* 21 Ran off end of vocabulary table
* 22 Vocabulary type (N/1000) not between 0 and 3
* 23 Intransitive action verb exceeds goto list
* 24 Transitive action verb exceeds goto list
* 25 Conditional travel entry with no alternative
* 26 Location has no travel entries
* 27 Hint number exceeds goto list
* 28 Invalid month returned by date function
* 29 Too many parameters given to SETPRM */
fprintf(stderr, "Fatal error %ld. See source code for interpretation.\n", NUM);
exit(EXIT_FAILURE);
}
static void MAPLIN(FILE *OPENED) static void MAPLIN(FILE *OPENED)
{ {
/* Read a line of input, from the specified input source, /* Read a line of input, from the specified input source,
@ -236,12 +204,15 @@ static void read_messages(FILE* database, long sect)
long loc; long loc;
LINUSE = KK; LINUSE = KK;
loc = GETNUM(database); loc = GETNUM(database);
if (LNLENG >= LNPOSN + 70)BUG(0); if (LNLENG >= LNPOSN + 70)
BUG(MESSAGE_LINE_GT_70_CHARACTERS);
if (loc == -1) return; if (loc == -1) return;
if (LNLENG < LNPOSN)BUG(1); if (LNLENG < LNPOSN)
BUG(NULL_LINE_IN_MESSAGE);
do { do {
KK = KK + 1; KK = KK + 1;
if (KK >= LINSIZ)BUG(2); if (KK >= LINSIZ)
BUG(TOO_MANY_WORDS_OF_MESSAGES);
LINES[KK] = GETTXT(false, false, false); LINES[KK] = GETTXT(false, false, false);
} while (LINES[KK] != -1); } while (LINES[KK] != -1);
LINES[LINUSE] = KK; LINES[LINUSE] = KK;
@ -250,20 +221,23 @@ static void read_messages(FILE* database, long sect)
LINES[LINUSE] = -KK; LINES[LINUSE] = -KK;
if (sect == 14) { if (sect == 14) {
TRNVLS = TRNVLS + 1; TRNVLS = TRNVLS + 1;
if (TRNVLS > TRNSIZ)BUG(11); if (TRNVLS > TRNSIZ)
BUG(TOO_MANY_CLASS_OR_TURN_MESSAGES);
TTEXT[TRNVLS] = LINUSE; TTEXT[TRNVLS] = LINUSE;
TRNVAL[TRNVLS] = loc; TRNVAL[TRNVLS] = loc;
continue; continue;
} }
if (sect == 10) { if (sect == 10) {
CLSSES = CLSSES + 1; CLSSES = CLSSES + 1;
if (CLSSES > CLSMAX)BUG(11); if (CLSSES > CLSMAX)
BUG(TOO_MANY_CLASS_OR_TURN_MESSAGES);
CTEXT[CLSSES] = LINUSE; CTEXT[CLSSES] = LINUSE;
CVAL[CLSSES] = loc; CVAL[CLSSES] = loc;
continue; continue;
} }
if (sect == 6) { if (sect == 6) {
if (loc > RTXSIZ)BUG(6); if (loc > RTXSIZ)
BUG(TOO_MANY_RTEXT_MESSAGES);
RTEXT[loc] = LINUSE; RTEXT[loc] = LINUSE;
continue; continue;
} }
@ -271,7 +245,8 @@ static void read_messages(FILE* database, long sect)
if (loc > 0 && loc <= NOBJECTS)PTEXT[loc] = LINUSE; if (loc > 0 && loc <= NOBJECTS)PTEXT[loc] = LINUSE;
continue; continue;
} }
if (loc > LOCSIZ)BUG(10); if (loc > LOCSIZ)
BUG(TOO_MANY_LOCATIONS);
if (sect == 1) { if (sect == 1) {
LTEXT[loc] = LINUSE; LTEXT[loc] = LINUSE;
continue; continue;
@ -300,7 +275,8 @@ static void read_section3_stuff(FILE* database)
while ((L = GETNUM(NULL)) != 0) { while ((L = GETNUM(NULL)) != 0) {
TRAVEL[TRVS] = newloc * 1000 + L; TRAVEL[TRVS] = newloc * 1000 + L;
TRVS = TRVS + 1; TRVS = TRVS + 1;
if (TRVS == TRVSIZ)BUG(3); if (TRVS == TRVSIZ)
BUG(TOO_MANY_TRAVEL_OPTIONS);
} }
TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1]; TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1];
} }
@ -316,7 +292,7 @@ static void read_vocabulary(FILE* database)
if (KTAB[TABNDX] == -1) return; if (KTAB[TABNDX] == -1) return;
ATAB[TABNDX] = GETTXT(true, true, true); ATAB[TABNDX] = GETTXT(true, true, true);
} /* end loop */ } /* end loop */
BUG(4); BUG(TOO_MANY_VOCABULARY_WORDS);
} }
/* Read in the initial locations for each object. Also the immovability info. /* Read in the initial locations for each object. Also the immovability info.
@ -347,7 +323,8 @@ static void read_conditions(FILE* database)
while ((K = GETNUM(database)) != -1) { while ((K = GETNUM(database)) != -1) {
long loc; long loc;
while ((loc = GETNUM(NULL)) != 0) { while ((loc = GETNUM(NULL)) != 0) {
if (is_set(COND[loc], K)) BUG(8); if (is_set(COND[loc], K))
BUG(LOCATION_HAS_CONDITION_BIT_BEING_SET_TWICE);
COND[loc] = COND[loc] + (1l << K); COND[loc] = COND[loc] + (1l << K);
} }
} }
@ -360,7 +337,8 @@ static void read_hints(FILE* database)
long K; long K;
HNTMAX = 0; HNTMAX = 0;
while ((K = GETNUM(database)) != -1) { while ((K = GETNUM(database)) != -1) {
if (K <= 0 || K > HNTSIZ)BUG(7); if (K <= 0 || K > HNTSIZ)
BUG(TOO_MANY_HINTS);
for (int I = 1; I <= 4; I++) { for (int I = 1; I <= 4; I++) {
HINTS[K][I] = GETNUM(NULL); HINTS[K][I] = GETNUM(NULL);
} /* end loop */ } /* end loop */
@ -473,7 +451,7 @@ static int read_database(FILE* database)
read_messages(database, sect); read_messages(database, sect);
break; break;
default: default:
BUG(9); BUG(INVALID_SECTION_NUMBER_IN_DATABASE);
} }
} }
} }

50
main.c
View file

@ -66,7 +66,7 @@ static void sig_handler(int signo)
* 15-treasure version (adventure) by Don Woods, April-June 1977 * 15-treasure version (adventure) by Don Woods, April-June 1977
* 20-treasure version (rev 2) by Don Woods, August 1978 * 20-treasure version (rev 2) by Don Woods, August 1978
* Errata fixed: 78/12/25 * Errata fixed: 78/12/25
* Revived 2017 as Open Advebture. * Revived 2017 as Open Adventure.
*/ */
static bool do_command(FILE *); static bool do_command(FILE *);
@ -102,6 +102,19 @@ int main(int argc, char *argv[])
case 's': case 's':
editline = false; editline = false;
break; break;
default:
fprintf(stderr,
"Usage: %s [-l logfilename] [-o] [-r restorefilename] [-s] \n", argv[0]);
fprintf(stderr,
" where -l creates a log file of your game named as specified'\n");
fprintf(stderr,
" -o 'oldstyle' (no prompt, no command editing, displays 'Initialising...')\n");
fprintf(stderr,
" -r indicates restoring from specified saved game file\n");
fprintf(stderr,
" -s indicates playing with command editing suppressed\n");
exit(-1);
break;
} }
} }
@ -174,7 +187,7 @@ static bool fallback_handler(char *buf)
* all come back here eventually to finish the loop. Ignore * all come back here eventually to finish the loop. Ignore
* "HINTS" < 4 (special stuff, see database notes). * "HINTS" < 4 (special stuff, see database notes).
*/ */
static void checkhints(FILE *cmdin) static void checkhints(void)
{ {
if (COND[game.loc] >= game.conds) { if (COND[game.loc] >= game.conds) {
for (int hint = 1; hint <= HNTMAX; hint++) { for (int hint = 1; hint <= HNTMAX; hint++) {
@ -245,7 +258,7 @@ static void checkhints(FILE *cmdin)
game.hintlc[hint] = 0; game.hintlc[hint] = 0;
return; return;
default: default:
BUG(27); BUG(HINT_NUMBER_EXCEEDS_GOTO_LIST);
break; break;
} }
@ -474,7 +487,7 @@ static bool dwarfmove(void)
* without the lamp!). game.oldloc is zapped so he can't just * without the lamp!). game.oldloc is zapped so he can't just
* "retreat". */ * "retreat". */
static void croak(FILE *cmdin) static void croak(void)
/* Okay, he's dead. Let's get on with it. */ /* Okay, he's dead. Let's get on with it. */
{ {
++game.numdie; ++game.numdie;
@ -511,12 +524,12 @@ static void croak(FILE *cmdin)
* him, so we need game.oldlc2, which is the last place he was * him, so we need game.oldlc2, which is the last place he was
* safe.) */ * safe.) */
static bool playermove(FILE *cmdin, token_t verb, int motion) static bool playermove(token_t verb, int motion)
{ {
int scratchloc, k2, kk = KEY[game.loc]; int scratchloc, k2, kk = KEY[game.loc];
game.newloc = game.loc; game.newloc = game.loc;
if (kk == 0) if (kk == 0)
BUG(26); BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES);
if (motion == NUL) if (motion == NUL)
return true; return true;
else if (motion == BACK) { else if (motion == BACK) {
@ -625,7 +638,8 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
break; break;
L12: L12:
do { do {
if (TRAVEL[kk] < 0)BUG(25); if (TRAVEL[kk] < 0)
BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION);
++kk; ++kk;
game.newloc = labs(TRAVEL[kk]) / 1000; game.newloc = labs(TRAVEL[kk]) / 1000;
} while } while
@ -687,10 +701,10 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
game.fixed[BEAR] = -1; game.fixed[BEAR] = -1;
game.prop[BEAR] = 3; game.prop[BEAR] = 3;
game.oldlc2 = game.newloc; game.oldlc2 = game.newloc;
croak(cmdin); croak();
} }
} }
BUG(20); BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST);
} }
} while } while
(false); (false);
@ -928,13 +942,13 @@ static bool do_command(FILE *cmdin)
game.loc = game.newloc; game.loc = game.newloc;
if (!dwarfmove()) if (!dwarfmove())
croak(cmdin); croak();
/* Describe the current location and (maybe) get next command. */ /* Describe the current location and (maybe) get next command. */
for (;;) { for (;;) {
if (game.loc == 0) if (game.loc == 0)
croak(cmdin); croak();
const char* msg = locations[game.loc].description.small; const char* msg = locations[game.loc].description.small;
if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == 0) if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == 0)
msg = locations[game.loc].description.big; msg = locations[game.loc].description.big;
@ -944,7 +958,7 @@ static bool do_command(FILE *cmdin)
if (game.wzdark && PCT(35)) { if (game.wzdark && PCT(35)) {
RSPEAK(PIT_FALL); RSPEAK(PIT_FALL);
game.oldlc2 = game.loc; game.oldlc2 = game.loc;
croak(cmdin); croak();
continue; /* back to top of main interpreter loop */ continue; /* back to top of main interpreter loop */
} }
msg = arbitrary_messages[PITCH_DARK]; msg = arbitrary_messages[PITCH_DARK];
@ -952,7 +966,7 @@ static bool do_command(FILE *cmdin)
if (TOTING(BEAR))RSPEAK(TAME_BEAR); if (TOTING(BEAR))RSPEAK(TAME_BEAR);
speak(msg); speak(msg);
if (FORCED(game.loc)) { if (FORCED(game.loc)) {
if (playermove(cmdin, verb, 1)) if (playermove(verb, 1))
return true; return true;
else else
continue; /* back to top of main interpreter loop */ continue; /* back to top of main interpreter loop */
@ -967,7 +981,7 @@ L2012:
obj = 0; obj = 0;
L2600: L2600:
checkhints(cmdin); checkhints();
/* If closing time, check for any objects being toted with /* If closing time, check for any objects being toted with
* game.prop < 0 and set the prop to -1-game.prop. This way * game.prop < 0 and set the prop to -1-game.prop. This way
@ -1062,7 +1076,7 @@ Lookup:
kmod = MOD(defn, 1000); kmod = MOD(defn, 1000);
switch (defn / 1000) { switch (defn / 1000) {
case 0: case 0:
if (playermove(cmdin, verb, kmod)) if (playermove(verb, kmod))
return true; return true;
else else
continue; /* back to top of main interpreter loop */ continue; /* back to top of main interpreter loop */
@ -1078,7 +1092,7 @@ Lookup:
RSPEAK(kmod); RSPEAK(kmod);
goto L2012; goto L2012;
default: default:
BUG(22); BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3);
} }
Laction: Laction:
@ -1086,7 +1100,7 @@ Laction:
case GO_TERMINATE: case GO_TERMINATE:
return true; return true;
case GO_MOVE: case GO_MOVE:
playermove(cmdin, verb, NUL); playermove(verb, NUL);
return true; return true;
case GO_TOP: case GO_TOP:
continue; /* back to top of main interpreter loop */ continue; /* back to top of main interpreter loop */
@ -1116,7 +1130,7 @@ Laction:
RSPEAK(DWARVES_AWAKEN); RSPEAK(DWARVES_AWAKEN);
terminate(endgame); terminate(endgame);
default: default:
BUG(99); BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH);
} }
} }
} }

42
misc.c
View file

@ -153,7 +153,7 @@ void SETPRM(long first, long p1, long p2)
* are stored into PARMS(first) and PARMS(first+1). */ * are stored into PARMS(first) and PARMS(first+1). */
{ {
if (first >= MAXPARMS) if (first >= MAXPARMS)
BUG(29); BUG(TOO_MANY_PARAMETERS_GIVEN_TO_SETPRM);
else { else {
PARMS[first] = p1; PARMS[first] = p1;
PARMS[first + 1] = p2; PARMS[first + 1] = p2;
@ -228,7 +228,7 @@ char* get_input()
size_t n = 0; size_t n = 0;
if (isatty(0)) if (isatty(0))
printf("%s", input_prompt); printf("%s", input_prompt);
getline(&input, &n, stdin); IGNORE(getline(&input, &n, stdin));
} }
if (input == NULL) // Got EOF; quit. if (input == NULL) // Got EOF; quit.
@ -268,7 +268,7 @@ bool YES(vocab_t question, vocab_t yes_response, vocab_t no_response)
char* firstword = (char*) xmalloc(strlen(reply)); char* firstword = (char*) xmalloc(strlen(reply));
sscanf(reply, "%s", firstword); sscanf(reply, "%s", firstword);
for (int i = 0; i < strlen(firstword); ++i) for (int i = 0; i < (int)strlen(firstword); ++i)
firstword[i] = tolower(firstword[i]); firstword[i] = tolower(firstword[i]);
int yes = strncmp("yes", firstword, sizeof("yes") - 1); int yes = strncmp("yes", firstword, sizeof("yes") - 1);
@ -384,7 +384,7 @@ long VOCAB(long id, long init)
lexeme = -1; lexeme = -1;
if (init < 0) if (init < 0)
return (lexeme); return (lexeme);
BUG(5); BUG(REQUIRED_VOCABULARY_WORD_NOT_FOUND);
} }
if (init >= 0 && KTAB[i] / 1000 != init) if (init >= 0 && KTAB[i] / 1000 != init)
continue; continue;
@ -395,7 +395,7 @@ long VOCAB(long id, long init)
return (lexeme); return (lexeme);
} }
} }
BUG(21); BUG(RAN_OFF_END_OF_VOCABULARY_TABLE);
} }
void JUGGLE(long object) void JUGGLE(long object)
@ -497,7 +497,7 @@ long ATDWRF(long where)
} }
/* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value, /* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value,
* randrange, RNDVOC, BUG) */ * randrange, RNDVOC) */
long SETBIT(long bit) long SETBIT(long bit)
/* Returns 2**bit for use in constructing bit-masks. */ /* Returns 2**bit for use in constructing bit-masks. */
@ -559,36 +559,6 @@ long RNDVOC(long second, long force)
return rnd; return rnd;
} }
void BUG(long num)
/* The following conditions are currently considered fatal bugs. Numbers < 20
* are detected while reading the database; the others occur at "run time".
* 0 Message line > 70 characters
* 1 Null line in message
* 2 Too many words of messages
* 3 Too many travel options
* 4 Too many vocabulary words
* 5 Required vocabulary word not found
* 6 Too many RTEXT messages
* 7 Too many hints
* 8 Location has cond bit being set twice
* 9 Invalid section number in database
* 10 Too many locations
* 11 Too many class or turn messages
* 20 Special travel (500>L>300) exceeds goto list
* 21 Ran off end of vocabulary table
* 22 Vocabulary type (N/1000) not between 0 and 3
* 23 Intransitive action verb exceeds goto list
* 24 Transitive action verb exceeds goto list
* 25 Conditional travel entry with no alternative
* 26 Location has no travel entries
* 27 Hint number exceeds goto list
* 28 Invalid month returned by date function
* 29 Too many parameters given to SETPRM */
{
printf("Fatal error %ld. See source code for interpretation.\n", num);
exit(0);
}
/* Machine dependent routines (MAPLIN, SAVEIO) */ /* Machine dependent routines (MAPLIN, SAVEIO) */

View file

@ -30,7 +30,7 @@ struct save_t {
struct save_t save; struct save_t save;
/* Suspend and resume */ /* Suspend and resume */
int suspend(FILE *input) int suspend(void)
{ {
/* Suspend. Offer to save things in a file, but charging /* Suspend. Offer to save things in a file, but charging
* some points (so can't win by using saved games to retry * some points (so can't win by using saved games to retry
@ -71,7 +71,7 @@ int suspend(FILE *input)
exit(0); exit(0);
} }
int resume(FILE *input) int resume(void)
{ {
/* Resume. Read a suspended game back from a file. /* Resume. Read a suspended game back from a file.
* If ADVENT_NOSAVE is defined, do nothing instead. */ * If ADVENT_NOSAVE is defined, do nothing instead. */