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


Reply via email to