Subversion Repositories wimsdev

Rev

Rev 11125 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18. #include "wims.h"
  19.  
  20. void calc_itemof(char *p);
  21. void calc_rowof(char *p);
  22. void calc_columnof(char *p);
  23.  
  24. /* It is this routine which uses print_precision. */
  25. void float2str(double d, char *p)
  26. {
  27.   char buf[16];
  28.   int i;
  29.   if(d==0) {
  30.     ovlstrcpy(p,"0"); return;
  31.   }
  32.   if(!isfinite(d)) { /* isinf, isnan possibly not available */
  33.     if (d == d) ovlstrcpy(p, (d > 0)? "Inf": "-Inf"); else ovlstrcpy(p,"NaN");
  34.     return;
  35.   }
  36.   if(d<1000000 && d>-1000000 && d==floor(d)) {
  37.     mystrncpy(p,int2str(d),MAX_LINELEN); return;
  38.   }
  39.   i=print_precision;
  40.   if(i<2) i=2;
  41.   if(i>32) i=32;  /* Simple limitation. */
  42.   buf[0]='%';buf[1]='.';
  43.   if(i>=10) {
  44.     buf[2]='0'+i/10; buf[3]='0'+i%10; buf[4]='g'; buf[5]=0;
  45.   }
  46.   else {
  47.     buf[2]='0'+i; buf[3]='g'; buf[4]=0;
  48.   }
  49.   snprintf(p,MAX_LINELEN,buf,(double) d);
  50.   if(isspace(*p)) ovlstrcpy(p,find_word_start(p));
  51. }
  52.  
  53. /* substitute variable names by their environment strings
  54.  * The buffer pointed to by p must have enough space
  55.  * (defined by MAX_LINELEN).
  56.  */
  57. char *substit(char *p)
  58. {
  59.   char *pp, *p2, *ev;
  60.   char *oldlast, *oldnext, *oldend, *newend;
  61.   char buf[MAX_LINELEN+1], oldbuf[MAX_LINELEN+1];
  62.   int ln;
  63.  
  64.   if((p2=strchr(p,'$'))==NULL) return p;
  65.   if(substnest>SUBST_LIMIT) module_error("subst_exceeded");
  66.   ln=strlen(p); if(ln>=MAX_LINELEN) goto too_long;
  67.   memmove(oldbuf,p,ln); oldbuf[ln]=0; oldend=oldbuf+ln;
  68.   newend=p; oldlast=oldnext=oldbuf;
  69.   for(pp=oldbuf+(p2-p); pp!=NULL; pp=strchr(pp,'$')) {
  70.     if(*(pp+1)=='$') { /* escaped dollar sign */
  71.       pp++; if(newend-p+(pp-oldlast)>=MAX_LINELEN) goto too_long;
  72.       memmove(newend,oldlast,pp-oldlast); newend+=pp-oldlast;
  73.       pp++; oldlast=pp; continue;
  74.     }
  75.     switch(*(pp+1)) {
  76.       case 0: {
  77.         *pp=0; oldend--; goto end;
  78.       }
  79.       case '(': {
  80.         p2=find_matching(pp+2,')');
  81.         if(p2==NULL) {
  82.           module_error("unmatched_parentheses");
  83.           *p=0; return p;
  84.         }
  85.         *p2++=0; oldnext=p2; memmove(buf,pp+2,p2-pp-2);
  86.         substnest++; substit(buf); substnest--;
  87.         break;
  88.       }
  89.  
  90.       case '[': {
  91.         double d;
  92.         p2=find_matching(pp+2,']');
  93.         if(p2==NULL) {
  94.           module_error("unmatched_parentheses");
  95.           *p=0; return p;
  96.         }
  97.         *p2=0; ovlstrcpy(buf,pp+2); oldnext=p2+1;
  98.         substnest++; substit(buf); substnest--;
  99.         d=evalue(buf); float2str(d,buf);
  100.         goto replace;
  101.       }
  102.  
  103.       default: {
  104.         for(p2=pp+1; myisalnum(*p2) || *p2=='_'; p2++);
  105.         oldnext=p2; memmove(buf,pp+1,p2-(pp+1)); buf[p2-(pp+1)]=0;
  106.         goto noarray;
  107.       }
  108.     }
  109.     if((p2=strchr(buf,'['))!=NULL) {
  110.       char *pt1, tbuf[MAX_LINELEN+1];
  111.       *p2++=0; pt1=find_matching(p2,']');
  112.       if(pt1==NULL) {buf[0]=0; goto replace;}
  113.       *pt1=0; pt1=strchr(p2,';');
  114.       if(pt1==NULL) {
  115.         if(*find_word_start(p2)==0) {*p2=0; goto noarray;}
  116.          snprintf(tbuf,sizeof(tbuf),"%s of $%s",p2,buf);
  117.          calc_itemof(tbuf); ovlstrcpy(buf,tbuf); goto replace;
  118.       }
  119.       else {
  120.         *pt1++=0; p2=find_word_start(p2);
  121.         if(*p2) {
  122.           snprintf(tbuf,sizeof(tbuf),"%s of $%s",p2,buf);
  123.           calc_rowof(tbuf);
  124.         }
  125.         else {
  126.           snprintf(tbuf,sizeof(tbuf),"$%s",buf); substit(tbuf);
  127.         }
  128.         if(*find_word_start(pt1)) {
  129.           snprintf(buf,sizeof(buf),"%s of %s",pt1,tbuf);
  130.           calc_columnof(buf); goto replace;
  131.         }
  132.         else ovlstrcpy(buf,tbuf);
  133.         goto replace;
  134.       }
  135.     }
  136.     noarray: ev=getvar(buf); ln=getvar_len;
  137.     if(ev==NULL) ev="";
  138.     if(strchr(ev,'$')==NULL) goto rep2;
  139.     memmove(buf,ev,ln); buf[ln]=0;
  140.     substnest++; substit(buf); substnest--;
  141.     replace: ev=buf; ln=strlen(ev);
  142.     rep2:
  143.     if(pp>oldlast) {
  144.       if(newend-p+(pp-oldlast)>=MAX_LINELEN) goto too_long;
  145.       memmove(newend,oldlast,pp-oldlast); newend+=pp-oldlast;
  146.     }
  147.     if(ln>0) {
  148.       if((newend-p)+ln>=MAX_LINELEN) goto too_long;
  149.       memmove(newend,ev,ln); newend+=ln;
  150.     }
  151.     pp=oldlast=oldnext;
  152.     continue;
  153.   }
  154.   end:
  155.   if(oldlast<oldend) {
  156.     if(newend-p+(oldend-oldlast)>=MAX_LINELEN) goto too_long;
  157.     memmove(newend,oldlast,oldend-oldlast); newend+=oldend-oldlast;
  158.   }
  159.   *newend=0; return p;
  160.   too_long: user_error("cmd_output_too_long"); return NULL;
  161. }
  162.  
  163. struct forstruct forstruct;
  164.  
  165. int for_getvar(char *p)
  166. {
  167.   char *vp, buf[MAX_LINELEN+1];
  168.   mystrncpy(buf,p,sizeof(buf)); substit(buf);
  169.   vp=find_word_start(buf); for(p=vp; myisalnum(*p) || *p=='_'; p++);
  170.   *p=0; if(p-vp<=0 || p-vp>MAX_NAMELEN) return -1;
  171.   mystrncpy(forstruct.var,vp,sizeof(forstruct.var));
  172.   return 0;
  173. }
  174.  
  175. /* If bufp=NULL then numeric. Else string-wise.
  176.  * returns 0 if success,
  177.  * -1 if syntax error, 1 if bad values
  178.  */
  179. int cutfor(char *p, char *bufp)
  180. {
  181.   char *eqp, *fromp, *top, *stepp, *inp;
  182.  
  183.   p=find_word_start(p);
  184.   inp=find_word_start(find_word_end(p));
  185.   if(wordchr(inp,"in")==inp) {
  186.     char buf[MAX_LINELEN+1], *bp;
  187.      int i;
  188.     double d;
  189.     *inp=0; inp+=strlen("in");
  190.     forin: inp=find_word_start(inp); forstruct.type=for_in;
  191.     if(for_getvar(p)) return -1;
  192.     if(bufp!=NULL) bp=bufp; else bp=buf;
  193.     mystrncpy(bp,inp,MAX_LINELEN); substit(bp);
  194.     strip_trailing_spaces(bp);
  195.     if(bp[0]==0) {
  196.       forstruct.from=0; forstruct.to=-1; forstruct.step=1; return 0;
  197.     }
  198.     for(i=0, inp=bp; i<MAX_VALUE_LIST && inp!=NULL; inp=top) {
  199.       top=strparchr(inp,','); if(top) *top++=0;
  200.       if(bufp==NULL) {
  201.         d=evalue(inp); if(isfinite(d)) forstruct.list[i++]=d;
  202.         else return 1;
  203.       }
  204.       else {
  205.         strip_trailing_spaces(inp);
  206.         forstruct.pos[i++]=find_word_start(inp);
  207.       }
  208.     }
  209.     forstruct.from=0; forstruct.to=i-1; forstruct.step=1; return 0;
  210.   }
  211.   top=wordchr(p,"to"); if(top==NULL) {
  212.     inp=strchr(p,'='); if(inp==NULL) return -1;
  213.     *inp++=0; goto forin;
  214.   }
  215.   *top=0; top+=strlen("to");
  216.   stepp=wordchr(top,"step"); if(stepp!=NULL) {
  217.     *stepp=0; stepp+=strlen("step"); forstruct.step=evalue(stepp);
  218.   }
  219.   else forstruct.step=1;
  220.   forstruct.to=evalue(top); forstruct.type=for_from;
  221.   eqp=strchr(p,'='); fromp=wordchr(p,"from"); inp=wordchr(p,"in");
  222.   if(eqp!=NULL && (fromp==NULL || eqp<fromp)) {
  223.     *eqp++=0; fromp=eqp;
  224.   }
  225.   else {
  226.     if(fromp==NULL) return -1;
  227.     *fromp=0; fromp+=strlen("from");
  228.   }
  229.   forstruct.from=evalue(fromp);
  230.   if(for_getvar(p)) return -1;
  231.   if(!isfinite(forstruct.from+forstruct.to+forstruct.step)) return 1;
  232.   else return 0;
  233. }
  234.