Subversion Repositories wimsdev

Rev

Rev 8171 | Rev 11125 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 reyssat 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
 
8185 bpr 18
#include "wims.h"
19
 
10 reyssat 20
void calc_itemof(char *p);
21
void calc_rowof(char *p);
22
void calc_columnof(char *p);
23
 
7673 bpr 24
/* It is this routine which uses print_precision. */
10 reyssat 25
void float2str(double d, char *p)
26
{
27
    char buf[16];
28
    int i;
29
    if(d==0) {
7673 bpr 30
     ovlstrcpy(p,"0"); return;
10 reyssat 31
    }
8171 bpr 32
    if(!isfinite(d)) { /* isinf, isnan possibly not available */
7673 bpr 33
     if (d == d) ovlstrcpy(p, (d > 0)? "Inf": "-Inf"); else ovlstrcpy(p,"NaN");
34
     return;
10 reyssat 35
    }
36
    if(d<1000000 && d>-1000000 && d==floor(d)) {
7673 bpr 37
     mystrncpy(p,int2str(d),MAX_LINELEN); return;
10 reyssat 38
    }
39
    i=print_precision;
40
    if(i<2) i=2; if(i>32) i=32;  /* Simple limitation. */
41
    buf[0]='%';buf[1]='.';
42
    if(i>=10) {
7673 bpr 43
     buf[2]='0'+i/10; buf[3]='0'+i%10; buf[4]='g'; buf[5]=0;
10 reyssat 44
    }
45
    else {
7673 bpr 46
     buf[2]='0'+i; buf[3]='g'; buf[4]=0;
10 reyssat 47
    }
48
    snprintf(p,MAX_LINELEN,buf,(double) d);
3718 reyssat 49
    if(isspace(*p)) ovlstrcpy(p,find_word_start(p));
10 reyssat 50
}
51
 
7673 bpr 52
/* substitute variable names by their environment strings
53
 * The buffer pointed to by p must have enough space
8155 bpr 54
 * (defined by MAX_LINELEN).
55
 */
10 reyssat 56
char *substit(char *p)
57
{
58
    char *pp, *p2, *ev;
59
    char *oldlast, *oldnext, *oldend, *newend;
60
    char buf[MAX_LINELEN+1], oldbuf[MAX_LINELEN+1];
61
    int ln;
62
 
63
    if((p2=strchr(p,'$'))==NULL) return p;
64
    if(substnest>SUBST_LIMIT) module_error("subst_exceeded");
65
    ln=strlen(p); if(ln>=MAX_LINELEN) goto too_long;
66
    memmove(oldbuf,p,ln); oldbuf[ln]=0; oldend=oldbuf+ln;
67
    newend=p; oldlast=oldnext=oldbuf;
68
    for(pp=oldbuf+(p2-p); pp!=NULL; pp=strchr(pp,'$')) {
7673 bpr 69
     if(*(pp+1)=='$') { /* escaped dollar sign */
70
         pp++; if(newend-p+(pp-oldlast)>=MAX_LINELEN) goto too_long;
71
         memmove(newend,oldlast,pp-oldlast); newend+=pp-oldlast;
72
         pp++; oldlast=pp; continue;
73
     }
74
     switch(*(pp+1)) {
75
         case 0: {
76
          *pp=0; oldend--; goto end;
77
         }
78
         case '(': {
79
          p2=find_matching(pp+2,')');
80
          if(p2==NULL) {
81
              module_error("unmatched_parentheses");
82
              *p=0; return p;
83
          }
84
          *p2++=0; oldnext=p2; memmove(buf,pp+2,p2-pp-2);
85
          substnest++; substit(buf); substnest--;
86
          break;
87
         }
10 reyssat 88
 
7673 bpr 89
         case '[': {
90
          double d;
91
          p2=find_matching(pp+2,']');
92
          if(p2==NULL) {
93
              module_error("unmatched_parentheses");
94
              *p=0; return p;
95
          }
96
          *p2=0; ovlstrcpy(buf,pp+2); oldnext=p2+1;
97
          substnest++; substit(buf); substnest--;
98
          d=evalue(buf); float2str(d,buf);
99
          goto replace;
100
         }
101
 
102
         default: {
103
          for(p2=pp+1; myisalnum(*p2) || *p2=='_'; p2++);
104
          oldnext=p2; memmove(buf,pp+1,p2-(pp+1)); buf[p2-(pp+1)]=0;
105
          goto noarray;
106
         }
107
     }
108
     if((p2=strchr(buf,'['))!=NULL) {
109
         char *pt1, tbuf[MAX_LINELEN+1];
110
         *p2++=0; pt1=find_matching(p2,']');
111
         if(pt1==NULL) {buf[0]=0; goto replace;}
112
         *pt1=0; pt1=strchr(p2,';');
113
         if(pt1==NULL) {
114
          if(*find_word_start(p2)==0) {*p2=0; goto noarray;}
115
          snprintf(tbuf,sizeof(tbuf),"%s of $%s",p2,buf);
116
          calc_itemof(tbuf); ovlstrcpy(buf,tbuf); goto replace;
117
         }
118
         else {
119
          *pt1++=0; p2=find_word_start(p2);
120
          if(*p2) {
121
              snprintf(tbuf,sizeof(tbuf),"%s of $%s",p2,buf);
122
              calc_rowof(tbuf);
123
          }
124
          else {
125
              snprintf(tbuf,sizeof(tbuf),"$%s",buf); substit(tbuf);
126
          }
127
          if(*find_word_start(pt1)) {
128
              snprintf(buf,sizeof(buf),"%s of %s",pt1,tbuf);
129
              calc_columnof(buf); goto replace;
130
          }
131
          else ovlstrcpy(buf,tbuf);
132
          goto replace;
133
         }
134
     }
135
     noarray: ev=getvar(buf); ln=getvar_len;
136
     if(ev==NULL) ev=""; if(strchr(ev,'$')==NULL) goto rep2;
137
     memmove(buf,ev,ln); buf[ln]=0;
138
     substnest++; substit(buf); substnest--;
139
     replace: ev=buf; ln=strlen(ev);
140
     rep2:
141
     if(pp>oldlast) {
142
         if(newend-p+(pp-oldlast)>=MAX_LINELEN) goto too_long;
143
         memmove(newend,oldlast,pp-oldlast); newend+=pp-oldlast;
144
     }
145
     if(ln>0) {
146
         if((newend-p)+ln>=MAX_LINELEN) goto too_long;
147
         memmove(newend,ev,ln); newend+=ln;
148
     }
149
     pp=oldlast=oldnext;
150
     continue;
10 reyssat 151
    }
7673 bpr 152
    end:
10 reyssat 153
    if(oldlast<oldend) {
7673 bpr 154
     if(newend-p+(oldend-oldlast)>=MAX_LINELEN) goto too_long;
155
     memmove(newend,oldlast,oldend-oldlast); newend+=oldend-oldlast;
10 reyssat 156
    }
157
    *newend=0; return p;
158
    too_long: user_error("cmd_output_too_long"); return NULL;
159
}
160
 
