diff options
author | Paul Janzen <pjanzen@cvs.openbsd.org> | 2002-07-18 07:13:58 +0000 |
---|---|---|
committer | Paul Janzen <pjanzen@cvs.openbsd.org> | 2002-07-18 07:13:58 +0000 |
commit | 54a6ff4e941f27f74b5c69277796845213e0d171 (patch) | |
tree | 2c06b08145f5cdf2bf02ab2032ff977b2e523505 /games/rogue/inventory.c | |
parent | 58277074e3e354b7bbce4f4f0f8c25ae270f47cb (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.c | 439 |
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); } |