05 Feb, 2010, Bojack wrote in the 1st comment:
Votes: 0
Ok its official, I cant figure out how to correctly write a calloc call. Newbie needs help please.
Before anyone criticizes, I already know im doing it wrong. This is what I have:
void fread_clan (FILE *fp)
{
char buf[MSL];
CLAN_DATA *pClan;
char *string;
bool fMatch;
int i;

if ( ((pClan) = (CLAN_DATA *) calloc ( (1), sizeof(CLAN_DATA) )) )
{
for (;;)
{
string = feof(fp) ? "End" : fread_word (fp);
fMatch = FALSE;

switch (UPPER(string[0]))
{
case 'C':
if (!str_cmp (string, "Clan") )
{
pClan->name = fread_string (fp);
fMatch = TRUE;
}
break;

case 'E':
if (!str_cmp (string, "End") )
{
fMatch = TRUE;
if (clan_first == NULL)
clan_first = pclan;

if (clan_last != NULL)
clan_last->next = pClan;

clan_last = pClan;
pClan->next = NULL;
top_clan++;

return;
}
break;
case 'F':
if (!str_cmp (string, "Flags") )
{
pClan->flags = fread_flag( fp );
fMatch = TRUE;
}
break;

case 'L':
if (!str_cmp (string, "Leader") )
{
pclan->leader = fread_string(fp);
fMatch = TRUE;
}
break;

case 'R':
if (!str_cmp(string, "CRank") || !str_cmp(string, "Rank"))
{
i = fread_number(fp);
pClan->c_rank[i].rankname = fread_string(fp);
fMatch = TRUE;
}
break;

case 'W':
if (!str_cmp (string, "Who") )
{
pClan->who_name = fread_string(fp);
fMatch = TRUE;
}
break;
} /* end of switch */

if ( !fMatch )
{
sprintf( buf, "Fread_clans: no string match '%s'", string );
logstr( LOG_BUG, buf, 0 );
}
} /* end loop */
} /* end if */

if (!pClan)
{
logstr( LOG_BUG, "Memory allocating for clans failed", 0);
abort();
return NULL;
}
}


What im trying to figure out is if I need to allocate per clan or just all at once? Also am I writing it correctly? They are all in one file but each clan starts with #Clan and ends with End.
05 Feb, 2010, Davion wrote in the 2nd comment:
Votes: 0
The function looks sound. It all depends on how you're calling it, though. Care you post the function where you call fread_clan()?

Also, here's a few clan system snippets. You might be able to use them as examples.

