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