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 /battlestar | |
| parent | 66bc28438e19fafc7abecfa76bce72d10174c9be (diff) | |
| download | bsdgames-darwin-0ba05dd5a679e7723ea4b9f1426175b1651926cf.tar.gz 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.
Diffstat (limited to 'battlestar')
| -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 }, |
