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