1 /********************************************************************
2 This file is part of the abs 0.907 distribution. abs is a spreadsheet
3 with graphical user interface.
4
5 Copyright (C) 1998-2001 Andr� Bertin (Andre.Bertin@ping.be)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version if in the same spirit as version 2.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 Concact: abs@pi.be
22 http://home.pi.be/bertin/abs.shtml
23
24 *********************************************************************/
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #include "cell.h"
52 #include "worksheet.h"
53 #include "workbook.h"
54 #include "style.h"
55 #include "y.tab.h"
56 #include "memory.h"
57 #include "date.h"
58 #include "cell_vb.h"
59 #include "gram_ext.h"
60 #include "application.h"
61
62 #include <string.h>
63
64
65 static int updating = 0;
66 static int parsing = 0;
67 static int setting_formula = 0;
68 static int ncell = 0;
69 static int parsingmacro;
70
71 static Cell **toredraw = NULL;
72 static int ntoredraw = 0;
73
74
75
76
77
78 static char tmpbuf[256];
79
80 Cell *ActiveCell;
81
82 Cell *
cell_activate(Cell * cell)83 cell_activate (Cell * cell)
84 {
85 ActiveCell = cell;
86 if (ActiveWorksheet != NULL)
87 {
88 ActiveWorksheet->activecell = cell;
89 if (ActiveWorksheet->cur_r != cell->r && ActiveWorksheet->cur_c != cell->c)
90 worksheet_setcursor (ActiveWorksheet, cell->r, cell->c);
91 }
92 return ActiveCell;
93 }
94
95 Cell *
newcell(r,c)96 newcell (r, c)
97 int r, c;
98 {
99 Cell *nc;
100 nc = (Cell *) absmalloc (sizeof (Cell), "newcell:Cell ");
101 if (nc == NULL)
102 {
103 fprintf (stderr, "Cell: not allocated!");
104 return NULL;
105 }
106
107 nc->val.rec.d = 0.0;
108 nc->val.type = DOUBLE;
109 nc->formula = NULL;
110
111 nc->style = NULL;
112 nc->r = r;
113 nc->c = c;
114
115 nc->familly = NULL;
116 nc->worksheet = ActiveWorksheet;
117 nc->tree = NULL;
118
119
120 nc->type = undef;
121
122 nc->objnum = ncell++;
123
124 return nc;
125 }
126
127 int
clear_cell(Cell * cell)128 clear_cell (Cell * cell)
129 {
130 if (cell == NULL)
131 return 1;
132
133
134
135
136 if (cell->val.type == STRING_CONSTANT && cell->val.rec.s != cell->formula + 1)
137 if (cell->val.rec.s != NULL)
138 absfree (cell->val.rec.s, "freecell:cell->val.rec.s ");
139
140 if (cell->formula != NULL)
141 absfree (cell->formula, "freecell:cell->formula ");
142 if (cell->tree != NULL)
143 {
144 freenode (cell->tree);
145 cell->tree = NULL;
146 }
147 if (cell->style != NULL)
148 {
149 freestyle (cell->style);
150 cell->style = NULL;
151 }
152 cell->val.rec.d = 0.0;
153 cell->val.type = DOUBLE;
154 cell->formula = NULL;
155
156 cell_isnew (cell);
157 nupdate2 (cell, 1);
158
159 cell->type = undef;
160 return 0;
161 }
162 int
freecell(cell)163 freecell (cell)
164 Cell *cell;
165 {
166 if (cell == NULL)
167 return 1;
168
169
170
171
172 if (cell->val.type == STRING_CONSTANT && cell->val.rec.s != cell->formula + 1)
173 if (cell->val.rec.s != NULL)
174 absfree (cell->val.rec.s, "freecell:cell->val.rec.s ");
175
176 if (cell->formula != NULL)
177 absfree (cell->formula, "freecell:cell->formula ");
178 if (cell->tree != NULL)
179 {
180 freenode (cell->tree);
181 cell->tree = NULL;
182 }
183 if (cell->style != NULL)
184 {
185 freestyle (cell->style);
186 cell->style = NULL;
187 }
188 absfree (cell, "freecell:cell ");
189
190 return 0;
191 }
192
193
194 int
cell_write(cell,fp)195 cell_write (cell, fp)
196 Cell *cell;
197 FILE *fp;
198 {
199
200 int deci, format;
201 char *end = NULL;
202 char chr[2];
203 int len = 0;
204 int i;
205
206 if (cell == NULL)
207 return -1;
208
209 if (cell->type == constant)
210 {
211 fprintf (fp, "absnc(%d,%d,\"", cell->r, cell->c);
212 fprintf (fp, "%g", cell_getvalue (cell));
213 fprintf (fp, "\")\n");
214 }
215 else if (cell->type == text || cell->type == formula)
216 {
217 fprintf (fp, "absnc(%d,%d,\"", cell->r, cell->c);
218 if (cell->formula != NULL)
219 {
220 chr[1] = '\0';
221 end = strchr (cell->formula, '\n');
222 if (end != NULL)
223 end[0] = '\0';
224 len = strlen (cell->formula);
225
226
227
228 if (cell->formula[0] != '\'' && cell->formula[0] != '-'
229 && cell->formula[0] != '=' && cell->formula[0] != '+'
230 && !('0' <= cell->formula[0] && cell->formula[0] <= '9'))
231 fprintf (fp, "=");
232
233 for (i = 0; i < len; i++)
234 {
235 if (cell->formula[i] == '\"')
236 fprintf (fp, "\"");
237 chr[0] = cell->formula[i];
238 fprintf (fp, "%s", chr);
239 }
240 fprintf (fp, "\")\n");
241 }
242 }
243
244 if (cell->style != NULL)
245 {
246 if (getstyle (cell->style, STY_BORDER_TOP) &&
247 getstyle (cell->style, STY_BORDER_BOT) &&
248 getstyle (cell->style, STY_BORDER_RIG) &&
249 getstyle (cell->style, STY_BORDER_LEF)
250 )
251 {
252 fprintf (fp, "Cells(%d,%d).Borders.LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
253 }
254 else
255 {
256 if (getstyle (cell->style, STY_BORDER_TOP))
257 fprintf (fp, "Cells(%d,%d).Borders(xlEdgeTop).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
258 if (getstyle (cell->style, STY_BORDER_BOT))
259 fprintf (fp, "Cells(%d,%d).Borders(xlEdgeBottom).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
260 if (getstyle (cell->style, STY_BORDER_RIG))
261 fprintf (fp, "Cells(%d,%d).Borders(xlEdgeRight).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
262 if (getstyle (cell->style, STY_BORDER_LEF))
263 fprintf (fp, "Cells(%d,%d).Borders(xlEdgeLeft).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
264 }
265
266
267 if (getstyle (cell->style, STY_FONT) != getstyle (ActiveWorkbook->style, STY_FONT))
268 switch (getstyle (cell->style, STY_FONT))
269 {
270 case 0:
271 fprintf (fp, "Cells(%d,%d).Font.Name = \"Fixed\"\n", cell->r, cell->c);
272 break;
273 case 1:
274 fprintf (fp, "Cells(%d,%d).Font.Name = \"Courier\"\n", cell->r, cell->c);
275 break;
276 case 2:
277 fprintf (fp, "Cells(%d,%d).Font.Name = \"Helvetica\"\n", cell->r, cell->c);
278 break;
279 case 3:
280 fprintf (fp, "Cells(%d,%d).Font.Name = \"Times\"\n", cell->r, cell->c);
281 break;
282 case 4:
283 fprintf (fp, "Cells(%d,%d).Font.Name = \"Symbol\"\n", cell->r, cell->c);
284 break;
285 }
286
287 if (getstyle (cell->style, STY_FONTS) != getstyle (ActiveWorkbook->style, STY_FONTS))
288 switch (getstyle (cell->style, STY_FONTS))
289 {
290 case 0:
291 fprintf (fp, "Cells(%d,%d).Font.Size = 6\n", cell->r, cell->c);
292 break;
293 case 1:
294 fprintf (fp, "Cells(%d,%d).Font.Size = 8\n", cell->r, cell->c);
295 break;
296 case 2:
297 fprintf (fp, "Cells(%d,%d).Font.Size = 10\n", cell->r, cell->c);
298 break;
299 case 3:
300 fprintf (fp, "Cells(%d,%d).Font.Size = 12\n", cell->r, cell->c);
301 break;
302 case 4:
303 fprintf (fp, "Cells(%d,%d).Font.Size = 14\n", cell->r, cell->c);
304 break;
305 case 5:
306 fprintf (fp, "Cells(%d,%d).Font.Size = 18\n", cell->r, cell->c);
307 break;
308 case 6:
309 fprintf (fp, "Cells(%d,%d).Font.Size = 24\n", cell->r, cell->c);
310 break;
311 }
312 if (getstyle (cell->style, STY_FONTW) == 1 || getstyle (cell->style, STY_FONTW) == 3)
313 fprintf (fp, "Cells(%d,%d).Font.Bold = True \n", cell->r, cell->c);
314
315 if (getstyle (cell->style, STY_FONTW) == 2 || getstyle (cell->style, STY_FONTW) == 3)
316 fprintf (fp, "Cells(%d,%d).Font.Italic = True \n", cell->r, cell->c);
317
318
319 if (getstyle (cell->style, STY_JUSTIF) != getstyle (ActiveWorkbook->style, STY_JUSTIF))
320 switch (getstyle (cell->style, STY_JUSTIF))
321 {
322 case 0:
323 fprintf (fp, "Cells(%d,%d).HorizontalAlignment = xlLeft\n",
324 cell->r, cell->c);
325 break;
326 case 1:
327 fprintf (fp, "Cells(%d,%d).HorizontalAlignment = xlCenter\n",
328 cell->r, cell->c);
329 break;
330 case 2:
331 fprintf (fp, "Cells(%d,%d).HorizontalAlignment = xlRight\n",
332 cell->r, cell->c);
333 break;
334 }
335
336 if (getstyle (cell->style, STY_BG) != getstyle (ActiveWorkbook->style, STY_BG))
337 fprintf (fp, "Cells(%d,%d).Interior.ColorIndex = %d\n",
338 cell->r, cell->c, getstyle (cell->style, STY_BG) - 5);
339 if (getstyle (cell->style, STY_FG) != getstyle (ActiveWorkbook->style, STY_FG))
340 fprintf (fp, "Cells(%d,%d).Font.ColorIndex = %d\n",
341 cell->r, cell->c, getstyle (cell->style, STY_FG) - 5);
342
343
344 format = getstyle (cell->style, STY_FORMAT);
345 deci = getstyle (cell->style, STY_DECIMAL);
346 if ((format != getstyle (ActiveWorkbook->style, STY_FORMAT) ||
347 deci != getstyle (ActiveWorkbook->style, STY_DECIMAL)) &&
348 format != 0)
349 {
350 if (format >= 2 && format <= 4)
351 {
352 fprintf (fp, "Cells(%d,%d).NumberFormat = \"0", cell->r, cell->c);
353 if (deci)
354 fprintf (fp, ".");
355 while (deci > 0)
356 {
357 fprintf (fp, "0");
358 deci--;
359 };
360 }
361 switch (format)
362 {
363 case 2:
364 fprintf (fp, "\"\n");
365 break;
366 case 3:
367 fprintf (fp, "E+00\"\n");
368 break;
369 case 4:
370 fprintf (fp, "%%\"\n");
371 break;
372 case 5:
373 {
374 fprintf (fp, "Cells(%d,%d).NumberFormat = \"", cell->r, cell->c);
375 fprintf (fp, "dd/mm/yy\"\n");
376 break;
377 }
378 default:
379 fprintf (fp, "\"\n");
380 }
381 }
382
383
384 }
385 return 0;
386 }
387
388 int
cell_setnumberformat(cell,buf)389 cell_setnumberformat (cell, buf)
390 Cell *cell;
391 char *buf;
392 {
393
394
395 int deci = 0;
396 char *dot;
397 char *token;
398
399 if (strstr (buf, "General"))
400 return 0;
401
402 token = strchr (buf, ';');
403 if (token != NULL)
404 {
405 token[0] = '\0';
406 token++;
407 }
408
409 if (buf == NULL)
410 return 1;
411
412 if (strchr (buf, '/'))
413 {
414 cell_setformat (cell, 5, 0);
415 return 0;
416 }
417
418 dot = strchr (buf, '.');
419
420 if (dot != NULL)
421 while (dot[deci + 1] == '0' && deci < strlen (dot))
422 {
423 deci++;
424 }
425
426 if (strchr (buf, 'E') || strchr (buf, 'e'))
427 {
428 cell_setformat (cell, 3, deci);
429 }
430 else if (strchr (buf, '%'))
431 {
432 cell_setformat (cell, 4, deci);
433 }
434 else
435 {
436 cell_setformat (cell, 2, deci);
437 }
438
439 return 0;
440 }
441
442
443 int
cell_setformula(cell,str)444 cell_setformula (cell, str)
445 Cell *cell;
446 char *str;
447 {
448 int format, deci, date;
449
450 int ret;
451 int len;
452 int second = 0;
453 char *buf = NULL;
454
455
456 if (cell == NULL)
457 {
458 return 1;
459 }
460
461 if (cell->formula != NULL)
462 {
463 if (str != NULL)
464 if (strcmp (cell->formula, str) == 0)
465 return 1;
466
467 if (cell->val.type == STRING_CONSTANT &&
468 cell->val.rec.s == cell->formula + 1)
469 cell->val.rec.s = NULL;
470
471 absfree (cell->formula, "cell_setformula:cell->formula ");
472 cell->formula = NULL;
473 }
474
475 if (cell->tree != NULL)
476 {
477 freenode (cell->tree);
478 cell->tree = NULL;
479 };
480
481 cell_isnew (cell);
482
483 if (str == NULL)
484 {
485 cell->formula = NULL;
486 cell->val.rec.d = 0.0;
487 cell->val.type = DOUBLE;
488
489 cell->type = undef;
490 return -1;
491 };
492
493 while (str[0] == ' ' && str[0] != '\0' && str[0] != '\n')
494 str++;
495 len = strlen (str);
496 if (len < 1)
497 {
498 cell->formula = NULL;
499 cell->val.rec.d = 0.0;
500 cell->val.type = DOUBLE;
501
502 cell->type = undef;
503 return -1;
504 };
505
506 {
507 buf = (char *) absmalloc (sizeof (char) * (len + 3), "cell_setformula:buf");
508
509 if (len > 1)
510 if ('0' <= str[1] && str[1] <= '9')
511 {
512 second = 1;
513 }
514
515 if (str[0] == '=' ||
516 str[0] == '+' ||
517 str[0] == '-' ||
518 str[0] == '\'' ||
519 ('0' <= str[0] && str[0] <= '9') ||
520 (len > 1 && str[0] == '.' && second == 1)
521 )
522 {
523 strcpy (buf, str);
524 }
525 else
526 {
527 buf[0] = '\'';
528 strcpy (buf + 1, str);
529 }
530
531
532
533 cell->formula = (char *) absmalloc (sizeof (char) * (strlen (buf) + 5), "cell_setformula:cell->formula ");
534 if (cell->formula == NULL)
535 {
536 fprintf (stderr, "formula not allocated\n");
537 absfree (buf, "cell_setformula:buf");
538 return -2;
539 }
540
541
542 cell_getformat (cell, &format, &deci);
543 if (format == 5)
544 {
545 date = scandate (buf);
546 if (date)
547 sprintf (buf, "%d\n", date);
548 };
549
550 len = strlen (buf);
551 strcpy (cell->formula, buf);
552 cell->formula[len] = '\0';
553
554 if (strncmp (cell->formula, "'", 1) == 0)
555 {
556
557
558
559
560
561 cell->val.type = STRING_CONSTANT;
562 cell->val.rec.s = cell->formula + 1;
563
564 cell->type = text;
565 nupdate2 (cell, 1);
566 absfree (buf, "cell_setformula:buf");
567 return 1;
568 }
569 cell->type = constant;
570
571
572 ActiveCell = cell;
573 setting_formula = 1;
574
575
576 ret = parsecell (cell);
577
578
579 if (ret)
580 {
581 cell->val.type = STRING_CONSTANT;
582 cell->val.rec.s = "ERR!";
583
584 cell->type = text;
585 }
586 else
587 {
588 if (cell_is_constant (cell))
589 {
590 freenode (cell->tree);
591 cell->tree = NULL;
592 absfree (cell->formula, "cell_setformula:cell->formula ");
593 cell->formula = NULL;
594
595 }
596 else
597 {
598 execcelltree (cell);
599 cell->type = formula;
600 }
601 }
602
603 setting_formula = 0;
604 nupdate2 (cell, 1);
605 absfree (buf, "cell_setformula:buf");
606 return 0;
607 }
608 cell->formula = NULL;
609 cell->val.type = STRING_CONSTANT;
610 cell->val.rec.s = NULL;
611
612 cell->type = text;
613 absfree (buf, "cell_setformula:buf");
614 return 0;
615 }
616
617 int
cell_settext(cell,buf)618 cell_settext (cell, buf)
619 Cell *cell;
620 char *buf;
621 {
622 char *end;
623 char *first;
624
625
626
627
628 if (cell == NULL)
629 {
630 return 1;
631 }
632 if (cell->val.type == STRING_CONSTANT)
633 if (cell->val.rec.s != NULL)
634 {
635 absfree (cell->val.rec.s, "cell_settext:cell->val.rec.s ");
636 cell->val.rec.s = NULL;
637 }
638
639
640 if (strlen (buf) > 0)
641 {
642
643 end = strchr (buf, '\n');
644 if (end != NULL)
645 end = '\0';
646
647 cell->val.rec.s = (char *) absmalloc (sizeof (char) * (strlen (buf) + 5), "cell_settext:cell->formula ");
648 if (cell->val.rec.s == NULL)
649 fprintf (stderr, "val.rec.s not allocated\n");
650
651
652 first = buf;
653 while (*first == ' ' && first < buf + strlen (buf))
654 first++;
655 if (*first == '\'')
656 {
657 strcpy (cell->val.rec.s, "'");
658 strcat (cell->val.rec.s, first + 1);
659 cell->formula = cell->val.rec.s;
660 cell->val.rec.s = cell->formula + 1;
661 }
662 else
663 strcpy (cell->val.rec.s, buf);
664
665 }
666 else
667 cell->val.rec.s = NULL;
668
669 cell->val.type = STRING_CONSTANT;
670
671 cell->type = text;
672
673 return 0;
674 }
675
676
677 char *
cell_getformula(cell)678 cell_getformula (cell)
679 Cell *cell;
680 {
681 if (cell != NULL)
682 switch (cell->type)
683 {
684 case constant:
685 {
686 double val = cell_getvalue (cell);
687 if (val != 0.0)
688 {
689 sprintf (tmpbuf, "%g", cell_getvalue (cell));
690 return tmpbuf;
691 }
692 break;
693 }
694 case text:
695 return cell->formula;
696 case formula:
697 return cell->formula;
698 case undef:
699 return NULL;
700 }
701 return NULL;
702 }
703
704 char *
cell_getnumberformat(cell)705 cell_getnumberformat (cell)
706 Cell *cell;
707 {
708
709
710 return NULL;
711 }
712
713 double
cell_setvalue(cell,val)714 cell_setvalue (cell, val)
715 Cell *cell;
716 double val;
717 {
718 if (cell != NULL)
719 {
720 obj o;
721 o.rec.d = val;
722 o.type = DOUBLE;
723 cell_setobj (cell, o);
724 }
725 return 0.0;
726 }
727
728 obj
cell_setobj(cell,o)729 cell_setobj (cell, o)
730 Cell *cell;
731 obj o;
732 {
733
734
735
736
737
738
739
740
741
742
743 char tmp[64];
744 char *buf;
745
746 if (o.type == STRING)
747 o.type = STRING_CONSTANT;
748
749 if (cell != NULL)
750 {
751 switch (o.type)
752 {
753 case STRING_CONSTANT:
754 {
755 if (o.rec.s == NULL)
756 {
757 clear_cell (cell);
758 return o;
759 }
760 buf = absmalloc (sizeof (char) * (strlen (o.rec.s) + 2), "cell_setobj:buf");
761 if (o.rec.s[0] == '\'')
762 strcpy (buf, o.rec.s);
763 else
764 sprintf (buf, "'%s", o.rec.s);
765 cell_setformula (cell, buf);
766 absfree (buf, "cell_setobj:buf");
767 break;
768 };
769 case DOUBLE:
770 sprintf (tmp, "%f", o.rec.d);
771 cell_setformula (cell, tmp);
772 break;
773 case INTEGER:
774 sprintf (tmp, "%d", o.rec.i);
775 cell_setformula (cell, tmp);
776 break;
777 }
778 }
779 return o;
780 }
781
782 obj
cell_setresval(cell,o)783 cell_setresval (cell, o)
784 Cell *cell;
785 obj o;
786 {
787
788
789
790
791
792 int len = 0;
793
794 if (o.type == STRING)
795 o.type = STRING_CONSTANT;
796
797
798 if (cell != NULL)
799 {
800
801 if (o.type == STRING_CONSTANT && o.rec.s != NULL)
802 {
803 len = strlen (o.rec.s);
804 }
805
806
807 if (o.type == STRING_CONSTANT && len == 0)
808 {
809 if (cell->val.type == STRING_CONSTANT && cell->val.rec.s != NULL)
810 absfree (cell->val.rec.s, "cell->val.rec.s:null_str");
811 cell->val.rec.s = NULL;
812 cell->val.type = STRING_CONSTANT;
813 return o;
814 }
815
816
817 if (cell->val.type == STRING_CONSTANT)
818 {
819 if (o.type == STRING_CONSTANT)
820 {
821 cell->val.rec.s = (char *) absrealloc (cell->val.rec.s, (len + 1) * sizeof (char),
822 "cell_setresobj::val.rec.s");
823 strcpy (cell->val.rec.s, o.rec.s);
824 return cell->val;
825 }
826 else
827 {
828 if (cell->val.rec.s != NULL)
829 absfree (cell->val.rec.s, "cell_setresobj::val.rec.s");
830 cell->val.rec.s = NULL;
831 }
832 }
833
834 if (o.type == STRING_CONSTANT)
835 {
836 cell->val.type = STRING_CONSTANT;
837 cell->val.rec.s = (char *) absmalloc ((len + 1) * sizeof (char), "cell_setresobj::val.rec.s");
838 strcpy (cell->val.rec.s, o.rec.s);
839 return cell->val;
840 };
841
842
843 cell->val = o;
844 return cell->val;
845 }
846 return o;
847 }
848
849
850 double
cell_getvalue(cell)851 cell_getvalue (cell)
852 Cell *cell;
853 {
854 if (cell == NULL)
855 {
856 return 0.0;
857 }
858
859 switch (cell->val.type)
860 {
861 case DOUBLE:
862 return cell->val.rec.d;
863 case INTEGER:
864 {
865 double val = cell->val.rec.i;
866 return val;
867 }
868 }
869 return 0.0;
870 }
871
872 obj
cell_getobj(cell)873 cell_getobj (cell)
874 Cell *cell;
875 {
876 if (cell == NULL)
877 {
878 obj o;
879 printf ("getvalue for NULL cell\n");
880 o.type = INTEGER;
881 o.rec.i = 0;
882 return o;
883 }
884 return cell->val;
885 }
886
887 int
cell_istext(cell)888 cell_istext (cell)
889 Cell *cell;
890 {
891 if (cell == NULL)
892 return 0;
893 if (cell->type == text)
894 return 1;
895 return 0;
896
897 }
898
899 char *
cell_gettext(cell)900 cell_gettext (cell)
901 Cell *cell;
902 {
903 char form[8];
904 int format, deci;
905 int dd, mm, yy;
906 double value;
907 if (cell == NULL)
908 {
909 return NULL;
910 }
911 if (cell->type != constant && cell->formula == NULL)
912 {
913 return NULL;
914 }
915
916
917 if (cell->type == text || cell->val.type == STRING_CONSTANT)
918 return cell->val.rec.s;
919
920 cell_getformat (cell, &format, &deci);
921
922 value = cell_getvalue (cell);
923
924 switch (format)
925 {
926 case 1:
927 {
928 sprintf (form, "%%g");
929 sprintf (tmpbuf, form, value);
930 break;
931 }
932 case 2:
933 {
934 sprintf (form, "%%.%dlf", deci);
935 sprintf (tmpbuf, form, value);
936 break;
937 }
938 case 3:
939 {
940 sprintf (form, "%%.%de", deci);
941 sprintf (tmpbuf, form, value);
942 break;
943 }
944 case 4:
945 {
946 sprintf (form, "%%.%dlf%%%%", deci);
947 sprintf (tmpbuf, form, value * 100.);
948 break;
949 }
950 case 5:
951 {
952 int date = value;
953 num2date (date, &dd, &mm, &yy);
954 sprintf (tmpbuf, "%2d/%2d/%4d", dd, mm, yy);
955 break;
956 }
957
958 }
959
960 return tmpbuf;
961 }
962
963
964
965
966
967
968 int
cell_setfg(cell,f)969 cell_setfg (cell, f)
970 Cell *cell;
971 int f;
972 {
973 if (cell == NULL)
974 return -1;
975 if (cell->style == NULL)
976 cell->style = newstyle (STY_CELL);
977 setstyle (cell->style, STY_FG, f + 5);
978 return 0;
979 }
980 int
cell_getfg(cell)981 cell_getfg (cell)
982 Cell *cell;
983 {
984 if (cell == NULL || cell->style == NULL)
985 return getstyle (ActiveWorkbook->style, STY_FG);
986
987 return getstyle (cell->style, STY_FG);
988 }
989
990 int
cell_setbg(cell,f)991 cell_setbg (cell, f)
992 Cell *cell;
993 int f;
994 {
995 if (cell == NULL)
996 return -1;
997 if (cell->style == NULL)
998 cell->style = newstyle (STY_CELL);
999
1000 setstyle (cell->style, STY_BG, f + 5);
1001 return 0;
1002 }
1003
1004 int
cell_getbg(cell)1005 cell_getbg (cell)
1006 Cell *cell;
1007 {
1008 if (cell == NULL || cell->style == NULL)
1009 return getstyle (ActiveWorkbook->style, STY_BG);
1010 return getstyle (cell->style, STY_BG);
1011 }
1012
1013
1014 int
cell_gettop(cell)1015 cell_gettop (cell)
1016 Cell *cell;
1017 {
1018 if (cell == NULL || cell->style == NULL)
1019 return getstyle (ActiveWorkbook->style, STY_BORDER_TOP);
1020 return getstyle (cell->style, STY_BORDER_TOP);
1021 }
1022 int
cell_getbot(cell)1023 cell_getbot (cell)
1024 Cell *cell;
1025 {
1026 if (cell == NULL || cell->style == NULL)
1027 return getstyle (ActiveWorkbook->style, STY_BORDER_BOT);
1028 return getstyle (cell->style, STY_BORDER_BOT);
1029 }
1030 int
cell_getrig(cell)1031 cell_getrig (cell)
1032 Cell *cell;
1033 {
1034 if (cell == NULL || cell->style == NULL)
1035 return getstyle (ActiveWorkbook->style, STY_BORDER_RIG);
1036 return getstyle (cell->style, STY_BORDER_RIG);
1037 }
1038 int
cell_getlef(cell)1039 cell_getlef (cell)
1040 Cell *cell;
1041 {
1042 if (cell == NULL || cell->style == NULL)
1043 return getstyle (ActiveWorkbook->style, STY_BORDER_LEF);
1044 return getstyle (cell->style, STY_BORDER_LEF);
1045 }
1046
1047 int
cell_settop(cell,v)1048 cell_settop (cell, v)
1049 Cell *cell;
1050 int v;
1051 {
1052 if (cell == NULL)
1053 return -1;
1054 if (cell->style == NULL)
1055 cell->style = newstyle (STY_CELL);
1056 setstyle (cell->style, STY_BORDER_TOP, v);
1057 return 0;
1058 }
1059 int
cell_setbot(cell,v)1060 cell_setbot (cell, v)
1061 Cell *cell;
1062 int v;
1063 {
1064 if (cell == NULL)
1065 return -1;
1066 if (cell->style == NULL)
1067 cell->style = newstyle (STY_CELL);
1068 setstyle (cell->style, STY_BORDER_BOT, v);
1069 return 0;
1070 }
1071 int
cell_setrig(cell,v)1072 cell_setrig (cell, v)
1073 Cell *cell;
1074 int v;
1075 {
1076 if (cell == NULL)
1077 return -1;
1078 if (cell->style == NULL)
1079 cell->style = newstyle (STY_CELL);
1080 setstyle (cell->style, STY_BORDER_RIG, v);
1081 return 0;
1082 }
1083
1084 int
cell_setlef(cell,v)1085 cell_setlef (cell, v)
1086 Cell *cell;
1087 int v;
1088 {
1089 if (cell == NULL)
1090 return -1;
1091 if (cell->style == NULL)
1092 cell->style = newstyle (STY_CELL);
1093 setstyle (cell->style, STY_BORDER_LEF, v);
1094 return 0;
1095 }
1096
1097
1098
1099
1100
1101
1102 int
cell_setformat(cell,format,deci)1103 cell_setformat (cell, format, deci)
1104 Cell *cell;
1105 int format, deci;
1106 {
1107 double date;
1108
1109 if (cell == NULL)
1110 return -1;
1111 if (cell->style == NULL)
1112 cell->style = newstyle (STY_CELL);
1113
1114
1115 if (format == 5 && getstyle (cell->style, STY_FORMAT) != 5)
1116 {
1117 date = scandate (cell_getformula (cell));
1118 if (date)
1119 cell_setvalue (cell, date);
1120 }
1121
1122 setstyle (cell->style, STY_FORMAT, format);
1123 setstyle (cell->style, STY_DECIMAL, deci);
1124 return 0;
1125
1126 }
1127
1128 int
cell_getformat(cell,format,decimal)1129 cell_getformat (cell, format, decimal)
1130 Cell *cell;
1131 int *format, *decimal;
1132 {
1133 if (cell == NULL)
1134 return -1;
1135 if (cell->style == NULL)
1136 {
1137 *format = getstyle (ActiveWorkbook->style, STY_FORMAT);
1138 *decimal = getstyle (ActiveWorkbook->style, STY_DECIMAL);
1139 return 0;
1140 }
1141 *format = getstyle (cell->style, STY_FORMAT);
1142 *decimal = getstyle (cell->style, STY_DECIMAL);
1143 return 0;
1144 }
1145
1146
1147 int
cell_setjust(cell,just)1148 cell_setjust (cell, just)
1149 Cell *cell;
1150 int just;
1151 {
1152 if (cell == NULL)
1153 return -1;
1154 if (cell->style == NULL)
1155 cell->style = newstyle (STY_CELL);
1156 setstyle (cell->style, STY_JUSTIF, just);
1157 return 0;
1158 }
1159
1160 int
cell_getjust(cell)1161 cell_getjust (cell)
1162 Cell *cell;
1163 {
1164 if (cell == NULL || cell->style == NULL)
1165 return getstyle (ActiveWorkbook->style, STY_JUSTIF);
1166 return getstyle (cell->style, STY_JUSTIF);
1167 }
1168
1169
1170
1171 int
cell_setfont(cell,font,weight,size)1172 cell_setfont (cell, font, weight, size)
1173 Cell *cell;
1174 int font;
1175 {
1176 if (cell == NULL)
1177 return -1;
1178 if (cell->style == NULL)
1179 cell->style = newstyle (STY_CELL);
1180 if (font >= 0)
1181 setstyle (cell->style, STY_FONT, font);
1182 if (weight >= 0)
1183 setstyle (cell->style, STY_FONTW, weight);
1184 if (size >= 0)
1185 setstyle (cell->style, STY_FONTS, size);
1186 return 0;
1187 }
1188
1189 int
cell_fontname(Cell * cell,char * name)1190 cell_fontname (Cell * cell, char *name)
1191 {
1192
1193 if (cell->style == NULL)
1194 cell->style = newstyle (STY_CELL);
1195 if (!strcasecmp (name, "fixed"))
1196 setstyle (cell->style, STY_FONT, 0);
1197 if (!strcasecmp (name, "courier"))
1198 setstyle (cell->style, STY_FONT, 1);
1199 if (!strcasecmp (name, "helvetica"))
1200 setstyle (cell->style, STY_FONT, 2);
1201 if (!strcasecmp (name, "times"))
1202 setstyle (cell->style, STY_FONT, 3);
1203 if (!strcasecmp (name, "symbol"))
1204 setstyle (cell->style, STY_FONT, 4);
1205 return 0;
1206 }
1207
1208 int
cell_fontsize(cell,v)1209 cell_fontsize (cell, v)
1210 Cell *cell;
1211 int v;
1212 {
1213
1214 if (cell->style == NULL)
1215 cell->style = newstyle (STY_CELL);
1216 switch (v)
1217 {
1218 case 6:
1219 setstyle (cell->style, STY_FONTS, 0);
1220 break;
1221 case 8:
1222 setstyle (cell->style, STY_FONTS, 1);
1223 break;
1224 case 10:
1225 setstyle (cell->style, STY_FONTS, 2);
1226 break;
1227 case 12:
1228 setstyle (cell->style, STY_FONTS, 3);
1229 break;
1230 case 14:
1231 setstyle (cell->style, STY_FONTS, 4);
1232 break;
1233 case 18:
1234 setstyle (cell->style, STY_FONTS, 5);
1235 break;
1236 case 24:
1237 setstyle (cell->style, STY_FONTS, 6);
1238 break;
1239 }
1240 return 0;
1241 }
1242
1243 int
cell_fontbold(cell,v)1244 cell_fontbold (cell, v)
1245 Cell *cell;
1246 int v;
1247 {
1248
1249 if (cell->style == NULL)
1250 cell->style = newstyle (STY_CELL);
1251 if (v == 0)
1252 {
1253 if (getstyle (cell->style, STY_FONTW) > 1)
1254 setstyle (cell->style, STY_FONTW, 2);
1255 else
1256 setstyle (cell->style, STY_FONTW, 0);
1257 }
1258 else
1259 {
1260 if (getstyle (cell->style, STY_FONTW) > 1)
1261 setstyle (cell->style, STY_FONTW, 3);
1262 else
1263 setstyle (cell->style, STY_FONTW, 1);
1264 }
1265 return 0;
1266 }
1267
1268 int
cell_fontitalic(cell,v)1269 cell_fontitalic (cell, v)
1270 Cell *cell;
1271 int v;
1272 {
1273 int w;
1274
1275 if (cell->style == NULL)
1276 cell->style = newstyle (STY_CELL);
1277 w = getstyle (cell->style, STY_FONTW);
1278 if (v == 0)
1279 {
1280 if (w == 1 || w == 3)
1281 setstyle (cell->style, STY_FONTW, 1);
1282 else
1283 setstyle (cell->style, STY_FONTW, 0);
1284 }
1285 else
1286 {
1287 if (w == 1 || w == 3)
1288 setstyle (cell->style, STY_FONTW, 3);
1289 else
1290 setstyle (cell->style, STY_FONTW, 2);
1291 }
1292 return 0;
1293 }
1294
1295 int
cell_getfont(cell)1296 cell_getfont (cell)
1297 Cell *cell;
1298 {
1299 if (cell == NULL || cell->style == NULL)
1300 return getstyle (ActiveWorkbook->style, STY_FONT);
1301 return getstyle (cell->style, STY_FONT);
1302 return 0;
1303 }
1304
1305 int
cell_getfontw(cell)1306 cell_getfontw (cell)
1307 Cell *cell;
1308 {
1309 if (cell == NULL || cell->style == NULL)
1310 return getstyle (ActiveWorkbook->style, STY_FONTW);
1311 return getstyle (cell->style, STY_FONTW);
1312 return 0;
1313 }
1314 int
cell_getfonts(cell)1315 cell_getfonts (cell)
1316 Cell *cell;
1317 {
1318 if (cell == NULL || cell->style == NULL)
1319 return getstyle (ActiveWorkbook->style, STY_FONTS);
1320 return getstyle (cell->style, STY_FONTS);
1321 return 0;
1322 }
1323
1324
1325 int
cell_setborders(cell,border,type)1326 cell_setborders (cell, border, type)
1327 Cell *cell;
1328 int border;
1329 int type;
1330 {
1331 if (cell == NULL)
1332 return -1;
1333 if (cell->style == NULL)
1334 cell->style = newstyle (STY_CELL);
1335
1336 if (border == 8 || border == 0)
1337 setstyle (cell->style, STY_BORDER_TOP, type);
1338 if (border == 7 || border == 0)
1339 setstyle (cell->style, STY_BORDER_LEF, type);
1340 if (border == 9 || border == 0)
1341 setstyle (cell->style, STY_BORDER_BOT, type);
1342 if (border == 10 || border == 0)
1343 setstyle (cell->style, STY_BORDER_RIG, type);
1344 return 0;
1345 }
1346
1347
1348 int
cell_setborder(cell,border)1349 cell_setborder (cell, border)
1350 Cell *cell;
1351 int border;
1352 {
1353 if (cell == NULL)
1354 return -1;
1355 if (cell->style == NULL)
1356 cell->style = newstyle (STY_CELL);
1357
1358 setstyle (cell->style, STY_BORDER, border);
1359 return 0;
1360 }
1361
1362 int
cell_getborder(cell)1363 cell_getborder (cell)
1364 Cell *cell;
1365 {
1366 if (cell == NULL || cell->style == NULL)
1367 return getstyle (ActiveWorkbook->style, STY_BORDER);
1368 return getstyle (cell->style, STY_BORDER);
1369 return 0;
1370 }
1371
1372
1373
1374 int
parsecell(cell)1375 parsecell (cell)
1376 Cell *cell;
1377 {
1378 ActiveCell = cell;
1379 if (cell == NULL)
1380 return -1;
1381 if (cell->formula == NULL)
1382 return -2;
1383
1384 cell->tree = parseexpression (cell->formula);
1385
1386 if (cell->tree == NULL)
1387 return 1;
1388
1389 setcelltree (cell->tree);
1390 return 0;
1391 }
1392
1393 int
copymod(ii,jj,i,j,incr)1394 copymod (ii, jj, i, j, incr)
1395 int i, j, ii, jj, incr;
1396 {
1397 Cell *cell1;
1398 Cell *cell2;
1399 cell1 = (Cell *) applicationcell (i, j, 1);
1400 cell2 = (Cell *) applicationcell (ii, jj, 1);
1401 return copymod2 (cell1, cell2, i, j, (i - ii) * incr, (j - jj) * incr);
1402 }
1403
1404
1405
1406 int
copymod2(cell1,cell2,_curi,_curj,_di,_dj)1407 copymod2 (cell1, cell2, _curi, _curj, _di, _dj)
1408 Cell *cell1;
1409 Cell *cell2;
1410 int _curi, _curj, _di, _dj;
1411 {
1412 setdi (_di);
1413 setdj (_dj);
1414 cell_setformula (cell1, cell_getformula (cell2));
1415 setdi (0);
1416 setdj (0);
1417
1418 return 0;
1419 }
1420
1421 int
copymod3(cell1,cell2,incr)1422 copymod3 (cell1, cell2, incr)
1423 Cell *cell1;
1424 Cell *cell2;
1425 int incr;
1426 {
1427 if (cell1 == NULL || cell2 == NULL)
1428 return -1;
1429
1430 setdi ((cell1->r - cell2->r) * incr);
1431 setdj ((cell1->c - cell2->c) * incr);
1432 cell_setformula (cell1, cell_getformula (cell2));
1433 setdi (0);
1434 setdj (0);
1435
1436 return 0;
1437 return 0;
1438 }
1439
1440
1441
1442
1443
1444
1445
1446 char *
tolower(char * s)1447 tolower (char *s)
1448 {
1449 int j;
1450 int len;
1451 len = strlen (s);
1452 for (j = 0; j < len; j++)
1453 if (s[j] >= 'A' && s[j] <= 'Z')
1454 s[j] = 'a' + s[j] - 'A';
1455 return s;
1456 }
1457
1458 char *
sstrcasestr_(char * str1,char * str2)1459 sstrcasestr_ (char *str1, char *str2)
1460 {
1461 char *s1;
1462 char *s2;
1463 char *pos = NULL;
1464 int l1;
1465 s1 = strdup (str1);
1466 if (s1 == NULL)
1467 return NULL;
1468 s2 = strdup (str2);
1469 if (s2 == NULL)
1470 {
1471 free (s1);
1472 return NULL;
1473 }
1474
1475 tolower (s1);
1476 tolower (s2);
1477 pos = strstr (s1, s2);
1478 l1 = pos - s1;
1479 free (s1);
1480 free (s2);
1481 if (pos == NULL)
1482 return NULL;
1483
1484 return str1 + l1;
1485 }
1486
1487 int
cell_chgwksname(Cell * cell,char * oldname,char * newname)1488 cell_chgwksname (Cell * cell, char *oldname, char *newname)
1489 {
1490 int len = 0;
1491 int i = 0;
1492 int diffsize;
1493 char *newformula = NULL;
1494 char *old, *pos, *end;
1495 if (cell == NULL)
1496 return -1;
1497 if (cell->formula == NULL)
1498 return 0;
1499 if (cell->tree == NULL)
1500 return 0;
1501 if (oldname == NULL || newname == NULL)
1502 return -1;
1503 if (strlen (oldname) < 1 || strlen (newname) < 1)
1504 return -1;
1505 if (!strcmp (oldname, newname))
1506 return 0;
1507 if (sstrcasestr_ (cell->formula, oldname) == NULL)
1508 return 0;
1509
1510
1511 diffsize = strlen (oldname) - strlen (newname);
1512 old = absmalloc ((strlen (oldname) + 2) * sizeof (char), "cell_chgwksname:old");
1513 sprintf (old, "%s!", oldname);
1514
1515 pos = sstrcasestr_ (cell->formula, old);
1516 while (pos != NULL)
1517 {
1518 len = strlen (cell->formula);
1519 newformula = (char *) absmalloc ((len + 1 + diffsize) * sizeof (char), "cell_chgwksname:newformula");
1520 end = strchr (pos, '!');
1521 pos[0] = '\0';
1522 i = strlen (cell->formula) + strlen (newname) + 1;
1523 sprintf (newformula, "%s%s%s", cell->formula, newname, end);
1524 absfree (cell->formula, "cell_chgwksname:cell->formula");
1525 cell->formula = newformula;
1526 end = sstrcasestr_ (cell->formula, old);
1527 if (end > cell->formula + i)
1528 pos = end;
1529 else
1530 pos = NULL;
1531 }
1532
1533
1534 return 0;
1535 }
1536
1537 int
cell1isfcell2(cell1,cell2)1538 cell1isfcell2 (cell1, cell2)
1539 Cell *cell1;
1540 Cell *cell2;
1541 {
1542 int numpar1;
1543 int numchi2;
1544 int k;
1545 Cell **tmp;
1546
1547
1548
1549
1550
1551
1552 if (cell1 == cell2)
1553 return 1;
1554
1555 if (cell1->familly == NULL)
1556 {
1557 cell1->familly = (Familly *) absmalloc (sizeof (Familly), "cell1isfcell2:cell1->familly ");
1558 if (cell1->familly == NULL)
1559 fprintf (stderr, "cell1->familly not allocated!\n");
1560 cell1->familly->numpar = 0;
1561 cell1->familly->dimparlist = 0;
1562 cell1->familly->parentlist = NULL;
1563 cell1->familly->numchi = 0;
1564 cell1->familly->dimchilist = 0;
1565 cell1->familly->childlist = NULL;
1566 }
1567 if (cell2->familly == NULL)
1568 {
1569 cell2->familly = (Familly *) absmalloc (sizeof (Familly), "cell1isfcell2:cell2->familly ");
1570 if (cell2->familly == NULL)
1571 fprintf (stderr, "cell2->familly not allocated!\n");
1572 cell2->familly->numpar = 0;
1573 cell2->familly->dimparlist = 0;
1574 cell2->familly->parentlist = NULL;
1575 cell2->familly->numchi = 0;
1576 cell2->familly->dimchilist = 0;
1577 cell2->familly->childlist = NULL;
1578 }
1579
1580 numpar1 = cell1->familly->numpar;
1581 numchi2 = cell2->familly->numchi;
1582
1583 if (cell1->familly->dimparlist < numpar1 + 1)
1584 {
1585 tmp = (Cell **) absmalloc (sizeof (Cell *) * (2 * numpar1 + 2), "cell1isfcell2:tmp ");
1586 if (tmp == NULL)
1587 fprintf (stderr, "tmp not allocated!\n");
1588 for (k = 0; k < numpar1; k++)
1589 tmp[k] = cell1->familly->parentlist[k];
1590 if (cell1->familly->parentlist != NULL)
1591 absfree (cell1->familly->parentlist, "cell1isfcell2:cell1->familly->parentlist ");
1592 cell1->familly->parentlist = tmp;
1593 cell1->familly->dimparlist = 2 * numpar1 + 2;
1594 }
1595
1596 if (cell2->familly->dimchilist < numchi2 + 1)
1597 {
1598 tmp = (Cell **) absmalloc (sizeof (Cell *) * (2 * numchi2 + 2), "cell1isfcell2:tmp ");
1599 if (tmp == NULL)
1600 fprintf (stderr, "tmp not allocated!\n");
1601 for (k = 0; k < numchi2; k++)
1602 {
1603 tmp[k] = cell2->familly->childlist[k];
1604
1605 }
1606 if (cell2->familly->dimchilist > 0 && cell2->familly->childlist != NULL)
1607 absfree (cell2->familly->childlist, "cell1isfcell2:cell2->familly->childlist ");
1608 cell2->familly->childlist = tmp;
1609 cell2->familly->dimchilist = 2 * numchi2 + 2;
1610 }
1611
1612 for (k = 0; k < numpar1; k++)
1613 {
1614
1615 if (cell2 == cell1->familly->parentlist[k])
1616 return 2;
1617 }
1618 cell1->familly->parentlist[numpar1] = cell2;
1619 cell1->familly->numpar++;
1620 cell2->familly->childlist[numchi2] = cell1;
1621 cell2->familly->numchi++;
1622
1623
1624
1625
1626 return 0;
1627 }
1628
1629 int
pfamilly2(cell)1630 pfamilly2 (cell)
1631 Cell *cell;
1632 {
1633 int k;
1634 Cell *cell2;
1635 if (cell == NULL)
1636 fprintf (stderr, "pfamilly of null cell\n");
1637
1638 if (cell->familly == NULL)
1639 return 1;
1640
1641
1642 printf ("cell %d (r=%d c=%d)\n", cell->objnum, cell->r, cell->c);
1643
1644
1645 for (k = 0; k < cell->familly->numchi; k++)
1646 {
1647 cell2 = cell->familly->childlist[k];
1648 if (cell2)
1649 printf (" - child %d: %d (wks=%s r=%d c=%d)\n", k, cell2->objnum, cell2->worksheet->Name, cell2->r, cell2->c);
1650 else
1651 printf (" - child %d: NULL\n", k);
1652 }
1653
1654 for (k = 0; k < cell->familly->numpar; k++)
1655 {
1656 cell2 = cell->familly->parentlist[k];
1657 if (cell2)
1658 printf (" - parent %d: %d (wks=%s r=%d c=%d)\n", k, cell2->objnum, cell2->worksheet->Name, cell2->r, cell2->c);
1659 else
1660 printf (" - parent %d: NULL\n", k);
1661
1662 }
1663
1664 return 0;
1665 }
1666
1667 void
cell_auditcell(Cell * cell)1668 cell_auditcell (Cell * cell)
1669 {
1670 pfamilly2 (cell);
1671 }
1672
1673 int
cell_isnew(cell)1674 cell_isnew (cell)
1675 Cell *cell;
1676 {
1677 int k;
1678 Cell *i2j2;
1679 int l, found;
1680
1681 if (updating || parsing)
1682 return 1;
1683
1684 if (cell->familly == NULL)
1685 return 2;
1686
1687 for (k = 0; k < cell->familly->numpar; k++)
1688 {
1689 i2j2 = cell->familly->parentlist[k];
1690
1691
1692 found = 0;
1693 if (i2j2->familly != NULL)
1694 {
1695 for (l = 0; l < i2j2->familly->numchi; l++)
1696 {
1697 if (i2j2->familly->childlist[l] == cell)
1698 found = 1;
1699 if (found)
1700 {
1701 i2j2->familly->childlist[l] = i2j2->familly->childlist[l + 1];
1702 }
1703 }
1704 i2j2->familly->numchi--;
1705 }
1706 }
1707
1708
1709 if (cell->familly->numpar > 0)
1710 {
1711 cell->familly->numpar = 0;
1712 absfree (cell->familly->parentlist, "cell_isnew:cell->familly->parentlist ");
1713 cell->familly->parentlist = NULL;
1714 cell->familly->dimparlist = 0;
1715 }
1716 cell->familly->numpar = 0;
1717
1718 if (cell->familly->numchi == 0)
1719 {
1720 if (cell->familly->dimchilist > 0)
1721 absfree (cell->familly->childlist, "cell_isnew:cell->familly->childlist ");
1722 absfree (cell->familly, "cell_isnew:cell->familly ");
1723 cell->familly = NULL;
1724 }
1725
1726
1727
1728
1729 return 0;
1730
1731 }
1732
1733 extern int xdrawcell ();
1734 static Cell *iterbase;
1735 int
nupdate2(Cell * cell,int redraw)1736 nupdate2 (Cell * cell, int redraw)
1737 {
1738 int k;
1739 Cell *cell2;
1740
1741 if (parsing)
1742 return 1;
1743
1744 if (cell == NULL)
1745 return 2;
1746
1747 if (cell->familly == NULL)
1748 {
1749 return 3;
1750 }
1751 if (updating == 0)
1752 iterbase = cell;
1753 else if (cell == iterbase)
1754 {
1755 fprintf (stderr, "circular reference in cell %d %d\n", cell->r, cell->c);
1756 return 0;
1757 }
1758
1759 updating++;
1760
1761 for (k = 0; k < cell->familly->numchi; k++)
1762 {
1763 cell2 = cell->familly->childlist[k];
1764 if (cell2->formula != NULL && cell2->tree != NULL)
1765 {
1766 int exist = 0;
1767 int i;
1768 execcelltree (cell2);
1769 nupdate2 (cell2, redraw);
1770 if (redraw)
1771 for (i = 0; i < ntoredraw; i++)
1772 {
1773 if (toredraw[i] == cell2)
1774 {
1775 exist = 1;
1776 i = ntoredraw;
1777 }
1778 }
1779
1780 if (!exist)
1781 {
1782 toredraw = (Cell **) absrealloc (toredraw, sizeof (Cell *) * (ntoredraw + 1), "nupdate2:toredraw ");
1783 toredraw[ntoredraw] = cell2;
1784 ntoredraw++;
1785 }
1786 }
1787 }
1788 updating--;
1789
1790
1791 if (updating == 0 && ntoredraw > 0)
1792 {
1793 for (k = 0; k < ntoredraw; k++)
1794 xdrawcell (toredraw[k]->r, toredraw[k]->c, 0);
1795 absfree (toredraw, "nupdate2:toredraw ");
1796 toredraw = NULL;
1797 ntoredraw = 0;
1798 }
1799 return 0;
1800 }
1801
1802
1803 extern char *obj2string (obj o);
1804 extern obj getidval3 (int i);
1805 extern int findid (char *s);
1806
1807
1808 char *
textparsing(buf)1809 textparsing (buf)
1810 char *buf;
1811 {
1812 Cell *cell;
1813 Cell *activecell = ActiveCell;
1814 if (parsingmacro)
1815 {
1816 sprintf (tmpbuf, "to update");
1817 return tmpbuf;
1818 }
1819 cell = newcell (0, 1);
1820
1821 cell_setformula (cell, buf);
1822 strcpy (tmpbuf, cell_gettext (cell));
1823
1824 cell_isnew (cell);
1825 freecell (cell);
1826 ActiveCell = activecell;
1827 return tmpbuf;
1828 }
1829
1830
1831 Cell *
cell_cpy(cell1,cell2)1832 cell_cpy (cell1, cell2)
1833 Cell *cell1;
1834 Cell *cell2;
1835 {
1836 int len;
1837
1838 if (cell1 == NULL || cell2 == NULL)
1839 return NULL;
1840
1841 if (cell2->val.type == DOUBLE)
1842 {
1843 cell1->val.rec.d = cell2->val.rec.d;
1844 cell1->val.type = DOUBLE;
1845 }
1846
1847 if (cell2->val.type == INTEGER)
1848 {
1849 cell1->val.rec.i = cell2->val.rec.i;
1850 cell1->val.type = INTEGER;
1851 }
1852
1853
1854
1855
1856 if (cell2->formula != NULL)
1857 {
1858 len = strlen (cell2->formula);
1859 if (len > 0)
1860 {
1861 cell1->formula = (char *) absmalloc (sizeof (char) * len, "cell_cpy:cell1->formula ");
1862 if (cell1->formula == NULL)
1863 fprintf (stderr, "cell1->formula not allocated!\n");
1864 strcpy (cell1->formula, cell2->formula);
1865 cell1->formula[len] = '\0';
1866 }
1867 }
1868
1869 cell1->type = cell2->type;
1870
1871 if (cell2->style != NULL)
1872 {
1873 if (cell1->style == NULL)
1874 cell1->style = newstyle (STY_CELL);
1875 style_cpy (cell1->style, cell2->style);
1876 }
1877 else
1878 {
1879 if (cell1->style != NULL)
1880 {
1881 freestyle (cell1->style);
1882 cell1->style = NULL;
1883 }
1884 }
1885 return cell1;
1886 }
1887
1888 Cell *
cell_stycpy(cell1,cell2)1889 cell_stycpy (cell1, cell2)
1890 Cell *cell1;
1891 Cell *cell2;
1892 {
1893
1894 if (cell1 == NULL || cell2 == NULL)
1895 return NULL;
1896
1897 if (cell2->style != NULL)
1898 {
1899 if (cell1->style == NULL)
1900 cell1->style = newstyle (STY_CELL);
1901 style_cpy (cell1->style, cell2->style);
1902 }
1903 else
1904 {
1905 if (cell1->style != NULL)
1906 {
1907 freestyle (cell1->style);
1908 cell1->style = NULL;
1909 }
1910 }
1911 return cell1;
1912 }
1913
1914 int
cell_calculate(Cell * cell)1915 cell_calculate (Cell * cell)
1916 {
1917 return nupdate2 (cell, 0);
1918 }
1919
1920 int
cell_print(Cell * cell)1921 cell_print (Cell * cell)
1922 {
1923 if (cell == NULL)
1924 fprintf (stderr, "cell is NULL!\n");
1925 else
1926 fprintf (stderr, "cell %d %d formula %s\n", cell->r, cell->c, cell_getformula (cell));
1927 return 0;
1928 }
1929