02 Aug, 2007, Zeno wrote in the 1st comment:
Votes: 0
I'm trying to "edit" global notes. Since gnotes are stored in one file and appended, I need to remove the section and append it again with the update info. I thought I had it all done, but I ran into some issues. Once I edit the gnote on the MUD, it looks fine at first:
Quote
[ 1] Xio: Bugtest
Date: Thu Aug 2 09:27:17 2007
To: imm
Status: 2
===========================================================================
Testinga

Then it changes.
Quote
[ 2] Xio: @
Date: smile $n
break
endif
endif

To: imm
Status: 1
===========================================================================
Testinga


I did something wrong, apparently. Here is the code:
sprintf( log_buf, "%s changed status of gnote; author was %s and subject was: %s", ch->name, p->sender, p->subject );
log_string( log_buf );

new_p->sender = p->sender;
new_p->date = p->date;
new_p->date_stamp = p->date_stamp;
new_p->expire = p->expire;
new_p->to_list = p->to_list;
new_p->subject = p->subject;
new_p->text = p->text;
new_p->status = atoi(arg2);

unlink_note (ch->pcdata->board,p);
free_global_note (p);

save_board(ch->pcdata->board); /* save the board */

if (ch->pcdata->board->note_first) /* are there any notes in there now? */
{
for (x = ch->pcdata->board->note_first; x->next; x = x->next )
; /* empty */

x->next = new_p;
}
else /* nope. empty list. */
ch->pcdata->board->note_first = new_p;

sprintf (filename, "%s%s", NOTE_DIR, ch->pcdata->board->short_name);

fp = fopen (filename, "a");
if (!fp)
{
bug ("Could not open one of the note files in append mode",0);
ch->pcdata->board->changed = TRUE; /* set it to TRUE hope it will be OK later? */
return;
}

append_note (fp, new_p);
fclose (fp);

send_to_char_color ("Gnote status changed!\n\r",ch);


Any idea what I did wrong? The actual data written to file is not changed.

I have a feeling I should be using STRALLOC or str_dup when copying the struct?
02 Aug, 2007, Keberus wrote in the 2nd comment:
Votes: 0
Quote
I have a feeling I should be using STRALLOC or str_dup when copying the struct? Posted Today, 1:46 pm


Well you're pretty much right. It looks to me as if your problem is that you are freeing the data before writing it.

Here:
new_p->sender = p->sender;
new_p->date = p->date;
new_p->date_stamp = p->date_stamp;
new_p->expire = p->expire;
new_p->to_list = p->to_list;
new_p->subject = p->subject;
new_p->text = p->text;
new_p->status = atoi(arg2);


All you did is set new_p to point to the memory locations of p. Problem is…
unlink_note (ch->pcdata->board,p);
free_global_note (p);


You free up the memory locations of p before appending to the file so new_p points to invalid memory. One possible thing to do is just set p->status = atoi(arg2) and send p instead of new_p and free it after apending so it would look something like this:

sprintf( log_buf, "%s changed status of gnote; author was %s and subject was: %s", ch->name, p->sender, p->subject );
log_string( log_buf );

p->status = atoi(arg2);

save_board(ch->pcdata->board); /* save the board */

if (ch->pcdata->board->note_first) /* are there any notes in there now? */
{
for (x = ch->pcdata->board->note_first; x->next; x = x->next )
; /* empty */

x->next = p;
}
else /* nope. empty list. */
ch->pcdata->board->note_first = p;

sprintf (filename, "%s%s", NOTE_DIR, ch->pcdata->board->short_name);

fp = fopen (filename, "a");
if (!fp)
{
bug ("Could not open one of the note files in append mode",0);
ch->pcdata->board->changed = TRUE; /* set it to TRUE hope it will be OK later? */
return;
}

append_note (fp, p);
fclose (fp);
unlink_note (ch->pcdata->board,p);
free_global_note (p);

send_to_char_color ("Gnote status changed!\n\r",ch);


I mean you can do that if there's no real other reason you are using new_p then setting it to p. The other option would be to use STRALLOC or str_dup, but make sure you use whatever corresponds to how you free them in free_gloabl_note.

If in free_global_note you use STRFREE, the STRALLOC it. If you use DISPOSE, then str_dup it.

Hope this helps,
KeB
02 Aug, 2007, kiasyn wrote in the 3rd comment:
Votes: 0
Kavir said:
If in free_global_note you use STRFREE, the STRALLOC it. If you use DISPOSE, then str_dup it.


Actually, if it uses STRFREE, use QUICKLINK =

