summaryrefslogtreecommitdiff
path: root/games/rogue/inventory.c
diff options
context:
space:
mode:
authorPaul Janzen <pjanzen@cvs.openbsd.org>2002-07-18 07:13:58 +0000
committerPaul Janzen <pjanzen@cvs.openbsd.org>2002-07-18 07:13:58 +0000
commit54a6ff4e941f27f74b5c69277796845213e0d171 (patch)
tree2c06b08145f5cdf2bf02ab2032ff977b2e523505 /games/rogue/inventory.c
parent58277074e3e354b7bbce4f4f0f8c25ae270f47cb (diff)
- string handling patch from David Holland, minimally modified. Highlights
are fewer magic constants, sprintf->snprintf, and better scorefile handling. Also, won't hang if forking a subshell fails. - a few needless functions have been trimmed, and a few extra defaults have been added to a few switches, just in case.
Diffstat (limited to 'games/rogue/inventory.c')
-rw-r--r--games/rogue/inventory.c439
1 files changed, 252 insertions, 187 deletions
diff --git a/games/rogue/inventory.c b/games/rogue/inventory.c
index 2db81877a2b..d69158dd611 100644
--- a/games/rogue/inventory.c
+++ b/games/rogue/inventory.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inventory.c,v 1.4 2000/07/23 22:23:42 pjanzen Exp $ */
+/* $OpenBSD: inventory.c,v 1.5 2002/07/18 07:13:57 pjanzen Exp $ */
/* $NetBSD: inventory.c,v 1.3 1995/04/22 10:27:35 cgd Exp $ */
/*
@@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)inventory.c 8.1 (Berkeley) 5/31/93";
#else
-static char rcsid[] = "$OpenBSD: inventory.c,v 1.4 2000/07/23 22:23:42 pjanzen Exp $";
+static const char rcsid[] = "$OpenBSD: inventory.c,v 1.5 2002/07/18 07:13:57 pjanzen Exp $";
#endif
#endif /* not lint */
@@ -57,6 +57,7 @@ static char rcsid[] = "$OpenBSD: inventory.c,v 1.4 2000/07/23 22:23:42 pjanzen E
*
*/
+#include <stdarg.h>
#include "rogue.h"
boolean is_wood[WANDS];
@@ -220,43 +221,57 @@ inventory(pack, mask)
unsigned short mask;
{
object *obj;
- short i = 0, j, maxlen = 0, n;
- char descs[MAX_PACK_COUNT+1][DCOLS];
+ short i = 0, j;
+ size_t maxlen = 0, n;
short row, col;
+ struct {
+ short letter;
+ short sepchar;
+ char desc[DCOLS];
+ char savebuf[DCOLS+8];
+ } descs[MAX_PACK_COUNT+1];
obj = pack->next_object;
if (!obj) {
- message("your pack is empty", 0);
+ messagef(0, "your pack is empty");
return;
}
while (obj) {
if (obj->what_is & mask) {
- descs[i][0] = ' ';
- descs[i][1] = obj->ichar;
- descs[i][2] = ((obj->what_is & ARMOR) && obj->is_protected)
+ descs[i].letter = obj->ichar;
+ descs[i].sepchar = ((obj->what_is & ARMOR) && obj->is_protected)
? '}' : ')';
- descs[i][3] = ' ';
- get_desc(obj, descs[i]+4);
- if ((n = strlen(descs[i])) > maxlen) {
+ get_desc(obj, descs[i].desc, sizeof(descs[i].desc));
+ n = strlen(descs[i].desc) + 4;
+ if (n > maxlen) {
maxlen = n;
}
- i++;
+ i++;
+ if (i > MAX_PACK_COUNT) {
+ clean_up("Too many objects in pack?!?");
+ }
}
obj = obj->next_object;
}
- (void) strcpy(descs[i++], press_space);
- if (maxlen < 27) maxlen = 27;
+ if (maxlen < 27)
+ maxlen = 27;
+ if (maxlen > DCOLS - 2)
+ maxlen = DCOLS - 2;
col = DCOLS - (maxlen + 2);
- for (row = 0; ((row < i) && (row < DROWS)); row++) {
- if (row > 0) {
- for (j = col; j < DCOLS; j++) {
- descs[row-1][j-col] = mvinch(row, j);
- }
- descs[row-1][j-col] = 0;
+ for (row = 0; ((row <= i) && (row < DROWS)); row++) {
+ for (j = col; j < DCOLS; j++) {
+ descs[row].savebuf[j - col] = mvinch(row, j);
+ }
+ descs[row].savebuf[j - col] = '\0';
+ if (row < i) {
+ mvprintw(row, col, " %c%c %s",
+ descs[row].letter, descs[row].sepchar,
+ descs[row].desc);
+ } else {
+ mvaddstr(row, col, press_space);
}
- mvaddstr(row, col, descs[row]);
clrtoeol();
}
refresh();
@@ -265,8 +280,8 @@ inventory(pack, mask)
move(0, 0);
clrtoeol();
- for (j = 1; ((j < i) && (j < DROWS)); j++) {
- mvaddstr(j, col, descs[j-1]);
+ for (j = 1; ((j <= i) && (j < DROWS)); j++) {
+ mvaddstr(j, col, descs[j].savebuf);
}
}
@@ -278,10 +293,10 @@ id_com()
while (ch != CANCEL) {
check_message();
- message("Character you want help for (* for all):", 0);
+ messagef(0, "Character you want help for (* for all):");
refresh();
- ch = rgetchar();
+ ch = getchar();
switch(ch) {
case LIST:
@@ -338,7 +353,7 @@ MORE:
if (!pr_com_id(ch)) {
if (!pr_motion_char(ch)) {
check_message();
- message("unknown character", 0);
+ messagef(0, "unknown character");
}
}
ch = CANCEL;
@@ -357,20 +372,20 @@ pr_com_id(ch)
return(0);
}
check_message();
- message(com_id_tab[i].com_desc, 0);
+ messagef(0, "%s", com_id_tab[i].com_desc);
return(1);
}
int
-get_com_id(index, ch)
- int *index;
+get_com_id(indexp, ch)
+ int *indexp;
short ch;
{
short i;
for (i = 0; i < COMS; i++) {
if (com_id_tab[i].com_char == ch) {
- *index = i;
+ *indexp = i;
return(1);
}
}
@@ -397,20 +412,19 @@ pr_motion_char(ch)
(ch == '\031') ||
(ch == '\016') ||
(ch == '\002')) {
- char until[18], buf[DCOLS];
+ const char *until;
int n;
if (ch <= '\031') {
ch += 96;
- (void) strcpy(until, "until adjacent");
+ until = " until adjacent";
} else {
ch += 32;
- until[0] = '\0';
+ until = "";
}
(void) get_com_id(&n, ch);
- sprintf(buf, "run %s %s", com_id_tab[n].com_desc + 8, until);
check_message();
- message(buf, 0);
+ messagef(0, "run %s%s", com_id_tab[n].com_desc + 8, until);
return(1);
} else {
return(0);
@@ -421,14 +435,15 @@ void
mix_colors()
{
short i, j, k;
- char *t;
+ char t[MAX_TITLE_LENGTH];
for (i = 0; i <= 32; i++) {
j = get_rand(0, (POTIONS - 1));
k = get_rand(0, (POTIONS - 1));
- t = id_potions[j].title;
- id_potions[j].title = id_potions[k].title;
- id_potions[k].title = t;
+ strlcpy(t, id_potions[j].title, sizeof(t));
+ strlcpy(id_potions[j].title, id_potions[k].title,
+ sizeof(id_potions[j].title));
+ strlcpy(id_potions[k].title, t, sizeof(id_potions[k].title));
}
}
@@ -437,181 +452,234 @@ make_scroll_titles()
{
short i, j, n;
short sylls, s;
+ size_t maxlen;
+ maxlen = sizeof(id_scrolls[0].title);
for (i = 0; i < SCROLS; i++) {
sylls = get_rand(2, 5);
- (void) strcpy(id_scrolls[i].title, "'");
+ (void) strlcpy(id_scrolls[i].title, "'", maxlen);
for (j = 0; j < sylls; j++) {
s = get_rand(1, (MAXSYLLABLES-1));
- (void) strcat(id_scrolls[i].title, syllables[s]);
+ (void) strlcat(id_scrolls[i].title, syllables[s], maxlen);
}
+ /* trim trailing space */
n = strlen(id_scrolls[i].title);
- (void) strcpy(id_scrolls[i].title+(n-1), "' ");
+ id_scrolls[i].title[n-1] = '\'';
+ strlcat(id_scrolls[i].title, " ", maxlen);
}
}
+struct sbuf {
+ char *buf;
+ size_t maxlen;
+};
+
+static void sbuf_init(struct sbuf *s, char *buf, size_t maxlen);
+static void sbuf_addstr(struct sbuf *s, const char *str);
+static void sbuf_addf(struct sbuf *s, const char *fmt, ...);
+static void desc_count(struct sbuf *s, int n);
+static void desc_called(struct sbuf *s, const object *);
+
+static void
+sbuf_init(s, buf, maxlen)
+ struct sbuf *s;
+ char *buf;
+ size_t maxlen;
+{
+ s->buf = buf;
+ s->maxlen = maxlen;
+ s->buf[0] = 0;
+}
+
+static void
+sbuf_addstr(s, str)
+ struct sbuf *s;
+ const char *str;
+{
+ strlcat(s->buf, str, s->maxlen);
+}
+
+static void
+sbuf_addf(struct sbuf *s, const char *fmt, ...)
+{
+ va_list ap;
+ size_t initlen;
+
+ initlen = strlen(s->buf);
+ va_start(ap, fmt);
+ vsnprintf(s->buf+initlen, s->maxlen-initlen, fmt, ap);
+ va_end(ap);
+}
+
+static void
+desc_count(s, n)
+ struct sbuf *s;
+ int n;
+{
+ if (n == 1) {
+ sbuf_addstr(s, "an ");
+ } else {
+ sbuf_addf(s, "%d ", n);
+ }
+}
+
+static void
+desc_called(s, obj)
+ struct sbuf *s;
+ const object *obj;
+{
+ struct id *id_table;
+
+ id_table = get_id_table(obj);
+ sbuf_addstr(s, name_of(obj));
+ sbuf_addstr(s, "called ");
+ sbuf_addstr(s, id_table[obj->which_kind].title);
+}
+
void
-get_desc(obj, desc)
- object *obj;
+get_desc(obj, desc, desclen)
+ const object *obj;
char *desc;
+ size_t desclen;
{
- char *item_name;
+ const char *item_name;
struct id *id_table;
- char more_info[32];
- short i;
+ struct sbuf db;
+ unsigned short objtype_id_status;
if (obj->what_is == AMULET) {
- (void) strcpy(desc, "the amulet of Yendor ");
+ (void) strlcpy(desc, "the amulet of Yendor ", desclen);
return;
}
- item_name = name_of(obj);
-
if (obj->what_is == GOLD) {
- sprintf(desc, "%d pieces of gold", obj->quantity);
+ snprintf(desc, desclen, "%d pieces of gold", obj->quantity);
return;
}
- if (obj->what_is != ARMOR) {
- if (obj->quantity == 1) {
- (void) strcpy(desc, "a ");
- } else {
- sprintf(desc, "%d ", obj->quantity);
+ item_name = name_of(obj);
+ id_table = get_id_table(obj);
+ if (wizard || id_table == NULL) {
+ objtype_id_status = IDENTIFIED;
+ } else {
+ objtype_id_status = id_table[obj->which_kind].id_status;
+ }
+ if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
+ if (obj->identified) {
+ objtype_id_status = IDENTIFIED;
}
}
- if (obj->what_is == FOOD) {
+ sbuf_init(&db, desc, desclen);
+
+ switch(obj->what_is) {
+ case FOOD:
if (obj->which_kind == RATION) {
if (obj->quantity > 1) {
- sprintf(desc, "%d rations of ", obj->quantity);
+ sbuf_addf(&db, "%d rations of %s", obj->quantity,
+ item_name);
} else {
- (void) strcpy(desc, "some ");
+ sbuf_addf(&db, "some %s", item_name);
}
} else {
- (void) strcpy(desc, "a ");
+ sbuf_addf(&db, "an %s", item_name);
}
- (void) strcat(desc, item_name);
- goto ANA;
- }
- id_table = get_id_table(obj);
-
- if (wizard) {
- goto ID;
- }
- if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
- goto CHECK;
- }
-
- switch(id_table[obj->which_kind].id_status) {
- case UNIDENTIFIED:
-CHECK:
- switch(obj->what_is) {
- case SCROL:
- (void) strcat(desc, item_name);
- (void) strcat(desc, "entitled: ");
- (void) strcat(desc, id_table[obj->which_kind].title);
- break;
- case POTION:
- (void) strcat(desc, id_table[obj->which_kind].title);
- (void) strcat(desc, item_name);
- break;
- case WAND:
- case RING:
- if (obj->identified ||
- (id_table[obj->which_kind].id_status == IDENTIFIED)) {
- goto ID;
- }
- if (id_table[obj->which_kind].id_status == CALLED) {
- goto CALL;
- }
- (void) strcat(desc, id_table[obj->which_kind].title);
- (void) strcat(desc, item_name);
- break;
- case ARMOR:
- if (obj->identified) {
- goto ID;
- }
- (void) strcpy(desc, id_table[obj->which_kind].title);
- break;
- case WEAPON:
- if (obj->identified) {
- goto ID;
- }
- (void) strcat(desc, name_of(obj));
- break;
+ break;
+ case SCROL:
+ desc_count(&db, obj->quantity);
+ if (objtype_id_status==UNIDENTIFIED) {
+ sbuf_addstr(&db, item_name);
+ sbuf_addstr(&db, "entitled: ");
+ sbuf_addstr(&db, id_table[obj->which_kind].title);
+ } else if (objtype_id_status==CALLED) {
+ desc_called(&db, obj);
+ } else {
+ sbuf_addstr(&db, item_name);
+ sbuf_addstr(&db, id_table[obj->which_kind].real);
}
break;
- case CALLED:
-CALL: switch(obj->what_is) {
- case SCROL:
- case POTION:
- case WAND:
- case RING:
- (void) strcat(desc, item_name);
- (void) strcat(desc, "called ");
- (void) strcat(desc, id_table[obj->which_kind].title);
- break;
+ case POTION:
+ desc_count(&db, obj->quantity);
+ if (objtype_id_status==UNIDENTIFIED) {
+ sbuf_addstr(&db, id_table[obj->which_kind].title);
+ sbuf_addstr(&db, item_name);
+ } else if (objtype_id_status==CALLED) {
+ desc_called(&db, obj);
+ } else {
+ sbuf_addstr(&db, item_name);
+ sbuf_addstr(&db, id_table[obj->which_kind].real);
}
break;
- case IDENTIFIED:
-ID: switch(obj->what_is) {
- case SCROL:
- case POTION:
- (void) strcat(desc, item_name);
- (void) strcat(desc, id_table[obj->which_kind].real);
- break;
- case RING:
- if (wizard || obj->identified) {
- if ((obj->which_kind == DEXTERITY) ||
- (obj->which_kind == ADD_STRENGTH)) {
- sprintf(more_info, "%s%d ", ((obj->class > 0) ? "+" : ""),
- obj->class);
- (void) strcat(desc, more_info);
- }
- }
- (void) strcat(desc, item_name);
- (void) strcat(desc, id_table[obj->which_kind].real);
- break;
- case WAND:
- (void) strcat(desc, item_name);
- (void) strcat(desc, id_table[obj->which_kind].real);
+ case WAND:
+ desc_count(&db, obj->quantity);
+ if (objtype_id_status==UNIDENTIFIED) {
+ sbuf_addstr(&db, id_table[obj->which_kind].title);
+ sbuf_addstr(&db, item_name);
+ } else if (objtype_id_status==CALLED) {
+ desc_called(&db, obj);
+ } else {
+ sbuf_addstr(&db, item_name);
+ sbuf_addstr(&db, id_table[obj->which_kind].real);
if (wizard || obj->identified) {
- sprintf(more_info, "[%d]", obj->class);
- (void) strcat(desc, more_info);
+ sbuf_addf(&db, "[%d]", obj->class);
}
- break;
- case ARMOR:
- sprintf(desc, "%s%d ", ((obj->d_enchant >= 0) ? "+" : ""),
- obj->d_enchant);
- (void) strcat(desc, id_table[obj->which_kind].title);
- sprintf(more_info, "[%d] ", get_armor_class(obj));
- (void) strcat(desc, more_info);
- break;
- case WEAPON:
- sprintf(desc+strlen(desc), "%s%d,%s%d ",
- ((obj->hit_enchant >= 0) ? "+" : ""), obj->hit_enchant,
- ((obj->d_enchant >= 0) ? "+" : ""), obj->d_enchant);
- (void) strcat(desc, name_of(obj));
- break;
}
break;
- }
-ANA:
- if (!strncmp(desc, "a ", 2)) {
- if (is_vowel(desc[2])) {
- for (i = strlen(desc) + 1; i > 1; i--) {
- desc[i] = desc[i-1];
- }
- desc[1] = 'n';
+ case RING:
+ desc_count(&db, obj->quantity);
+ if (objtype_id_status==UNIDENTIFIED) {
+ sbuf_addstr(&db, id_table[obj->which_kind].title);
+ sbuf_addstr(&db, item_name);
+ } else if (objtype_id_status==CALLED) {
+ desc_called(&db, obj);
+ } else {
+ if ((wizard || obj->identified) &&
+ (obj->which_kind == DEXTERITY ||
+ obj->which_kind == ADD_STRENGTH))
+ sbuf_addf(&db, "%+d ", obj->class);
+ sbuf_addstr(&db, item_name);
+ sbuf_addstr(&db, id_table[obj->which_kind].real);
+ }
+ break;
+ case ARMOR:
+ /* no desc_count() */
+ if (objtype_id_status==UNIDENTIFIED) {
+ sbuf_addstr(&db, id_table[obj->which_kind].title);
+ } else {
+ sbuf_addf(&db, "%+d %s[%d] ", obj->d_enchant,
+ id_table[obj->which_kind].title,
+ get_armor_class(obj));
+ }
+ break;
+ case WEAPON:
+ desc_count(&db, obj->quantity);
+ if (objtype_id_status==UNIDENTIFIED) {
+ sbuf_addstr(&db, name_of(obj));
+ } else {
+ sbuf_addf(&db, "%+d,%+d %s", obj->hit_enchant,
+ obj->d_enchant, name_of(obj));
}
+ break;
+ /* Should never execute */
+ default:
+ sbuf_addstr(&db, "grot");
+ break;
}
+
if (obj->in_use_flags & BEING_WIELDED) {
- (void) strcat(desc, "in hand");
+ sbuf_addstr(&db, "in hand");
} else if (obj->in_use_flags & BEING_WORN) {
- (void) strcat(desc, "being worn");
+ sbuf_addstr(&db, "being worn");
} else if (obj->in_use_flags & ON_LEFT_HAND) {
- (void) strcat(desc, "on left hand");
+ sbuf_addstr(&db, "on left hand");
} else if (obj->in_use_flags & ON_RIGHT_HAND) {
- (void) strcat(desc, "on right hand");
+ sbuf_addstr(&db, "on right hand");
+ }
+
+ if (!strncmp(db.buf, "an ", 3)) {
+ if (!is_vowel(db.buf[3])) {
+ memmove(db.buf+2, db.buf+3, strlen(db.buf+3)+1);
+ db.buf[1] = ' ';
+ }
}
}
@@ -629,7 +697,8 @@ get_wand_and_ring_materials()
j = get_rand(0, WAND_MATERIALS-1);
} while (used[j]);
used[j] = 1;
- (void) strcpy(id_wands[i].title, wand_materials[j]);
+ strlcpy(id_wands[i].title, wand_materials[j],
+ sizeof(id_wands[i].title));
is_wood[i] = (j > MAX_METAL);
}
for (i = 0; i < GEMS; i++) {
@@ -640,7 +709,8 @@ get_wand_and_ring_materials()
j = get_rand(0, GEMS-1);
} while (used[j]);
used[j] = 1;
- (void) strcpy(id_rings[i].title, gems[j]);
+ strlcpy(id_rings[i].title, gems[j],
+ sizeof(id_rings[i].title));
}
}
@@ -648,7 +718,7 @@ void
single_inv(ichar)
short ichar;
{
- short ch;
+ short ch, ch2;
char desc[DCOLS];
object *obj;
@@ -658,20 +728,17 @@ single_inv(ichar)
return;
}
if (!(obj = get_letter_object(ch))) {
- message("no such item.", 0);
+ messagef(0, "no such item.");
return;
}
- desc[0] = ch;
- desc[1] = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
- desc[2] = ' ';
- desc[3] = 0;
- get_desc(obj, desc+3);
- message(desc, 0);
+ ch2 = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
+ get_desc(obj, desc, sizeof(desc));
+ messagef(0, "%c%c %s", ch, ch2, desc);
}
struct id *
get_id_table(obj)
- object *obj;
+ const object *obj;
{
switch(obj->what_is) {
case SCROL:
@@ -698,13 +765,13 @@ inv_armor_weapon(is_weapon)
if (rogue.weapon) {
single_inv(rogue.weapon->ichar);
} else {
- message("not wielding anything", 0);
+ messagef(0, "not wielding anything");
}
} else {
if (rogue.armor) {
single_inv(rogue.armor->ichar);
} else {
- message("not wearing anything", 0);
+ messagef(0, "not wearing anything");
}
}
}
@@ -712,11 +779,10 @@ inv_armor_weapon(is_weapon)
void
id_type()
{
- char *id;
+ const char *id;
int ch;
- char buf[DCOLS];
- message("what do you want identified?", 0);
+ messagef(0, "what do you want identified?");
ch = rgetchar();
@@ -785,6 +851,5 @@ id_type()
}
}
check_message();
- sprintf(buf, "'%c': %s", ch, id);
- message(buf, 0);
+ messagef(0, "'%c': %s", ch, id);
}