From 04eca720d9a5282b47f51c5d19910a094f3d1882 Mon Sep 17 00:00:00 2001 From: Bob Little Date: Sun, 18 Jun 2017 19:33:21 -0400 Subject: [PATCH] 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). --- .gitignore | 2 +- Makefile | 22 ++++++++++++++++- actions.c | 20 ++++++++-------- advent.h | 6 ++--- common.c | 2 ++ common.h | 40 +++++++++++++++++++++++++++++++ dungeon.c | 68 ++++++++++++++++++---------------------------------- main.c | 50 ++++++++++++++++++++++++-------------- misc.c | 42 +++++--------------------------- saveresume.c | 4 ++-- 10 files changed, 140 insertions(+), 116 deletions(-) diff --git a/.gitignore b/.gitignore index 6311696..1e3ef43 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,10 @@ dungeon *.o *.html database.h -database.c advent.6 *.tar.gz MANIFEST *.adv +.*~ newdb.h newdb.c diff --git a/Makefile b/Makefile index 80f1c12..1179507 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,8 @@ # # To build with save/resume disabled, pass CCFLAGS="-D ADVENT_NOSAVE" +.PHONY: debug indent release refresh dist linty html clean + VERS=1.0 CC?=gcc @@ -118,7 +120,25 @@ refresh: advent.html 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 debug: CCFLAGS += -O0 --coverage -g diff --git a/actions.c b/actions.c index 5348d3d..7ade463 100644 --- a/actions.c +++ b/actions.c @@ -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. */ { if (YES(REALLY_QUIT, OK_MAN, OK_MAN)) @@ -797,7 +797,7 @@ static int quit(FILE *input) 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. */ { int spk = ACTSPK[verb]; @@ -1100,7 +1100,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj) case 16: /* TOSS */ return GO_UNKNOWN; case 17: /* QUIT */ - return quit(input); + return quit(); case 18: /* FIND */ return GO_UNKNOWN; case 19: /* INVEN */ @@ -1120,15 +1120,15 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj) case 25: /* BRIEF */ return brief(); case 26: /* READ */ - return read(input, verb, INTRANSITIVE); + return read(verb, INTRANSITIVE); case 27: /* BREAK */ return GO_UNKNOWN; case 28: /* WAKE */ return GO_UNKNOWN; case 29: /* SUSP */ - return suspend(input); + return suspend(); case 30: /* RESU */ - return resume(input); + return resume(); case 31: /* FLY */ return fly(verb, INTRANSITIVE); case 32: /* LISTE */ @@ -1136,7 +1136,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj) case 33: /* ZZZZ */ return reservoir(); } - BUG(23); + BUG(INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST); } /* FALLTHRU */ case transitive: @@ -1210,7 +1210,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj) return GO_CLEAROBJ; } case 26: /* READ */ - return read(input, verb, obj); + return read(verb, obj); case 27: /* BREAK */ return vbreak(verb, obj); case 28: /* WAKE */ @@ -1232,13 +1232,13 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj) case 33: /* ZZZZ */ return reservoir(); } - BUG(24); + BUG(TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST); case unknown: /* Unknown verb, couldn't deduce object - might need hint */ SETPRM(1, WD1, WD1X); RSPEAK(WHAT_DO); return GO_CHECKHINT; default: - BUG(99); + BUG(SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN); } } diff --git a/advent.h b/advent.h index d23d8fd..bc3c1cc 100644 --- a/advent.h +++ b/advent.h @@ -1,4 +1,5 @@ #include +#include #include #include "common.h" @@ -106,7 +107,6 @@ extern long ATDWRF(long); extern long SETBIT(long); extern bool TSTBIT(long,int); extern long RNDVOC(long,long); -extern void BUG(long) __attribute__((noreturn)); extern bool MAPLIN(FILE *); extern void DATIME(long*, long*); @@ -117,8 +117,8 @@ extern unsigned long get_next_lcg_value(void); extern long randrange(long); extern long score(enum termination); extern void terminate(enum termination) __attribute__((noreturn)); -extern int suspend(FILE *); -extern int resume(FILE *); +extern int suspend(void); +extern int resume(void); extern int restore(FILE *); /* diff --git a/common.c b/common.c index a53f4f5..8418a09 100644 --- a/common.c +++ b/common.c @@ -1,3 +1,5 @@ +#include +#include #include "common.h" const char advent_to_ascii[] = { diff --git a/common.h b/common.h index 0fadd5e..3df8b0c 100644 --- a/common.h +++ b/common.h @@ -1,3 +1,5 @@ +#ifndef COMMON_H +#define COMMON_H /* maximum size limits shared by dungeon compiler and runtime */ #define LOCSIZ 185 @@ -6,3 +8,41 @@ extern const char advent_to_ascii[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 diff --git a/dungeon.c b/dungeon.c index 1ca2832..ffa5140 100644 --- a/dungeon.c +++ b/dungeon.c @@ -3,7 +3,6 @@ * defining (mostly) invariant state. A couple of slots are messed with * at runtime. */ -#include "common.h" #define LINESIZE 100 #define RTXSIZ 277 @@ -20,6 +19,7 @@ #include #include #include +#include "common.h" // Global variables for use in functions below that can gradually disappear as code is cleaned up static long LNLENG; @@ -114,38 +114,6 @@ static long GETTXT(long SKIP, long ONEWRD, long UPPER) 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) { /* Read a line of input, from the specified input source, @@ -236,12 +204,15 @@ static void read_messages(FILE* database, long sect) long loc; LINUSE = KK; loc = GETNUM(database); - if (LNLENG >= LNPOSN + 70)BUG(0); + if (LNLENG >= LNPOSN + 70) + BUG(MESSAGE_LINE_GT_70_CHARACTERS); if (loc == -1) return; - if (LNLENG < LNPOSN)BUG(1); + if (LNLENG < LNPOSN) + BUG(NULL_LINE_IN_MESSAGE); do { KK = KK + 1; - if (KK >= LINSIZ)BUG(2); + if (KK >= LINSIZ) + BUG(TOO_MANY_WORDS_OF_MESSAGES); LINES[KK] = GETTXT(false, false, false); } while (LINES[KK] != -1); LINES[LINUSE] = KK; @@ -250,20 +221,23 @@ static void read_messages(FILE* database, long sect) LINES[LINUSE] = -KK; if (sect == 14) { TRNVLS = TRNVLS + 1; - if (TRNVLS > TRNSIZ)BUG(11); + if (TRNVLS > TRNSIZ) + BUG(TOO_MANY_CLASS_OR_TURN_MESSAGES); TTEXT[TRNVLS] = LINUSE; TRNVAL[TRNVLS] = loc; continue; } if (sect == 10) { CLSSES = CLSSES + 1; - if (CLSSES > CLSMAX)BUG(11); + if (CLSSES > CLSMAX) + BUG(TOO_MANY_CLASS_OR_TURN_MESSAGES); CTEXT[CLSSES] = LINUSE; CVAL[CLSSES] = loc; continue; } if (sect == 6) { - if (loc > RTXSIZ)BUG(6); + if (loc > RTXSIZ) + BUG(TOO_MANY_RTEXT_MESSAGES); RTEXT[loc] = LINUSE; continue; } @@ -271,7 +245,8 @@ static void read_messages(FILE* database, long sect) if (loc > 0 && loc <= NOBJECTS)PTEXT[loc] = LINUSE; continue; } - if (loc > LOCSIZ)BUG(10); + if (loc > LOCSIZ) + BUG(TOO_MANY_LOCATIONS); if (sect == 1) { LTEXT[loc] = LINUSE; continue; @@ -300,7 +275,8 @@ static void read_section3_stuff(FILE* database) while ((L = GETNUM(NULL)) != 0) { TRAVEL[TRVS] = newloc * 1000 + L; TRVS = TRVS + 1; - if (TRVS == TRVSIZ)BUG(3); + if (TRVS == TRVSIZ) + BUG(TOO_MANY_TRAVEL_OPTIONS); } TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1]; } @@ -316,7 +292,7 @@ static void read_vocabulary(FILE* database) if (KTAB[TABNDX] == -1) return; ATAB[TABNDX] = GETTXT(true, true, true); } /* end loop */ - BUG(4); + BUG(TOO_MANY_VOCABULARY_WORDS); } /* 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) { long loc; 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); } } @@ -360,7 +337,8 @@ static void read_hints(FILE* database) long K; HNTMAX = 0; 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++) { HINTS[K][I] = GETNUM(NULL); } /* end loop */ @@ -473,7 +451,7 @@ static int read_database(FILE* database) read_messages(database, sect); break; default: - BUG(9); + BUG(INVALID_SECTION_NUMBER_IN_DATABASE); } } } diff --git a/main.c b/main.c index b97e44c..a92fa3e 100644 --- a/main.c +++ b/main.c @@ -66,7 +66,7 @@ static void sig_handler(int signo) * 15-treasure version (adventure) by Don Woods, April-June 1977 * 20-treasure version (rev 2) by Don Woods, August 1978 * Errata fixed: 78/12/25 - * Revived 2017 as Open Advebture. + * Revived 2017 as Open Adventure. */ static bool do_command(FILE *); @@ -102,6 +102,19 @@ int main(int argc, char *argv[]) case 's': editline = false; 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 * "HINTS" < 4 (special stuff, see database notes). */ -static void checkhints(FILE *cmdin) +static void checkhints(void) { if (COND[game.loc] >= game.conds) { for (int hint = 1; hint <= HNTMAX; hint++) { @@ -245,7 +258,7 @@ static void checkhints(FILE *cmdin) game.hintlc[hint] = 0; return; default: - BUG(27); + BUG(HINT_NUMBER_EXCEEDS_GOTO_LIST); break; } @@ -474,7 +487,7 @@ static bool dwarfmove(void) * without the lamp!). game.oldloc is zapped so he can't just * "retreat". */ -static void croak(FILE *cmdin) +static void croak(void) /* Okay, he's dead. Let's get on with it. */ { ++game.numdie; @@ -511,12 +524,12 @@ static void croak(FILE *cmdin) * him, so we need game.oldlc2, which is the last place he was * 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]; game.newloc = game.loc; if (kk == 0) - BUG(26); + BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES); if (motion == NUL) return true; else if (motion == BACK) { @@ -625,7 +638,8 @@ static bool playermove(FILE *cmdin, token_t verb, int motion) break; L12: do { - if (TRAVEL[kk] < 0)BUG(25); + if (TRAVEL[kk] < 0) + BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); ++kk; game.newloc = labs(TRAVEL[kk]) / 1000; } while @@ -687,10 +701,10 @@ static bool playermove(FILE *cmdin, token_t verb, int motion) game.fixed[BEAR] = -1; game.prop[BEAR] = 3; game.oldlc2 = game.newloc; - croak(cmdin); + croak(); } } - BUG(20); + BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST); } } while (false); @@ -928,13 +942,13 @@ static bool do_command(FILE *cmdin) game.loc = game.newloc; if (!dwarfmove()) - croak(cmdin); + croak(); /* Describe the current location and (maybe) get next command. */ for (;;) { if (game.loc == 0) - croak(cmdin); + croak(); const char* msg = locations[game.loc].description.small; if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == 0) msg = locations[game.loc].description.big; @@ -944,7 +958,7 @@ static bool do_command(FILE *cmdin) if (game.wzdark && PCT(35)) { RSPEAK(PIT_FALL); game.oldlc2 = game.loc; - croak(cmdin); + croak(); continue; /* back to top of main interpreter loop */ } msg = arbitrary_messages[PITCH_DARK]; @@ -952,7 +966,7 @@ static bool do_command(FILE *cmdin) if (TOTING(BEAR))RSPEAK(TAME_BEAR); speak(msg); if (FORCED(game.loc)) { - if (playermove(cmdin, verb, 1)) + if (playermove(verb, 1)) return true; else continue; /* back to top of main interpreter loop */ @@ -967,7 +981,7 @@ L2012: obj = 0; L2600: - checkhints(cmdin); + checkhints(); /* If closing time, check for any objects being toted with * game.prop < 0 and set the prop to -1-game.prop. This way @@ -1062,7 +1076,7 @@ Lookup: kmod = MOD(defn, 1000); switch (defn / 1000) { case 0: - if (playermove(cmdin, verb, kmod)) + if (playermove(verb, kmod)) return true; else continue; /* back to top of main interpreter loop */ @@ -1078,7 +1092,7 @@ Lookup: RSPEAK(kmod); goto L2012; default: - BUG(22); + BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); } Laction: @@ -1086,7 +1100,7 @@ Laction: case GO_TERMINATE: return true; case GO_MOVE: - playermove(cmdin, verb, NUL); + playermove(verb, NUL); return true; case GO_TOP: continue; /* back to top of main interpreter loop */ @@ -1116,7 +1130,7 @@ Laction: RSPEAK(DWARVES_AWAKEN); terminate(endgame); default: - BUG(99); + BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); } } } diff --git a/misc.c b/misc.c index fc7ac5f..d097bad 100644 --- a/misc.c +++ b/misc.c @@ -153,7 +153,7 @@ void SETPRM(long first, long p1, long p2) * are stored into PARMS(first) and PARMS(first+1). */ { if (first >= MAXPARMS) - BUG(29); + BUG(TOO_MANY_PARAMETERS_GIVEN_TO_SETPRM); else { PARMS[first] = p1; PARMS[first + 1] = p2; @@ -228,7 +228,7 @@ char* get_input() size_t n = 0; if (isatty(0)) printf("%s", input_prompt); - getline(&input, &n, stdin); + IGNORE(getline(&input, &n, stdin)); } 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)); 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]); int yes = strncmp("yes", firstword, sizeof("yes") - 1); @@ -384,7 +384,7 @@ long VOCAB(long id, long init) lexeme = -1; if (init < 0) return (lexeme); - BUG(5); + BUG(REQUIRED_VOCABULARY_WORD_NOT_FOUND); } if (init >= 0 && KTAB[i] / 1000 != init) continue; @@ -395,7 +395,7 @@ long VOCAB(long id, long init) return (lexeme); } } - BUG(21); + BUG(RAN_OFF_END_OF_VOCABULARY_TABLE); } void JUGGLE(long object) @@ -497,7 +497,7 @@ long ATDWRF(long where) } /* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value, - * randrange, RNDVOC, BUG) */ + * randrange, RNDVOC) */ long SETBIT(long bit) /* Returns 2**bit for use in constructing bit-masks. */ @@ -559,36 +559,6 @@ long RNDVOC(long second, long force) 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) */ diff --git a/saveresume.c b/saveresume.c index 5009171..20b6344 100644 --- a/saveresume.c +++ b/saveresume.c @@ -30,7 +30,7 @@ struct save_t { struct save_t save; /* Suspend and resume */ -int suspend(FILE *input) +int suspend(void) { /* Suspend. Offer to save things in a file, but charging * some points (so can't win by using saved games to retry @@ -71,7 +71,7 @@ int suspend(FILE *input) exit(0); } -int resume(FILE *input) +int resume(void) { /* Resume. Read a suspended game back from a file. * If ADVENT_NOSAVE is defined, do nothing instead. */ -- 2.31.1