8185 bpr 161
struct forstruct forstruct;
10 reyssat 162
 
163
int for_getvar(char *p)
164
{
165
    char *vp, buf[MAX_LINELEN+1];
166
    mystrncpy(buf,p,sizeof(buf)); substit(buf);
167
    vp=find_word_start(buf); for(p=vp; myisalnum(*p) || *p=='_'; p++);
168
    *p=0; if(p-vp<=0 || p-vp>MAX_NAMELEN) return -1;
169
    mystrncpy(forstruct.var,vp,sizeof(forstruct.var));
170
    return 0;
171
}
172
 
7673 bpr 173
/* If bufp=NULL then numeric. Else string-wise.
174
 * returns 0 if success,
8155 bpr 175
 * -1 if syntax error, 1 if bad values
176
 */
10 reyssat 177
int cutfor(char *p, char *bufp)
178
{
179
    char *eqp, *fromp, *top, *stepp, *inp;
180
 
181
    p=find_word_start(p);
182
    inp=find_word_start(find_word_end(p));
183
    if(wordchr(inp,"in")==inp) {
7673 bpr 184
     char buf[MAX_LINELEN+1], *bp;
185
     int i;
186
     double d;
187
     *inp=0; inp+=strlen("in");
188
     forin: inp=find_word_start(inp); forstruct.type=for_in;
189
     if(for_getvar(p)) return -1;
190
     if(bufp!=NULL) bp=bufp; else bp=buf;
191
     mystrncpy(bp,inp,MAX_LINELEN); substit(bp);
192
     strip_trailing_spaces(bp);
193
     if(bp[0]==0) {
194
         forstruct.from=0; forstruct.to=-1; forstruct.step=1; return 0;
195
     }
196
     for(i=0, inp=bp; i<MAX_VALUE_LIST && inp!=NULL; inp=top) {
197
         top=strparchr(inp,','); if(top) *top++=0;
198
         if(bufp==NULL) {
8171 bpr 199
          d=evalue(inp); if(isfinite(d)) forstruct.list[i++]=d;
7673 bpr 200
          else return 1;
201
         }
202
         else {
203
          strip_trailing_spaces(inp);
204
          forstruct.pos[i++]=find_word_start(inp);
205
         }
206
     }
207
     forstruct.from=0; forstruct.to=i-1; forstruct.step=1; return 0;
10 reyssat 208
    }
209
    top=wordchr(p,"to"); if(top==NULL) {
7673 bpr 210
     inp=strchr(p,'='); if(inp==NULL) return -1;
211
     *inp++=0; goto forin;
10 reyssat 212
    }
213
    *top=0; top+=strlen("to");
214
    stepp=wordchr(top,"step"); if(stepp!=NULL) {
7673 bpr 215
     *stepp=0; stepp+=strlen("step"); forstruct.step=evalue(stepp);
10 reyssat 216
    }
217
    else forstruct.step=1;
218
    forstruct.to=evalue(top); forstruct.type=for_from;
219
    eqp=strchr(p,'='); fromp=wordchr(p,"from"); inp=wordchr(p,"in");
220
    if(eqp!=NULL && (fromp==NULL || eqp<fromp)) {
7673 bpr 221
     *eqp++=0; fromp=eqp;
10 reyssat 222
    }
223
    else {
7673 bpr 224
     if(fromp==NULL) return -1;
225
     *fromp=0; fromp+=strlen("from");
10 reyssat 226
    }
227
    forstruct.from=evalue(fromp);
228
    if(for_getvar(p)) return -1;
8171 bpr 229
    if(!isfinite(forstruct.from+forstruct.to+forstruct.step)) return 1;
10 reyssat 230
    else return 0;
231
}
232