Your technique for switching commands is...interesting.
What are you copying all that data several times for? It's a linked list!
Treat it like a linked list! Don't swap all the data in the structures;
move the nodes around in the linked list!
As far as your memory issue in move()... Have you ever heard of automatic
local variables? I.E. "CMD_DATA cmd3;"? What's up with the pointer?
Pointers are useful when you don't know how much memeory you're going
to need, or how many items you'll need. They're just a pain to use when
you already know exactly how much memory you need.
Of course, the second paragraph is really irrelevant, since you should
just swap the nodes instead of the data.
Dennis
On Sun, 17 Mar 2002, Steven Radziul wrote:
> Greetings List,
>
> It has been awhile since I have seen someone post code to the list to get
> critique on their work as well as add to the community. I
> am currently studying linked lists and nodes and working with transferring
> most of my mud from tables to linked lists. The following
> commands I wrote are for transversing stuff in the list of commands.
>
> get_cpointer is a simple function to return the pointer of a command in the
> list;
> move is to move a command before a command in the list
>
> Link is to take a unlinked command and place it at the end of the list
> unlink is to take a command in the list and unlink it ( my new way of
> dealing with deleting commands from the list
> switch will switch two nodes in the list with eachother ( I need this one
> critiqued for possible memory issues. I am not sur
> what entirely to do with the allocated command besides the way I handled it,
> just storing it for use later. if there is a better
> way to free it or if the function just frees it anyways I would like to know
> this.
>
> I hope these are readable and commented enough and understanding. These
> really aren't for your newbie programmer
> and only will work if you have the command struct setup as a linked list as
> they deal with pointers instead of the tables.
>
> If Anyone wants to use them in their code, go ahead.. I tested it and it
> seems to work.. I don't seem to be "loosing" any
> commands in the work. If there is a better way to do this somehow specially
> with the switch command, I would like to
> hear it..
>
> Any comments appreciated, good or bad.
>
> Sincerely,
> Steven Radziul
> Senior Engineer - Redkoala MUD Project.
>
> //function to retrieve a command structure pointer based on the name of the
> command (handler.c)
> CMD_DATA *get_cpointer( const char *name)
> {
> CMD_DATA *pCmd;
> char buf[MSL];
>
> for( pCmd = cmd_first; pCmd; pCmd = pCmd->next )
> {
>
>
> if (LOWER(name[0]) == LOWER(pCmd->name[0]) &&
> !str_prefix(name, pCmd->name) )
> return pCmd;
> }
>
> return NULL;
> }
>
> //storage spot for a free command
> CMD_DATA *cmd_free;
>
> CMDEDIT( cmdedit_move )
> {
> char buf[MSL];
> char arg1[MIL];
> char arg2[MIL];
>
> CMD_DATA *cmd1; //storage for first command structure
> CMD_DATA *cmd2; //storage for second command strcture
> CMD_DATA *cmd3; //temp storage place for command structure
>
> argument = one_argument(argument, arg1);
> argument = one_argument(argument, arg2);
>
> if ( arg1[0] == '\0' || arg2[0] == '\0' )
> {
> send_to_char("Syntax: move [cmd1 name] [cmd2 name]",ch );
> send_to_char("For a list of current commands available, type
> list",ch );
> return FALSE;
> }
>
>
> //retrieve the pointers
> cmd1 = get_cpointer(arg1);
> cmd2 = get_cpointer(arg2);
>
> if ( !cmd1 || !cmd2 )
> {
> send_to_char("Invalid Command names specified\n\r",ch);
> return FALSE;
> }
>
> //allocate a temporary storage container for what you want to move
> if ( !cmd_free )
> cmd3 = alloc_perm( sizeof( *cmd3) );
> else cmd3 = cmd_free;
>
> if (!cmd3 )
> {
> send_to_char("There has been some problems allocating the temp storage
> container\n\r",ch);
> send_to_char("Notify a Programmer immediately!\n\r",ch);
> return FALSE;
> }
>
> cmd3->name = cmd1->name;
> cmd3->funcname = cmd1->funcname;
> cmd3->do_fun = cmd1->do_fun;
> cmd3->vnum = cmd1->vnum;
> cmd3->position = cmd1->position;
> cmd3->level = cmd1->level;
> cmd3->log = cmd1->log;
>
> /* FLAG_COPY is a macro which I wrote which deals with my flag/bit system
> which I developed and designed for Redkoala. It
> works very similiar to the STR_COPY_STR seen in alot of Unlimited bits
> snipplets out there, but this one I wrote myself as I
> try to write my own code then using a snipplet */
>
> FLAG_COPY(cmd3->rsectors, cmd1->rsectors, SECTOR_FLAGS);
> FLAG_COPY(cmd3->flags, cmd1->flags, CMD_FLAGS);
> //reset the first spot with the info from the second spot. maintaining the
> pointers through the list.
> cmd1->name = cmd2->name;
> cmd1->funcname = cmd2->funcname;
> cmd1->do_fun = cmd2->do_fun;
> cmd1->vnum = cmd2->vnum;
> cmd1->position = cmd2->position;
> cmd1->level = cmd2->level;
> cmd1->log = cmd2->log;
> FLAG_COPY(cmd1->rsectors, cmd2->rsectors, SECTOR_FLAGS);
> FLAG_COPY(cmd1->flags, cmd2->flags, CMD_FLAGS);
> cmd2->name = cmd3->name;
> cmd2->funcname = cmd3->funcname;
> cmd2->do_fun = cmd3->do_fun;
> cmd2->vnum = cmd3->vnum;
> cmd2->position = cmd3->position;
> cmd2->level = cmd3->level;
> cmd2->log = cmd3->log;
> FLAG_COPY(cmd2->rsectors, cmd3->rsectors, SECTOR_FLAGS);
> FLAG_COPY(cmd2->flags, cmd3->flags, CMD_FLAGS);
>
> //no need to keep storing up memory, copy it to a holder for this function
> cmd_free = cmd3;
>
> send_to_char("These commands have been successfully moved in the
> table\n\r",ch);
> return TRUE;
>
> }
>
>
> //removes a command from the list
> CMDEDIT( cmdedit_unlink )
> {
> CMD_DATA *pCmd;
> EDIT_CMD(ch, pCmd);
>
> if ( pCmd->next != NULL )
> pCmd->next->prev = pCmd->prev;
> else cmd_last = pCmd->prev;
> if ( pCmd->prev != NULL )
> pCmd->prev->next = pCmd->next;
> else cmd_first = pCmd->next;
>
> pCmd->next = NULL;
> pCmd->prev = NULL;
> send_to_char("This Command has been successfully unlinked from the
> list\n\r",ch);
> return TRUE;
> }
>
> CMDEDIT( cmdedit_test )
> {
> char arg1[MIL];
> CMD_DATA *pCmd;
> CMD_DATA *move;
>
> argument = one_argument(argument, arg1);
> if ( arg1[0] == '\0' )
> {
> send_to_char("Syntax: move [command name]\n\r",ch);
> send_to_char("This function will move a command before another
> command in the list\n\r",ch);
> return FALSE;
> }
>
> EDIT_CMD(ch,pCmd);
>
> move = get_cpointer(arg1);
>
> if ( !move )
> {
> send_to_char("Invalid Command Specified\n\r",ch );
> return FALSE;
> }
>
> if ( pCmd == move )
> {
> send_to_char("You been drinking again\n\r",ch);
> return FALSE;
> }
>
> if ( move == cmd_first )
> {
> //unlink the command from the list we are moving
> if ( pCmd->next != NULL )
> pCmd->next->prev = pCmd->prev;
> else cmd_last = pCmd->prev;
>
> pCmd->prev->next = pCmd->next;
> pCmd->next = NULL; //just incase
> pCmd->prev = NULL; //just incase
> move->prev = pCmd;
> pCmd->next = move;
> cmd_first = pCmd; //mark the first command in the list pCmd now!
> return TRUE;
> }
>
> //unlink the command from the list we are moving
> if ( pCmd->next != NULL )
> pCmd->next->prev = pCmd->prev;
> else cmd_last = pCmd->prev;
> if ( pCmd->prev != NULL )
> pCmd->prev->next = pCmd->next;
> else cmd_first = pCmd->next;
> pCmd->next = NULL;
> pCmd->prev = NULL;
> move->prev->next = pCmd;
> pCmd->prev = move->prev;
> move->prev = pCmd;
> pCmd->next = move;
>
> return TRUE;
> }
>
> CMDEDIT( cmdedit_link )
> {
>
> CMD_DATA *pCmd;
> EDIT_CMD(ch,pCmd);
>
> if ( pCmd->next != NULL && pCmd->prev != NULL )
> {
> send_to_char("This command is already linked in the list",ch);
> return FALSE;
> }
>
> cmd_last->next = pCmd;
> pCmd->prev = cmd_last;
> cmd_last = pCmd;
>
> send_to_char("Command has been successfully linked to the command
> list\n\r",ch);
> return TRUE;
> }
>
>
>