1 /*
2 * $Id: oleofile.c,v 1.26 2001/02/13 23:38:06 danny Exp $
3 *
4 * Copyright � 1990-2000, 2001 Free Software Foundation, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this software; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #ifdef WITH_DMALLOC
26 #include <dmalloc.h>
27 #endif
28
29 #include "funcdef.h"
30 #include <stdio.h>
31 #include <ctype.h>
32 #include "sysdef.h"
33 #include "io-generic.h"
34 #include "io-abstract.h"
35 #include "io-utils.h"
36 #include "io-term.h"
37 #include "font.h"
38 #include "global.h"
39 #include "cell.h"
40 #include "line.h"
41 #include "sylk.h"
42 #include "lists.h"
43 #include "ref.h"
44 #include "regions.h"
45 #include "window.h"
46 #include "info.h"
47 #include "cmd.h"
48
49 #include "graph.h"
50
51 #include "oleosql.h"
52
53 /* These functions read and write OLEO style files. */
54
55 void
oleo_read_file(fp,ismerge)56 oleo_read_file (fp, ismerge)
57 FILE *fp;
58 int ismerge;
59 {
60 char *ptr;
61 CELLREF crow = 0, ccol = 0, czrow = 0, czcol = 0;
62 int lineno;
63 char cbuf[1024];
64 char expbuf[1024];
65 char *vname, *vval;
66 int vlen = 0;
67 int cprot;
68 char *cexp, *cval;
69 CELL *cp;
70 struct rng rng;
71 int fmt = 0, prc = 0;
72 int jst = 0;
73 struct font_memo * fnt = 0;
74 struct font_memo ** fnt_map = 0;
75 int fnt_map_size = 0;
76 int fnt_map_alloc = 0;
77 int font_spec_in_format = 1; /* Reset if we discover this is a v1.1 file. */
78
79 long mx_row = MAX_ROW, mx_col = MAX_COL;
80 int old_a0;
81 int next_a0;
82
83 Global->return_from_error = 1;
84
85 old_a0 = Global->a0;
86 next_a0 = old_a0;
87 Global->a0 = 0;
88 lineno = 0;
89 if (!ismerge)
90 clear_spreadsheet ();
91 while (fgets (cbuf, sizeof (cbuf), fp))
92 {
93 lineno++;
94
95 #if 0
96 if (lineno % 50 == 0)
97 io_info_msg ("Line %d", lineno);
98 #endif
99 if ((ptr = (char *)index (cbuf, '\n')))
100 *ptr = '\0';
101
102 ptr = cbuf;
103 switch (*ptr)
104 {
105 case '#': /* comment line -- ignored */
106 break;
107 case '%': /* Font or pixel size data. */
108 ptr++;
109 switch (*ptr) {
110 case 'F': /* %F font-name */
111 if (fnt_map_size == fnt_map_alloc)
112 {
113 fnt_map_alloc = (fnt_map_alloc + 1) * 2;
114 fnt_map =
115 ((struct font_memo **)
116 ck_remalloc
117 (fnt_map, fnt_map_alloc * sizeof (struct font_memo *)));
118 }
119 fnt_map[fnt_map_size++] = parsed_matching_font (ptr + 1);
120 break;
121 case 'f': /* %f range font-name */
122 {
123 struct rng rng;
124 /* This field only occurs in files written by 1.1
125 * oleo. It's presense indicates that when parsing
126 * format fields, we should *not* reset cell fonts to 0.
127 */
128 font_spec_in_format = 0;
129 ++ptr;
130 while (isspace (*ptr))
131 ++ptr;
132 if (!parse_cell_or_range (&ptr, &rng))
133 goto bad_field;
134 while (isspace (*ptr))
135 ++ptr;
136 {
137 struct font_memo * fm = parsed_matching_font (ptr);
138 set_region_font (&rng, fm->names->oleo_name, fm->scale);
139 }
140 break;
141 }
142 default: /* % with something invalid */
143 goto bad_field;
144 }
145 break;
146 case 'F': /* Format field */
147 vlen = 0;
148 ptr++;
149 fnt = 0; /* The font must be explicitly overriden for a cell. */
150 while (*ptr)
151 {
152 if (*ptr != ';')
153 goto bad_field;
154 ptr++;
155 switch (*ptr++) {
156 int clo, chi, cwid;
157 case 'C': /* Column from rows 1 to 255 */
158 czcol = astol (&ptr);
159 vlen = 2;
160 break;
161
162 case 'D': /* Default format */
163 switch (*ptr++)
164 {
165 case 'G':
166 default_fmt = FMT_GEN;
167 break;
168 case 'E':
169 default_fmt = FMT_EXP;
170 break;
171 case 'F':
172 default_fmt = FMT_FXT;
173 break;
174 case '$':
175 default_fmt = FMT_DOL;
176 break;
177 case '*': /* * format implemented as +- format */
178 default_fmt = FMT_GPH;
179 break;
180 case ',': /* JF */
181 default_fmt = FMT_CMA;
182 break;
183 case 'U':
184 default_fmt = FMT_USR;
185 break;
186 case '%':
187 default_fmt = FMT_PCT;
188 break;
189 case 'H':
190 default_fmt = FMT_HID;
191 break;
192 case 'd': /* Date */
193 default_fmt = FMT_DATE;
194 break;
195 /* End of JF */
196 default:
197 io_error_msg ("Line %d: format %c not supported", lineno, ptr[-1]);
198 break;
199 }
200 if (*ptr == 'F')
201 {
202 prc = default_prc = FLOAT_PRECISION;
203 ptr++;
204 }
205 else
206 default_prc = prc = astol (&ptr);
207
208 switch (*ptr++)
209 {
210 case 'C':
211 default_jst = JST_CNT;
212 break;
213 case 'L':
214 default_jst = JST_LFT;
215 break;
216 case 'R':
217 default_jst = JST_RGT;
218 break;
219 case 'G': /* General format not supported */
220 default:
221 io_error_msg ("Line %d: Alignment %c not supported", lineno, ptr[-1]);
222 break;
223 }
224 default_width = astol (&ptr);
225 break;
226
227 case 'f': /* Font specification */
228 {
229 int id;
230 id = astol(&ptr);
231 if (id < 0 || id >= fnt_map_size)
232 {
233 io_error_msg ("Line %d: Undefined font (%d)\n",
234 lineno, id);
235 break;
236 }
237 fnt = fnt_map[id];
238 break;
239 }
240
241 case 'F':
242 switch (*ptr++)
243 {
244 case 'D':
245 fmt = FMT_DEF;
246 break;
247 case 'G':
248 fmt = FMT_GEN;
249 break;
250 case 'E':
251 fmt = FMT_EXP;
252 break;
253 case 'F':
254 fmt = FMT_FXT;
255 break;
256 case '$':
257 fmt = FMT_DOL;
258 break;
259 case '*': /* JF implemented as +- format */
260 fmt = FMT_GPH;
261 break;
262 case ',': /* JF */
263 fmt = FMT_CMA;
264 break;
265 case 'U':
266 fmt = FMT_USR;
267 break;
268 case '%':
269 fmt = FMT_PCT;
270 break;
271 case 'H':
272 fmt = FMT_HID;
273 break; /* END of JF */
274 case 'd':
275 fmt = FMT_DATE;
276 break;
277 case 'C':
278 default:
279 io_error_msg ("Line %d: format %c not supported", lineno, ptr[-1]);
280 fmt = FMT_DEF;
281 break;
282 }
283 if (*ptr == 'F') {
284 prc = FLOAT_PRECISION;
285 ptr++;
286 } else {
287 prc = astol(&ptr);
288 }
289 switch (*ptr++)
290 {
291 case 'C':
292 jst = JST_CNT;
293 break;
294 case 'L':
295 jst = JST_LFT;
296 break;
297 case 'R':
298 jst = JST_RGT;
299 break;
300 case 'D':
301 jst = JST_DEF;
302 break;
303 default:
304 io_error_msg ("Line %d: Alignment %c not supported", lineno, ptr[-1]);
305 jst = JST_DEF;
306 break;
307 }
308 vlen = 1;
309 break;
310 case 'R': /* Row from cols 1 to 63 */
311 czrow = astol (&ptr);
312 vlen = 4;
313 break;
314
315 case 'W': /* Width of clo to chi is cwid */
316 clo = astol (&ptr);
317 chi = astol (&ptr);
318 cwid = astol (&ptr) + 1;
319 for (; clo <= chi; clo++) {
320 set_width (clo, cwid);
321 }
322 break;
323
324 case 'H': /* JF: extension */
325 clo = astol (&ptr);
326 chi = astol (&ptr);
327 cwid = astol (&ptr) + 1;
328 for (; clo <= chi; clo++)
329 set_height (clo, cwid);
330 break;
331 case 'c':
332 ccol = astol (&ptr);
333 break;
334 case 'r':
335 crow = astol (&ptr);
336 break;
337
338 default:
339 goto bad_field;
340 }
341 }
342 switch (vlen)
343 {
344 case 1:
345 cp = find_or_make_cell (crow, ccol);
346 SET_FORMAT (cp, fmt);
347 SET_PRECISION(cp, prc);
348 SET_JST (cp, jst);
349 if (font_spec_in_format)
350 cp->cell_font = fnt;
351 break;
352 case 2:
353 rng.lr = MIN_ROW;
354 rng.lc = czcol;
355 rng.hr = mx_row;
356 rng.hc = czcol;
357 make_cells_in_range (&rng);
358 while ((cp = next_cell_in_range ()))
359 {
360 SET_FORMAT (cp, fmt);
361 SET_PRECISION(cp, prc);
362 SET_JST (cp, jst);
363 if (font_spec_in_format)
364 cp->cell_font = fnt;
365 }
366 break;
367 case 4:
368 rng.lr = czrow;
369 rng.lc = MIN_COL;
370 rng.hr = czrow;
371 rng.hc = mx_col;
372 make_cells_in_range (&rng);
373 while ((cp = next_cell_in_range ()))
374 {
375 SET_FORMAT (cp, fmt);
376 SET_JST (cp, jst);
377 if (font_spec_in_format)
378 cp->cell_font = fnt;
379 }
380 break;
381 default:
382 break;
383 }
384 break;
385
386 case 'B': /* Boundry field, ignored */
387 ptr++;
388 while (*ptr)
389 {
390 if (*ptr != ';')
391 goto bad_field;
392 ptr++;
393 switch (*ptr++)
394 {
395 case 'c':
396 mx_col = astol (&ptr);
397 if (mx_col > MAX_COL)
398 {
399 io_error_msg ("Boundry column %lu too large!", mx_col);
400 mx_col = MAX_COL;
401 }
402 break;
403 case 'r':
404 mx_row = astol (&ptr);
405 if (mx_row > MAX_ROW)
406 {
407 io_error_msg ("Boundry row %lu too large!", mx_row);
408 mx_row = MAX_ROW;
409 }
410 break;
411 default:
412 goto bad_field;
413 }
414 }
415 break;
416
417 case 'N': /* A Name field */
418 if (ptr[1] != 'N')
419 goto bad_field;
420 ptr += 2;
421 vname = 0;
422 vval = 0;
423 while (*ptr)
424 {
425 if (*ptr != ';')
426 goto bad_field;
427 *ptr++ = '\0';
428 switch (*ptr++)
429 {
430 case 'N': /* Name is */
431 vname = ptr;
432 while (*ptr && *ptr != ';')
433 ptr++;
434 vlen = ptr - vname;
435 break;
436 case 'E': /* Expression is */
437 vval = ptr;
438 while (*ptr && *ptr != ';')
439 ptr++;
440 break;
441 default:
442 --ptr;
443 goto bad_field;
444 }
445 }
446 if (!vname || !vval)
447 goto bad_field;
448 *ptr = '\0';
449 ptr = old_new_var_value (vname, vlen, vval);
450 if (ptr)
451 io_error_msg ("Line %d: Couldn't set %.*s to %s: %s", lineno, vlen, vname, vval, ptr);
452 break;
453
454 case 'C': /* A Cell entry */
455 cprot = 0;
456 cval = 0;
457 cexp = 0;
458 cval = 0;
459 ptr++;
460 while (*ptr)
461 {
462 int quotes;
463
464 if (*ptr != ';')
465 goto bad_field;
466 *ptr++ = '\0';
467 switch (*ptr++)
468 {
469 case 'c':
470 ccol = astol (&ptr);
471 break;
472 case 'r':
473 crow = astol (&ptr);
474 break;
475 case 'R':
476 czrow = astol (&ptr);
477 break;
478 case 'C':
479 czcol = astol (&ptr);
480 break;
481 case 'P': /* This cell is Protected */
482 cprot++;
483 break;
484 case 'K': /* This cell's Konstant value */
485 cval = ptr;
486 quotes = 0;
487 while (*ptr && (*ptr != ';' || quotes > 0))
488 if (*ptr++ == '"')
489 quotes = !quotes;
490 break;
491 case 'E': /* This cell's Expression */
492 cexp = ptr;
493 quotes = 0;
494 while (*ptr && (*ptr != ';' || quotes > 0))
495 if (*ptr++ == '"')
496 quotes = !quotes;
497
498 break;
499 case 'G':
500 strcpy (expbuf, cval);
501 break;
502 case 'D':
503 strcpy (expbuf, cexp);
504 break;
505 case 'S':
506 cexp = expbuf;
507 break;
508 default:
509 --ptr;
510 goto bad_field;
511 }
512 }
513 *ptr = '\0';
514 if (cexp && cval && strcmp (cexp, cval))
515 {
516 ptr = read_new_value (crow, ccol, cexp, cval);
517 if (ptr)
518 {
519 io_error_msg ("Line %d: %d,%d: Read '%s' %s", lineno, crow, ccol, cexp, ptr);
520 break;
521 }
522 }
523 else if (cval)
524 {
525 ptr = read_new_value (crow, ccol, 0, cval);
526 if (ptr)
527 {
528 io_error_msg ("Line %d: %d,%d: Val '%s' %s", lineno, crow, ccol, cexp, ptr);
529 break;
530 }
531 }
532 else if (cexp)
533 {
534 ptr = read_new_value (crow, ccol, cexp, 0);
535 if (ptr)
536 {
537 io_error_msg ("Line %d: %d,%d: Exp '%s' %s", lineno, crow, ccol, cexp, ptr);
538 break;
539 }
540 }
541 if (cprot)
542 SET_LCK (find_or_make_cell (crow, ccol), LCK_LCK);
543 if (ismerge)
544 push_cell (crow, ccol);
545 /* ... */
546 break;
547 case 'E': /* End of input ?? */
548 break;
549 case 'W':
550 io_read_window_config (ptr + 2);
551 break;
552 case 'U':
553 /* JF extension: read user-defined formats */
554 read_mp_usr_fmt (ptr + 1);
555 break;
556 /* JF extension: read uset-settable options */
557 case 'O':
558 Global->a0 = next_a0;
559 read_mp_options (ptr + 2);
560 next_a0 = Global->a0;
561 Global->a0 = 0;
562 break;
563 case 'G': /* Graph data */
564 /* fprintf(stderr, "Graph input line '%s'\n", cbuf); */
565 switch (*(ptr+1)) {
566 case 'T': /* Graph Title */
567 graph_set_title(cbuf+2);
568 break;
569 case 'D': /* Axis title : GDxtitle */
570 graph_set_axis_title(cbuf[2], cbuf+3);
571 break;
572 case 't': /* Graph data title : Gtxtitle */
573 graph_set_data_title(cbuf[2] - '0', cbuf+3);
574 break;
575 case 'a': /* Automatic axis setting : Gax0 or Gax1 */
576 graph_set_axis_auto(cbuf[2] - '0', cbuf[3] == '1');
577 break;
578 case 'o': /* Whether to draw line to offscreen data points */
579 graph_set_linetooffscreen(cbuf[2] == '1');
580 break;
581 case 'r': /* Axis range : GrxlVALUE , l = 0 for low, 1 for high */
582 if (cbuf[3] == '0')
583 graph_set_axis_lo('x' + cbuf[2] - '0', &cbuf[4]);
584 else if (cbuf[3] == '1')
585 graph_set_axis_hi('x' + cbuf[2] - '0', &cbuf[4]);
586 break;
587 case 'L': /* Axis logness GLx0 or GLx1 */
588 graph_set_logness(cbuf[2], 1, cbuf[3] == '1');
589 break;
590 case '0': case '1': case '2': case '3':
591 case '4': case '5': case '6': case '7':
592 case '8': case '9':
593 {
594 int i, a, b, c, d;
595 struct rng r;
596 sscanf(cbuf, "G%d,%d,%d,%d,%d", &i, &a, &b, &c, &d);
597 r.lc = a;
598 r.lr = b;
599 r.hc = c;
600 r.hr = d;
601 graph_set_data(i, &r);
602 }
603 break;
604 case 'm': /* Tick marks Gmxts, x = 0 or 1, t = 0 .. 4 (the tick type),
605 * s is the format string, if any.
606 */
607 {
608 int axis, tp;
609
610 axis = cbuf[2] - '0';
611 tp = cbuf[3] - '0';
612
613 graph_set_axis_ticks(axis, tp, strdup(&cbuf[4]));
614 }
615 break;
616 default:
617 fprintf(stderr, "Graph: invalid line '%s'\n", cbuf);
618 }
619 break;
620 case 'D': /* Database Access */
621 ptr++;
622 switch (*ptr) {
623 case 'u':
624 DatabaseSetUser(ptr+1);
625 break;
626 case 'h':
627 DatabaseSetHost(ptr+1);
628 break;
629 case 'n':
630 DatabaseSetName(ptr+1);
631 break;
632 default:
633 io_error_msg("Line %d - unknown code %s\n", lineno, cbuf);
634 }
635 break;
636 default:
637 bad_field:
638 Global->a0 = old_a0;
639 if (!ismerge)
640 clear_spreadsheet ();
641 io_recenter_all_win ();
642 io_error_msg ("Line %d: Unknown OLEO line \"%s\"", lineno, cbuf);
643 Global->return_from_error = 0;
644 return;
645 } /* End of switch */
646 }
647 if (!feof (fp)) {
648 if (!ismerge)
649 clear_spreadsheet ();
650 io_recenter_all_win ();
651 io_error_msg ("read-file: read-error near line %d.", lineno);
652 Global->return_from_error = 0;
653 return;
654 }
655 Global->a0 = next_a0;
656 io_recenter_all_win ();
657
658 Global->return_from_error = 0;
659 }
660
661 static char *
oleo_fmt_to_str(int f1,int p1)662 oleo_fmt_to_str (int f1, int p1)
663 {
664 static char p_buf[40];
665
666 p_buf[1] = '\0';
667 switch (f1)
668 {
669 case FMT_DEF:
670 p_buf[0] = 'D';
671 break;
672 case FMT_HID:
673 p_buf[0] = 'H';
674 break;
675 case FMT_GPH:
676 p_buf[0] = '*';
677 break;
678 default:
679 if (p1 == FLOAT_PRECISION)
680 {
681 p_buf[1] = 'F';
682 p_buf[2] = '\0';
683 }
684 else
685 sprintf (&p_buf[1], "%d", p1);
686
687 switch (f1)
688 {
689 case FMT_USR:
690 p_buf[0] = 'U';
691 break;
692 case FMT_GEN:
693 p_buf[0] = 'G';
694 break;
695 case FMT_DOL:
696 p_buf[0] = '$';
697 break;
698 case FMT_PCT:
699 p_buf[0] = '%';
700 break;
701 case FMT_FXT:
702 p_buf[0] = 'F';
703 break;
704 case FMT_CMA:
705 p_buf[0] = ',';
706 break;
707 case FMT_EXP:
708 p_buf[0] = 'E';
709 break;
710 case FMT_DATE:
711 p_buf[0] = 'd';
712 break;
713 default:
714 p_buf[0] = '?';
715 #if 0
716 fprintf(stderr, "OleoWrite: format %d not supported\n", f1);
717 #endif
718 break;
719 }
720 break;
721 }
722 return p_buf;
723 }
724
725 static char
jst_to_chr(just)726 jst_to_chr (just)
727 int just;
728 {
729 switch (just)
730 {
731 case JST_DEF:
732 return 'D';
733 case JST_LFT:
734 return 'L';
735 case JST_RGT:
736 return 'R';
737 case JST_CNT:
738 return 'C';
739 default:
740 return '?';
741 }
742 }
743
744 static FILE *oleo_fp;
745 static struct rng *oleo_rng;
746
747 static void
oleo_write_var(name,var)748 oleo_write_var (name, var)
749 char *name;
750 struct var *var;
751 {
752 if (var->var_flags == VAR_UNDEF
753 && (!var->var_ref_fm || var->var_ref_fm->refs_used == 0))
754 return;
755
756 switch (var->var_flags) {
757 case VAR_UNDEF:
758 break;
759 case VAR_CELL:
760 if (var->v_rng.lr >= oleo_rng->lr && var->v_rng.lr <= oleo_rng->hr
761 && var->v_rng.lc >= oleo_rng->lc && var->v_rng.lc <= oleo_rng->hc)
762 (void) fprintf(oleo_fp, "NN;N%s;E%s\n",
763 var->var_name, cell_name(var->v_rng.lr, var->v_rng.lc));
764 break;
765 case VAR_RANGE:
766 if (var->v_rng.lr < oleo_rng->lr || var->v_rng.hr > oleo_rng->hr
767 || var->v_rng.lc < oleo_rng->lc || var->v_rng.hc > oleo_rng->hc)
768 break;
769
770 (void) fprintf(oleo_fp, "NN;N%s;E%s\n", var->var_name, range_name (&(var->v_rng)));
771 break;
772 #ifdef TEST
773 default:
774 panic ("Unknown var type %d", var->var_flags);
775 #endif
776 }
777 }
778
779 static void
write_mp_windows(fp)780 write_mp_windows (fp)
781 FILE *fp;
782 {
783 struct line line;
784
785 line.alloc = 0;
786 line.buf = 0;
787 io_write_window_config (&line);
788 fputs (line.buf, fp);
789 free (line.buf);
790 }
791
792 void
oleo_write_file(fp,rng)793 oleo_write_file (fp, rng)
794 FILE *fp;
795 struct rng *rng;
796 {
797 CELLREF r, c;
798 CELL *cp;
799 CELLREF crow = 0, ccol = 0;
800 unsigned short w;
801 /* struct var *var; */
802 int old_a0, i, fnt_map_size = 0;
803 char *s;
804
805 (void) fprintf (fp, "# This file was created by GNU Oleo\n");
806
807 /* All versions of the oleo file format should have a
808 * version cookie on the second line.
809 */
810 (void) fprintf (fp, "# format 2.1 (requires Oleo 1.99.9 or higher)\n");
811
812 /* If no range given, write the entire file */
813 if (!rng)
814 {
815 int n;
816 int fmts;
817 char *data[9];
818
819 rng = &all_rng;
820
821 (void) fprintf (fp, "F;D%s%c%u\n",
822 oleo_fmt_to_str (default_fmt, default_prc),
823 jst_to_chr (default_jst),
824 default_width);
825
826 fmts = usr_set_fmts ();
827 for (n = 0; n < 16; n++)
828 {
829 if (fmts & (1 << n))
830 {
831 get_usr_stats (n, data);
832 fprintf (fp, "U;N%u;P%s;S%s", n + 1, data[7], data[8]);
833 if (data[0][0])
834 fprintf (fp, ";HP%s", data[0]);
835 if (data[1][0])
836 fprintf (fp, ";HN%s", data[1]);
837 if (data[2][0])
838 fprintf (fp, ";TP%s", data[2]);
839 if (data[3][0])
840 fprintf (fp, ";TN%s", data[3]);
841 if (data[4][0])
842 fprintf (fp, ";Z%s", data[4]);
843 if (data[5][0])
844 fprintf (fp, ";C%s", data[5]);
845 if (data[6])
846 fprintf (fp, ";D%s", data[6]);
847 putc ('\n', fp);
848 }
849 }
850 write_mp_options (fp);
851 }
852
853 old_a0 = Global->a0;
854 Global->a0 = 0;
855
856 find_widths (rng->lc, rng->hc);
857 w = next_width (&c);
858 while (w)
859 {
860 CELLREF cc, ccc;
861 unsigned short ww;
862 cc = c;
863 do
864 ww = next_width (&ccc);
865 while (ccc == ++cc && ww == w);
866 (void) fprintf (fp, "F;W%u %u %u\n", c, cc - 1, w - 1);
867 c = ccc;
868 w = ww;
869 }
870
871 find_heights (rng->lr, rng->hr);
872 w = next_height (&r);
873 while (w)
874 {
875 CELLREF rr, rrr;
876 unsigned short ww;
877
878 rr = r;
879 do
880 ww = next_height (&rrr);
881 while (rrr == ++rr && ww == w);
882 (void) fprintf (fp, "F;H%u %u %u\n", r, rr - 1, w - 1);
883 r = rrr;
884 w = ww;
885 }
886
887 oleo_fp = fp;
888 oleo_rng = rng;
889 for_all_vars (oleo_write_var);
890 find_cells_in_range (rng);
891
892 {
893 struct font_memo * fm;
894 for (fm = font_list; fm; fm = fm->next)
895 fm->id_memo = -1;
896 }
897 while ((cp = next_row_col_in_range (&r, &c)))
898 {
899 char *ptr;
900 int f1, j1;
901 char p_buf[40];
902
903 f1 = GET_FORMAT (cp);
904 j1 = GET_JST (cp);
905 if (f1 != FMT_DEF || j1 != JST_DEF || cp->cell_font)
906 {
907 if (cp->cell_font)
908 {
909 if (cp->cell_font->id_memo < 0)
910 {
911 cp->cell_font->id_memo = fnt_map_size++;
912 if (isnan(cp->cell_font->scale))
913 fprintf (fp, "%%F%s,%s,%f\n",
914 cp->cell_font->names->x_name,
915 cp->cell_font->names->ps_name,
916 cp->cell_font->scale);
917 else
918 fprintf (fp, "%%F%s,%s,%f\n",
919 cp->cell_font->names->x_name,
920 cp->cell_font->names->ps_name,
921 1.0);
922 }
923 }
924 (void) fprintf (fp, "F;");
925 if (c != ccol)
926 {
927 (void) fprintf (fp, "c%u;", c);
928 ccol = c;
929 }
930 if (r != crow)
931 {
932 (void) fprintf (fp, "r%u;", r);
933 crow = r;
934 }
935 if (cp->cell_font)
936 (void) fprintf (fp, "f%d;", cp->cell_font->id_memo);
937 (void) fprintf (fp, "F%s%c\n",
938 oleo_fmt_to_str (f1, GET_PRECISION(cp)), jst_to_chr (j1));
939 }
940
941 if (!GET_TYP (cp) && !cp->cell_formula)
942 continue;
943
944 (void) fprintf (fp, "C;");
945 if (c != ccol)
946 {
947 (void) fprintf (fp, "c%u;", c);
948 ccol = c;
949 }
950 if (r != crow)
951 {
952 (void) fprintf (fp, "r%u;", r);
953 crow = r;
954 }
955
956 if (cp->cell_formula)
957 {
958 (void) fprintf (fp, "E%s", decomp(r, c, cp));
959 decomp_free();
960 }
961
962 switch (GET_TYP (cp))
963 {
964 case 0:
965 ptr = 0;
966 break;
967 case TYP_STR:
968 ptr = 0;
969 if (cp->cell_formula)
970 putc (';', fp);
971 (void) fprintf (fp, "K\"%s\"", cp->cell_str);
972 break;
973 case TYP_FLT:
974 ptr = flt_to_str (cp->cell_flt);
975 break;
976 case TYP_INT:
977 sprintf (p_buf, "%ld", cp->cell_int);
978 ptr = p_buf;
979 break;
980 case TYP_BOL:
981 ptr = bname[cp->cell_bol];
982 break;
983 case TYP_ERR:
984 ptr = ename[cp->cell_err];
985 break;
986 default:
987 ptr = 0;
988 #ifdef TEST
989 panic ("What cell type %d", GET_TYP (cp));
990 #endif
991 }
992
993 if (ptr)
994 {
995 if (cp->cell_formula)
996 putc (';', fp);
997 (void) fprintf (fp, "K%s", ptr);
998 }
999 if (GET_LCK (cp) == LCK_LCK)
1000 (void) fprintf (fp, ";P");
1001
1002 putc ('\n', fp);
1003 }
1004
1005 if (rng == &all_rng)
1006 write_mp_windows (fp);
1007
1008 /* Graphs */
1009 for (i=0; i<NUM_DATASETS; i++) {
1010 struct rng r;
1011 int a, b, c, d;
1012
1013 r = graph_get_data(i);
1014 if (r.lc == 0 && r.lr == 0 && r.hc == 0 && r.hr == 0)
1015 continue;
1016
1017 /* Write this thing */
1018 a = r.lc;
1019 b = r.lr;
1020 c = r.hc;
1021 d = r.hr;
1022 fprintf(fp, "G%d,%d,%d,%d,%d\n", i, a, b, c, d);
1023 }
1024 /* Graph title */
1025 s = graph_get_title();
1026 if (s && strlen(s)) {
1027 fprintf(fp, "GT%s\n", s);
1028 }
1029
1030 s = graph_get_axis_title('x');
1031 if (s && strlen(s)) {
1032 fprintf(fp, "GDx%s\n", s);
1033 }
1034
1035 s = graph_get_axis_title('y');
1036 if (s && strlen(s)) {
1037 fprintf(fp, "GDy%s\n", s);
1038 }
1039
1040 for (i=0; i<NUM_DATASETS; i++) {
1041 if (graph_get_data_title(i))
1042 fprintf(fp, "Gt%c%s\n", i + '0', graph_get_data_title(i));
1043 }
1044
1045 /* Axis range : GrxlVALUE , l = 0 for low, 1 for high */
1046 for (i=0; i< 2; i++) {
1047 double d;
1048 d = graph_get_axis_lo(i);
1049 if (! isnan(d))
1050 fprintf(fp, "Gr%c0%f\n", '0' + i, d);
1051 d = graph_get_axis_hi(i);
1052 if (! isnan(d))
1053 fprintf(fp, "Gr%c1%f\n", '0' + i, d);
1054 }
1055
1056 /* Automatic axis setting : Gax0 or Gax1 */
1057 fprintf(fp, "Ga0%c\n", graph_get_axis_auto(0) ? '1' : '0'); /* X axis */
1058 fprintf(fp, "Ga1%c\n", graph_get_axis_auto(1) ? '1' : '0'); /* Y axis */
1059
1060 /* Draw line to offscreen data points */
1061 fprintf(fp, "Go%c\n", graph_get_linetooffscreen() ? '1' : '0');
1062
1063 /* Axis tick marks */
1064 fprintf(fp, "Gm0%c%s\n",
1065 '0' + graph_get_axis_ticktype(0),
1066 graph_get_axis_tickformat(0) ? graph_get_axis_tickformat(0) : "(null)");
1067 fprintf(fp, "Gm1%c%s\n",
1068 '0' + graph_get_axis_ticktype(1),
1069 graph_get_axis_tickformat(1) ? graph_get_axis_tickformat(1) : "(null)");
1070
1071 /* Database stuff */
1072 if (DatabaseInitialised()) {
1073 fprintf(fp, "Dn%s\n", DatabaseGetName() ? DatabaseGetName() : "");
1074 fprintf(fp, "Dh%s\n", DatabaseGetHost() ? DatabaseGetHost() : "");
1075 fprintf(fp, "Du%s\n", DatabaseGetUser() ? DatabaseGetUser() : "");
1076 }
1077
1078 /* End of writing */
1079 (void) fprintf (fp, "E\n");
1080 Global->a0 = old_a0;
1081 }
1082
1083 int
oleo_set_options(set_opt,option)1084 oleo_set_options
1085 (set_opt, option)
1086 int set_opt;
1087 char *option;
1088 {
1089 return -1;
1090 }
1091
1092 void
oleo_show_options()1093 oleo_show_options ()
1094 {
1095 io_text_line ("File format: oleo.");
1096 }
1097
1098
1099 #if 0
1100 This was used in releases 1.0 and 1.1 to write fonts.
1101 It is no longer used but is kept here for reference since 1.2 and later
1102 versions should continue to understand the older file format for a while.
1103
1104 static int
1105 oleo_write_fonts (rng, font, ignore)
1106 struct rng *rng;
1107 struct font_memo *font;
1108 void *ignore;
1109 {
1110 struct rng r;
1111 char *rname;
1112 r = *rng;
1113 if (r.lr < oleo_rng->lr)
1114 r.lr = oleo_rng->lr;
1115 if (r.lc < oleo_rng->lc)
1116 r.lc = oleo_rng->lc;
1117 if (r.hr > oleo_rng->hr)
1118 r.hr = oleo_rng->hr;
1119 if (r.hc > oleo_rng->hc)
1120 r.hc = oleo_rng->hc;
1121 rname = range_name (&r);
1122 fprintf (oleo_fp, "%%f %s %s,%s,%f\n",
1123 rname, font->name, font->psname, font->scale);
1124 return 1;
1125 }
1126
1127
1128 #endif
1129
1130