Actually, if it uses STRFREE, use QUICKLINK =[
02 Aug, 2007, KaVir wrote in the 4th comment:
Votes: 0
kiasyn said:
Kavir said:


No I didn't!
02 Aug, 2007, Zeno wrote in the 5th comment:
Votes: 0
kiasyn said:
Kavir said:
If in free_global_note you use STRFREE, the STRALLOC it. If you use DISPOSE, then str_dup it.


Actually, if it uses STRFREE, use QUICKLINK =

Actually, if it uses STRFREE, use QUICKLINK =[
[/quote]
Strange, Smaug uses STRALLOC in most cases if it was freed by STRFREE.

Okay, and how about strcat? This causes problems:
[code] strcat(new_p->text, buf);[/code]
Would I do this?
[code] strcat(new_p->text, STRALLOC(buf));[/code]
02 Aug, 2007, Keberus wrote in the 6th comment:
Votes: 0
Zeno said:
Okay, and how about strcat? This causes problems:
strcat(new_p->text, buf);

Would I do this?
strcat(new_p->text, STRALLOC(buf));


Pretty sure you have to create a tempbuf to strcat to then stralloc it after freeing the old contents. If I were doing it, I would probably do something like so:

char tempbuf[MAX_STRING_LENGTH];

snprintf(tempbuf, MAX_STRING_LENGTH, "%s", new_p->text);
strncat(tempbuf, buf, MAX_STRING_LENGTH);
STRFREE(new_p->text);
new_p->text = STRALLOC(tempbuf);


Of course, thats just how I would do it.

Later,
KeB
02 Aug, 2007, Keberus wrote in the 7th comment:
Votes: 0
Quote
Actually, if it uses STRFREE, use QUICKLINK =Actually, if it uses STRFREE, use QUICKLINK =[ [/quote]

Don't you usually only QUICKLINK something if the string is already in the hash table …ie STRALLOC'ed?

Just wondering, because I would like to get that straight.

Thanks,
KeB
03 Aug, 2007, Zeno wrote in the 8th comment:
Votes: 0
Ah okay. That worked too, thanks.

I think this should be the last thing. :P Why does this not work?
ch->desc->connected = CON_NOTE_TEXT;
if (ch->substate == SUB_NONE)
{
ch->substate = SUB_APPEND_GNOTE;
ch->dest_buf = ch;
start_editing( ch, ch->pcdata->in_progress->text );
//handle_con_note_text(ch->desc, NULL);
}

snprintf(tempbuf, MAX_STRING_LENGTH, "%s", new_p->text);
strncat(tempbuf, copy_buffer(ch), MAX_STRING_LENGTH);
new_p->text = STRALLOC(tempbuf);


copy_buffer should have data in it that the player entered, but nothing is appended to the note. I'm trying to simply have them enter a buffer to append to a note, but the MUD wants to make it complicated. :P
03 Aug, 2007, Keberus wrote in the 9th comment:
Votes: 0
Quote
I think this should be the last thing. :P Why does this not work?
ch->desc->connected = CON_NOTE_TEXT;
if (ch->substate == SUB_NONE)
{
ch->substate = SUB_APPEND_GNOTE;
ch->dest_buf = ch;
start_editing( ch, ch->pcdata->in_progress->text );
//handle_con_note_text(ch->desc, NULL);
}

snprintf(tempbuf, MAX_STRING_LENGTH, "%s", new_p->text);
strncat(tempbuf, copy_buffer(ch), MAX_STRING_LENGTH);
new_p->text = STRALLOC(tempbuf);


Why do you change the CON state since you are using substates instead. Maybe remove that line completely. You could handle substates like that I guess but usually you use a switch statement. Also, I believe that copy_buffer returns a STRALLOC'ed value so in that case it would need free'ed. So maybe something like this would be better?

switch ( ch->substate )
{
default:
break;

case SUB_ABORT:
send_to_char("&RAborted note apending!\r\n", ch );
return;

case SUB_APPEND_GNOTE:
char *cbuf;
cbuf = copy_buffer(ch);
snprintf(tempbuf, MAX_STRING_LENGTH, "%s", new_p->text );
strncat(tempbuf, cbuf, MAX_STRING_LENGTH );
STRFREE( new_p->text);
new_p->text = STRALLOC(tempbuf);
stop_editing( ch );
STRFREE(cbuf);
send_to_char("Note board has been appended\r\n", ch );
return;
}
ch->substate == SUB_APPENT_GNOTE;
//before you call start_editing make sure you point the in_progress to note board
start_editing( ch, ch->pcdata->in_progress->text );


Btw, that was me modifying hedit to suit your needs, at least I think. If I seem left field I might need to see the whole append command.

KeB
03 Aug, 2007, Guest wrote in the 10th comment:
Votes: 0
You use QUICKLINK to allocate another string if you know for sure the original is in the hash, ie: because you STRALLOC'd it there earlier or something else did.

You should never use QUICKLINK to allocate fresh as it will most likely crash.
03 Aug, 2007, Keberus wrote in the 11th comment:
Votes: 0
Samson said:
You use QUICKLINK to allocate another string if you know for sure the original is in the hash, ie: because you STRALLOC'd it there earlier or something else did.

You should never use QUICKLINK to allocate fresh as it will most likely crash.


Thanks for the clarification Samson.
03 Aug, 2007, Zeno wrote in the 12th comment:
Votes: 0
Hm, I don't seem to have SUB_ABORT.

I'm also getting this error:
board.c:1853: error: expected expression before 'char'

On this line:
char *cbuf;

Strange.
03 Aug, 2007, Guest wrote in the 13th comment:
Votes: 0
Depending on the compiler version you're using, you may need to put specific brackets around the body of case SUB_APPEND_GNOTE.

And see if SUB_EDIT_ABORT is what you're after.
03 Aug, 2007, Zeno wrote in the 14th comment:
Votes: 0
Ah, the error is because you can't declare vars except at the top of the scope.

I don't have SUB_EDIT_ABORT either.

[EDIT] Took out SUB_EDIT_ABORT for now to test.

I still get nothing. The note being appended is not appended anything even though I typed stuff in the buffer.
Quote
gn append 1
Enter your text now (/? = help /s = save /c = clear /l = list /f = format)
——————————————————————————-
>
Hi test
>
/s
No new gnotes in this gboard.
Changed to next board, Clan.


[EDIT] I think I know why. The syntax was "gnote append #", thus it was taking me to do_gnote even though the append thing was a different function.

[EDIT 2] Okay I'm all set. Thanks.
0.0/14