"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "sc.c" see the
Fossies "Dox" file reference documentation.
1 /* #includes */ /*{{{C}}}*//*{{{*/
2 #ifndef NO_POSIX_SOURCE
3 #undef _POSIX_SOURCE
4 #define _POSIX_SOURCE 1
5 #undef _POSIX_C_SOURCE
6 #define _POSIX_C_SOURCE 2
7 #endif
8
9 #ifdef DMALLOC
10 #include "dmalloc.h"
11 #endif
12
13 #include <assert.h>
14 #include <errno.h>
15 #include <limits.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20
21 #include "eval.h"
22 #include "main.h"
23 #include "sheet.h"
24 #include "sc.h"
25 /*}}}*/
26
27 static const char *s2t_s;
28 static char *s2t_t;
29
30 static int s2t_term(Sheet *sheet);
31
32 /* s2t_loc */ /*{{{*/
33 static int s2t_loc(Sheet *sheet, const char **s, char **t)
34 {
35 int x,y;
36 char label[10],*l;
37
38 l=label;
39 if (**s>='A' && **s<='Z')
40 {
41 *l++=**s;
42 *(*t)++=**s;
43 x=*(*s)++-'A';
44 }
45 else return 0;
46 if (**s>='A' && **s<='Z')
47 {
48 *l++=**s;
49 *(*t)++=**s;
50 x=x*26+(*(*s)++-'A');
51 }
52 if (**s>='0' && **s<='9')
53 {
54 *l++=**s;
55 y=**s-'0';
56 *(*t)++=*(*s)++;
57 }
58 else return 0;
59 while (**s>='0' && **s<='9')
60 {
61 *l++=**s;
62 y=y*10+(**s-'0');
63 *(*t)++=*(*s)++;
64 }
65 *l='\0';
66 if (*getlabel(sheet,x,y,0)=='\0') setlabel(sheet,x,y,0,label,0);
67 return 1;
68 }
69 /*}}}*/
70 /* s2t_range */ /*{{{*/
71 static int s2t_range(Sheet *sheet)
72 {
73 if (s2t_loc(sheet,&s2t_s,&s2t_t)==0) return 0;
74 if (*s2t_s==':')
75 {
76 s2t_s++; *s2t_t++=',';
77 if (s2t_loc(sheet,&s2t_s,&s2t_t)==0) return 0;
78 return 1;
79 }
80 else return 0;
81 }
82 /*}}}*/
83 /* s2t_primary */ /*{{{*/
84 static int s2t_primary(Sheet *sheet)
85 {
86 if (*s2t_s=='@')
87 /* @function */ /*{{{*/
88 {
89 ++s2t_s;
90 if (strncmp(s2t_s,"sum(",4)==0)
91 /* @sum(range) -> sum(range) */ /*{{{*/
92 {
93 s2t_s+=4;
94 *s2t_t++='s'; *s2t_t++='u'; *s2t_t++='m'; *s2t_t++='(';
95 if (s2t_range(sheet)==0) return 0;
96 *s2t_t++=')';
97 return 1;
98 }
99 /*}}}*/
100 else if (strncmp(s2t_s,"rnd(",4)==0)
101 /* @rnd(e) -> int(e,-1,1) */ /*{{{*/
102 {
103 s2t_s+=4;
104 *s2t_t++='i'; *s2t_t++='n'; *s2t_t++='t'; *s2t_t++='(';
105 if (s2t_term(sheet)==0) return 0;
106 *s2t_t++=','; *s2t_t++='-'; *s2t_t++='1'; *s2t_t++=','; *s2t_t++='1'; *s2t_t++=')';
107 return 1;
108 }
109 /*}}}*/
110 else if (strncmp(s2t_s,"floor(",6)==0)
111 /* @floor(e) -> int(e,-2,-2) */ /*{{{*/
112 {
113 s2t_s+=6;
114 *s2t_t++='i'; *s2t_t++='n'; *s2t_t++='t'; *s2t_t++='(';
115 if (s2t_term(sheet)==0) return 0;
116 *s2t_t++=','; *s2t_t++='-'; *s2t_t++='2'; *s2t_t++=','; *s2t_t++='-'; *s2t_t++='2'; *s2t_t++=')';
117 return 1;
118 }
119 /*}}}*/
120 else if (strncmp(s2t_s,"ceil(",5)==0)
121 /* @ceil(e) -> int(e,2,2) */ /*{{{*/
122 {
123 s2t_s+=5;
124 *s2t_t++='i'; *s2t_t++='n'; *s2t_t++='t'; *s2t_t++='(';
125 if (s2t_term(sheet)==0) return 0;
126 *s2t_t++=','; *s2t_t++='2'; *s2t_t++=','; *s2t_t++='2'; *s2t_t++=')';
127 return 1;
128 }
129 /*}}}*/
130 else return 0;
131 }
132 /*}}}*/
133 else if ((*s2t_s>='0' && *s2t_s<='9') || *s2t_s=='.')
134 /* number */ /*{{{*/
135 {
136 if (*s2t_s=='.') *s2t_t++='0'; else *s2t_t++=*s2t_s++;
137 while (*s2t_s>='0' && *s2t_s<='9') *s2t_t++=*s2t_s++;
138 if (*s2t_s=='.')
139 {
140 *s2t_t++=*s2t_s++;
141 while (*s2t_s>='0' && *s2t_s<='9') *s2t_t++=*s2t_s++;
142 }
143 else
144 {
145 *s2t_t++='.'; *s2t_t++='0';
146 }
147 return 1;
148 }
149 /*}}}*/
150 else if (*s2t_s>='A' && *s2t_s<='Z')
151 /* cell value */ /*{{{*/
152 {
153 *s2t_t++='@'; *s2t_t++='(';
154 if (s2t_loc(sheet,&s2t_s,&s2t_t)==0) return 0;
155 *s2t_t++=')';
156 return 1;
157 }
158 /*}}}*/
159 else if (*s2t_s) return 0;
160 else return 1;
161 }
162 /*}}}*/
163 /* s2t_powterm */ /*{{{*/
164 static int s2t_powterm(Sheet *sheet)
165 {
166 if (s2t_primary(sheet)==0) return 0;
167 while (*s2t_s=='^')
168 {
169 *s2t_t++=*s2t_s++;
170 if (s2t_primary(sheet)==0) return 0;
171 }
172 return 1;
173 }
174 /*}}}*/
175 /* s2t_piterm */ /*{{{*/
176 static int s2t_piterm(Sheet *sheet)
177 {
178 if (s2t_powterm(sheet)==0) return 0;
179 while (*s2t_s=='*' || *s2t_s=='/')
180 {
181 *s2t_t++=*s2t_s++;
182 if (s2t_powterm(sheet)==0) return 0;
183 }
184 return 1;
185 }
186 /*}}}*/
187 /* s2t_term */ /*{{{*/
188 static int s2t_term(Sheet *sheet)
189 {
190 if (s2t_piterm(sheet)==0) return 0;
191 while (*s2t_s=='+' || *s2t_s=='-')
192 {
193 *s2t_t++=*s2t_s++;
194 if (s2t_piterm(sheet)==0) return 0;
195 }
196 return 1;
197 }
198 /*}}}*/
199
200 /* loadsc */ /*{{{*/
201 const char *loadsc(Sheet *sheet, const char *name)
202 {
203 /* variables */ /*{{{*/
204 static char errbuf[80];
205 FILE *fp;
206 char buf[256];
207 int line;
208 size_t width;
209 const char *err;
210 int x,y;
211 /*}}}*/
212
213 if ((fp=fopen(name,"r"))==(FILE*)0) return strerror(errno);
214 freesheet(sheet,0);
215 err=(const char*)0;
216 line=1;
217 while (fgets(buf,sizeof(buf),fp)!=(char*)0)
218 {
219 /* remove nl */ /*{{{*/
220 width=strlen(buf);
221 if (width>0 && buf[width-1]=='\n') buf[width-1]='\0';
222 /*}}}*/
223 if (buf[0] && buf[0]!='#')
224 {
225 if (strncmp(buf,"format ",7)==0) /* format col width precision whoknows */ /*{{{*/
226 {
227 char colstr[3];
228 int col,colwidth,precision,whoknows;
229
230 sscanf(buf+7,"%s %d %d %d",colstr,&colwidth,&precision,&whoknows);
231 col=(colstr[0]-'A'); if (colstr[1]) col=col*26+(colstr[1]-'A');
232 initcell(sheet,col,0,0);
233 SHEET(sheet,col,0,0)->adjust=RIGHT;
234 SHEET(sheet,col,0,0)->precision=precision;
235 setwidth(sheet,col,0,colwidth);
236 }
237 /*}}}*/
238 else if (strncmp(buf,"leftstring ",11)==0 || strncmp(buf,"rightstring ",12)==0) /* rightstring/leftstring cell = "string" */ /*{{{*/
239 {
240 int x,y;
241 const char *s;
242 Token **contents;
243
244 if (strncmp(buf,"leftstring ",11)==0) s=buf+11; else s=buf+12;
245 x=*s++-'A'; if (*s>='A' && *s<='Z') x=x*26+(*s++-'A');
246 y=*s++-'0'; while (*s>='0' && *s<='9') y=10*y+(*s++-'0');
247 s+=3;
248 contents=scan(&s);
249 if (contents==(Token**)0)
250 {
251 tvecfree(contents);
252 sprintf(errbuf,_("Expression syntax error in line %d"),line);
253 err=errbuf;
254 goto eek;
255 }
256 initcell(sheet,x,y,0);
257 SHEET(sheet,x,y,0)->adjust=strncmp(buf,"leftstring ",11) ? RIGHT : LEFT;
258 SHEET(sheet,x,y,0)->contents=contents;
259 }
260 /*}}}*/
261 else if (strncmp(buf,"let ",4)==0) /* let cell = expression */ /*{{{*/
262 {
263 /* variables */ /*{{{*/
264 const char *s;
265 Token **contents;
266 char newbuf[512];
267 /*}}}*/
268
269 s=buf+4;
270 x=*s++-'A'; if (*s>='A' && *s<='Z') x=x*26+(*s++-'A');
271 y=*s++-'0'; while (*s>='0' && *s<='9') y=10*y+(*s++-'0');
272 if (getcont(sheet,x,y,0,0)==(Token**)0)
273 {
274 s+=3;
275 s2t_s=s; s2t_t=newbuf;
276 if (s2t_term(sheet)==0)
277 {
278 *s2t_t='\0';
279 if (err==(const char*)0)
280 {
281 sprintf(errbuf,_("Unimplemented SC feature in line %d"),line);
282 err=errbuf;
283 }
284 }
285 *s2t_t='\0';
286 s=newbuf;
287 contents=scan(&s);
288 if (contents==(Token**)0)
289 {
290 tvecfree(contents);
291 sprintf(errbuf,_("Expression syntax error in line %d"),line);
292 err=errbuf;
293 goto eek;
294 }
295 initcell(sheet,x,y,0);
296 SHEET(sheet,x,y,0)->adjust=RIGHT;
297 SHEET(sheet,x,y,0)->contents=contents;
298 }
299 }
300 /*}}}*/
301 }
302 ++line;
303 }
304 /* set precisions for each column */ /*{{{*/
305 for (x=0; x<sheet->dimx; ++x)
306 {
307 int prec;
308
309 prec=getprecision(sheet,x,0,0)==def_precision ? 2 : getprecision(sheet,x,0,0);
310 for (y=1; y<sheet->dimy; ++y) if (SHEET(sheet,x,y,0)) SHEET(sheet,x,y,0)->precision=prec;
311 }
312 /*}}}*/
313 eek:
314 if (fclose(fp)==EOF && err==(const char*)0) err=strerror(errno);
315 sheet->changed=0;
316 cachelabels(sheet);
317 forceupdate(sheet);
318 return err;
319 }
320 /*}}}*/