Re: GUILD related layout

From: Mysidia (jmhess@i-55.com)
Date: 04/01/01


On Sat, 31 Mar 2001, Peter Ajamian wrote:

> > db.c:

> Huh?!?  I think you meant to enclose that with an if () statement or
> something.  At any rate, you have a comparison that does nothing and
> you're missing a ; here.  Also, I always preferred using strtok()/atoi()
> to parse input lines.  It allows you to parse them a little at a time so
> you don't have to allocate an array like numbers[] to store the whole
> thing at once.

   There are very good reasons to _AVOID_ using strtok() which is really
a very nasty function.   Because of its use of static buffers, you can't
use strtok() parsing within a function called by strtok() parsing.

ex:

foofun1()  { char *p = "asdf";
  strtok(p, " ");
  while(p) {
     foofun2(p);
     strtok(NULL, " ");
  }
}

foofun2(char *b) {
    char *x = strtok(b, ":");
    ...
}

Would _NOT_ do what you want it to do.

For this reason, and the fact that strtok() is not even recursion safe,
strtok() is a thing that should never be used haphazardly because it is
prone to causing future troubles -- the exception is for example if you
have 'command functions' (and you determine commands are never called
recursively or within other commands).

What is "OK" is the function called 'strtoken', which uses a supplied
iterator... unfortunately, it's not ANSI C, and many compilers just
don't have that... so, implement it yourself <chuckle>

Ex (the following is from ircd which falls under the GNU General Public
license):

#ifdef NEED_STRTOKEN
/*
**      strtoken.c --   walk through a string of tokens, using a set
**                      of separators
**                      argv 9/90
**
*/

char *strtoken(char **save, char *str, char *fs)
{
    char *pos = *save;  /* keep last position across calls */
    char *tmp;

    if (str)
        pos = str;              /* new string scan */
    while (pos && *pos && index(fs, *pos) != NULL)
        pos++;                  /* skip leading separators */

    if (!pos || !*pos)
        return (pos = *save = NULL);    /* string contains only sep's */

    tmp = pos;                  /* now, keep position of the token */

    while (*pos && index(fs, *pos) == NULL)
        pos++;                  /* skip content of the token */

    if (*pos)
        *pos++ = '\0';          /* remove first sep after the token */
    else
        pos = NULL;             /* end of string */

    *save = pos;
    return(tmp);
}
#endif /* NEED_STRTOKEN */


"How does it work?"   Exactly like strtoken, except you have a 'save'
buffer which you pass by reference to a char *  and it stores
the last buffer you were working with -- so you can call it recursively,
iteratively, within functions at any level, however you please without
causing undefined or '#defined troublesome' behavior.

-Mysid

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/05/01 PST