Logo Search packages:      
Sourcecode: wims version File versions  Download package

evalue.c

/*    Copyright (C) 1998 XIAO, Gang of Universite de Nice - Sophia Antipolis
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

      /* It is this routine which uses print_precision. */
void float2str(double d, char *p)
{
    char buf[16];
    int i;
    if(d==0) {
      strcpy(p,"0"); return;
    }
    if(!finite(d)) {
      if(isinf(d)) {
          if(d>0) strcpy(p,"Inf"); else strcpy(p,"-Inf");
      }
      else strcpy(p,"NaN");
      return;
    }
    if(d<1000000 && d>-1000000 && d==floor(d)) {
      int n=d;
      snprintf(p,MAX_LINELEN,"%d",n);
      return;
    }
    i=print_precision;
    if(i<2) i=2; if(i>32) i=32;  /* Simple limitation. */
    buf[0]='%';buf[1]='.';
    if(i>=10) {
      buf[2]='0'+i/10; buf[3]='0'+i%10; buf[4]='g'; buf[5]=0;
    }
    else {
      buf[2]='0'+i; buf[3]='g'; buf[4]=0;
    }
    snprintf(p,MAX_LINELEN,buf,(double) d);
    if(isspace(*p)) strcpy(p,find_word_start(p));
}

      /* substitute variable names by their environment strings
       * The buffer pointed to by p must have enough space
       * (defined by MAX_LINELEN). */
char *substit(char *p)
{
    char *pp, *p2, *ev;
    char *oldlast, *oldnext, *oldend, *newend;
    char buf[MAX_LINELEN+1], oldbuf[MAX_LINELEN+1];
    int ln;

    if(strchr(p,'$')==NULL) return p;
    if(substnest>SUBST_LIMIT) error2("subst_exceeded");
    ln=strlen(p); if(ln>=MAX_LINELEN) goto too_long;
    memmove(oldbuf,p,ln); oldbuf[ln]=0; oldend=oldbuf+ln;
    newend=p; oldlast=oldnext=oldbuf;
    for(pp=strchr(oldbuf,'$'); pp!=NULL; pp=strchr(pp,'$')) {
      if(*(pp+1)=='$') {      /* escaped dollar sign */
          pp++; if(newend-p+(pp-oldlast)>=MAX_LINELEN) goto too_long;
          memmove(newend,oldlast,pp-oldlast); newend+=pp-oldlast;
          pp++; oldlast=pp; continue;
      }
      switch(*(pp+1)) {
          case 0: {
            *pp=0; oldend--; goto end;
          }
          case '(': {
            p2=find_matching(pp+2,')');
            if(p2==NULL) {
                error2("unmatched_parentheses");
                *p=0; return p;
            }
            *p2=0; oldnext=p2+1; strcpy(buf,pp+2);
            substnest++; substit(buf); substnest--;
            break;
          }

          case '[': {
            double d;
            p2=find_matching(pp+2,']');
            if(p2==NULL) {
                error2("unmatched_parentheses");
                *p=0; return p;
            }
            *p2=0; strcpy(buf,pp+2); oldnext=p2+1;
            substnest++; substit(buf); substnest--;
            d=evalue(buf); float2str(d,buf);
            goto replace;
          }
            
        default:
          for(p2=pp+1; isalnum(*p2) || *p2=='_'; p2++);
          oldnext=p2; memmove(buf,pp+1,p2-(pp+1)); buf[p2-(pp+1)]=0;
      }
      if(strlen(buf)>MAX_NAMELEN) {
          error2("defn_too_long"); continue;
      }
      ev=getvar(buf); 
      if(ev==NULL || *ev==0) buf[0]=0;
      else {
          ln=strlen(ev); if(ln>=MAX_LINELEN) goto too_long;
          memmove(buf,ev,ln); buf[ln]=0;
      }
      substnest++; substit(buf); substnest--;
      replace:
      if(pp>oldlast) {
          if(newend-p+(pp-oldlast)>=MAX_LINELEN) goto too_long;
          memmove(newend,oldlast,pp-oldlast); newend+=pp-oldlast;
      }
      ln=strlen(buf); if(ln>0) {
          if((newend-p)+ln>=MAX_LINELEN) goto too_long;
          memmove(newend,buf,ln); newend+=ln;
      }
      pp=oldlast=oldnext;
      continue;
    }
    end: 
    if(oldlast<oldend) {
      if(newend-p+(oldend-oldlast)>=MAX_LINELEN) goto too_long;
      memmove(newend,oldlast,oldend-oldlast); newend+=oldend-oldlast;
    }
    *newend=0; return p;
    too_long: user_error("cmd_output_too_long"); return NULL;
}

enum {for_in, for_from};
struct {
    char var[MAX_NAMELEN+1];
    int type;
    double list[MAX_VALUE_LIST];
    double from, to, step;
} forstruct;

int for_getvar(char *p)
{
    char *vp, buf[MAX_LINELEN+1];
    snprintf(buf,sizeof(buf),"%s",p); substit(buf);
    vp=find_word_start(buf); for(p=vp; isalnum(*p) || *p=='_'; p++);
    *p=0; if(p-vp<=0 || p-vp>MAX_NAMELEN) return -1;
    snprintf(forstruct.var,sizeof(forstruct.var),"%s",vp);
    return 0;
}

      /* returns 0 if success, 
       * -1 if syntax error, 1 if bad values */
int cutfor(char *p)
{
    char *eqp, *fromp, *top, *stepp, *inp;

    p=find_word_start(p);
    inp=find_word_start(find_word_end(p));
    if(wordchr(inp,"in")==inp) {
      char buf[MAX_LINELEN+1];
      int i;
      double d;
      *inp=0; inp+=strlen("in");
      forin: inp=find_word_start(inp); forstruct.type=for_in;
      if(for_getvar(p)) return -1;
      snprintf(buf,sizeof(buf),"%s",inp); substit(buf);
      strip_trailing_spaces(buf);
      for(i=0, inp=buf; i<MAX_VALUE_LIST && inp!=NULL; inp=top) {
          top=strparchr(inp,','); if(top) *top++=0;
          d=evalue(inp); if(finite(d)) forstruct.list[i++]=d;
          else return 1;
      }
      forstruct.from=0; forstruct.to=i-1; forstruct.step=1; return 0;
    }
    top=wordchr(p,"to"); if(top==NULL) {
      inp=strchr(p,'='); if(inp==NULL) return -1;
      *inp++=0; goto forin;
    }
    *top=0; top+=strlen("to");
    stepp=wordchr(top,"step"); if(stepp!=NULL) {
      *stepp=0; stepp+=strlen("step"); forstruct.step=evalue(stepp);
    }
    else forstruct.step=1;
    forstruct.to=evalue(top); forstruct.type=for_from;
    eqp=strchr(p,'='); fromp=wordchr(p,"from"); inp=wordchr(p,"in");
    if(eqp!=NULL && (fromp==NULL || eqp<fromp)) {
      *eqp++=0; fromp=eqp;
    }
    else {
      if(fromp==NULL) return -1;
      *fromp=0; fromp+=strlen("from");
    }
    forstruct.from=evalue(fromp);
    if(for_getvar(p)) return -1;
    if(!finite(forstruct.from+forstruct.to+forstruct.step)) return 1;
    else return 0;
}


Generated by  Doxygen 1.6.0   Back to index