"Fossies" - the Fresh Open Source Software Archive 
Member "teapot-2.3.0/main.c" (6 Feb 2012, 55065 Bytes) of package /linux/privat/old/teapot-2.3.0.tar.gz:
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 "main.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 #undef _XOPEN_SOURCE
8 #define _XOPEN_SOURCE 500
9 #endif
10
11 #ifdef DMALLOC
12 #include "dmalloc.h"
13 #endif
14
15 #include <assert.h>
16 #include <ctype.h>
17 #include <float.h>
18 #include <limits.h>
19 #include <locale.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 extern char *optarg;
24 extern int optind,opterr,optopt;
25 int getopt(int argc, char * const *argv, const char *optstring);
26 #include <string.h>
27 #include <unistd.h>
28
29
30 #include "default.h"
31 #include "display.h"
32 #include "eval.h"
33 #include "htmlio.h"
34 #include "latex.h"
35 #include "context.h"
36 #include "main.h"
37 #include "misc.h"
38 #include "sc.h"
39 #include "scanner.h"
40 #include "utf8.h"
41 #include "parser.h"
42 #include "sheet.h"
43 #include "wk1.h"
44 /*}}}*/
45
46 /* variables */ /*{{{*/
47 char helpfile[PATH_MAX];
48 int batch=0;
49 unsigned int batchln=0;
50 int def_precision=DEF_PRECISION;
51 int quote=0;
52 int header=1;
53 static int usexdr=1;
54 /*}}}*/
55
56 static void get_mark(Sheet *sheet, int *x1, int *x2, int *y1, int *y2, int *z1, int *z2, int everything)
57 {
58 if (sheet->marking) {
59 posorder(&sheet->mark1x, &sheet->mark2x);
60 posorder(&sheet->mark1y, &sheet->mark2y);
61 posorder(&sheet->mark1z, &sheet->mark2z);
62 sheet->marking = 0;
63 }
64 if (x1) {
65 if (sheet->mark1x >= 0) {
66 *x1 = sheet->mark1x;
67 *x2 = sheet->mark2x;
68 *y1 = sheet->mark1y;
69 *y2 = sheet->mark2y;
70 *z1 = sheet->mark1z;
71 *z2 = sheet->mark2z;
72 } else if (everything) {
73 *x1 = 0;
74 *x2 = sheet->dimx-1;
75 *y1 = 0;
76 *y2 = sheet->dimy-1;
77 *z1 = 0;
78 *z2 = sheet->dimz-1;
79 } else {
80 *x1 = *x2 = sheet->curx;
81 *y1 = *y2 = sheet->cury;
82 *z1 = *z2 = sheet->curz;
83 }
84 }
85 }
86
87 void moveto(Sheet *sheet, int x, int y, int z)
88 {
89 int need_redraw = 0;
90 int xdir = x > sheet->curx?1:-1;
91
92 if (x >= 0) sheet->curx = x;
93 if (y >= 0) sheet->cury = y;
94 if (z >= 0) need_redraw++, sheet->curz = z;
95 while (sheet->curx > 0 && shadowed(sheet, sheet->curx, sheet->cury, sheet->curz)) sheet->curx += xdir;
96
97 if (sheet->marking) {
98 sheet->mark2x = sheet->curx;
99 sheet->mark2y = sheet->cury;
100 sheet->mark2z = sheet->curz;
101 }
102
103 if (sheet->curx <= sheet->offx && sheet->offx) need_redraw++, sheet->offx = (sheet->curx?sheet->curx-1:0);
104 if (sheet->cury <= sheet->offy && sheet->offy) need_redraw++, sheet->offy = (sheet->cury?sheet->cury-1:0);
105 if (sheet->curx >= sheet->offx+sheet->maxx) need_redraw++, sheet->offx = sheet->curx-sheet->maxx+2;
106 if (sheet->cury >= sheet->offy+sheet->maxy) need_redraw++, sheet->offy = sheet->cury-sheet->maxy+2;
107
108 if (need_redraw) redraw_sheet(sheet);
109 else if (x != sheet->curx || y != sheet->cury || z != sheet->curz) redraw_cell(sheet, sheet->curx, sheet->cury, sheet->curz);
110 }
111
112 void relmoveto(Sheet *sheet, int x, int y, int z)
113 {
114 moveto(sheet, sheet->curx+x, sheet->cury+y, (z?sheet->curz+z:-1));
115 }
116
117 /* line_numedit -- number line editor function */ /*{{{*/
118 static int line_numedit(int *n, const char *prompt, size_t *x, size_t *offx)
119 {
120 /* variables */ /*{{{*/
121 char buf[20];
122 const char *s;
123 Token **t;
124 int c;
125 /*}}}*/
126
127 /* asserts */ /*{{{*/
128 assert(prompt!=(char*)0);
129 assert(x!=(size_t*)0);
130 assert(offx!=(size_t*)0);
131 /*}}}*/
132 t=(Token**)0;
133 sprintf(buf,"%d",*n);
134 s=buf+strlen(buf);
135 do
136 {
137 tvecfree(t);
138 *x=s-buf;
139 if ((c=line_edit((Sheet*)0,buf,sizeof(buf),prompt,x,offx))<0) return c;
140 s=buf;
141 t=scan(&s);
142 } while ((*s!='\0' && t==(Token**)0) || !(t!=(Token**)0 && ((*t)==(Token*)0 || ((*t)->type==INT && (*t)->u.integer>=0 && *(t+1)==(Token*)0))));
143 if (t==(Token**)0 || *t==(Token*)0) *n=-1;
144 else *n=(*t)->u.integer;
145 tvecfree(t);
146 return 0;
147 }
148 /*}}}*/
149 /* line_lidedit -- label identifier line editor function */ /*{{{*/
150 static int line_idedit(char *ident, size_t size, const char *prompt, size_t *x, size_t *offx)
151 {
152 /* variables */ /*{{{*/
153 const char *s;
154 Token **t;
155 int c;
156 /*}}}*/
157
158 t=(Token**)0;
159 s=ident+strlen(ident);
160 do
161 {
162 tvecfree(t);
163 *x=s-ident;
164 if ((c=line_edit((Sheet*)0,ident,size,prompt,x,offx))<0) return c;
165 s=ident;
166 t=scan(&s);
167 } while ((*s!='\0' && t==(Token**)0) || !(t!=(Token**)0 && ((*t)==(Token*)0 || ((*t)->type==LIDENT && *(t+1)==(Token*)0))));
168 tvecfree(t);
169 return 0;
170 }
171 /*}}}*/
172 /* doanyway -- ask if action should be done despite unsaved changes */ /*{{{*/
173 int doanyway(Sheet *sheet, const char *msg)
174 {
175 int result;
176
177 if (sheet->changed) {
178 result=line_ok(msg,0);
179 if (result < 0) return 0;
180 return result;
181 }
182 return 1;
183 }
184 /*}}}*/
185
186 /* do_edit -- set or modify cell contents */ /*{{{*/
187 static int do_edit(Sheet *cursheet, Key c, const char *expr, int clocked)
188 {
189 /* variables */ /*{{{*/
190 char buf[1024];
191 const char *s;
192 size_t x,offx;
193 int curx,cury,curz;
194 Token **t;
195 /*}}}*/
196
197 if (locked(cursheet,cursheet->curx,cursheet->cury,cursheet->curz)) line_msg(_("Edit cell:"),_("Cell is locked"));
198 else
199 {
200 curx=cursheet->curx;
201 cury=cursheet->cury;
202 curz=cursheet->curz;
203 if (expr)
204 {
205 s=expr;
206 t=scan(&s);
207 if (*s!='\0' && t==(Token**)0) line_msg(clocked ? _("Clocked cell contents:") : _("Cell contents:"),"XXX invalid expression");
208 }
209 else
210 {
211 offx=0;
212 if (c==K_NONE)
213 {
214 print(buf,sizeof(buf),0,1,getscientific(cursheet,cursheet->curx,cursheet->cury,cursheet->curz),-1,getcont(cursheet,cursheet->curx,cursheet->cury,cursheet->curz,clocked));
215 s=buf+strlen(buf);
216 }
217 else if (c==K_BACKSPACE)
218 {
219 print(buf,sizeof(buf),0,1,getscientific(cursheet,cursheet->curx,cursheet->cury,cursheet->curz),-1,getcont(cursheet,cursheet->curx,cursheet->cury,cursheet->curz,clocked));
220 if (strlen(buf)) *mbspos(buf+strlen(buf),-1)='\0';
221 s=buf+strlen(buf);
222 }
223 else if (c==K_DC)
224 {
225 print(buf,sizeof(buf),0,1,getscientific(cursheet,cursheet->curx,cursheet->cury,cursheet->curz),-1,getcont(cursheet,cursheet->curx,cursheet->cury,cursheet->curz,clocked));
226 memmove(buf,mbspos(buf,1),strlen(mbspos(buf,1))+1);
227 s=buf;
228 }
229 else if (isalpha(c))
230 {
231 buf[0] = '"';
232 buf[1] = c;
233 buf[2] = 0;
234 s=buf+2;
235 }
236 else
237 {
238 if (c < 256) buf[0]=c;
239 else buf[0] = 0;
240 buf[1]='\0';
241 s=buf+1;
242 }
243 do
244 {
245 int r;
246
247 x=mbslen(buf)-mbslen(s);
248 if ((r=line_edit(cursheet,buf,sizeof(buf),clocked ? _("Clocked cell contents:") : _("Cell contents:"),&x,&offx))<0) return r;
249 s=buf;
250 if (buf[0] == '"' && buf[strlen(buf)-1] != '"' && strlen(buf)+1 < sizeof(buf)) {
251 buf[strlen(buf)+1] = 0;
252 buf[strlen(buf)] = '"';
253 }
254 t=scan(&s);
255 } while (*s!='\0' && t==(Token**)0);
256 }
257 if (t!=(Token**)0 && *t==(Token*)0) { free(t); t=(Token**)0; }
258 moveto(cursheet,curx,cury,curz);
259 putcont(cursheet,cursheet->curx,cursheet->cury,cursheet->curz,t,clocked);
260 forceupdate(cursheet);
261 }
262 return 0;
263 }
264 /*}}}*/
265 /* do_label -- modify cell label */ /*{{{*/
266 static int do_label(Sheet *sheet)
267 {
268 /* variables */ /*{{{*/
269 char buf[1024],oldlabel[1024];
270 size_t edx,offx,ok;
271 Token t;
272 int x,y,z,x1,y1,z1,x2,y2,z2;
273 int c;
274 /*}}}*/
275
276 assert(sheet!=(Sheet*)0);
277 if (sheet->mark1x==-1 && locked(sheet,sheet->curx,sheet->cury,sheet->curz)) line_msg(_("Cell label:"),_("Cell is locked"));
278 else
279 {
280 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 0);
281 ok=edx=offx=0;
282 (void)strcpy(buf,getlabel(sheet,sheet->curx,sheet->cury,sheet->curz));
283 (void)strcpy(oldlabel,buf);
284 do
285 {
286 if ((c=line_idedit(buf,sizeof(buf),_("Cell label:"),&edx,&offx))<0) return c;
287 if (buf[0]=='\0') ok=1;
288 else
289 {
290 ok=((t=findlabel(sheet,buf)).type==EEK || (t.type==LOCATION && t.u.location[0]==sheet->curx && t.u.location[1]==sheet->cury && t.u.location[2]==sheet->curz));
291 tfree(&t);
292 }
293 } while (!ok);
294 setlabel(sheet,sheet->curx,sheet->cury,sheet->curz,buf,1);
295 if (buf[0]!='\0') for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) relabel(sheet,oldlabel,buf,x,y,z);
296 }
297 return -1;
298 }
299 /*}}}*/
300 /* do_columnwidth -- set the column width */ /*{{{*/
301 static int do_columnwidth(Sheet *cursheet)
302 {
303 /* variables */ /*{{{*/
304 size_t edx,offx;
305 int n;
306 int x,x1,x2,z,z1,z2;
307 int c;
308 /*}}}*/
309
310 offx=0;
311 edx=0;
312 n=columnwidth(cursheet,cursheet->curx,cursheet->curz);
313 do if ((c=line_numedit(&n,_("Column width:"),&edx,&offx))<0) return c; while (n<=0);
314 if (cursheet->mark1x==-1)
315 /* range is the current cell */ /*{{{*/
316 {
317 x1=x2=cursheet->curx;
318 z1=z2=cursheet->curz;
319 }
320 /*}}}*/
321 else
322 /* range is the marked cube */ /*{{{*/
323 {
324 x1=cursheet->mark1x; x2=cursheet->mark2x;
325 z1=cursheet->mark1z; z2=cursheet->mark2z;
326 }
327 /*}}}*/
328 for (x=x1; x<=x2; ++x) for (z=z1; z<=z2; ++z) setwidth(cursheet,x,z,n);
329 return -1;
330 }
331 /*}}}*/
332 /* do_attribute -- set cell attributes */ /*{{{*/
333 static void do_attribute(Sheet *cursheet, Key action)
334 {
335 /* variables */ /*{{{*/
336 int x,y,z;
337 int x1,y1,z1;
338 int x2,y2,z2;
339 int c = 0;
340 /*}}}*/
341
342 get_mark(cursheet, &x1, &x2, &y1, &y2, &z1, &z2, 0);
343
344 if (action != ADJUST_LOCK && cursheet->mark1x==-1 && action != ADJUST_LOCK && locked(cursheet,cursheet->curx,cursheet->cury,cursheet->curz))
345 {
346 line_msg(_("Cell attribute:"),_("Cell is locked"));
347 return;
348 }
349 switch ((int)action)
350 {
351 /* 0 -- adjust left */ /*{{{*/
352 case ADJUST_LEFT:
353 {
354 if (cursheet->mark1x != -1 && line_ok(_("Make block left-adjusted:"), 0) <= 0) break;
355 for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) setadjust(cursheet,x,y,z,LEFT);
356 break;
357 }
358 /*}}}*/
359 /* 1 -- adjust right */ /*{{{*/
360 case ADJUST_RIGHT:
361 {
362 if (cursheet->mark1x != -1 && line_ok(_("Make block right-adjusted:"), 0) <= 0) break;
363 for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) setadjust(cursheet,x,y,z,RIGHT);
364 break;
365 }
366 /*}}}*/
367 /* 2 -- adjust centered */ /*{{{*/
368 case ADJUST_CENTER:
369 {
370 if (cursheet->mark1x != -1 && line_ok(_("Make block centered:"), 0) <= 0) break;
371 for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) setadjust(cursheet,x,y,z,CENTER);
372 break;
373 }
374 /*}}}*/
375 /* 3 -- set scientific notation flag */ /*{{{*/
376 case ADJUST_SCIENTIFIC:
377 {
378 int n;
379
380 if (cursheet->mark1x==-1) n = !getscientific(cursheet,x1,y1,z1);
381 else n = line_ok(_("Make block notation scientific:"), getscientific(cursheet,x1,y1,z1));
382 if (n >= 0) for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) setscientific(cursheet,x,y,z,n);
383 break;
384 }
385 /*}}}*/
386 /* 5 -- set precision */ /*{{{*/
387 case ADJUST_PRECISION:
388 {
389 size_t ex,offx;
390 int n;
391
392 offx=0;
393 ex=0;
394 n=getprecision(cursheet,x1,y1,z1);
395 do if (line_numedit(&n,cursheet->mark1x==-1 ? _("Precision for cell:") : _("Precision for block:"),&ex,&offx)==-1) return; while (n!=-1 && (n==0 || n>20));
396 for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) setprecision(cursheet,x,y,z,n);
397 break;
398 }
399 /*}}}*/
400 /* 6 -- shadow */ /*{{{*/
401 case ADJUST_SHADOW:
402 {
403 int n;
404
405 if (cursheet->mark1x==-1) n = !shadowed(cursheet,x1,y1,z1);
406 else n = line_ok(_("Shadow block:"), shadowed(cursheet,x1,y1,z1));
407 if (x1 == 0 && n == 1) {
408 line_msg(_("Shadow cell:"),_("You can not shadow cells in column 0"));
409 break;
410 }
411
412 if (n >= 0) {
413 for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z)
414 {
415 int rx;
416
417 if (n==0) for (rx=x+1; shadowed(cursheet,rx,y,z); ++rx) shadow(cursheet,rx,y,z,0);
418 else if (x>0) shadow(cursheet,x,y,z,1);
419 }
420 }
421 break;
422 }
423 /*}}}*/
424 /* 7 -- transparent */ /*{{{*/
425 case ADJUST_TRANSPARENT:
426 {
427 int n;
428
429 if (cursheet->mark1x==-1) n = !transparent(cursheet,x1,y1,z1);
430 else n = line_ok(_("Make block transparent:"), transparent(cursheet,x1,y1,z1));
431 if (n >= 0) for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) maketrans(cursheet,x,y,z,n);
432 break;
433 }
434 /*}}}*/
435 /* 8 -- bold */ /*{{{*/
436 case ADJUST_BOLD:
437 {
438 int n;
439
440 if (cursheet->mark1x==-1) n = !isbold(cursheet,x1,y1,z1);
441 else n = line_ok(_("Make block bold:"), isbold(cursheet,x1,y1,z1));
442 if (n >= 0) for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) bold(cursheet,x,y,z,n);
443 break;
444 }
445 /*}}}*/
446 /* 9 -- underline */ /*{{{*/
447 case ADJUST_UNDERLINE:
448 {
449 int n;
450
451 if (cursheet->mark1x==-1) n = !underlined(cursheet,x1,y1,z1);
452 else n = line_ok(_("Make block underlined:"), underlined(cursheet,x1,y1,z1));
453 if (n >= 0) for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) underline(cursheet,x,y,z,n);
454 break;
455 }
456 /*}}}*/
457 /* 1 -- edit label and goto end */ /*{{{*/
458 case ADJUST_LABEL:
459 {
460 do_label(cursheet);
461 return;
462 }
463 /*}}}*/
464 /* 2 -- lock */ /*{{{*/
465 case ADJUST_LOCK:
466 {
467 int n;
468
469 if (cursheet->mark1x==-1) n = !locked(cursheet,x1,y1,z1);
470 else n = line_ok(_("Lock block:"), locked(cursheet,x1,y1,z1));
471 if (n >= 0) for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) lockcell(cursheet,x,y,z,n);
472
473 break;
474 }
475 /*}}}*/
476 /* 3 -- ignore */ /*{{{*/
477 case ADJUST_IGNORE:
478 {
479 int n;
480
481 if (cursheet->mark1x==-1) n = !ignored(cursheet,x1,y1,z1);
482 else n = line_ok(_("Ignore values of all cells in this block:"), ignored(cursheet,x1,y1,z1));
483 if (n >= 0) for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) igncell(cursheet,x,y,z,n);
484 break;
485 }
486 /*}}}*/
487 /* default -- should not happen */ /*{{{*/
488 default: assert(0);
489 /*}}}*/
490 }
491 if (c>=0)
492 {
493 if (cursheet->mark1x==-1) redraw_cell(cursheet, cursheet->curx, cursheet->cury, cursheet->curz);
494 else redraw_sheet(cursheet);
495 }
496 forceupdate(cursheet);
497 return;
498 }
499 /*}}}*/
500 /* do_savexdr -- save sheet as XDR file */ /*{{{*/
501 static int do_savexdr(Sheet *cursheet, const char *name)
502 {
503 char buf[PATH_MAX];
504 const char *msg;
505 unsigned int count;
506
507 if (!name) {
508 name = cursheet->name;
509
510 if (strcmp(name+strlen(name)-3,".tp")) {
511 snprintf(buf, sizeof(buf), "%s.tp", name);
512 name = buf;
513 }
514 }
515
516 if ((msg = savexdr(cursheet, name, &count))) {
517 line_msg(_("Save sheet to XDR file:"), msg);
518 return -2;
519 }
520
521 snprintf(buf, sizeof(buf), _("%u cells written"), count);
522 if (!batch) line_msg(_("Save sheet to XDR file:"),buf);
523 return -1;
524 }
525 /*}}}*/
526 /* do_saveport -- save sheet as portable ASCII file */ /*{{{*/
527 static int do_saveport(Sheet *cursheet, const char *name)
528 {
529 char buf[PATH_MAX];
530 const char *msg;
531 unsigned int count;
532
533 if (!name) name = cursheet->name;
534
535 if ((msg = saveport(cursheet, name, &count))) {
536 line_msg(_("Save sheet to ASCII file:"),msg);
537 return -2;
538 }
539
540 snprintf(buf, sizeof(buf), _("%u cells written"), count);
541 if (!batch) line_msg(_("Save sheet to ASCII file:"),buf);
542 return -1;
543 }
544 /*}}}*/
545 /* do_savetbl -- save sheet as tbl file */ /*{{{*/
546 static int do_savetbl(Sheet *cursheet, const char *name)
547 {
548 char buf[PATH_MAX];
549 const char *msg;
550 int standalone=0;
551 int x1,y1,z1,x2,y2,z2;
552 unsigned int count;
553
554 get_mark(cursheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
555 if (!name) {
556 name = cursheet->name;
557 if ((standalone=line_ok(_("Save as stand-alone document:"),1))<0) return standalone;
558 }
559
560 if ((msg = savetbl(cursheet, name, !standalone, x1, y1, z1, x2, y2, z2, &count))) {
561 line_msg(_("Save in tbl format to file:"),msg);
562 return -2;
563 }
564
565 snprintf(buf, sizeof(buf), _("%u cells written"), count);
566 if (!batch) line_msg(_("Save in tbl format to file:"), buf);
567 return -1;
568 }
569 /*}}}*/
570 /* do_savelatex -- save sheet as LaTeX file */ /*{{{*/
571 static int do_savelatex(Sheet *cursheet, const char *name)
572 {
573 char buf[PATH_MAX];
574 const char *msg;
575 int standalone=0;
576 int x1,y1,z1,x2,y2,z2;
577 unsigned int count;
578
579 get_mark(cursheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
580 if (!name) {
581 name = cursheet->name;
582 if ((standalone=line_ok(_("Save as stand-alone document:"),1))<0) return standalone;
583 }
584
585 if ((msg = savelatex(cursheet, name, !standalone, x1, y1, z1, x2, y2, z2, &count))) {
586 line_msg(_("Save in LaTeX format to file:"),msg);
587 return -2;
588 }
589
590 snprintf(buf, sizeof(buf), _("%u cells written"), count);
591 if (!batch) line_msg(_("Save in LaTeX format to file:"), buf);
592 return -1;
593 }
594 /*}}}*/
595 /* do_savecontext -- save sheet as ConTeXt file */ /*{{{*/
596 static int do_savecontext(Sheet *cursheet, const char *name)
597 {
598 char buf[PATH_MAX];
599 const char *msg;
600 int standalone=0;
601 int x1,y1,z1,x2,y2,z2;
602 unsigned int count;
603
604 get_mark(cursheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
605 if (!name) {
606 name = cursheet->name;
607 if ((standalone=line_ok(_("Save as stand-alone document:"),1))<0) return standalone;
608 }
609
610 if ((msg = savecontext(cursheet, name, !standalone, x1, y1, z1, x2, y2, z2, &count))) {
611 line_msg(_("Save in ConTeXt format to file:"),msg);
612 return -2;
613 }
614
615 snprintf(buf, sizeof(buf), _("%u cells written"), count);
616 if (!batch) line_msg(_("Save in ConTeXt format to file:"), buf);
617 return -1;
618 }
619 /*}}}*/
620 /* do_savehtml -- save sheet as HTML file */ /*{{{*/
621 static int do_savehtml(Sheet *cursheet, const char *name)
622 {
623 char buf[PATH_MAX];
624 const char *msg;
625 int standalone=0;
626 int x1,y1,z1,x2,y2,z2;
627 unsigned int count;
628
629 get_mark(cursheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
630 if (!name) {
631 name = cursheet->name;
632 if ((standalone=line_ok(_("Save as stand-alone document:"),1))<0) return standalone;
633 }
634
635 if ((msg = savehtml(cursheet, name, !standalone, x1, y1, z1, x2, y2, z2, &count))) {
636 line_msg(_("Save in HTML format to file:"),msg);
637 return -2;
638 }
639
640 snprintf(buf, sizeof(buf), _("%u cells written"), count);
641 if (!batch) line_msg(_("Save in HTML format to file:"), buf);
642 return -1;
643 }
644 /*}}}*/
645 /* do_savetext -- save sheet as formatted text file */ /*{{{*/
646 static int do_savetext(Sheet *cursheet, const char *name)
647 {
648 char buf[PATH_MAX];
649 const char *msg;
650 int x1,y1,z1,x2,y2,z2;
651 unsigned int count;
652
653 get_mark(cursheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
654 if (!name) name = cursheet->name;
655
656 if ((msg = savetext(cursheet, name, x1, y1, z1, x2, y2, z2, &count))) {
657 line_msg(_("Save in plain text format to file:"),msg);
658 return -2;
659 }
660
661 snprintf(buf, sizeof(buf), _("%u cells written"), count);
662 if (!batch) line_msg(_("Save in plain text format to file:"), buf);
663 return -1;
664 }
665 /*}}}*/
666 /* do_savecsv -- save sheet as CSV file */ /*{{{*/
667 static int do_savecsv(Sheet *cursheet, const char *name)
668 {
669 char buf[PATH_MAX];
670 const char *msg;
671 int x1,y1,z1,x2,y2,z2;
672 unsigned int count;
673 int sep = 0;
674 const char seps[4] = ",;\t";
675
676 get_mark(cursheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
677 if (!name) {
678 MenuChoice menu[4];
679 name = cursheet->name;
680
681 menu[0].str=mystrmalloc(_("cC)omma (,)")); menu[0].c='\0';
682 menu[1].str=mystrmalloc(_("sS)emicolon (;)")); menu[1].c='\0';
683 menu[2].str=mystrmalloc(_("tT)ab (\\t)")); menu[2].c='\0';
684 menu[3].str=(char*)0;
685 sep=line_menu(_("Choose separator:"),menu,0);
686 if (sep < 0) return sep;
687 }
688
689 if ((msg = savecsv(cursheet, name, seps[sep], x1, y1, z1, x2, y2, z2, &count))) {
690 line_msg(_("Save in CSV format to file:"),msg);
691 return -2;
692 }
693
694 snprintf(buf, sizeof(buf), _("%u cells written"), count);
695 if (!batch) line_msg(_("Save in CSV format to file:"), buf);
696 return -1;
697 }
698 /*}}}*/
699 /* do_loadxdr -- load sheet from XDR file */ /*{{{*/
700 static int do_loadxdr(Sheet *cursheet)
701 {
702 const char *msg;
703
704 if ((msg=loadxdr(cursheet,cursheet->name))!=(const char*)0) line_msg(_("Load sheet from XDR file:"),msg);
705 return -1;
706 }
707 /*}}}*/
708 /* do_loadport -- load sheet from portable ASCII file */ /*{{{*/
709 static int do_loadport(Sheet *cursheet)
710 {
711 const char *msg;
712 /*}}}*/
713
714 if ((msg=loadport(cursheet,cursheet->name))!=(const char*)0) line_msg(_("Load sheet from ASCII file:"),msg);
715 return -1;
716 }
717 /*}}}*/
718 /* do_loadsc -- load sheet from SC file */ /*{{{*/
719 static int do_loadsc(Sheet *cursheet)
720 {
721 const char *msg;
722
723 if ((msg=loadsc(cursheet,cursheet->name))!=(const char*)0) line_msg(_("Load sheet from SC file:"),msg);
724 return -1;
725 }
726 /*}}}*/
727 /* do_loadwk1 -- load sheet from WK1 file */ /*{{{*/
728 static int do_loadwk1(Sheet *cursheet)
729 {
730 const char *msg;
731
732 if ((msg=loadwk1(cursheet,cursheet->name))!=(const char*)0) line_msg(_("Load sheet from WK1 file:"),msg);
733 return -1;
734 }
735 /*}}}*/
736 /* do_loadcsv -- load/merge sheet from CSV file */ /*{{{*/
737 static int do_loadcsv(Sheet *cursheet)
738 {
739 const char *msg;
740
741 if ((msg=loadcsv(cursheet,cursheet->name))!=(const char*)0) line_msg(_("Load sheet from CSV file:"),msg);
742 return -1;
743 }
744 /*}}}*/
745 /* do_mark -- set mark */ /*{{{*/
746 void do_mark(Sheet *cursheet, int force)
747 {
748 if (force==0)
749 {
750 if (!cursheet->marking && cursheet->mark1x==-1) force=1;
751 else if (cursheet->marking) force=2;
752 else force=3;
753 }
754 switch (force)
755 {
756 case 1:
757 {
758 cursheet->mark1x=cursheet->mark2x=cursheet->curx;
759 cursheet->mark1y=cursheet->mark2y=cursheet->cury;
760 cursheet->mark1z=cursheet->mark2z=cursheet->curz;
761 cursheet->marking=1;
762 break;
763 }
764 case 2:
765 {
766 cursheet->marking=0;
767 break;
768 }
769 case 3:
770 {
771 cursheet->mark1x=-1;
772 break;
773 }
774 default: assert(0);
775 }
776 }
777 /*}}}*/
778 static int do_name(Sheet *cursheet);
779 /* do_save -- save sheet */ /*{{{*/
780 static int do_save(Sheet *cursheet)
781 {
782 const char *ext = cursheet->name;
783 if (ext==(char*)0) return do_name(cursheet);
784
785 ext += strlen(ext)-1;
786
787 if (!strcmp(ext-3, ".tpa")) return do_saveport(cursheet, NULL);
788 if (!strcmp(ext-3, ".tbl")) return do_savetbl(cursheet, NULL);
789 if (!strcmp(ext-5, ".latex")) return do_savelatex(cursheet, NULL);
790 if (!strcmp(ext-4, ".html")) return do_savehtml(cursheet, NULL);
791 if (!strcmp(ext-3, ".csv")) return do_savecsv(cursheet, NULL);
792 if (!strcmp(ext-3, ".txt")) return do_savetext(cursheet, NULL);
793 if (!strcmp(ext-3, ".tex")) return do_savecontext(cursheet, NULL);
794 return do_savexdr(cursheet, NULL);
795 }
796 /*}}}*/
797 /* do_name -- (re)name sheet */ /*{{{*/
798 static int do_name(Sheet *cursheet)
799 {
800 const char *name;
801
802 name = line_file(cursheet->name, _("Teapot \t*.tp\nTeapot ASCII \t*.tpa\ntbl \t*.tbl\nLaTeX \t*.latex\nHTML \t*.html\nCSV \t*.csv\nFormatted ASCII \t*.txt\nConTeXt \t*.tex"), _("New file name:"), 1);
803 if (!name) return -1;
804
805 if (cursheet->name!=(char*)0) free(cursheet->name);
806 cursheet->name=strdup(name);
807 return do_save(cursheet);
808 }
809 /*}}}*/
810 /* do_load -- load sheet */ /*{{{*/
811 static int do_load(Sheet *cursheet)
812 {
813 const char *name, *ext;
814
815 if (doanyway(cursheet, _("Sheet modified, load new file anyway?")) != 1) return -1;
816
817 name = line_file(cursheet->name, _("Teapot \t*.tp\nTeapot ASCII \t*.tpa\nSC Spreadsheet Calculator \t*.sc\nLotus 1-2-3 \t*.wk1\nCSV \t*.csv"), _("Load sheet:"), 0);
818 if (!name) return -1;
819 if (cursheet->name!=(char*)0) free(cursheet->name);
820 cursheet->name=strdup(name);
821
822 ext = name+strlen(name)-1;
823 if (!strcmp(ext-3, ".tpa")) return do_loadport(cursheet);
824 if (!strcmp(ext-2, ".sc")) return do_loadsc(cursheet);
825 if (!strcmp(ext-3, ".wk1")) return do_loadwk1(cursheet);
826 if (!strcmp(ext-3, ".csv")) return do_loadcsv(cursheet);
827 return do_loadxdr(cursheet);
828 }
829 /*}}}*/
830
831 /* do_clear -- clear block */ /*{{{*/
832 static int do_clear(Sheet *sheet)
833 {
834 /* variables */ /*{{{*/
835 int x,y,z;
836 int x1,y1,z1;
837 int x2,y2,z2;
838 int c;
839 /*}}}*/
840
841 if (sheet->mark1x==-1 && locked(sheet,sheet->curx,sheet->cury,sheet->curz)) line_msg(_("Clear cell:"),_("Cell is locked"));
842 else
843 {
844 if (sheet->mark1x!=-1)
845 {
846 if ((c=line_ok(_("Clear block:"),0))<0) return c;
847 else if (c!=1) return -1;
848 }
849 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 0);
850 for (x=x1; x<=x2; ++x) for (y=y1; y<=y2; ++y) for (z=z1; z<=z2; ++z) freecell(sheet,x,y,z);
851 cachelabels(sheet);
852 forceupdate(sheet);
853 }
854 return -1;
855 }
856 /*}}}*/
857 /* do_insert -- insert block */ /*{{{*/
858 static int do_insert(Sheet *sheet)
859 {
860 /* variables */ /*{{{*/
861 int x1,y1,z1,x2,y2,z2,reply;
862 /*}}}*/
863
864 /* ask for direction of insertation */ /*{{{*/
865 {
866 MenuChoice menu[4];
867
868 menu[0].str=mystrmalloc(_("cC)olumn")); menu[0].c='\0';
869 menu[1].str=mystrmalloc(_("rR)ow")); menu[1].c='\0';
870 menu[2].str=mystrmalloc(_("dD)epth")); menu[2].c='\0';
871 menu[3].str=(char*)0;
872 reply=line_menu(_("Insert:"),menu,0);
873 free(menu[0].str);
874 free(menu[1].str);
875 free(menu[2].str);
876 if (reply<0) return reply;
877 }
878 /*}}}*/
879 if (sheet->mark1x==-1)
880 /* ask if current cell or whole dimension should be used */ /*{{{*/
881 {
882 /* variables */ /*{{{*/
883 MenuChoice menu[3];
884 int r;
885 /*}}}*/
886
887 /* show menu */ /*{{{*/
888 switch (reply)
889 {
890 case 0: menu[0].str=mystrmalloc(_("wW)hole column")); break;
891 case 1: menu[0].str=mystrmalloc(_("wW)hole line")); break;
892 case 2: menu[0].str=mystrmalloc(_("wW)hole sheet")); break;
893 default: assert(0);
894 }
895 menu[1].str=mystrmalloc(_("sS)ingle cell")); menu[1].c='\0';
896 menu[2].str=(char*)0;
897 r=line_menu(_("Insert:"),menu,0);
898 free(menu[0].str);
899 free(menu[1].str);
900 /*}}}*/
901 switch (r)
902 {
903 /* 0 -- use whole dimension */ /*{{{*/
904 case 0:
905 {
906 switch (reply)
907 {
908 /* 0 -- use whole column */ /*{{{*/
909 case 0:
910 {
911 x1=x2=sheet->curx;
912 y1=0; y2=sheet->dimy;
913 z1=z2=sheet->curz;
914 break;
915 }
916 /*}}}*/
917 /* 1 -- use whole line */ /*{{{*/
918 case 1:
919 {
920 x1=0; x2=sheet->dimx;
921 y1=y2=sheet->cury;
922 z1=z2=sheet->curz;
923 break;
924 }
925 /*}}}*/
926 /* 2 -- use whole layer */ /*{{{*/
927 case 2:
928 {
929 x1=0; x2=sheet->dimx;
930 y1=0; y2=sheet->dimy;
931 z1=z2=sheet->curz;
932 break;
933 }
934 /*}}}*/
935 /* default -- should not happen */ /*{{{*/
936 default: assert(0);
937 /*}}}*/
938 }
939 break;
940 }
941 /*}}}*/
942 /* 1 -- use current cell */ /*{{{*/
943 case 1:
944 {
945 x1=x2=sheet->curx;
946 y1=y2=sheet->cury;
947 z1=z2=sheet->curz;
948 break;
949 }
950 /*}}}*/
951 /* -2,-1 -- go up or abort */ /*{{{*/
952 case -2:
953 case -1: return r;
954 /*}}}*/
955 /* default -- should not happen */ /*{{{*/
956 default: assert(0);
957 /*}}}*/
958 }
959 }
960 /*}}}*/
961 else
962 /* range is the marked cube */ /*{{{*/
963 {
964 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 0);
965 }
966 /*}}}*/
967 switch (reply)
968 {
969 /* 0 -- columns */ /*{{{*/
970 case 0: insertcube(sheet,x1,y1,z1,x2,y2,z2,IN_X); break;
971 /*}}}*/
972 /* 1 -- rows */ /*{{{*/
973 case 1: insertcube(sheet,x1,y1,z1,x2,y2,z2,IN_Y); break;
974 /*}}}*/
975 /* 2 -- depth */ /*{{{*/
976 case 2: insertcube(sheet,x1,y1,z1,x2,y2,z2,IN_Z); break;
977 /*}}}*/
978 }
979 return 0;
980 }
981 /*}}}*/
982 /* do_delete -- delete block */ /*{{{*/
983 static int do_delete(Sheet *sheet)
984 {
985 /* variables */ /*{{{*/
986 int x1,y1,z1,x2,y2,z2,reply;
987 /*}}}*/
988
989 firstmenu:
990 /* ask for direction of deletion */ /*{{{*/
991 {
992 MenuChoice menu[4];
993
994 menu[0].str=mystrmalloc(_("cC)olumn")); menu[0].c='\0';
995 menu[1].str=mystrmalloc(_("rR)ow")); menu[1].c='\0';
996 menu[2].str=mystrmalloc(_("dD)epth")); menu[2].c='\0';
997 menu[3].str=(char*)0;
998 reply=line_menu(_("Delete:"),menu,0);
999 free(menu[0].str);
1000 free(menu[1].str);
1001 free(menu[2].str);
1002 if (reply<0) return reply;
1003 }
1004 /*}}}*/
1005 if (sheet->mark1x==-1)
1006 /* ask if range is the current cell or whole dimension should be used */ /*{{{*/
1007 {
1008 /* variables */ /*{{{*/
1009 MenuChoice menu[3];
1010 int r;
1011 /*}}}*/
1012
1013 /* show menu */ /*{{{*/
1014 switch (reply)
1015 {
1016 case 0: menu[0].str=mystrmalloc(_("wW)hole column")); break;
1017 case 1: menu[0].str=mystrmalloc(_("wW)hole line")); break;
1018 case 2: menu[0].str=mystrmalloc(_("wW)hole sheet")); break;
1019 default: assert(0);
1020 }
1021 menu[1].str=mystrmalloc(_("sS)ingle cell")); menu[1].c='\0';
1022 menu[2].str=(char*)0;
1023 r=line_menu(_("Delete:"),menu,0);
1024 free(menu[0].str);
1025 free(menu[1].str);
1026 /*}}}*/
1027 switch (r)
1028 {
1029 /* 0 -- use whole dimension */ /*{{{*/
1030 case 0:
1031 {
1032 switch (reply)
1033 {
1034 /* 0 -- use whole column */ /*{{{*/
1035 case 0:
1036 {
1037 x1=x2=sheet->curx;
1038 y1=0; y2=sheet->dimy;
1039 z1=z2=sheet->curz;
1040 break;
1041 }
1042 /*}}}*/
1043 /* 1 -- use whole line */ /*{{{*/
1044 case 1:
1045 {
1046 x1=0; x2=sheet->dimx;
1047 y1=y2=sheet->cury;
1048 z1=z2=sheet->curz;
1049 break;
1050 }
1051 /*}}}*/
1052 /* 2 -- use whole layer */ /*{{{*/
1053 case 2:
1054 {
1055 x1=0; x2=sheet->dimx;
1056 y1=0; y2=sheet->dimy;
1057 z1=z2=sheet->curz;
1058 break;
1059 }
1060 /*}}}*/
1061 /* default -- should not happen */ /*{{{*/
1062 default: assert(0);
1063 /*}}}*/
1064 }
1065 break;
1066 }
1067 /*}}}*/
1068 /* 1 -- use current cell */ /*{{{*/
1069 case 1:
1070 {
1071 x1=x2=sheet->curx;
1072 y1=y2=sheet->cury;
1073 z1=z2=sheet->curz;
1074 break;
1075 }
1076 /*}}}*/
1077 /* -1 -- abort */ /*{{{*/
1078 case -1: return -1;
1079 /*}}}*/
1080 /* -2 -- go back to previous menu */ /*{{{*/
1081 case -2: goto firstmenu;
1082 /*}}}*/
1083 /* default -- should not happen */ /*{{{*/
1084 default: assert(0);
1085 /*}}}*/
1086 }
1087 }
1088 /*}}}*/
1089 else
1090 /* range is the marked cube */ /*{{{*/
1091 {
1092 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 0);
1093 }
1094 /*}}}*/
1095 switch(reply)
1096 {
1097 /* 0 -- columns */ /*{{{*/
1098 case 0: deletecube(sheet,x1,y1,z1,x2,y2,z2,IN_X); break;
1099 /*}}}*/
1100 /* 1 -- rows */ /*{{{*/
1101 case 1: deletecube(sheet,x1,y1,z1,x2,y2,z2,IN_Y); break;
1102 /*}}}*/
1103 /* 2 -- depth */ /*{{{*/
1104 case 2: deletecube(sheet,x1,y1,z1,x2,y2,z2,IN_Z); break;
1105 /*}}}*/
1106 }
1107 return -1;
1108 }
1109 /*}}}*/
1110 /* do_move -- copy or move a block */ /*{{{*/
1111 static int do_move(Sheet *sheet, int copy, int force)
1112 {
1113 int c;
1114
1115 c=-1;
1116 if (sheet->mark1x==-1) line_msg(copy ? _("Copy block:") : _("Move block:"),_("No block marked"));
1117 else if (force || (c=line_ok(copy ? _("Copy block:") : _("Move block:"),0))==1)
1118 {
1119 int x1,y1,z1;
1120 int x2,y2,z2;
1121
1122 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 0);
1123 moveblock(sheet,x1,y1,z1,x2,y2,z2,sheet->curx,sheet->cury,sheet->curz,copy);
1124 if (!copy) sheet->mark1x=-1;
1125 }
1126 if (c<0) return c; else return -1;
1127 }
1128 /*}}}*/
1129 /* do_fill -- fill a block */ /*{{{*/
1130 static int do_fill(Sheet *sheet)
1131 {
1132 /* variables */ /*{{{*/
1133 size_t offx,edx;
1134 int cols,rows,layers;
1135 int x,y,z;
1136 int x1,y1,z1;
1137 int x2,y2,z2;
1138 int c;
1139 /*}}}*/
1140
1141 if (sheet->mark1x==-1) line_msg(_("Fill block:"),_("No block marked"));
1142 else
1143 {
1144 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 0);
1145 cols=rows=layers=1;
1146 firstmenu:
1147 offx=0;
1148 edx=0;
1149 do if ((c=line_numedit(&cols,_("Number of column-wise repetitions:"),&edx,&offx))<0) return c; while (cols<=0);
1150 secondmenu:
1151 offx=0;
1152 edx=0;
1153 do
1154 {
1155 c=line_numedit(&rows,_("Number of row-wise repetitions:"),&edx,&offx);
1156 if (c==-1) return -1;
1157 else if (c==-2) goto firstmenu;
1158 } while (rows<=0);
1159 offx=0;
1160 edx=0;
1161 do
1162 {
1163 c=line_numedit(&layers,_("Number of depth-wise repetitions:"),&edx,&offx);
1164 if (c==-1) return -1;
1165 else if (c==-2) goto secondmenu;
1166 } while (layers<=0);
1167 for (x=0; x<cols; ++x) for (y=0; y<rows; ++y) for (z=0; z<layers; ++z) moveblock(sheet,x1,y1,z1,x2,y2,z2,sheet->curx+x*(x2-x1+1),sheet->cury+y*(y2-y1+1),sheet->curz+z*(z2-z1+1),1);
1168 }
1169 return -1;
1170 }
1171 /*}}}*/
1172 /* do_sort -- sort block */ /*{{{*/
1173 static int do_sort(Sheet *sheet)
1174 {
1175 /* variables */ /*{{{*/
1176 MenuChoice menu1[4],menu2[3],menu3[3];
1177 Sortkey sk[MAX_SORTKEYS];
1178 unsigned int key;
1179 size_t x,offx;
1180 const char *msg;
1181 Direction in_dir=(Direction)-2; /* cause run time error */
1182 int x1,y1,z1,x2,y2,z2;
1183 int doit=-1;
1184 int c;
1185 int last;
1186 /*}}}*/
1187
1188 /* note and order block coordinates */ /*{{{*/
1189 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
1190 /*}}}*/
1191 /* build menues */ /*{{{*/
1192 menu1[0].str=mystrmalloc(_("cC)olumn")); menu1[0].c='\0';
1193 menu1[1].str=mystrmalloc(_("rR)ow")); menu1[1].c='\0';
1194 menu1[2].str=mystrmalloc(_("dD)epth")); menu1[2].c='\0';
1195 menu1[3].str=(char*)0;
1196 menu2[0].str=mystrmalloc(_("sS)ort region")); menu2[0].c='\0';
1197 menu2[1].str=mystrmalloc(_("aA)dd key")); menu2[1].c='\0';
1198 menu2[2].str=(char*)0;
1199 menu3[0].str=mystrmalloc(_("aA)scending")); menu3[0].c='\0';
1200 menu3[1].str=mystrmalloc(_("dD)escending")); menu3[0].c='\0';
1201 menu3[2].str=(char*)0;
1202 /*}}}*/
1203
1204 last=-1;
1205 /* ask for sort direction */ /*{{{*/
1206 zero: switch (c=line_menu(_("Sort block:"),menu1,0))
1207 {
1208 /* 0 -- in X */ /*{{{*/
1209 case 0: in_dir=IN_X; break;
1210 /*}}}*/
1211 /* 1 -- in Y */ /*{{{*/
1212 case 1: in_dir=IN_Y; break;
1213 /*}}}*/
1214 /* 2 -- in Z */ /*{{{*/
1215 case 2: in_dir=IN_Z; break;
1216 /*}}}*/
1217 /* -2,-1 -- abort */ /*{{{*/
1218 case -2:
1219 case -1: goto greak;
1220 /*}}}*/
1221 /* default -- should not happen */ /*{{{*/
1222 default: assert(0);
1223 /*}}}*/
1224 }
1225 last=0;
1226 /*}}}*/
1227 key=0;
1228 do
1229 {
1230 /* ask for positions */ /*{{{*/
1231 one: if (in_dir==IN_X) sk[key].x=0; else /* ask for x position */ /*{{{*/
1232 {
1233 x=0;
1234 offx=0;
1235 sk[key].x=0;
1236 do
1237 {
1238 c=line_numedit(&(sk[key].x),_("X position of key vector:"),&x,&offx);
1239 if (c==-1) goto greak;
1240 else if (c==-2) switch (last)
1241 {
1242 case -1: goto greak;
1243 case 0: goto zero;
1244 case 2: goto two;
1245 case 3: goto three;
1246 case 5: goto five;
1247 }
1248 } while (sk[key].x<0);
1249 last=1;
1250 }
1251 /*}}}*/
1252 two: if (in_dir==IN_Y) sk[key].y=0; else /* ask for y position */ /*{{{*/
1253 {
1254 x=0;
1255 offx=0;
1256 sk[key].y=0;
1257 do
1258 {
1259 c=line_numedit(&(sk[key].y),_("Y position of key vector:"),&x,&offx);
1260 if (c==-1) goto greak;
1261 else if (c==-2) switch (last)
1262 {
1263 case -1: goto greak;
1264 case 0: goto zero;
1265 case 1: goto one;
1266 case 3: goto three;
1267 case 5: goto five;
1268 default: assert(0);
1269 }
1270 } while (sk[key].y<0);
1271 last=2;
1272 }
1273 /*}}}*/
1274 three: if (in_dir==IN_Z) sk[key].z=0; else /* ask for z position */ /*{{{*/
1275 {
1276 x=0;
1277 offx=0;
1278 sk[key].z=0;
1279 do
1280 {
1281 c=line_numedit(&(sk[key].z),_("Z position of key vector:"),&x,&offx);
1282 if (c==-1) goto greak;
1283 else if (c==-2) switch (last)
1284 {
1285 case -1: goto greak;
1286 case 0: goto zero;
1287 case 1: goto one;
1288 case 2: goto two;
1289 case 5: goto five;
1290 default: assert(0);
1291 }
1292 } while (sk[key].z<0);
1293 last=3;
1294 }
1295 /*}}}*/
1296 /*}}}*/
1297 /* ask for sort key */ /*{{{*/
1298 four: sk[key].sortkey=0;
1299 switch (c=line_menu(_("Sort block:"),menu3,0))
1300 {
1301 /* 0 -- ascending */ /*{{{*/
1302 case 0: sk[key].sortkey|=ASCENDING; break;
1303 /*}}}*/
1304 /* 1 -- descending */ /*{{{*/
1305 case 1: sk[key].sortkey&=~ASCENDING; break;
1306 /*}}}*/
1307 /* -1 -- abort */ /*{{{*/
1308 case -1: goto greak;
1309 /*}}}*/
1310 /* -2 -- go to first menu */ /*{{{*/
1311 case -2: switch (last)
1312 {
1313 case -1: goto greak;
1314 case 1: goto one;
1315 case 2: goto two;
1316 case 3: goto three;
1317 default: assert(0);
1318 }
1319 /*}}}*/
1320 /* default -- should not happen */ /*{{{*/
1321 default: assert(0);
1322 /*}}}*/
1323 }
1324 last=4;
1325 /*}}}*/
1326 ++key;
1327 five:
1328 if (key==MAX_SORTKEYS) /* ask for sort comfirmation */ /*{{{*/
1329 {
1330 c=line_ok(_("Sort block:"),0);
1331 if (c==-1) goto greak;
1332 else if (c==-2) goto four;
1333 else if (c==0) doit=1;
1334 }
1335 /*}}}*/
1336 else /* ask for sort or adding another key */ /*{{{*/
1337 switch (line_menu(_("Sort block:"),menu2,0))
1338 {
1339 /* 0 -- sort it */ /*{{{*/
1340 case 0: doit=1; break;
1341 /*}}}*/
1342 /* 1 -- add another key */ /*{{{*/
1343 case 1: doit=0; break;
1344 /*}}}*/
1345 /* -1 -- abort */ /*{{{*/
1346 case -1: goto greak;
1347 /*}}}*/
1348 case -2: goto four;
1349 /* default -- should not happen */ /*{{{*/
1350 default: assert(0);
1351 /*}}}*/
1352 }
1353 /*}}}*/
1354 last=5;
1355 } while (!doit);
1356 c=-1;
1357 if ((msg=sortblock(sheet,x1,y1,z1,x2,y2,z2,in_dir,sk,key))!=(const char*)0) line_msg(_("Sort block:"),msg);
1358 greak:
1359 /* free menues */ /*{{{*/
1360 free((char*)menu1[0].str);
1361 free((char*)menu1[1].str);
1362 free((char*)menu1[2].str);
1363 free((char*)menu2[0].str);
1364 free((char*)menu2[1].str);
1365 free((char*)menu2[2].str);
1366 free((char*)menu3[0].str);
1367 free((char*)menu3[1].str);
1368 free((char*)menu3[2].str);
1369 /*}}}*/
1370 return c;
1371 }
1372 /*}}}*/
1373 /* do_batchsort -- sort block in a batch*/ /*{{{*/
1374 static void do_batchsort(Sheet *sheet, Direction dir, char* arg)
1375 {
1376 Sortkey sk[MAX_SORTKEYS];
1377 int x1,y1,z1,x2,y2,z2;
1378 unsigned int key = 0;
1379 char* next;
1380 while( *arg != '\0' )
1381 {
1382 while (isspace((int)*arg)) arg++;
1383 sk[key].x=sk[key].y=sk[key].z=sk[key].sortkey=0;
1384 switch (*arg)
1385 {
1386 case 'a': sk[key].sortkey|=ASCENDING; arg++; break;
1387 case 'd': sk[key].sortkey&=~ASCENDING; arg++; break;
1388 }
1389 if ( *arg != '\0' && dir != IN_X ) { sk[key].x=strtol(arg, &next, 10); arg = next; }
1390 if ( *arg != '\0' && dir != IN_Y ) { sk[key].y=strtol(arg, &next, 10); arg = next; }
1391 if ( *arg != '\0' && dir != IN_Z ) { sk[key].z=strtol(arg, &next, 10); arg = next; }
1392 key++;
1393 }
1394 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
1395 sortblock(sheet, x1, y1, z1, x2, y2, z2, dir, sk, key);
1396 }
1397 /*}}}*/
1398 /* do_mirror -- mirror block */ /*{{{*/
1399 static int do_mirror(Sheet *sheet)
1400 {
1401 /* variables */ /*{{{*/
1402 int x1,y1,z1,x2,y2,z2,reply;
1403 /*}}}*/
1404
1405 /* note and order block coordinates */ /*{{{*/
1406 get_mark(sheet, &x1, &x2, &y1, &y2, &z1, &z2, 1);
1407 /*}}}*/
1408 /* ask for direction of mirroring */ /*{{{*/
1409 {
1410 MenuChoice menu[4];
1411
1412 menu[0].str=mystrmalloc(_("lL)eft-right")); menu[0].c='\0';
1413 menu[1].str=mystrmalloc(_("uU)pside-down")); menu[1].c='\0';
1414 menu[2].str=mystrmalloc(_("fF)ront-back")); menu[2].c='\0';
1415 menu[3].str=(char*)0;
1416 reply=line_menu(_("Mirror block:"),menu,0);
1417 free(menu[0].str);
1418 free(menu[1].str);
1419 free(menu[2].str);
1420 if (reply<0) return reply;
1421 }
1422 /*}}}*/
1423 switch (reply)
1424 {
1425 /* 0 -- left-right */ /*{{{*/
1426 case 0: mirrorblock(sheet,x1,y1,z1,x2,y2,z2,IN_X); break;
1427 /*}}}*/
1428 /* 1 -- upside-down */ /*{{{*/
1429 case 1: mirrorblock(sheet,x1,y1,z1,x2,y2,z2,IN_Y); break;
1430 /*}}}*/
1431 /* 2 -- front-back */ /*{{{*/
1432 case 2: mirrorblock(sheet,x1,y1,z1,x2,y2,z2,IN_Z); break;
1433 /*}}}*/
1434 default: assert(0);
1435 }
1436 return 0;
1437 }
1438 /*}}}*/
1439 /* do_goto -- go to a specific cell */ /*{{{*/
1440 static int do_goto(Sheet *sheet, const char *expr)
1441 {
1442 /* variables */ /*{{{*/
1443 char buf[1024];
1444 const char *s;
1445 size_t x,offx;
1446 Token **t;
1447 int c;
1448 /*}}}*/
1449
1450 assert(sheet!=(Sheet*)0);
1451 buf[0]='\0';
1452 x=offx=0;
1453 if (expr) strcpy(buf,expr);
1454 else if ((c=line_edit(sheet,buf,sizeof(buf),_("Go to location:"),&x,&offx))<0) return c;
1455 s=buf;
1456 t=scan(&s);
1457 if (t!=(Token**)0)
1458 {
1459 Token value;
1460
1461 upd_x=sheet->curx;
1462 upd_y=sheet->cury;
1463 upd_z=sheet->curz;
1464 upd_sheet=sheet;
1465 value=eval(t);
1466 tvecfree(t);
1467 if (value.type==LOCATION && value.u.location[0]>=0 && value.u.location[1]>=0 && value.u.location[2]>=0)
1468 moveto(sheet,value.u.location[0],value.u.location[1],value.u.location[2]);
1469 else
1470 line_msg(_("Go to location:"),_("Not a valid location"));
1471 tfree(&value);
1472 }
1473 return -1;
1474 }
1475 /*}}}*/
1476
1477 /* do_sheetcmd -- process one key press */ /*{{{*/
1478 int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
1479 {
1480 switch ((int)c)
1481 {
1482 case K_GOTO: do_goto(cursheet, (const char *)0); break;
1483 case K_COLWIDTH: do_columnwidth(cursheet); break;
1484 case BLOCK_CLEAR: do_clear(cursheet); redraw_sheet(cursheet); break;
1485 case BLOCK_INSERT: do_insert(cursheet); redraw_sheet(cursheet); break;
1486 case BLOCK_DELETE: do_delete(cursheet); redraw_sheet(cursheet); break;
1487 case BLOCK_MOVE: do_move(cursheet,0,0); redraw_sheet(cursheet); break;
1488 case BLOCK_COPY: do_move(cursheet,1,0); redraw_sheet(cursheet); break;
1489 case BLOCK_FILL: do_fill(cursheet); redraw_sheet(cursheet); break;
1490 case BLOCK_SORT: do_sort(cursheet); redraw_sheet(cursheet); break;
1491 case BLOCK_MIRROR: do_mirror(cursheet); redraw_sheet(cursheet); break;
1492 case ADJUST_LEFT:
1493 case ADJUST_RIGHT:
1494 case ADJUST_CENTER:
1495 case ADJUST_SCIENTIFIC:
1496 case ADJUST_PRECISION:
1497 case ADJUST_SHADOW:
1498 case ADJUST_BOLD:
1499 case ADJUST_UNDERLINE:
1500 case ADJUST_TRANSPARENT:
1501 case ADJUST_LABEL:
1502 case ADJUST_LOCK:
1503 case ADJUST_IGNORE: do_attribute(cursheet, c); break;
1504 /* UP -- move up */ /*{{{*/
1505 case K_UP:
1506 {
1507 relmoveto(cursheet, 0, -1, 0);
1508 break;
1509 }
1510 /*}}}*/
1511 /* DOWN -- move down */ /*{{{*/
1512 case K_DOWN:
1513 {
1514 relmoveto(cursheet, 0, 1, 0);
1515 break;
1516 }
1517 /*}}}*/
1518 /* LEFT -- move left */ /*{{{*/
1519 case K_LEFT:
1520 {
1521 relmoveto(cursheet, -1, 0, 0);
1522 break;
1523 }
1524 /*}}}*/
1525 /* RIGHT -- move right */ /*{{{*/
1526 case K_RIGHT:
1527 {
1528 relmoveto(cursheet, 1, 0, 0);
1529 break;
1530 }
1531 /*}}}*/
1532 /* FIRSTL -- move to first line */ /*{{{*/
1533 case K_FIRSTL:
1534 case '<':
1535 {
1536 moveto(cursheet, -1, 0, -1);
1537 break;
1538 }
1539 /*}}}*/
1540 /* LASTL -- move to last line */ /*{{{*/
1541 case K_LASTL:
1542 case '>':
1543 {
1544 moveto(cursheet, -1, (cursheet->dimy ? cursheet->dimy-1 : 0), -1);
1545 break;
1546 }
1547 /*}}}*/
1548 /* HOME -- move to beginning of line */ /*{{{*/
1549 case K_HOME:
1550 {
1551 moveto(cursheet, 0, -1, -1);
1552 break;
1553 }
1554 /*}}}*/
1555 /* END -- move to end of line */ /*{{{*/
1556 case K_END:
1557 {
1558 moveto(cursheet, (cursheet->dimx ? cursheet->dimx-1 : 0), -1, -1);
1559 break;
1560 }
1561 /*}}}*/
1562 /* + -- move one sheet down */ /*{{{*/
1563 case K_NSHEET:
1564 case '+':
1565 {
1566 relmoveto(cursheet, 0, 0, 1);
1567 break;
1568 }
1569 /*}}}*/
1570 /* - -- move one sheet up */ /*{{{*/
1571 case K_PSHEET:
1572 case '-':
1573 {
1574 relmoveto(cursheet, 0, 0, -1);
1575 break;
1576 }
1577 /*}}}*/
1578 /* * -- move to bottom sheet */ /*{{{*/
1579 case K_LSHEET:
1580 case '*':
1581 {
1582 moveto(cursheet, -1, -1, (cursheet->dimz ? cursheet->dimz-1 : 0));
1583 break;
1584 }
1585 /*}}}*/
1586 /* _ -- move to top sheet */ /*{{{*/
1587 case K_FSHEET:
1588 case '_':
1589 {
1590 moveto(cursheet, -1, -1, 0);
1591 break;
1592 }
1593 /*}}}*/
1594 /* ENTER -- edit current cell */ /*{{{*/
1595 case K_ENTER: if (moveonly) break; do_edit(cursheet,'\0',(const char*)0,0); break;
1596 /*}}}*/
1597 /* MENTER -- edit current clocked cell */ /*{{{*/
1598 case K_MENTER: if (moveonly) break; do_edit(cursheet,'\0',(const char*)0,1); break;
1599 /*}}}*/
1600 /* ", @, digit -- edit current cell with character already in buffer */ /*{{{*/
1601 case K_BACKSPACE:
1602 case K_DC:
1603 case '"':
1604 case '@':
1605 case '0':
1606 case '1':
1607 case '2':
1608 case '3':
1609 case '4':
1610 case '5':
1611 case '6':
1612 case '7':
1613 case '8':
1614 case '9': if (moveonly) break; do_edit(cursheet,c,(const char*)0,0); break;
1615 /*}}}*/
1616 /* MARK -- toggle block marking */ /*{{{*/
1617 case '.':
1618 case K_MARK: if (moveonly) break; do_mark(cursheet,0); break;
1619 /*}}}*/
1620 /* _("Save sheet file format:") -- save menu */ /*{{{*/
1621 case K_SAVEMENU: if (moveonly) break; do_save(cursheet); break;
1622 /*}}}*/
1623 /* _("Load sheet file format:") -- load menu */ /*{{{*/
1624 case K_LOAD:
1625 case K_LOADMENU: if (moveonly) break; do_load(cursheet); break;
1626 /*}}}*/
1627 /* _("nN)ame") -- set name */ /*{{{*/
1628 case K_NAME: if (moveonly) break; do_name(cursheet); break;
1629 /*}}}*/
1630 #ifdef ENABLE_HELP
1631 case K_HELP: show_text(helpfile); break;
1632 #else
1633 case K_HELP: show_text(_("Sorry, manual is not installed.")); break;
1634 #endif
1635 case K_ABOUT: show_text(_("<html><head><title>About teapot</title></head><body><center><pre>\n\n"
1636 " ` ',` ' ' \n"
1637 " ` ' ` ' ' \n"
1638 " `' ' '`' \n"
1639 " ' ` ' '` \n"
1640 " ' '` ' ` '`` ` \n"
1641 " `. Table Editor And Planner, or: \n"
1642 " , . , , . . \n"
1643 " ` ' ` ' ' \n"
1644 " `::\\ /:::::::::::::::::\\ ___ \n"
1645 " `::\\ /:::::::::::::::::::\\,'::::\\ \n"
1646 " :::\\/:::::::::::::::::::::\\/ \\:\\ \n"
1647 " :::::::::::::::::::::::::::\\ ::: \n"
1648 " ::::::::::::::::::::::::::::; /:;' \n"
1649 " `::::::::::::::::::::::::::::_/:;' \n"
1650 " `::::::::::::::::::::::::::::' \n"
1651 " `////////////////////////' \n"
1652 " `:::::::::::::::::::::' \n"
1653 "</pre>\n"
1654 "<p>Teapot " VERSION "</p>\n"
1655 "\n"
1656 "<p>Original Version: Michael Haardt<br>\n"
1657 "Current Maintainer: Joerg Walter<br>\n"
1658 "Home Page: <a href='http://www.syntax-k.de/projekte/teapot/'>http://www.syntax-k.de/projekte/teapot/</a></p>\n"
1659 "\n"
1660 "<p>Copyright 1995-2006 Michael Haardt,<br>\n"
1661 "Copyright 2009-2010 Joerg Walter (<a href='mailto:info@syntax-k.de'>info@syntax-k.de</a>)</p></center>\n"
1662 "\f"
1663 "<p>This program is free software: you can redistribute it and/or modify\n"
1664 "it under the terms of the GNU General Public License as published by\n"
1665 "the Free Software Foundation, either version 3 of the License, or\n"
1666 "(at your option) any later version.</p>\n"
1667 "\n"
1668 "<p>This program is distributed in the hope that it will be useful,\n"
1669 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1670 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1671 "GNU General Public License for more details.</p>\n"
1672 "\n"
1673 "<p>You should have received a copy of the GNU General Public License\n"
1674 "along with this program. If not, see <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.</p>"
1675 "</body></html>"));
1676 break;
1677 /* MENU, / -- main menu */ /*{{{*/
1678 case '/': if (!moveonly && do_sheetcmd(cursheet, show_menu(cursheet), 0)) return 1; break;
1679 /*}}}*/
1680 /* _("sS)ave") -- save in current native format */ /*{{{*/
1681 case K_SAVE: do_save(cursheet); break;
1682 /*}}}*/
1683 /* _("cC)opy") -- copy block */ /*{{{*/
1684 case K_COPY: if (moveonly) break; do_move(cursheet,1,1); break;
1685 /*}}}*/
1686 /* RECALC -- recalculate */ /*{{{*/
1687 case K_RECALC: if (moveonly) break; forceupdate(cursheet); break;
1688 /*}}}*/
1689 /* _("Usage: clock(condition,location[,location])") -- clock */ /*{{{*/
1690 case K_CLOCK:
1691 {
1692 int x,y,z;
1693
1694 for (x=0; x<cursheet->dimx; ++x)
1695 for (y=0; y<cursheet->dimy; ++y)
1696 for (z=0; z<cursheet->dimz; ++z)
1697 clk(cursheet,x,y,z);
1698 update(cursheet);
1699 break;
1700 }
1701 /*}}}*/
1702 /* NPAGE -- page down */ /*{{{*/
1703 case K_NPAGE:
1704 {
1705 cursheet->offy+=(cursheet->maxy-3);
1706 relmoveto(cursheet, 0, cursheet->maxy-3, 0);
1707 break;
1708 }
1709 /*}}}*/
1710 /* PPAGE -- page up */ /*{{{*/
1711 case K_PPAGE:
1712 {
1713 cursheet->offy = (cursheet->offy>=(cursheet->maxy-3) ? cursheet->offy-(cursheet->maxy-3) : 0);
1714 relmoveto(cursheet, 0, (cursheet->cury>=(cursheet->maxy-3) ? -(cursheet->maxy-3) : -cursheet->cury), 0);
1715 break;
1716 }
1717 /*}}}*/
1718 /* FPAGE -- page right */ /*{{{*/
1719 case K_FPAGE:
1720 {
1721 cursheet->offx+=cursheet->width;
1722 relmoveto(cursheet, cursheet->width, 0, 0);
1723 break;
1724 }
1725 /*}}}*/
1726 /* BPAGE -- page left */ /*{{{*/
1727 case K_BPAGE:
1728 {
1729 cursheet->offx=(cursheet->offx>=cursheet->width ? cursheet->offx-cursheet->width : 0);
1730 relmoveto(cursheet, (cursheet->curx>=cursheet->width ? -cursheet->width : -cursheet->curx), 0, 0);
1731 break;
1732 }
1733 /*}}}*/
1734 /* SAVEQUIT -- save and quit */ /*{{{*/
1735 case K_SAVEQUIT:
1736 {
1737 if (moveonly) break;
1738 if (do_save(cursheet)!=-2) return 1;
1739 break;
1740 }
1741 /*}}}*/
1742 /* _("qQ)uit") -- quit */ /*{{{*/
1743 case K_QUIT: if (moveonly) break; return 1;
1744 /*}}}*/
1745 default:
1746 if (isalpha(c) && !moveonly) do_edit(cursheet,c,(const char*)0,0);
1747 break;
1748 }
1749 return 0;
1750 }
1751 /*}}}*/
1752
1753 /* main */ /*{{{*/
1754 int main(int argc, char *argv[])
1755 {
1756 /* variables */ /*{{{*/
1757 Sheet sheet,*cursheet;
1758 int o;
1759 const char *loadfile;
1760 int always_redraw=0;
1761 char ln[1024];
1762 /*}}}*/
1763
1764 setlocale(LC_ALL, "");
1765 find_helpfile(helpfile, sizeof(helpfile), argv[0]);
1766
1767 /* parse options */ /*{{{*/
1768 while ((o=getopt(argc,argv,"abhnrqHp:?"))!=EOF) switch (o)
1769 {
1770 /* a -- use ascii as default */ /*{{{*/
1771 case 'a':
1772 {
1773 usexdr=0;
1774 break;
1775 }
1776 /*}}}*/
1777 /* b -- run batch */ /*{{{*/
1778 case 'b': batch=1; break;
1779 /*}}}*/
1780 /* n -- no quoted strings */ /*{{{*/
1781 case 'n': quote=0; break;
1782 /*}}}*/
1783 /* q -- force quoted strings */ /*{{{*/
1784 case 'q': quote=1; break;
1785 /*}}}*/
1786 /* H -- no row/column headers */ /*{{{*/
1787 case 'H': header=0; break;
1788 /*}}}*/
1789 /* r -- always redraw */ /*{{{*/
1790 case 'r':
1791 {
1792 always_redraw=1;
1793 break;
1794 }
1795 /*}}}*/
1796 /* p -- precision */ /*{{{*/
1797 case 'p':
1798 {
1799 long n;
1800 char *end;
1801
1802 n=strtol(optarg,&end,0);
1803 if (*end || n<0 || n>DBL_DIG)
1804 {
1805 fprintf(stderr,_("teapot: precision must be between 0 and %d.\n"),DBL_DIG);
1806 exit(1);
1807 }
1808 def_precision=n;
1809 break;
1810 }
1811 /*}}}*/
1812 /* default -- includes ? and h */ /*{{{*/
1813 default:
1814 {
1815 fprintf(stderr,_(
1816 "Usage: %s [-a] [-b] [-n] [-H] [-r] [-p digits] [file]\n"
1817 " -a: use ASCII file format as default\n"
1818 " -b: batch mode\n"
1819 " -q: display strings in quotes\n"
1820 " -H: hide row/column headers\n"
1821 " -r: redraw more often\n"
1822 " -p: set decimal precision\n"
1823 ), argv[0]);
1824 exit(1);
1825 }
1826 /*}}}*/
1827 }
1828 loadfile=(optind<argc ? argv[optind] : (const char*)0);
1829 /*}}}*/
1830 /* create empty sheet */ /*{{{*/
1831 cursheet=&sheet;
1832 cursheet->curx=cursheet->cury=cursheet->curz=0;
1833 cursheet->offx=cursheet->offy=0;
1834 cursheet->dimx=cursheet->dimy=cursheet->dimz=0;
1835 cursheet->sheet=(Cell**)0;
1836 cursheet->column=(int*)0;
1837 cursheet->orix=0;
1838 cursheet->oriy=0;
1839 cursheet->maxx=0;
1840 cursheet->maxy=0;
1841 cursheet->name=(char*)0;
1842 cursheet->mark1x=-1;
1843 cursheet->marking=0;
1844 cursheet->changed=0;
1845 cursheet->moveonly=0;
1846 cursheet->clk=0;
1847 (void)memset(cursheet->labelcache,0,sizeof(cursheet->labelcache));
1848 /*}}}*/
1849 /* start display */ /*{{{*/
1850 if (!batch) {
1851 display_init(&sheet, always_redraw);
1852 line_msg((const char*)0,"");
1853 }
1854 /*}}}*/
1855 if (loadfile) /* load given sheet */ /*{{{*/
1856 {
1857 const char *msg;
1858
1859 cursheet->name=mystrmalloc(loadfile);
1860 if (usexdr)
1861 {
1862 if ((msg=loadxdr(cursheet,cursheet->name))!=(const char*)0) line_msg(_("Load sheet from XDR file:"),msg);
1863 }
1864 else
1865 {
1866 if ((msg=loadport(cursheet,cursheet->name))!=(const char*)0) line_msg(_("Load sheet from ASCII file:"),msg);
1867 }
1868 }
1869 /*}}}*/
1870 if (batch) /* process batch */ /*{{{*/
1871 while (fgets(ln,sizeof(ln),stdin)!=(char*)0)
1872 {
1873 /* variables */ /*{{{*/
1874 size_t len;
1875 char *cmd,*arg;
1876 /*}}}*/
1877
1878 /* set cmd and arg */ /*{{{*/
1879 ++batchln;
1880 len=strlen(ln);
1881 if (len && ln[len-1]=='\n') ln[len-1]='\0';
1882 cmd=ln; while (isspace((int)*cmd)) ++cmd;
1883 arg=cmd;
1884 while (*arg && !isspace((int)*arg)) ++arg;
1885 while (isspace((int)*arg)) *arg++='\0';
1886 /*}}}*/
1887
1888 /* goto location */ /*{{{*/
1889 if (strcmp(cmd,"goto")==0) do_goto(cursheet,arg);
1890 /*}}}*/
1891 /* from location */ /*{{{*/
1892 else if (strcmp(cmd,"from")==0)
1893 {
1894 do_goto(cursheet,arg);
1895 do_mark(cursheet,1);
1896 }
1897 /*}}}*/
1898 /* to location */ /*{{{*/
1899 else if (strcmp(cmd,"to")==0)
1900 {
1901 do_goto(cursheet,arg);
1902 do_mark(cursheet,2);
1903 }
1904 /*}}}*/
1905 /* save-tbl file */ /*{{{*/
1906 else if (strcmp(cmd,"save-tbl")==0) do_savetbl(cursheet,arg);
1907 /*}}}*/
1908 /* save-latex file */ /*{{{*/
1909 else if (strcmp(cmd,"save-latex")==0) do_savelatex(cursheet,arg);
1910 /*}}}*/
1911 /* save-context file */ /*{{{*/
1912 else if (strcmp(cmd,"save-context")==0) do_savecontext(cursheet,arg);
1913 /*}}}*/
1914 /* save-csv file */ /*{{{*/
1915 else if (strcmp(cmd,"save-csv")==0) do_savecsv(cursheet,arg);
1916 /*}}}*/
1917 /* save-html file */ /*{{{*/
1918 else if (strcmp(cmd,"save-html")==0) do_savehtml(cursheet,arg);
1919 /*}}}*/
1920 /* load-csv file */ /*{{{*/
1921 else if (strcmp(cmd,"load-csv")==0) { loadcsv(cursheet,arg); forceupdate(cursheet); }
1922 /*}}}*/
1923 /* sort in x direction */ /*{{{*/
1924 else if (strcmp(cmd,"sort-x")==0) do_batchsort(cursheet, IN_X, arg);
1925 /*}}}*/
1926 /* sort in y direction */ /*{{{*/
1927 else if (strcmp(cmd,"sort-y")==0) do_batchsort(cursheet, IN_Y, arg);
1928 /*}}}*/
1929 /* sort in z direction */ /*{{{*/
1930 else if (strcmp(cmd,"sort-z")==0) do_batchsort(cursheet, IN_Z, arg);
1931 /*}}}*/
1932 /* this is an unknown command */ /*{{{*/
1933 else line_msg(_("Unknown batch command:"),cmd);
1934 /*}}}*/
1935 }
1936 /*}}}*/
1937 else /* process interactive input */ /*{{{*/
1938 {
1939 display_main(cursheet);
1940 display_end();
1941 }
1942 /*}}}*/
1943 freesheet(cursheet,1);
1944 fclose(stdin);
1945 return 0;
1946 }
1947 /*}}}*/