-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- ----- Forwarded message from Diane Bruce  -----

*** parse.c.orig        Tue Dec  3 14:31:11 2002
- --- parse.c   Wed Dec  4 00:29:18 2002
***************
*** 55,66 ****
  #include <string.h>
  #include <stdlib.h>
  
! 
  
  struct MessageTree {
    char *final;
    struct Message *msg;
!   struct MessageTree *pointers[26];
  };
  
  
- --- 55,70 ----
  #include <string.h>
  #include <stdlib.h>
  
! #define MAXPTRLEN     32      /* Must be a power of 2, and
!                                * larger than 26 [a-z]|[A-Z]
!                                */
! #define MAXPREFIXLEN  64      /* Must be longer than every command name */
! #define UPPERCASE_MASK        0xdf    /* mask to turn ASCII into wine er upper case*/
  
  struct MessageTree {
    char *final;
    struct Message *msg;
!   struct MessageTree *pointers[MAXPTRLEN];
  };
  
  
***************
*** 611,637 ****
  /*
   * Guts of making the token tree...
   */
! static struct Message **do_msg_tree_tok(struct MessageTree *mtree, char *prefix,
!     struct Message **mptr)
  {
!   char newprefix[64];           /* Must be longer than every command name */
    int c, c2, lp;
    struct MessageTree *mtree1;
  
    lp = strlen(prefix);
!   if (!lp || !strncmp((*mptr)->tok, prefix, lp))
    {
      if (!mptr[1] || (lp && strncmp(mptr[1]->tok, prefix, lp)))
      {
        /* last command in the message struct or last command in this prefix */
        mtree->final = (*mptr)->tok + lp;
        mtree->msg = *mptr;
!       for (c = 0; c < 26; ++c)
          mtree->pointers[c] = NULL;
        return mptr + 1;
      }
      /* command in this prefix */
!     if (0 == ircd_strcmp((*mptr)->tok, prefix))
      {
        mtree->final = "";
        mtree->msg = *mptr++;
- --- 615,641 ----
  /*
   * Guts of making the token tree...
   */
! static struct Message **
! do_msg_tree_tok(struct MessageTree *mtree, char *prefix, struct Message **mptr)
  {
!   char newprefix[MAXPREFIXLEN];
    int c, c2, lp;
    struct MessageTree *mtree1;
  
    lp = strlen(prefix);
!   if ((lp == 0) || (strncmp((*mptr)->tok, prefix, lp) == 0))
    {
      if (!mptr[1] || (lp && strncmp(mptr[1]->tok, prefix, lp)))
      {
        /* last command in the message struct or last command in this prefix */
        mtree->final = (*mptr)->tok + lp;
        mtree->msg = *mptr;
!       for (c = 0; c < MAXPTRLEN; c++)
          mtree->pointers[c] = NULL;
        return mptr + 1;
      }
      /* command in this prefix */
!     if (ircd_strcmp((*mptr)->tok, prefix) == 0)
      {
        mtree->final = "";
        mtree->msg = *mptr++;
***************
*** 645,664 ****
        {
          mtree1 = (struct MessageTree *)MyMalloc(sizeof(struct MessageTree));
          mtree1->final = NULL;
!         mtree->pointers[c - 'A'] = mtree1;
          strcpy(newprefix, prefix);
          newprefix[lp] = c;
          newprefix[lp + 1] = '\0';
          mptr = do_msg_tree_tok(mtree1, newprefix, mptr);
          if (!*mptr || strncmp((*mptr)->tok, prefix, lp))
          {
!           for (c2 = c + 1 - 'A'; c2 < 26; ++c2)
              mtree->pointers[c2] = NULL;
            return mptr;
          }
        }
        else
!         mtree->pointers[c - 'A'] = NULL;
      }
      return mptr;
    }
- --- 649,668 ----
        {
          mtree1 = (struct MessageTree *)MyMalloc(sizeof(struct MessageTree));
          mtree1->final = NULL;
!         mtree->pointers[c & (MAXPTRLEN-1)] = mtree1;
          strcpy(newprefix, prefix);
          newprefix[lp] = c;
          newprefix[lp + 1] = '\0';
          mptr = do_msg_tree_tok(mtree1, newprefix, mptr);
          if (!*mptr || strncmp((*mptr)->tok, prefix, lp))
          {
!           for (c2 = (c + 1) & (MAXPTRLEN-1); c2 < MAXPTRLEN; ++c2)
              mtree->pointers[c2] = NULL;
            return mptr;
          }
        }
        else
!         mtree->pointers[c & (MAXPTRLEN-1)] = NULL;
      }
      return mptr;
    }
***************
*** 671,698 ****
  
  /*
   * Guts of making the command tree...
   */
! static struct Message *do_msg_tree_cmd(struct MessageTree *mtree, char *prefix,
!     struct Message *mptr)
  {
!   char newprefix[64];           /* Must be longer than every command name */
    int c, c2, lp;
    struct MessageTree *mtree1;
  
    lp = strlen(prefix);
!   if (!lp || !strncmp(mptr->cmd, prefix, lp))
    {
      if (!mptr[1].cmd || (lp && strncmp(mptr[1].cmd, prefix, lp)))
      {
        /* last command in the message struct or last command in this prefix */
        mtree->final = mptr->cmd + lp;
        mtree->msg = mptr;
!       for (c = 0; c < 26; ++c)
          mtree->pointers[c] = NULL;
        return mptr + 1;
      }
      /* command in this prefix */
!     if (0 == ircd_strcmp(mptr->cmd, prefix))
      {
        mtree->final = "";
        mtree->msg = mptr++;
- --- 675,707 ----
  
  /*
   * Guts of making the command tree...
+  *
+  * Look at Knuth, Volume III "Sorting and Searching"
+  * What happens here is obvious. The command is split up and
+  * branches at each letter down, well, a trie (read the reference!)
   */
! static struct Message *
! do_msg_tree_cmd(struct MessageTree *mtree, char *prefix, struct Message *mptr)
  {
!   char newprefix[MAXPREFIXLEN];
    int c, c2, lp;
    struct MessageTree *mtree1;
  
    lp = strlen(prefix);
!   if ((lp == 0) || (strncmp(mptr->cmd, prefix, lp) == 0))
    {
      if (!mptr[1].cmd || (lp && strncmp(mptr[1].cmd, prefix, lp)))
      {
        /* last command in the message struct or last command in this prefix */
        mtree->final = mptr->cmd + lp;
        mtree->msg = mptr;
!       /* XXX oh you could optimise this 'for' if you wanted. -db */
!       for (c = 0; c < MAXPTRLEN; c++)
          mtree->pointers[c] = NULL;
        return mptr + 1;
      }
      /* command in this prefix */
!     if (ircd_strcmp(mptr->cmd, prefix) == 0)
      {
        mtree->final = "";
        mtree->msg = mptr++;
***************
*** 706,725 ****
        {
          mtree1 = (struct MessageTree *)MyMalloc(sizeof(struct MessageTree));
          mtree1->final = NULL;
!         mtree->pointers[c - 'A'] = mtree1;
          strcpy(newprefix, prefix);
          newprefix[lp] = c;
          newprefix[lp + 1] = '\0';
          mptr = do_msg_tree_cmd(mtree1, newprefix, mptr);
          if (!mptr->cmd || strncmp(mptr->cmd, prefix, lp))
          {
!           for (c2 = c + 1 - 'A'; c2 < 26; ++c2)
              mtree->pointers[c2] = NULL;
            return mptr;
          }
        }
        else
!         mtree->pointers[c - 'A'] = NULL;
      }
      return mptr;
    }
- --- 715,734 ----
        {
          mtree1 = (struct MessageTree *)MyMalloc(sizeof(struct MessageTree));
          mtree1->final = NULL;
!         mtree->pointers[c & (MAXPTRLEN-1)] = mtree1;
          strcpy(newprefix, prefix);
          newprefix[lp] = c;
          newprefix[lp + 1] = '\0';
          mptr = do_msg_tree_cmd(mtree1, newprefix, mptr);
          if (!mptr->cmd || strncmp(mptr->cmd, prefix, lp))
          {
!         for (c2 = (c + 1) & (MAXPTRLEN-1); c2 < MAXPTRLEN; ++c2)
              mtree->pointers[c2] = NULL;
            return mptr;
          }
        }
        else
!         mtree->pointers[c & (MAXPTRLEN-1)] = NULL;
      }
      return mptr;
    }
***************
*** 730,741 ****
    exit(1);
  }
  
! static int mcmdcmp(const struct Message *m1, const struct Message *m2)
  {
    return strcmp(m1->cmd, m2->cmd);
  }
  
! static int mtokcmp(const struct Message **m1, const struct Message **m2)
  {
    return strcmp((*m1)->tok, (*m2)->tok);
  }
- --- 739,752 ----
    exit(1);
  }
  
! static int
! mcmdcmp(const struct Message *m1, const struct Message *m2)
  {
    return strcmp(m1->cmd, m2->cmd);
  }
  
! static int
! mtokcmp(const struct Message **m1, const struct Message **m2)
  {
    return strcmp((*m1)->tok, (*m2)->tok);
  }
***************
*** 745,751 ****
   * Create table of pointers into msgtab for tokens.
   * Create trees for ->cmd and ->tok and free the token pointers.
   */
! void initmsgtree(void)
  {
    int i;
    struct Message *msg = msgtab;
- --- 756,763 ----
   * Create table of pointers into msgtab for tokens.
   * Create trees for ->cmd and ->tok and free the token pointers.
   */
! void
! initmsgtree(void)
  {
    int i;
    struct Message *msg = msgtab;
***************
*** 771,791 ****
  /*
   * Generic tree parser which works for both commands and tokens.
   * Optimized by Run.
   */
! static struct Message *msg_tree_parse(char *cmd, struct MessageTree *root)
  {
    struct MessageTree *mtree;
!   unsigned char r = (0xdf & (unsigned char)*cmd) - 'A';
!   if (r > 25 || !(mtree = root->pointers[r]))
!     return NULL;
!   for (;;)
    {
!     r = 0xdf & (unsigned char)*++cmd;
!     if (mtree->final && *mtree->final == r)
        return mtree->msg;
- -     if ((r -= 'A') > 25 || !(mtree = mtree->pointers[r]))
- -       return NULL;
    }
  }
  
  /*
- --- 783,803 ----
  /*
   * Generic tree parser which works for both commands and tokens.
   * Optimized by Run.
+  * Re-written by Dianora (db)
   */
! static struct Message *
! msg_tree_parse(char *cmd, struct MessageTree *root)
  {
    struct MessageTree *mtree;
! 
!   for (mtree = root->pointers[(*cmd++) & (MAXPTRLEN-1)];
!            mtree != NULL;
!                mtree = mtree->pointers[(*cmd++) & (MAXPTRLEN-1)])
    {
!     if (mtree->final && *mtree->final == (UPPERCASE_MASK & *cmd))
        return mtree->msg;
    }
+   return NULL;
  }
  
  /*
***************
*** 794,822 ****
   * This is to avoid confusion with commands like /quake on clients
   * that send unknown commands directly to the server.
   */
! static struct Message *msg_tree_parse_client(char *cmd,
!     struct MessageTree *root)
  {
    struct MessageTree *mtree;
!   unsigned char q = (0xdf & (unsigned char)*cmd) - 'A';
!   if (q > 25 || !(mtree = root->pointers[q]))
!     return NULL;
!   for (;;)
    {
!     q = 0xdf & (unsigned char)*++cmd;
!     if (mtree->final && 0 == ircd_strcmp(mtree->final, cmd))
        return mtree->msg;
- -     if ((q -= 'A') > 25 || !(mtree = mtree->pointers[q]))
- -       return NULL;
    }
  }
  
  /*
   * parse a buffer.
   *
   * NOTE: parse_*() should not be called recusively by any other fucntions!
   */
! int parse_client(struct Client *cptr, char *buffer, char *bufend)
  {
    struct Client*  from = cptr;
    char*           ch;
- --- 806,834 ----
   * This is to avoid confusion with commands like /quake on clients
   * that send unknown commands directly to the server.
   */
! static struct Message *
! msg_tree_parse_client(char *cmd, struct MessageTree *root)
  {
    struct MessageTree *mtree;
! 
!   for (mtree = root->pointers[(*cmd++) & (MAXPTRLEN-1)];
!            mtree != NULL;
!                mtree = mtree->pointers[(*cmd++) & (MAXPTRLEN-1)])
    {
!     if (mtree->final && (ircd_strcmp(mtree->final, cmd) == 0))
        return mtree->msg;
    }
+   return NULL;
  }
  
+ 
  /*
   * parse a buffer.
   *
   * NOTE: parse_*() should not be called recusively by any other fucntions!
   */
! int
! parse_client(struct Client *cptr, char *buffer, char *bufend)
  {
    struct Client*  from = cptr;
    char*           ch;
- -- 
Diane Bruce, http://www.db.net/~db [EMAIL PROTECTED]
- --- aphorisms are ephemeral, speling mistakes are not.

- ----- End forwarded message -----

- -- 
Life. Don't talk to me about life. - Marvin the Paranoid Anroid
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
Comment: Only when you are sure they have you, can you stop being paranoid

iD8DBQE97ZnpcAgRpy8z8UQRAjwVAJsEjMsfdyuEeLoH7HtAf7FjEnM+FwCaAown
aDF4ozXeJXxbmOefohpnyWs=
=l+iR
-----END PGP SIGNATURE-----

Reply via email to