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;
}