Пример #1
0
/*
 * How this works.
 *
 * Well, first off, the code recursively descends into the trie
 * until it finds the terminating letter of the command being removed.
 * Once it has done that, it marks the msg pointer as NULL then
 * reduces the reference count on that allocated struct MessageTree
 * since a command counts as a reference.
 *
 * Then it pops up the recurse stack. As it comes back up the recurse
 * The code checks to see if the child now has no pointers or msg
 * i.e. the links count has gone to zero. If it's no longer used, the
 * child struct MessageTree can be deleted. The parent reference
 * to this child is then removed and the parents link count goes down.
 * Thus, we continue to go back up removing all unused MessageTree(s)
 */
static void
del_msg_element(struct MessageTree *mtree_p, const char *cmd)
{
  struct MessageTree *ntree_p = NULL;

  /*
   * In case this is called for a nonexistent command
   * check that there is a msg pointer here, else links-- goes -ve
   * -db
   */
  if (*cmd == '\0' && mtree_p->msg)
  {
    mtree_p->msg = NULL;
    mtree_p->links--;
  }
  else
  {
    if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)]))
    {
      del_msg_element(ntree_p, cmd + 1);

      if (ntree_p->links == 0)
      {
        mtree_p->pointers[*cmd & (MAXPTRLEN - 1)] = NULL;
        mtree_p->links--;
        xfree(ntree_p);
      }
    }
  }
}
Пример #2
0
/* mod_del_cmd()
 *
 * inputs	- pointer to struct Message
 * output	- none
 * side effects - unload this one command name
 */
void
mod_del_cmd(struct Message *msg)
{
  assert(msg);
  assert(msg->cmd);

  if (msg_tree_parse(msg->cmd))
    del_msg_element(&msg_tree, msg->cmd);
}
Пример #3
0
/* mod_del_cmd()
 *
 * inputs	- pointer to struct Message
 * output	- none
 * side effects - unload this one command name
 */
void
mod_del_cmd(struct Message *msg)
{
  assert(msg != NULL);

  if (msg == NULL)
    return;

  del_msg_element(&msg_tree, msg->cmd);
}
Пример #4
0
/** Removes a service mapping.
 * @param[in] map Service mapping to remove.
 * @return Non-zero on success; zero if no command used the name.
 */
int unregister_mapping(struct s_map *map)
{
  if (!msg_tree_parse(map->command, &msg_tree))
  {
    /* This simply should never happen. */
    assert(0);
    return 0;
  }

  del_msg_element(&msg_tree, map->msg->cmd);

  map->msg->extra = NULL;
  MyFree(map->msg);
  map->msg = NULL;

  return 1;
}
Пример #5
0
/** Remove a message from the lookup trie.
 * @param[in,out] mtree_p Trie node to remove command from.
 * @param[in] cmd Text of command to remove.
 */
struct MessageTree *
del_msg_element(struct MessageTree *mtree_p, char *cmd)
{
  int slot = *cmd & (MAXPTRLEN-1);

  /* Either remove leaf message or from appropriate child. */
  if (*cmd == '\0')
    mtree_p->msg = NULL;
  else
    mtree_p->pointers[slot] = del_msg_element(mtree_p->pointers[slot], cmd + 1);

  /* If current message or any child still exists, keep this node. */
  if (mtree_p->msg)
    return mtree_p;
  for (slot = 0; slot < MAXPTRLEN; ++slot)
    if (mtree_p->pointers[slot])
      return mtree_p;

  /* Otherwise, if we're not a root node, free it and return null. */
  if (mtree_p != &msg_tree && mtree_p != &tok_tree)
    MyFree(mtree_p);
  return NULL;
}