25 Jan, 2009, Kline wrote in the 1st comment:
Votes: 0
So I decided to take some code to disable commands from one game of mine and port it into another (Erwin's snippet, probably). Re-wrote a few small bits of it, mostly to use STL lists, new/delete, etc.

Disabling commands works. Enabling them works. Saving them works. Loading them back from file does not work. I've looked over it numerous times and can't figure out why. I've even logged the loads line by line and they load and link correctly, then after making a final cycle through the for() to catch "End" suddenly the disabled_by changes to "End" and the list corrupts from there. Maybe another set of eyes will help?

void load_disabled( void )
{
FILE *fp;
DISABLED_DATA *p;
const char *word;
short i;

snprintf( log_buf, (2 * MIL), "Loading %s", DISABLED_FILE);
log_f( "%s", log_buf );

if( (fp = file_open(DISABLED_FILE,"r")) == NULL )
{
log_f("Done.");
file_close(fp);
return;
}

for( ;; )
{
word = feof(fp) ? "End" : fread_word(fp);

//p->disabled_by now is "End" somehow?

if( !str_cmp(word,"End") )
{
file_close(fp);
log_f("Done.");
return;
}

for( i = 0; cmd_table[i].name[0] != '\0'; i++ )
if( !str_cmp(cmd_table[i].name,word) )
break;

if( cmd_table[i].name[0] == '\0' ) // Old command now removed?
{
snprintf(log_buf,(2 * MIL),"Skipping unknown command (%s) in disabled commands.",word);
log_f("%",log_buf);
fread_number(fp); // Level
fread_word(fp); // Disabled by
}
else
{
p = new DISABLED_DATA;
p->command = &cmd_table[i];
p->level = fread_number(fp);
p->disabled_by = fread_word(fp);
//p looks fine at this point in logs
}
}

log_f("Done.");
file_close(fp);

return;
}
25 Jan, 2009, David Haley wrote in the 2nd comment:
Votes: 0
fread_word returns a pointer to a static buffer, not a newly allocated string.

the line
p->disabled_by = fread_word(fp)

makes disabled_by a pointer to this static buffer.

When you read the word 'End' into the static buffer, p->disabled_by – which points to the static buffer – is going to point to the string 'End'.
25 Jan, 2009, Kline wrote in the 3rd comment:
Votes: 0
Thanks! I knew it had to be something stupid floating around; teach me to do that at 1am :(
25 Jan, 2009, Kayle wrote in the 4th comment:
Votes: 0
Why split them off and save/load them separately? Wouldn't it be easier to just set a flag on the command that marks it as disabled and then check for said flag with the interpreter?
25 Jan, 2009, Kline wrote in the 5th comment:
Votes: 0
I'm not Smaug, so my commands aren't that fancy yet :). I still use a fat ugly const table for all command issues.
25 Jan, 2009, Kayle wrote in the 6th comment:
Votes: 0
Ewww….
0.0/6