[link=file]1968[/link]
[link=file]1970[/link]
[link=file]2264[/link]
05 Feb, 2010, Bojack wrote in the 3rd comment:
Votes: 0
Ive already looked at those before and none of them are as close as what I want. clan.zip does use calloc but still goes by an array that you have to manually go into the file and change where as mine is changed via an online editor. Anyways here's the other part:
void load_clans (void)
{
char buf[256];
FILE *fp;
CLAN_DATA *pClan;

sprintf (buf, "%s", CLAN_FILE);
if (!(fp = fopen( buf, "r" )) )
{
logstr( LOG_BUG, "Load_clans: file not found.", 0 );
exit(1);
}

else
{
for (;;)
{
char *word;

word = feof( fp ) ? "$" : fread_word( fp );

if (!str_cmp( word, "#CLAN" ) )
{
fread_clan( fp );
break;
}
else
{
char error[MSL];

sprintf( error, "Load_clans: bad string found '%s'", word );
logstr( LOG_BUG, error, 0 );
break;
}
}
fclose( fp );
}
return;
}
05 Feb, 2010, Kayle wrote in the 4th comment:
Votes: 0
If you're trying to do OLC Clans, look at SmaugFUSS. It supports clans that are created and maintained online, inside the game. The only thing it doesn't do is allow you to delete a clan from in the OLC. (Don't ask me why, I'm not sure. But it's probably something to look into fixing…)
05 Feb, 2010, Bojack wrote in the 5th comment:
Votes: 0
Well ive already created an online editor, im just updating it. Only thing I need to know if my loading is correct, once that works then im complete and can update my cedit function I wrote awhile ago.
05 Feb, 2010, Kline wrote in the 6th comment:
Votes: 0
After a quick glance I don't see any issues. Are you able the boot the game and load clans successfully without crashing? That would be the first determination of "if my loading is correct". After that, try running through Valgrind to ensure you aren't leaking anything.
06 Feb, 2010, Bojack wrote in the 7th comment:
Votes: 0
Update: It doesnt crash anymore after fixing one error, now it loads up fine but only loads one clan or I just cant see the other clans because of the way I have this part below set up:
case 'E':
if (!str_cmp (string, "End") )
{
fMatch = TRUE;
if (clan_first == NULL)
clan_first = pclan;

if (clan_last != NULL)
clan_last->next = pClan;

clan_last = pClan;
pClan->next = NULL;
top_clan++;

return;
}
06 Feb, 2010, Crelin wrote in the 8th comment:
Votes: 0
EDIT: delete post, looked at code further…question is irrelevant.
06 Feb, 2010, Kline wrote in the 9th comment:
Votes: 0
Can you post a sample file you are trying to read? It's possible you're not saving the data how you intended to read it, or vise versa.
06 Feb, 2010, Bojack wrote in the 10th comment:
Votes: 0
#CLAN
Clan Loner~
Who [ {GHermit{x ] ~
Leader None~
Rank 1 Unassigned~
Rank 2 Unassigned~
Rank 3 Unassigned~
Rank 4 Unassigned~
Rank 5 Unassigned~
Rank 6 Unassigned~
Rank 7 Unassigned~
Flags C
End

#CLAN
Clan Frozen Empire~
Who [-{r={D>{CF{WE{D<{r={x-] ~
Leader Velkyr~
Rank 1 Grunt~
Rank 2 Trainee~
Rank 3 Soldier~
Rank 4 Ice Soldier~
Rank 5 Apprentice of Ice~
Rank 6 Ice Master~
Rank 7 Lord of Ice~
Flags 0
End

#CLAN
Clan Universal Defense Force~
Who [ {D>{BU{DD{WF{D<{x ] ~
Leader Oachi~
Rank 1 Recruit~
Rank 2 Trainee~
Rank 3 Apprentice~
Rank 4 Universal Defender~
Rank 5 Universal Guardian~
Rank 6 High Defender~
Rank 7 High Guardian~
Flags 0
End

$
06 Feb, 2010, Crelin wrote in the 11th comment:
Votes: 0
it looks like we may be using pretty close to the same system, I'll just post my load_clans function and you can go from there…it seems to me it's the End returning in the for loop so it stops after it sees the first End in the clan file and doesn't read the others.

void load_clans(void)
{
FILE *fp;
char *string;
int count = 0;
int i;
bool fMatch = FALSE;

for (i = 0; i < (1 + top_clan); i++) //MAX_CLAN; i++)
{
clan_table[i].name = "";
clan_table[i].who_name = "";
clan_table[i].leader = "";
clan_table[i].c_rank[0].rankname = "";
clan_table[i].flags = 0;
}

if (!(fp = fopen(DATA_FILE, "r")) )
{
log_string("Error: guild.dat file not found!");
exit(1);
}

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

if (!str_cmp(string, "End"))
break;

switch (UPPER(string[0]))
{
case 'C':
top_clan++;
count++;
clan_table[count].name = fread_string(fp);
fMatch = TRUE;
break;

case 'F':
clan_table[count].flags = fread_flag( fp );
fMatch = TRUE;
break;

case 'L':
clan_table[count].leader = fread_string(fp);
fMatch = TRUE;
break;

case 'R':
if (!str_cmp(string, "CRank") || !str_cmp(string, "Rank"))
{
i = fread_number(fp);
clan_table[count].c_rank[i].rankname = fread_string(fp);
fMatch = TRUE;
}
break;

case 'W':
clan_table[count].who_name = fread_string(fp);
fMatch = TRUE;
break;
} /* end of switch */
} /* end of while (!feof) */

if (!fMatch)
{
bug("Fread_clans: no match.", 0);
fread_to_eol(fp);
}
fclose(fp);
return;
}
06 Feb, 2010, KaVir wrote in the 12th comment:
Votes: 0
Crelin said:
for (i = 0; i < (1 + top_clan); i++) //MAX_CLAN; i++)
{
clan_table[i].name = "";
clan_table[i].who_name = "";
clan_table[i].leader = "";
clan_table[i].c_rank[0].rankname = "";
clan_table[i].flags = 0;
}

I wouldn't suggest initialising your strings like that - set them to NULL instead. Otherwise if they're not initialised from the file you could run into real problems when you free them.
06 Feb, 2010, Crelin wrote in the 13th comment:
Votes: 0
Quote
I wouldn't suggest initialising your strings like that - set them to NULL instead. Otherwise if they're not initialised from the file you could run into real problems when you free them.

ahh, nod…ty…haven't looked at the code in a while until now (since I fixed the logfile bugs I was having with it) so thank you for pointing that out.
07 Feb, 2010, Bojack wrote in the 14th comment:
Votes: 0
Crelin, the reason it looks similar cuz it is. The clan editor you are using is the one I wrote, its cedit. I wrote it almost a year ago but I did a crappy job and did it the lazy way. Im redoing it cuz of mainly 2 reasons, the loading of the clans and cedit_delete, everything else is fine. Btw crelin, there is a small problem with cedit_delete, its kind of hard to explain but ill try in a diagram:
Each letter represents a clan:
A
B
C
D = Me
If I delete C, the list is moved up so the numbers are changed. So if D which is me is number 4, d becomes number 3 which used to be c. So now I get moved from being in clan D to being in no clan cuz the players side is still set at 4. I never came up with a fix for it just because of how I set cedit_delete up without using a temporary file to save the info in.
07 Feb, 2010, Sharmair wrote in the 15th comment:
Votes: 0
Your load_clan functions has a few issues, but the one causing your
load to end after loading the first clan is the break after the fread_clan
call. You should remove that break and add a new condition to the loop
to look for the $ end and break there.
08 Feb, 2010, Bojack wrote in the 16th comment:
Votes: 0
Alright now it loads 2 clans, which are the beginning of the file, and the end of the file clans but nothing in between. Here's what I changed:
This is in load_clans (void)
clan_first = NULL;
clan_last = NULL;

for (;;)
{
char *word;

word = feof( fp ) ? "$" : fread_word( fp );

if (!str_cmp( word, "#CLAN" ) )
fread_clan( fp );

else if (!str_cmp(word, "$") )
break;

else
{
char error[MSL];

sprintf( error, "Load_clans: bad string found '%s'", word );
logstr( LOG_BUG, error, 0 );
break;
}
}
fclose( fp );

This is in fread_clan (FILE *fp)
case 'E':
if (!str_cmp (string, "End") )
{
if (clan_first == NULL)
{
clan_first = pClan;
clan_last = pClan;
}

else {
clan_last->next = pClan;
}
pClan->next = NULL;
top_clan++;
fMatch = TRUE;

return;
}
break;

Weird thing is top_clan counts 4 clans in the mud but only display's 2.
08 Feb, 2010, Bojack wrote in the 17th comment:
Votes: 0
I figured it out, I forgot to add before pClan->next = NULL, clan_last = pClan; Thanks for everyone's help! I should be able to do deleting now by back tracking how its loaded.
0.0/17