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