30 Jun, 2009, Banner wrote in the 1st comment:
Votes: 0
I want to make this function print the entire list of flags from the flag list passed to it instead of just the ones passed from the first argument. Runter told me I need to drop the first argument, but I'm not sure how to modify the function after that.

const char *ext_flag_string( EXT_BV * bitvector, const char *const flagarray[] )
{
static char buf[MAX_STRING_LENGTH];
int x;

buf[0] = '\0';
for( x = 0; x < MAX_BITS; ++x )
if( xIS_SET( *bitvector, x ) )
{
mudstrlcat( buf, flagarray[x], MAX_STRING_LENGTH );
mudstrlcat( buf, " ", MAX_STRING_LENGTH );
}
if( ( x = strlen( buf ) ) > 0 )
buf[–x] = '\0';

return buf;
}


const char *ext_flag_string( EXT_BV * bitvector, const char *const flagarray[] );
const char *list_flag_string( const char *const flagarray[] );
30 Jun, 2009, Runter wrote in the 2nd comment:
Votes: 0
const char *ext_flag_string2( EXT_BV * bitvector, const char *const flagarray[] ) {
static char buf[MAX_STRING_LENGTH];
int x;
buf[0] = '\0';

// prints all bits.
for( x = 0; x < MAX_BITS; ++x ) {
if flagarray[x] {
mudstrlcat( buf, flagarray[x], MAX_STRING_LENGTH );
mudstrlcat( buf, " ", MAX_STRING_LENGTH );
}
}

if( ( x = strlen( buf ) ) > 0 )
buf[–x] = '\0';

return buf;
}


See if that works for you.
30 Jun, 2009, Banner wrote in the 3rd comment:
Votes: 0
I think the line was too long because it crashed.

Program received signal SIGSEGV, Segmentation fault.
0x0812f85f in mudstrlcat (
dst=0x82d4180 "dark death nomob indoors lawful neutral chaotic nomagic tunnel private safe solitary petshop norecall donation nodropall silence
logspeech nodrop clanstoreroom nosummon noastral teleport teleshowdesc "…, src=0x776f6c67 <Address 0x776f6c67 out of bounds>, siz=4096) at db.c:9025
9025 while( *s != '\0' )
Current language: auto; currently c++
(gdb) bt
#0 0x0812f85f in mudstrlcat (
dst=0x82d4180 "dark death nomob indoors lawful neutral chaotic nomagic tunnel private safe solitary petshop norecall donation nodropall silence
logspeech nodrop clanstoreroom nosummon noastral teleport teleshowdesc "…, src=0x776f6c67 <Address 0x776f6c67 out of bounds>, siz=4096) at db.c:9025
#1 0x080f9a70 in list_flag_string (flagarray=0x82616a0) at build.c:309
#2 0x080fa89a in do_redit (ch=0x849c430, argument=0xbff2239b "") at build.c:4783
#3 0x0817a7bf in interpret (ch=0x849c430, argument=0xbff22396 "flags") at interp.c:548
#4 0x0812a183 in game_loop () at comm.c:867
#5 0x0812c071 in main (argc=2, argv=0xbff22884) at comm.c:536
(gdb)


How can you make it break off after so many characters?
30 Jun, 2009, Runter wrote in the 4th comment:
Votes: 0
You might want to increase MAX_STRING_LENGTH there if it isn't enough? I dunno.
30 Jun, 2009, Guest wrote in the 5th comment:
Votes: 0
If the flagarray does not have MAX_BITS worth of actual named values you're crashing by trying to access beyond the boundary of the array.

Can't see why that would happen in Runter's ext_flag_string2 function, but that's the likely cause. MAX_BITS works out to 128 in stock code. And none of the flag lists have 128 members.
30 Jun, 2009, Runter wrote in the 6th comment:
Votes: 0
In that case, you probably only want to replace MAX_BITS in that code with whatever the size of your table is.
30 Jun, 2009, David Haley wrote in the 7th comment:
Votes: 0
Quote
if flagarray[x] {

This wouldn't do anything useful unless the string arrays are null terminated. (The strings themselves are, but the array isn't.)

Easiest would be to pass in the size as well.

So basically I think Samson was correct: you're trying to iterate over more array members than you actually have. It's happening because the above guard doesn't actually do anything unless the memory after the array happens to be null. (But if you step over it and go into unreachable memory, it doesn't matter what it contains.)
30 Jun, 2009, Runter wrote in the 8th comment:
Votes: 0
I was assuming that MAX_BITS was the size of the table in use.
30 Jun, 2009, David Haley wrote in the 9th comment:
Votes: 0
I think it's the maximum size of the "extended" bitvectors, because the previously limited bitvectors were replaced with newly limited bitvectors, instead of proper arbitrary-sized bitvectors. :rolleyes:
30 Jun, 2009, Runter wrote in the 10th comment:
Votes: 0
That's what I've gathered from Samson's post. But I admittedly have little or no experience with Smaug.
30 Jun, 2009, Banner wrote in the 11th comment:
Votes: 0
…. I'll just use send_to_chars to manually print the flags and update when one is added. ^_^
04 Jul, 2009, Sharmair wrote in the 12th comment:
Votes: 0
This code will list arrays of strings with 4 on a line and ignore entries starting with a
given prefix and a number (like r11 etc in a lot of the flag sets):
void list_array(CHAR_DATA* ch, const char* const* list, int size, const char* prefix){
int ct = 0;
int ind;

for(ind = 0; ind < size; ++ind){
if(!prefix || str_prefix(prefix, list[ind]) || !is_number(list[ind]+strlen(prefix))){
ch_printf(ch, " %-16.16s", list[ind]);
if(ct%4 == 3)
send_to_char("\r\n", ch);
++ct;
}
}
if(ct%4 != 0)
send_to_char("\r\n", ch);
}

If you don't need the prefix, or want to print all the entries, even the reserved ones, use NULL for prefix.
An example call would be (for room flags):
list_array(ch, r_flags, SIZE(r_flags), "r");

With SIZE defined as so if you don't already have such a thing:
#define SIZE(ar) ((int)(sizeof(ar)/sizeof((ar)[0])))
0.0/12