1 /* SC A Spreadsheet Calculator
2 * Routines for piping data to and from an external macro program
3 *
4 * Chuck Martin <nrocinu@myrealbox.com>
5 * Original Version Created: June, 2000
6 *
7 * $Revision: 7.16 $
8 */
9
10 #include <curses.h>
11 #include <unistd.h>
12 #include "sc.h"
13
14 #ifdef BSD42
15 #include <strings.h>
16 #include <sys/time.h>
17 #ifndef strchr
18 #define strchr index
19 #endif
20 #else
21 #include <time.h>
22 #ifndef SYSIII
23 #include <string.h>
24 #endif
25 #endif
26
27
28 void
getnum(int r0,int c0,int rn,int cn,int fd)29 getnum(int r0, int c0, int rn, int cn, int fd)
30 {
31 struct ent **pp;
32 struct ent *p;
33 int r, c;
34
35 for (r = r0; r <= rn; r++) {
36 for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
37 *line = '\0';
38 p = *pp;
39 if (p)
40 if (p->cellerror)
41 sprintf(line, "%s", (*pp)->cellerror == CELLERROR ?
42 "ERROR" : "INVALID");
43 else if (p->flags & is_valid)
44 sprintf(line, "%.15g", p->v);
45 if (c < cn)
46 strcat(line, "\t");
47 else
48 strcat(line, "\n");
49 write(fd, line, strlen(line));
50 if (brokenpipe) {
51 linelim = -1;
52 return;
53 }
54 }
55 }
56 linelim = -1;
57 }
58
59 void
fgetnum(int r0,int c0,int rn,int cn,int fd)60 fgetnum(int r0, int c0, int rn, int cn, int fd)
61 {
62 struct ent **pp;
63 struct ent *p;
64 int r, c;
65
66 for (r = r0; r <= rn; r++) {
67 for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
68 *line = '\0';
69 p = *pp;
70 if (p) {
71 if (p->cellerror)
72 sprintf(line, "%s", p->cellerror == CELLERROR ?
73 "ERROR" : "INVALID");
74 else if (p->flags & is_valid) {
75 if (p->format) {
76 if (*(p->format) == ctl('d')) {
77 time_t i = (time_t) (p->v);
78 strftime(line, sizeof(line), (p->format)+1,
79 localtime(&i));
80 } else
81 format(p->format, precision[c], p->v, line,
82 sizeof(line));
83 } else
84 engformat(realfmt[c], fwidth[c], precision[c],
85 p->v, line, sizeof(line));
86 }
87 }
88 if (c < cn)
89 strcat(line, "\t");
90 else
91 strcat(line, "\n");
92 write(fd, line, strlen(line));
93 if (brokenpipe) {
94 linelim = -1;
95 return;
96 }
97 }
98 }
99 linelim = -1;
100 }
101
102 void
getstring(int r0,int c0,int rn,int cn,int fd)103 getstring(int r0, int c0, int rn, int cn, int fd)
104 {
105 struct ent **pp;
106 int r, c;
107
108 for (r = r0; r <= rn; r++) {
109 for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
110 *line = '\0';
111 if (*pp && (*pp)->label)
112 sprintf(line, "%s", (*pp)->label);
113 if (c < cn)
114 strcat(line, "\t");
115 else
116 strcat(line, "\n");
117 write(fd, line, strlen(line));
118 if (brokenpipe) {
119 linelim = -1;
120 return;
121 }
122 }
123 }
124 linelim = -1;
125 }
126
127 void
getexp(int r0,int c0,int rn,int cn,int fd)128 getexp(int r0, int c0, int rn, int cn, int fd)
129 {
130 struct ent **pp;
131 struct ent *p;
132 int r, c;
133
134 for (r = r0; r <= rn; r++) {
135 for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
136 *line = '\0';
137 p = *pp;
138 if (p && p->expr) {
139 linelim = 0;
140 decompile(p->expr, 0); /* set line to expr */
141 line[linelim] = '\0';
142 if (*line == '?')
143 *line = '\0';
144 }
145 if (c < cn)
146 strcat(line, "\t");
147 else
148 strcat(line, "\n");
149 write(fd, line, strlen(line));
150 if (brokenpipe) {
151 linelim = -1;
152 return;
153 }
154 }
155 }
156 linelim = -1;
157 }
158
159 void
getformat(int col,int fd)160 getformat(int col, int fd)
161 {
162 sprintf(line, "%d %d %d\n", fwidth[col], precision[col], realfmt[col]);
163 write(fd, line, strlen(line));
164 linelim = -1;
165 }
166
167 void
getfmt(int r0,int c0,int rn,int cn,int fd)168 getfmt(int r0, int c0, int rn, int cn, int fd)
169 {
170 struct ent **pp;
171 int r, c;
172
173 for (r = r0; r <= rn; r++) {
174 for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
175 *line = '\0';
176 if (*pp && (*pp)->format)
177 sprintf(line, "%s", (*pp)->format);
178 if (c < cn)
179 strcat(line, "\t");
180 else
181 strcat(line, "\n");
182 write(fd, line, strlen(line));
183 if (brokenpipe) {
184 linelim = -1;
185 return;
186 }
187 }
188 }
189 linelim = -1;
190 }
191
192 void
getframe(int fd)193 getframe(int fd)
194 {
195 struct frange *fr;
196
197 *line = '\0';
198 if ((fr = find_frange(currow, curcol))) {
199 sprintf(line, "%s", r_name(fr->or_left->row, fr->or_left->col,
200 fr->or_right->row, fr->or_right->col));
201 strcat(line, " ");
202 sprintf(line + strlen(line), "%s", r_name(fr->ir_left->row,
203 fr->ir_left->col, fr->ir_right->row, fr->ir_right->col));
204 }
205 strcat(line, "\n");
206 write(fd, line, strlen(line));
207 linelim = -1;
208 }
209
210 void
getrange(char * name,int fd)211 getrange(char *name, int fd)
212 {
213 struct range *r;
214 char *p;
215
216 *line = '\0';
217 if (!find_range(name, strlen(name), (struct ent *)0, (struct ent *)0, &r)) {
218 sprintf(line, "%s%s%s%d",
219 r->r_left.vf & FIX_COL ? "$" : "",
220 coltoa(r->r_left.vp->col),
221 r->r_left.vf & FIX_ROW ? "$" : "",
222 r->r_left.vp->row);
223 if (r->r_is_range) {
224 p = line;
225 while (*p)
226 p++;
227 sprintf(p, ":%s%s%s%d",
228 r->r_right.vf & FIX_COL ? "$" : "",
229 coltoa(r->r_right.vp->col),
230 r->r_right.vf & FIX_ROW ? "$" : "",
231 r->r_right.vp->row);
232 }
233 /************************************************/
234 /* */
235 /* if(r->r_is_range) */
236 /* sprintf(line,"%d:%d:%d:%d", */
237 /* r->r_left.vp->col, */
238 /* r->r_left.vp->row, */
239 /* r->r_right.vp->col, */
240 /* r->r_right.vp->row); */
241 /* else */
242 /* sprintf(line,"%d:%d", */
243 /* r->r_left.vp->col, */
244 /* r->r_left.vp->row); */
245 /* */
246 /************************************************/
247 }
248 strcat(line, "\n");
249 write(fd, line, strlen(line));
250 linelim = -1;
251 }
252
253 void
doeval(struct enode * e,char * fmt,int row,int col,int fd)254 doeval(struct enode *e, char *fmt, int row, int col, int fd)
255 {
256 double v;
257
258 gmyrow = row;
259 gmycol = col;
260
261 v = eval(e);
262 if (fmt) {
263 if (*fmt == ctl('d')) {
264 time_t tv = v;
265 strftime(line, FBUFLEN, fmt + 1, localtime(&tv));
266 } else
267 format(fmt, precision[col], v, line, FBUFLEN);
268 } else
269 sprintf(line, "%.15g", v);
270 strcat(line, "\n");
271 write(fd, line, strlen(line));
272 linelim = -1;
273
274 efree(e);
275 if (fmt) scxfree(fmt);
276 }
277
278 void
doseval(struct enode * e,int row,int col,int fd)279 doseval(struct enode *e, int row, int col, int fd)
280 {
281 char *s;
282
283 gmyrow = row;
284 gmycol = col;
285
286 s = seval(e);
287 if (s)
288 write(fd, s, strlen(s));
289 write(fd, "\n", 1);
290 linelim = -1;
291
292 efree(e);
293 if (s)
294 scxfree(s);
295 }
296
297
298 void
doquery(char * s,char * data,int fd)299 doquery(char *s, char *data, int fd)
300 {
301 goraw();
302 query(s, data);
303 deraw(0);
304 if (linelim >= 0) {
305 write(fd, line, strlen(line));
306 write(fd, "\n", 1);
307 }
308
309 line[0] = '\0';
310 linelim = -1;
311 error("");
312 update(0);
313
314 if (s) scxfree(s);
315 }
316
317 void
dogetkey()318 dogetkey()
319 {
320 int c, len;
321
322 goraw();
323 c = nmgetch();
324 deraw(0);
325
326 if (c < 256) {
327 sprintf(line, "%c", c);
328 len = 1;
329 } else if (c >= KEY_MIN && c <= KEY_MAX) {
330 int i, j;
331 line[0] = '\0';
332 sprintf(line + 1, "%s\n", keyname(c));
333 for (i = 1, j = 5; line[j-1]; ) {
334 if (line[j] == '(' || line[j] == ')')
335 j++;
336 else
337 line[i++] = line[j++];
338 }
339 len = strlen(line + 1) + 1;
340 } else {
341 line[0] = '0';
342 sprintf(line + 1, "UNKNOWN KEY");
343 len = strlen(line + 1) + 1;
344 }
345
346
347 write(macrofd, line, len);
348 }
349
350 void
dostat(int fd)351 dostat(int fd)
352 {
353 *line = '\0';
354 if (modflg) sprintf(line, "m");
355 if (isatty(STDIN_FILENO)) strcat(line, "i");
356 if (isatty(STDOUT_FILENO)) strcat(line, "o");
357 strcat(line, "\n");
358 write(fd, line, strlen(line));
359 linelim = -1;
360 }
361