Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2001:
[Freeciv-Dev] Re: Split patch (was Re: [RFC PATCH] init_techs)
Home

[Freeciv-Dev] Re: Split patch (was Re: [RFC PATCH] init_techs)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Justin Moore <justin@xxxxxxxxxxx>
Cc: Freeciv Developers <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: Split patch (was Re: [RFC PATCH] init_techs)
From: Raimar Falke <hawk@xxxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 27 Sep 2001 11:31:42 +0200
Reply-to: rf13@xxxxxxxxxxxxxxxxxxxxxx

On Wed, Sep 26, 2001 at 07:44:25PM -0400, Justin Moore wrote:
> 
> > > > > > What about a strdup() in split?
> > > > >
> > > > >    I could, but I really think all memory allocation and de-allocation
> > > > > should be done at the same level, so-to-speak.
> > > >
> > > > What is the problem? split() will strdup() the string it gets and
> > > > frees it copy later.
> > >
> > > char *buf = "   foo bar ";
> > > char *args[2];
> > > int found = split("\S", buf, args, 2);
> > >
> > > If, within split, I do
> > >    char *copybuf = strdup(buf);
> > > and mess around with copybuf, I'm going to parse away the first few chars
> > > of it.  args[0] != copybuf, since I've cut away the first few characters.
> > > How will I know what to free?
> >
> > I was thinking of that split() will free the copybuf.
> 
>    I think I need some sample code to see how this works.  Even psuedocode
> could go a long ways.  Maybe I'm just missing something simple here.
> Given this function declaration:
> 
> int split(const char *toks, char *buf, char *args[], const int maxargs);
> 
> what happens where, allocation-wise?

Ross agrees with me (mark this day in the calendar) that the caller
should do the allocation. So the function declaration would be:

int split(const char *const toks, const char *const string, 
          char *items[], int max_items, int max_item_len)
{
   char *mycopy=strdup(string);
   int i=0;

   for(i=0;i<max_items;i++)
   {
      char *token;
      ....
      mystrlcpy(items[i],token,max_item_len);
   }
   free(mycopy);
}

> > enum split_flags {
> >  REMOVE_SPLIT_ON_WS=1,
> >  REMOVE_REMOVE_WS=2
> > };
> 
>    Ok, I know that's what you meant. ;p It just seems that your
> suggestions would lead to this definition:
> 
> int split(const char *toks, char *buf, char *args[], const int maxargs,
>           const int maxarg_length, const enum split_flags howto_split);
> 
> which just seems a bit, well ... overdone.  Plus you'd need a third
> enum value: REMOVE_NO_WHITESPACE = 3.

These split_flags were indented for OR-ing them. So
REMOVE_NO_WHITESPACE would be default.

>    I haven't really seen any concrete arguments from you about *why* your
> way is better.  My arguments are:
> 
> - It's no worse than strtok, MM-wise, and functionally more useful.
> - The caller is responsible for strdup'ing and free'ing from within the
>     same function, which is slightly more sane than random functions
>     allocating memory within them and passing it back.

> - Allowing a restricted subset of regex-like syntax leads to fewer
>     function parameters, which is easier on the programmer.

No. I can't assume that somebody has heard of regex or knows
regex. You can assume that the programmer can read a C function
declaration. Also note that your syntax is only a subset of regex.

> - My way requires no memory allocation, provided the caller is willing to
>     accept the buffer they pass in will be changed.

IMHO a general purpose method shouldn't change an arguement which does
have to be changed to carry out its function.

>    It seems at least one person has agreed with me so far.  I think we
> just need more people in on this, even if it's only "Raimar's right, and
> Justin's being an idiot" or vice versa. :)

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
  "brand memory are for windows users that think their stability
   problems come from the memory"
    -- bomek in #freeciv



[Prev in Thread] Current Thread [Next in Thread]