Branch: Tag:

2012-04-16

2012-04-16 23:02:23 by Stephen R. van den Berg <srb@cuci.nl>

Tabular: Update documentation, modularise code.

3:   //! character/column/delimiter-organised records.   //!   //! @seealso - //! @[Parser.LR] + //! @[Parser.LR], @url{http://www.wikipedia.org/wiki/Comma-separated_values@}, + //! @url{http://www.wikipedia.org/wiki/EDIFACT@}      #pike __REAL_VERSION__      Stdio.FILE _in; -  + int _eol;   private int prefetch=1024; // TODO: Document and make this available    // through compile().   private String.Buffer alread=String.Buffer(prefetch);   private mapping|array fms; - private int eol; +    private Regexp simple=Regexp("^[^[\\](){}<>^$|+*?\\\\]+$");   private Regexp emptyline=Regexp("^[ \t\v\r\x1a]*$");   private mixed severity=1;
106:    alread->add(s);alread->putchar('\n');    if(has_suffix(s,"\r"))    s=s[..<1]; -  eol=1; +  _eol=1;    }    return s;   }
143:      #define FETCHAR(c,buf,i) (catch((c)=(buf)[(i)++])?((c)=-1):(c))    - private mapping getrecord(array fmt,int found) - { mapping ret=([]),options; -  if(stringp(fmt[0])) -  { options=(["name":fmt[0]]); -  if(fmt[1]) -  options+=fmt[1]; -  else -  fmt[1]=0; -  } -  else -  options=fmt[0]; -  if(found) -  { if(options->single) -  throw(severity); // early exit, already found one -  } -  else if(options->mandatory) -  severity=2; -  if(verb<0) -  werror("Checking record %d for %O\n",recordcount,options->name); -  eol=0; -  foreach(fmt;int fi;array|mapping m) -  { if(fi<2) -  continue; -  string value; -  if(arrayp(m)) -  { array field=m; -  fmt[fi]=m=(["name":field[0]]); -  mixed nm=field[1]; -  if(!mappingp(nm)) -  { if(arrayp(nm)) -  ret+=getrecord(nm,found); -  else -  m+=([(intp(nm)?"width":(stringp(nm)?"match":"delim")):nm]); -  if(sizeof(field)>2) -  m+=field[2]; -  } -  fmt[fi]=m; -  } -  if(eol) -  throw(severity); -  if(!zero_type(m->width)) -  value=gets(m->width); -  if(m->delim) + string _getdelimword(mapping m)    { multiset delim=m->delim;    int i,pref=m->prefetch || prefetch;    String.Buffer word=String.Buffer(pref);
215:    { default:i--;    case '\r':case '\x1a':;    } -  eol=1; +  _eol=1;    break delimready;    case '\r':    FETCHAR(c,buf,i);    if(c!='\n')    i--; -  eol=1; +  _eol=1;    break delimready;    case '\x1a':;    }
245:    break csvready;    word->putchar(c);    } -  else switch(c) +  else +  switch(c)    { case '"':leadspace=0;    if(!inquotes)    inquotes=1;
272:    case '\r':case '\x1a':;    }    if(!inquotes) -  { eol=1; +  { _eol=1;    break csvready;    }    word->putchar('\n');
282:    if(c!='\n')    i--;    if(!inquotes) -  { eol=1; +  { _eol=1;    break csvready;    }    word->putchar('\n');
297:    }    alread->add(buf[..i-1]);    _in->unread(buf[i..]); -  value=word->get(); +  return word->get();   } -  +  + private mapping getrecord(array fmt,int found) + { mapping ret=([]),options; +  if(stringp(fmt[0])) +  { options=(["name":fmt[0]]); +  if(fmt[1]) +  options+=fmt[1]; +  else +  fmt[1]=0; +  } +  else +  options=fmt[0]; +  if(found) +  { if(options->single) +  throw(severity); // early exit, already found one +  } +  else if(options->mandatory) +  severity=2; +  if(verb<0) +  werror("Checking record %d for %O\n",recordcount,options->name); +  _eol=0; +  foreach(fmt;int fi;array|mapping m) +  { if(fi<2) +  continue; +  string value; +  if(arrayp(m)) +  { array field=m; +  fmt[fi]=m=(["name":field[0]]); +  mixed nm=field[1]; +  if(!mappingp(nm)) +  { if(arrayp(nm)) +  ret+=getrecord(nm,found); +  else +  m+=([(intp(nm)?"width":(stringp(nm)?"match":"delim")):nm]); +  if(sizeof(field)>2) +  m+=field[2]; +  } +  fmt[fi]=m; +  } +  if(_eol) +  throw(severity); +  if(!zero_type(m->width)) +  value=gets(m->width); +  if(m->delim) +  value=_getdelimword(m);    if(m->match)    { Regexp rgx;    if(stringp(m->match))
338:    if(!m->drop)    ret[m->name]=value;    } -  if(!eol && gets(0)!="") +  if(!_eol && gets(0)!="")    throw(severity);    severity=1;    if(verb&&verb!=-1)