From: Dean Luick Date: Sat, 9 Jan 2021 02:33:39 +0000 (-0600) Subject: Fix gcc sprintf warnings X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3ef0f889e63499f794fb09b628f0b7911c19bb6c;p=nethack Fix gcc sprintf warnings Gcc 9 has become more vocal with sprintf buffer overflow checking. Remove these sprintf warnings by changing the offending calls to a snprintf wrapper that will explicitly check the result. --- diff --git a/src/botl.c b/src/botl.c index b99de1ed0..413f912ce 100644 --- a/src/botl.c +++ b/src/botl.c @@ -216,17 +216,21 @@ do_statusline2() * interface supports that. */ if ((dln - dx) + 1 + hln + 1 + xln + 1 + tln + 1 + cln <= COLNO) { - Sprintf(newbot2, "%s %s %s %s %s", dloc, hlth, expr, tmmv, cond); + Snprintf(newbot2, sizeof(newbot2), "%s %s %s %s %s", dloc, hlth, expr, + tmmv, cond); } else { if (dln + 1 + hln + 1 + xln + 1 + tln + 1 + cln + 1 > MAXCO) { panic("bot2: second status line exceeds MAXCO (%u > %d)", (dln + 1 + hln + 1 + xln + 1 + tln + 1 + cln + 1), MAXCO); } else if ((dln - dx) + 1 + hln + 1 + xln + 1 + cln <= COLNO) { - Sprintf(newbot2, "%s %s %s %s %s", dloc, hlth, expr, cond, tmmv); + Snprintf(newbot2, sizeof(newbot2), "%s %s %s %s %s", dloc, hlth, + expr, cond, tmmv); } else if ((dln - dx) + 1 + hln + 1 + cln <= COLNO) { - Sprintf(newbot2, "%s %s %s %s %s", dloc, hlth, cond, expr, tmmv); + Snprintf(newbot2, sizeof(newbot2), "%s %s %s %s %s", dloc, hlth, + cond, expr, tmmv); } else { - Sprintf(newbot2, "%s %s %s %s %s", hlth, cond, dloc, expr, tmmv); + Snprintf(newbot2, sizeof(newbot2), "%s %s %s %s %s", hlth, cond, + dloc, expr, tmmv); } /* only two or three consecutive spaces available to squeeze out */ mungspaces(newbot2); @@ -3134,8 +3138,8 @@ status_hilite_linestr_gather_conditions() tmpattr = hlattr2attrname(atr, attrbuf, BUFSZ); if (tmpattr) Sprintf(eos(clrbuf), "&%s", tmpattr); - Sprintf(condbuf, "condition/%s/%s", - conditionbitmask2str(cond_maps[i].bm), clrbuf); + Snprintf(condbuf, sizeof(condbuf), "condition/%s/%s", + conditionbitmask2str(cond_maps[i].bm), clrbuf); status_hilite_linestr_add(BL_CONDITION, 0, cond_maps[i].bm, condbuf); } @@ -3236,7 +3240,8 @@ struct hilite_s *hl; if ((tmpattr = hlattr2attrname(attr, attrbuf, BUFSZ)) != 0) Sprintf(eos(clrbuf), "&%s", tmpattr); } - Sprintf(buf, "%s/%s/%s", initblstats[hl->fld].fldname, behavebuf, clrbuf); + Snprintf(buf, sizeof(buf), "%s/%s/%s", initblstats[hl->fld].fldname, + behavebuf, clrbuf); return buf; } diff --git a/src/cmd.c b/src/cmd.c index 1c7f466ed..bfc9ece1c 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -674,7 +674,7 @@ extcmd_via_menu() add_menu(win, &nul_glyphinfo, &any, any.a_char, 0, ATR_NONE, buf, MENU_ITEMFLAGS_NONE); } - Sprintf(prompt, "Extended Command: %s", cbuf); + Snprintf(prompt, sizeof(prompt), "Extended Command: %s", cbuf); end_menu(win, prompt); n = select_menu(win, PICK_ONE, &pick_list); destroy_nhwindow(win); @@ -2392,7 +2392,8 @@ dokeylist(VOID_ARGS) Sprintf(buf2, "[%s]", spkey_name(j)); /* lines up with the other unassigned commands which use "#%-20s ", but not with the other special keys */ - Sprintf(buf, "%-21s %s", buf2, misc_keys[i].desc); + Snprintf(buf, sizeof(buf), "%-21s %s", buf2, + misc_keys[i].desc); putstr(datawin, 0, buf); } } @@ -4807,7 +4808,8 @@ const char *prompt; Strcpy(pbuf + (QBUFSZ - 1) - k - 4, "...?"); /* -4: "...?" */ } - Sprintf(qbuf, "%s%s %s", promptprefix, pbuf, responsetype); + Snprintf(qbuf, sizeof(qbuf), "%s%s %s", promptprefix, pbuf, + responsetype); *ans = '\0'; getlin(qbuf, ans); (void) mungspaces(ans); diff --git a/src/do_name.c b/src/do_name.c index f0374b931..d74818069 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -205,7 +205,8 @@ const char *goal; } else { Sprintf(kbuf, "'%s'", visctrl(g.Cmd.spkeys[NHKF_GETPOS_PICK])); } - Sprintf(sbuf, "Type a %s when you are at the right place.", kbuf); + Snprintf(sbuf, sizeof(sbuf), + "Type a %s when you are at the right place.", kbuf); putstr(tmpwin, 0, sbuf); if (doing_what_is) { Sprintf(sbuf, diff --git a/src/do_wear.c b/src/do_wear.c index ebdf6102c..c8b84e1fe 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1514,7 +1514,8 @@ struct obj *obj; Strcat(what, " and "); Strcat(what, suit_simple_name(uarm)); } - Sprintf(why, " without taking off your %s first", what); + Snprintf(why, sizeof(why), " without taking off your %s first", + what); } else { Strcpy(why, "; it's embedded"); } diff --git a/src/dungeon.c b/src/dungeon.c index 907bf2765..7e6da3244 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -3537,8 +3537,8 @@ boolean printdun; (void) strsubst(tmpbuf, " herself", " yourself"); (void) strsubst(tmpbuf, " his ", " your "); (void) strsubst(tmpbuf, " her ", " your "); - Sprintf(buf, "%s%syou, %s%c", PREFIX, TAB, tmpbuf, - --kncnt ? ',' : '.'); + Snprintf(buf, sizeof(buf), "%s%syou, %s%c", PREFIX, TAB, + tmpbuf, --kncnt ? ',' : '.'); putstr(win, 0, buf); } for (bp = mptr->final_resting_place; bp; bp = bp->next) { diff --git a/src/eat.c b/src/eat.c index 72254a993..77b7b1c6c 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2353,16 +2353,17 @@ struct obj *otmp; */ if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && !Sick_resistance) { /* Tainted meat */ - Sprintf(buf, "%s like %s could be tainted! %s", foodsmell, it_or_they, - eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s like %s could be tainted! %s", + foodsmell, it_or_they, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else return 2; } if (stoneorslime) { - Sprintf(buf, "%s like %s could be something very dangerous! %s", - foodsmell, it_or_they, eat_it_anyway); + Snprintf(buf, sizeof(buf), + "%s like %s could be something very dangerous! %s", + foodsmell, it_or_they, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else @@ -2370,8 +2371,8 @@ struct obj *otmp; } if (otmp->orotten || (cadaver && rotted > 3L)) { /* Rotten */ - Sprintf(buf, "%s like %s could be rotten! %s", foodsmell, it_or_they, - eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s like %s could be rotten! %s", + foodsmell, it_or_they, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else @@ -2379,8 +2380,8 @@ struct obj *otmp; } if (cadaver && poisonous(&mons[mnum]) && !Poison_resistance) { /* poisonous */ - Sprintf(buf, "%s like %s might be poisonous! %s", foodsmell, - it_or_they, eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s like %s might be poisonous! %s", + foodsmell, it_or_they, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else @@ -2388,20 +2389,22 @@ struct obj *otmp; } if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) { /* causes sleep, for long enough to be dangerous */ - Sprintf(buf, "%s like %s might have been poisoned. %s", foodsmell, - it_or_they, eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s like %s might have been poisoned. %s", + foodsmell, it_or_they, eat_it_anyway); return (yn_function(buf, ynchars, 'n') == 'n') ? 1 : 2; } if (cadaver && !vegetarian(&mons[mnum]) && !u.uconduct.unvegetarian && Role_if(PM_MONK)) { - Sprintf(buf, "%s unhealthy. %s", foodsmell, eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s unhealthy. %s", foodsmell, + eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else return 2; } if (cadaver && acidic(&mons[mnum]) && !Acid_resistance) { - Sprintf(buf, "%s rather acidic. %s", foodsmell, eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s rather acidic. %s", + foodsmell, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else @@ -2409,8 +2412,8 @@ struct obj *otmp; } if (Upolyd && u.umonnum == PM_RUST_MONSTER && is_metallic(otmp) && otmp->oerodeproof) { - Sprintf(buf, "%s disgusting to you right now. %s", foodsmell, - eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s disgusting to you right now. %s", + foodsmell, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else @@ -2424,8 +2427,8 @@ struct obj *otmp; && ((material == LEATHER || material == BONE || material == DRAGON_HIDE || material == WAX) || (cadaver && !vegan(&mons[mnum])))) { - Sprintf(buf, "%s foul and unfamiliar to you. %s", foodsmell, - eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s foul and unfamiliar to you. %s", + foodsmell, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else @@ -2435,7 +2438,8 @@ struct obj *otmp; && ((material == LEATHER || material == BONE || material == DRAGON_HIDE) || (cadaver && !vegetarian(&mons[mnum])))) { - Sprintf(buf, "%s unfamiliar to you. %s", foodsmell, eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s unfamiliar to you. %s", + foodsmell, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else @@ -2444,8 +2448,8 @@ struct obj *otmp; if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && Sick_resistance) { /* Tainted meat with Sick_resistance */ - Sprintf(buf, "%s like %s could be tainted! %s", - foodsmell, it_or_they, eat_it_anyway); + Snprintf(buf, sizeof(buf), "%s like %s could be tainted! %s", + foodsmell, it_or_they, eat_it_anyway); if (yn_function(buf, ynchars, 'n') == 'n') return 1; else diff --git a/src/insight.c b/src/insight.c index eaf0f5aa2..a5cb1ecb6 100644 --- a/src/insight.c +++ b/src/insight.c @@ -242,8 +242,8 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */ *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */ /* as in background_enlightenment, when poly'd we need to use the saved gender in u.mfemale rather than the current you-as-monster gender */ - Sprintf(buf, "%s the %s's attributes:", tmpbuf, - ((Upolyd ? u.mfemale : flags.female) && g.urole.name.f) + Snprintf(buf, sizeof(buf), "%s the %s's attributes:", tmpbuf, + ((Upolyd ? u.mfemale : flags.female) && g.urole.name.f) ? g.urole.name.f : g.urole.name.m); @@ -330,9 +330,10 @@ int final; Sprintf(eos(tmpbuf), "%s in ", pmname(&mons[g.youmonst.cham], flags.female ? FEMALE : MALE)); - Sprintf(buf, "%s%s%s%s form", !final ? "currently " : "", - altphrasing ? just_an(anbuf, tmpbuf) : "in ", - tmpbuf, pmname(uasmon, flags.female ? FEMALE : MALE)); + Snprintf(buf, sizeof(buf), "%s%s%s%s form", + !final ? "currently " : "", + altphrasing ? just_an(anbuf, tmpbuf) : "in ", + tmpbuf, pmname(uasmon, flags.female ? FEMALE : MALE)); you_are(buf, ""); } @@ -427,8 +428,8 @@ int final; int egdepth = observable_depth(&u.uz); (void) endgamelevelname(tmpbuf, egdepth); - Sprintf(buf, "in the endgame, on the %s%s", - !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf); + Snprintf(buf, sizeof(buf), "in the endgame, on the %s%s", + !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf); } else if (Is_knox(&u.uz)) { /* this gives away the fact that the knox branch is only 1 level */ Sprintf(buf, "on the %s level", g.dungeons[u.uz.dnum].dname); @@ -448,7 +449,7 @@ int final; Strcat(tmpbuf, ", a primitive area"); else if (Is_bigroom(&u.uz) && !Blind) Strcat(tmpbuf, ", a very big room"); - Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf); + Snprintf(buf, sizeof(buf), "in %s, on %s", dgnbuf, tmpbuf); } you_are(buf, ""); @@ -1216,7 +1217,7 @@ int final; Strcat(buf, " and two weapons"); if (also3) { Strcpy(pfx, "You also "); - Sprintf(sfx, " %s", buf), buf[0] = '\0'; + Snprintf(sfx, sizeof(sfx), " %s", buf), buf[0] = '\0'; verb_present = hav2 ? "have" : "are"; verb_past = hav2 ? "had" : "were"; } @@ -2479,7 +2480,7 @@ boolean ask; : !digit(buf[2]) ? 4 : 0; if (class_header) ++pfx; - Sprintf(buftoo, "%*s%s", pfx, "", buf); + Snprintf(buftoo, sizeof(buftoo), "%*s%s", pfx, "", buf); putstr(klwin, 0, buftoo); } /* diff --git a/src/mhitm.c b/src/mhitm.c index f86843035..797b3ee32 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -576,29 +576,29 @@ int dieroll; buf[0] = '\0'; switch (mattk->aatyp) { case AT_BITE: - Sprintf(buf, "%s bites", magr_name); + Snprintf(buf, sizeof(buf), "%s bites", magr_name); break; case AT_STNG: - Sprintf(buf, "%s stings", magr_name); + Snprintf(buf, sizeof(buf), "%s stings", magr_name); break; case AT_BUTT: - Sprintf(buf, "%s butts", magr_name); + Snprintf(buf, sizeof(buf), "%s butts", magr_name); break; case AT_TUCH: - Sprintf(buf, "%s touches", magr_name); + Snprintf(buf, sizeof(buf), "%s touches", magr_name); break; case AT_TENT: - Sprintf(buf, "%s tentacles suck", s_suffix(magr_name)); + Snprintf(buf, sizeof(buf), "%s tentacles suck", s_suffix(magr_name)); break; case AT_HUGS: if (magr != u.ustuck) { - Sprintf(buf, "%s squeezes", magr_name); + Snprintf(buf, sizeof(buf), "%s squeezes", magr_name); break; } /*FALLTHRU*/ default: if (!weaponhit || !mwep || !mwep->oartifact) - Sprintf(buf, "%s hits", magr_name); + Snprintf(buf, sizeof(buf), "%s hits", magr_name); break; } if (*buf) diff --git a/src/options.c b/src/options.c index eec4d7e32..e8dd2412a 100644 --- a/src/options.c +++ b/src/options.c @@ -8283,8 +8283,8 @@ option_help() || (is_wc2_option(optname) && !wc2_supported(optname))) continue; Sprintf(buf2, "`%s'", optname); - Sprintf(buf, "%-20s - %s%c", buf2, allopt[i].descr, - allopt[i + 1].name ? ',' : '.'); + Snprintf(buf, sizeof(buf), "%-20s - %s%c", buf2, allopt[i].descr, + allopt[i + 1].name ? ',' : '.'); putstr(datawin, 0, buf); } putstr(datawin, 0, ""); diff --git a/src/pager.c b/src/pager.c index fb96e98b5..20346430e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1207,13 +1207,13 @@ struct permonst **for_supplement; *firstmatch = look_buf; if (*(*firstmatch)) { - Sprintf(temp_buf, " (%s)", *firstmatch); + Snprintf(temp_buf, sizeof(temp_buf), " (%s)", *firstmatch); (void) strncat(out_str, temp_buf, BUFSZ - strlen(out_str) - 1); found = 1; /* we have something to look up */ } if (monbuf[0]) { - Sprintf(temp_buf, " [seen: %s]", monbuf); + Snprintf(temp_buf, sizeof(temp_buf), " [seen: %s]", monbuf); (void) strncat(out_str, temp_buf, BUFSZ - strlen(out_str) - 1); } diff --git a/src/potion.c b/src/potion.c index 0cdb38e32..7e339728c 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1425,7 +1425,8 @@ int how; switch (obj->otyp) { case POT_WATER: - Sprintf(saddle_glows, "%s %s", buf, aobjnam(saddle, "glow")); + Snprintf(saddle_glows, sizeof(saddle_glows), "%s %s", + buf, aobjnam(saddle, "glow")); affected = H2Opotion_dip(obj, saddle, useeit, saddle_glows); break; case POT_POLYMORPH: @@ -1975,8 +1976,8 @@ dodip() here = levl[u.ux][u.uy].typ; /* Is there a fountain to dip into here? */ if (IS_FOUNTAIN(here)) { - Sprintf(qbuf, "%s%s into the fountain?", Dip_, - flags.verbose ? obuf : shortestname); + Snprintf(qbuf, sizeof(qbuf), "%s%s into the fountain?", Dip_, + flags.verbose ? obuf : shortestname); /* "Dip into the fountain?" */ if (yn(qbuf) == 'y') { dipfountain(obj); @@ -1985,8 +1986,8 @@ dodip() } else if (is_pool(u.ux, u.uy)) { const char *pooltype = waterbody_name(u.ux, u.uy); - Sprintf(qbuf, "%s%s into the %s?", Dip_, - flags.verbose ? obuf : shortestname, pooltype); + Snprintf(qbuf, sizeof(qbuf), "%s%s into the %s?", Dip_, + flags.verbose ? obuf : shortestname, pooltype); /* "Dip into the {pool, moat, &c}?" */ if (yn(qbuf) == 'y') { if (Levitation) { @@ -2005,7 +2006,8 @@ dodip() } /* "What do you want to dip into? [xyz or ?*] " */ - Sprintf(qbuf, "dip %s into", flags.verbose ? obuf : shortestname); + Snprintf(qbuf, sizeof(qbuf), "dip %s into", + flags.verbose ? obuf : shortestname); potion = getobj(qbuf, drink_ok, GETOBJ_NOFLAGS); if (!potion) return 0; diff --git a/src/spell.c b/src/spell.c index bea26783e..776f05ec8 100644 --- a/src/spell.c +++ b/src/spell.c @@ -715,7 +715,8 @@ int *spell_no; Sprintf(lets, "a-zA-%c", 'A' + nspells - 27); for (;;) { - Sprintf(qbuf, "Cast which spell? [%s *?]", lets); + Snprintf(qbuf, sizeof(qbuf), "Cast which spell? [%s *?]", + lets); ilet = yn_function(qbuf, (char *) 0, '\0'); if (ilet == '*' || ilet == '?') break; /* use menu mode */ diff --git a/src/topten.c b/src/topten.c index db9208114..554278037 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1058,7 +1058,7 @@ boolean so; topten_print_bold(linebuf); } else topten_print(linebuf); - Sprintf(linebuf, "%15s %s", "", linebuf3); + Snprintf(linebuf, sizeof(linebuf), "%15s %s", "", linebuf3); lngr = strlen(linebuf); } /* beginning of hp column not including padding */ diff --git a/src/trap.c b/src/trap.c index 00d4140ad..6cfd0e61d 100644 --- a/src/trap.c +++ b/src/trap.c @@ -4838,11 +4838,14 @@ boolean force; trap_skipped = TRUE; deal_with_floor_trap = FALSE; } else { - Sprintf( - qbuf, "There %s and %s here. %s %s?", - (boxcnt == 1) ? "is a container" : "are containers", - an(trapdescr), - (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap); + Snprintf(qbuf, sizeof(qbuf), + "There %s and %s here. %s %s?", + (boxcnt == 1) ? "is a container" + : "are containers", + an(trapdescr), + (ttmp->ttyp == WEB) ? "Remove" + : "Disarm", + the_trap); switch (ynq(qbuf)) { case 'q': return 0; diff --git a/src/uhitm.c b/src/uhitm.c index 102db57e4..09db7c852 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1320,11 +1320,12 @@ int dieroll; else if (silverobj && saved_oname[0]) { /* guard constructed format string against '%' in saved_oname[] from xname(via cxname()) */ - Sprintf(silverobjbuf, "Your %s%s %s", - strstri(saved_oname, "silver") ? "" : "silver ", - saved_oname, vtense(saved_oname, "sear")); + Snprintf(silverobjbuf, sizeof(silverobjbuf), "Your %s%s %s", + strstri(saved_oname, "silver") ? "" : "silver ", + saved_oname, vtense(saved_oname, "sear")); (void) strNsubst(silverobjbuf, "%", "%%", 0); - Strcat(silverobjbuf, " %s!"); + strncat(silverobjbuf, " %s!", + sizeof(silverobjbuf) - (strlen(silverobjbuf) + 1)); fmt = silverobjbuf; } else fmt = "The silver sears %s!"; diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 27c6fc9cb..5ab6af594 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -451,7 +451,7 @@ curses_choose_character() } prompt[count_off] = '\0'; - sprintf(choice, "%s%c", tmpchoice, '\033'); + Snprintf(choice, sizeof(choice), "%s%c", tmpchoice, '\033'); if (strchr(tmpchoice, 't')) { /* Tutorial mode */ mvaddstr(0, 1, "New? Press t to enter a tutorial."); } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index a272118ae..12ef0c903 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -961,10 +961,10 @@ tty_player_selection() Sprintf(plbuf, " %s", genders[GEND].adj); else *plbuf = '\0'; /* omit redundant gender */ - Sprintf(pbuf, "%s, %s%s %s %s", g.plname, aligns[ALGN].adj, plbuf, - races[RACE].adj, - (GEND == 1 && roles[ROLE].name.f) ? roles[ROLE].name.f - : roles[ROLE].name.m); + Snprintf(pbuf, sizeof(pbuf), "%s, %s%s %s %s", g.plname, + aligns[ALGN].adj, plbuf, races[RACE].adj, + (GEND == 1 && roles[ROLE].name.f) ? roles[ROLE].name.f + : roles[ROLE].name.m); add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, pbuf, MENU_ITEMFLAGS_NONE); /* blank separator */