diff options
author | jsm <jsm@NetBSD.org> | 2000-09-21 17:44:34 +0000 |
---|---|---|
committer | jsm <jsm@NetBSD.org> | 2000-09-21 17:44:34 +0000 |
commit | 0ba05dd5a679e7723ea4b9f1426175b1651926cf (patch) | |
tree | 8beede32304395cb7418af5573f1e3b042030ca8 | |
parent | 66bc28438e19fafc7abecfa76bce72d10174c9be (diff) | |
download | bsdgames-darwin-0ba05dd5a679e7723ea4b9f1426175b1651926cf.tar.gz bsdgames-darwin-0ba05dd5a679e7723ea4b9f1426175b1651926cf.tar.zst bsdgames-darwin-0ba05dd5a679e7723ea4b9f1426175b1651926cf.zip |
Various improvements to parsing in battlestar, mostly from OpenBSD.
Define a constant WORDLEN. Always use this constant and NWORD where
appropriate.
Use NWORD - 1 in battlestar.c to avoid off-by-one error.
Increment wordnumber after the INVEN verb to allow it to be followed
by a comma and other actions.
Avoid overflowing elements of the words array if input words are too
long.
Parse "," as AND except when followed by a verb, to allow such
constructions as "take foo, bar, and baz". Trim AND AND which may
occur from the ", and" in such a list.
Avoid crashes from EVERYTHING in the wrong place by moving it to the
start of OBJECT AND EVERYTHING and NOUNS AND EVERYTHING sequences, and
trimming EVERYTHING AND EVERYTHING.
-rw-r--r-- | battlestar/battlestar.c | 6 | ||||
-rw-r--r-- | battlestar/cypher.c | 5 | ||||
-rw-r--r-- | battlestar/extern.h | 5 | ||||
-rw-r--r-- | battlestar/getcom.c | 34 | ||||
-rw-r--r-- | battlestar/globals.c | 6 | ||||
-rw-r--r-- | battlestar/parse.c | 62 | ||||
-rw-r--r-- | battlestar/words.c | 5 |
7 files changed, 99 insertions, 24 deletions
diff --git a/battlestar/battlestar.c b/battlestar/battlestar.c index 6d0ab8ec..a6a11efa 100644 --- a/battlestar/battlestar.c +++ b/battlestar/battlestar.c @@ -1,4 +1,4 @@ -/* $NetBSD: battlestar.c,v 1.11 2000/09/08 17:22:01 jsm Exp $ */ +/* $NetBSD: battlestar.c,v 1.12 2000/09/21 17:44:34 jsm Exp $ */ /* * Copyright (c) 1983, 1993 @@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\ #if 0 static char sccsid[] = "@(#)battlestar.c 8.2 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: battlestar.c,v 1.11 2000/09/08 17:22:01 jsm Exp $"); +__RCSID("$NetBSD: battlestar.c,v 1.12 2000/09/21 17:44:34 jsm Exp $"); #endif #endif /* not lint */ @@ -96,7 +96,7 @@ start: run: next = getcom(mainbuf, sizeof mainbuf, ">-: ", "Please type in something."); - for (wordcount = 0; next && wordcount < 20; wordcount++) + for (wordcount = 0; next && wordcount < NWORD - 1; wordcount++) next = getword(next, words[wordcount], -1); parse(); switch (cypher()) { diff --git a/battlestar/cypher.c b/battlestar/cypher.c index ea39fd39..0f6c92cc 100644 --- a/battlestar/cypher.c +++ b/battlestar/cypher.c @@ -1,4 +1,4 @@ -/* $NetBSD: cypher.c,v 1.14 2000/09/17 23:03:43 jsm Exp $ */ +/* $NetBSD: cypher.c,v 1.15 2000/09/21 17:44:34 jsm Exp $ */ /* * Copyright (c) 1983, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)cypher.c 8.2 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: cypher.c,v 1.14 2000/09/17 23:03:43 jsm Exp $"); +__RCSID("$NetBSD: cypher.c,v 1.15 2000/09/21 17:44:34 jsm Exp $"); #endif #endif /* not lint */ @@ -287,6 +287,7 @@ cypher() printf("\nYou can still carry up to %d kilogram%s\n", WEIGHT, (WEIGHT == 1 ? "." : "s.")); } else puts("\nYou are in perfect health."); + wordnumber++; break; case USE: diff --git a/battlestar/extern.h b/battlestar/extern.h index efd6366c..81ffa9c3 100644 --- a/battlestar/extern.h +++ b/battlestar/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.20 2000/09/17 23:03:43 jsm Exp $ */ +/* $NetBSD: extern.h,v 1.21 2000/09/21 17:44:34 jsm Exp $ */ /* * Copyright (c) 1983, 1993 @@ -253,8 +253,9 @@ extern const int objwt[NUMOFOBJECTS]; extern const int objcumber[NUMOFOBJECTS]; /* current input line */ +#define WORDLEN 15 #define NWORD 20 /* words per line */ -extern char words[NWORD][15]; +extern char words[NWORD][WORDLEN]; extern int wordvalue[NWORD]; extern int wordtype[NWORD]; extern int wordcount, wordnumber; diff --git a/battlestar/getcom.c b/battlestar/getcom.c index 4c7e2935..5d68738c 100644 --- a/battlestar/getcom.c +++ b/battlestar/getcom.c @@ -1,4 +1,4 @@ -/* $NetBSD: getcom.c,v 1.8 2000/09/21 09:49:03 jsm Exp $ */ +/* $NetBSD: getcom.c,v 1.9 2000/09/21 17:44:34 jsm Exp $ */ /* * Copyright (c) 1983, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)getcom.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: getcom.c,v 1.8 2000/09/21 09:49:03 jsm Exp $"); +__RCSID("$NetBSD: getcom.c,v 1.9 2000/09/21 17:44:34 jsm Exp $"); #endif #endif /* not lint */ @@ -78,6 +78,9 @@ getword(buf1, buf2, flag) char *buf1, *buf2; int flag; { + int cnt; + + cnt = 1; while (isspace(*buf1)) buf1++; if (*buf1 != ',') { @@ -85,23 +88,34 @@ getword(buf1, buf2, flag) *buf2 = 0; return (0); } - while (*buf1 && !isspace(*buf1) && *buf1 != ',') + while (cnt < WORDLEN && *buf1 && !isspace(*buf1) && *buf1 != ',') if (flag < 0) { - if (isupper(*buf1)) + if (isupper(*buf1)) { *buf2++ = tolower(*buf1++); - else + cnt++; + } else { *buf2++ = *buf1++; + cnt++; + } } else if (flag > 0) { - if (islower(*buf1)) + if (islower(*buf1)) { *buf2++ = toupper(*buf1++); - else + cnt++; + } else { *buf2++ = *buf1++; - } else + cnt++; + } + } else { *buf2++ = *buf1++; + cnt++; + } + if (cnt == WORDLEN) + while (*buf1 && !isspace(*buf1)) + buf1++; } else *buf2++ = *buf1++; - *buf2 = 0; + *buf2 = '\0'; while (isspace(*buf1)) buf1++; - return (*buf1 ? buf1 : 0); + return (*buf1 ? buf1 : NULL); } diff --git a/battlestar/globals.c b/battlestar/globals.c index d285e527..5805cf96 100644 --- a/battlestar/globals.c +++ b/battlestar/globals.c @@ -1,4 +1,4 @@ -/* $NetBSD: globals.c,v 1.12 2000/09/17 23:03:43 jsm Exp $ */ +/* $NetBSD: globals.c,v 1.13 2000/09/21 17:44:34 jsm Exp $ */ /* * Copyright (c) 1983, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)globals.c 8.2 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: globals.c,v 1.12 2000/09/17 23:03:43 jsm Exp $"); +__RCSID("$NetBSD: globals.c,v 1.13 2000/09/21 17:44:34 jsm Exp $"); #endif #endif /* not lint */ @@ -228,7 +228,7 @@ int followfight = -1; struct room *location; /* current input line */ -char words[NWORD][15]; +char words[NWORD][WORDLEN]; int wordvalue[NWORD]; int wordtype[NWORD]; int wordcount, wordnumber; diff --git a/battlestar/parse.c b/battlestar/parse.c index 8d85e6c5..e79722ba 100644 --- a/battlestar/parse.c +++ b/battlestar/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.7 1999/02/10 01:36:50 hubertf Exp $ */ +/* $NetBSD: parse.c,v 1.8 2000/09/21 17:44:34 jsm Exp $ */ /* * Copyright (c) 1983, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)parse.c 8.2 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: parse.c,v 1.7 1999/02/10 01:36:50 hubertf Exp $"); +__RCSID("$NetBSD: parse.c,v 1.8 2000/09/21 17:44:34 jsm Exp $"); #endif #endif /* not lint */ @@ -98,6 +98,7 @@ parse() { struct wlist *wp; int n; + int flag; wordnumber = 0; /* for cypher */ for (n = 0; n <= wordcount; n++) { @@ -109,4 +110,61 @@ parse() wordtype[n] = wp->article; } } + /* Don't let a comma mean AND if followed by a verb. */ + for (n = 0; n < wordcount; n++) + if (wordvalue[n] == AND && words[n][0] == ',' + && wordtype[n + 1] == VERB) { + wordvalue[n] = -1; + wordtype[n] = -1; + } + /* Trim "AND AND" which can happen naturally at the end of a + * comma-delimited list. + */ + for (n = 1; n < wordcount; n++) + if (wordvalue[n - 1] == AND && wordvalue[n] == AND) { + int i; + for (i = n + 1; i < wordcount; i++) { + wordtype[i - 1] = wordtype[i]; + wordvalue[i - 1] = wordvalue[i]; + strcpy(words[i - 1], words[i]); + } + wordcount--; + } + + /* If there is a sequence (NOUN | OBJECT) AND EVERYTHING + * then move all the EVERYTHINGs to the beginning, since that's where + * they're expected. We can't get rid of the NOUNs and OBJECTs in + * case they aren't in EVERYTHING (i.e. not here or nonexistant). + */ + flag = 1; + while (flag) { + flag = 0; + for (n = 1; n < wordcount; n++) + if ((wordtype[n - 1] == NOUNS || wordtype[n - 1] == OBJECT) && + wordvalue[n] == AND && wordvalue[n + 1] == EVERYTHING) { + char tmpword[WORDLEN]; + wordvalue[n + 1] = wordvalue[n - 1]; + wordvalue[n - 1] = EVERYTHING; + wordtype[n + 1] = wordtype[n - 1]; + wordtype[n - 1] = OBJECT; + strcpy(tmpword, words[n - 1]); + strcpy(words[n - 1], words[n + 1]); + strcpy(words[n + 1], tmpword); + flag = 1; + } + /* And trim EVERYTHING AND EVERYTHING. */ + for (n = 1; n < wordcount; n++) + if (wordvalue[n - 1] == EVERYTHING && + wordvalue[n] == AND && wordvalue[n + 1] == EVERYTHING) { + int i; + for (i = n + 1; i < wordcount; i++) { + wordtype[i - 1] = wordtype[i + 1]; + wordvalue[i - 1] = wordvalue[i + 1]; + strcpy(words[i - 1], words[i + 1]); + } + wordcount--; + wordcount--; + flag = 1; + } + } } diff --git a/battlestar/words.c b/battlestar/words.c index b1386938..86365a87 100644 --- a/battlestar/words.c +++ b/battlestar/words.c @@ -1,4 +1,4 @@ -/* $NetBSD: words.c,v 1.8 2000/09/17 23:03:43 jsm Exp $ */ +/* $NetBSD: words.c,v 1.9 2000/09/21 17:44:34 jsm Exp $ */ /* * Copyright (c) 1983, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)words.c 8.2 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: words.c,v 1.8 2000/09/17 23:03:43 jsm Exp $"); +__RCSID("$NetBSD: words.c,v 1.9 2000/09/21 17:44:34 jsm Exp $"); #endif #endif /* not lint */ @@ -150,6 +150,7 @@ struct wlist wlist[] = { { "everything", EVERYTHING, OBJECT, NULL }, { "all", EVERYTHING, OBJECT, NULL }, { "and", AND, CONJ, NULL }, + { ",", AND, CONJ, NULL }, { "kill", KILL, VERB, NULL }, { "fight", KILL, VERB, NULL }, { "ravage", RAVAGE, VERB, NULL }, |