Complete.Org: Mailing Lists: Archives: freeciv-dev: October 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: Reinier Post <rp@xxxxxxxxxx>
Cc: Freeciv Developers <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: Split patch (was Re: [RFC PATCH] init_techs)
From: Daniel L Speyer <dspeyer@xxxxxxxxxxx>
Date: Sat, 6 Oct 2001 12:57:12 -0400 (EDT)

OK, here's version .2 of the split function I wrote.  It has more readable
variable names and takes carre of backslashes, but is otherwise
basically unaltered (some trivial readability stuff)

char ** splitprotect(char* string,char* on){
  int i,j,num_out=0,length_in=strlen(string),in_quotes=0,brace_level=0;
  char** out;
  for(i=0;i<length_in;i++){
    if (string[i]=='\\'){
      i++; /*Ignore anything backslashified*/
      continue;
    }
    if (string[i]=='"')
      in_quotes = !in_quotes;
    if (in_quotes)
      continue;
    if (string[i]=='{'){
      brace_level++;
      continue;
    }
    if (string[i]=='}'){
      brace_level--;
      continue;
    }
    if (brace_level==0){
      for(j=0;j<strlen(on);j++){ /*Check all split characters*/
        if (string[i]==on[j]){
          string[i]=0;
          num_out++;
        }
      }
    }
  }
  out=(char**)malloc((num_out+2)*sizeof(char*));
  *out=string;
  j=1;
  for(i=0;i<length_in;i++){
    if (!string[i])
      out[j++]=string+i+1;
  }
  out[num_out+1]=0;
  return(out);
}

And to deal with some questions/objections

On Sat, 6 Oct 2001, Reinier Post wrote:

>[massive ommisssion]
> 
> >     if (string[i]=='{'){
> >       b++;
> >       continue;
> >     }
> 
> What's the assumption on bracket matching vs. next line continuation?
> Do you assume the entire command is already in the buffer?  How do
> yopu know how many lines to fetch before parsing the brackets?

I'm assuming the buffer is proper.  I'm picturing something like bash in
insisting that braces and quotes get closed.  Psuedo-psuedocode would be
something like:

void main_loop(){
  char buf[BUFFER_SIZE];
  char **args;
  getline(buf,BUFFER_SIZE);
  while (!complete(buf)) /*unwritten function*/
    getline(buf+strlen(buf),BUFFER_SIZE-strlen(buf));
  args=split_protect(buf,whatever);
  ...
}

> [omissions]
> >   out=(char**)malloc((n+2)*sizeof(char*));
> 
> I thought the list agreed not to do this.  Return the modified input buffer.

The malloc is only mallocing char*s, not chars.  The data is left where it
is, but functions can treat it as a simple array of strings.  It also
means that rejoining a slit_protected string would be as simple as
for(i=1;args[i];i++) *(args[i]-1)=char_that_was_split_on; assuming that
only a single character was split on, of course.

Essentilly, I *am* returning the input string, I'm just returning multiple
places along it so the each function won't have to do slow and ugly things
looking for the next arg.

> 
> >   *out=string;
> >   j=1;
> >   for(i=0;i<l;i++){
> >     if (!string[i])
> >       out[j++]=string+i+1;
> >   }
> >   out[n+1]=0;
> >   return(out);
> > }
> > 
> > It doesn't do regexps, but I don't think we'll need them.
> 
> Agreed.
> 
> > It does handle
> > multiple split characters.
> 
> So '=' could be used - nice, except you'll lose the information in error
> messages, so I'm not sure this is desirable.
> 
> > It only allocates memory for the specific
> > array it returns, and it does mangle the input string.
> 
> If you mangle it, might as well use it to rturn the result.
> 
> > I think this is
> > the function I would want if I were writing the entire parser.  If not,
> > well, I didn't put all that much work into it anayway :)
> > 
> > --Daniel Speyer
> > "May the /src be with you, always"
> 
> Shouldn't that be the /usr/src ?
> 
> -- 
> Reinier
> 
> 



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