1 /*
2 * $Id: io-term.c,v 1.51 2001/02/13 23:38:06 danny Exp $
3 *
4 * Copyright 1990, 1992, 1993, 1999, 2000, 2001 Free Software Foundation, Inc.
5 *
6 * This file is part of Oleo, the GNU Spreadsheet.
7 *
8 * Oleo is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * Oleo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Oleo; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 static char *rcsid = "$Id: io-term.c,v 1.51 2001/02/13 23:38:06 danny Exp $";
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #ifdef WITH_DMALLOC
30 #include <dmalloc.h>
31 #endif
32
33 #include <ctype.h>
34 #include <stdio.h>
35 #include <locale.h>
36 #include <stdlib.h>
37
38 #include "global.h"
39
40 #include "basic.h"
41 #include "cell.h"
42 #include "cmd.h"
43 #include "format.h"
44 #include "font.h"
45 #include "getopt.h"
46 #include "init.h"
47 #define DEFINE_IO_VARS 1
48 #include "io-abstract.h"
49 #include "io-curses.h"
50 #include "io-edit.h"
51 #include "io-generic.h"
52 #include "io-term.h"
53 #include "io-utils.h"
54 #include "io-x11.h"
55 #include "key.h"
56 #include "line.h"
57 #include "lists.h"
58 #define obstack_chunk_alloc ck_malloc
59 #define obstack_chunk_free free
60 #include "obstack.h"
61 #include "oleofile.h"
62 #include "print.h"
63 #include "ref.h"
64 #include "regions.h"
65 #include "window.h"
66 #include "funcs.h"
67 #include "graph.h"
68 #include "mdi.h"
69 #include "postscript.h"
70
71 #include "userpref.h"
72 #include "mysql.h"
73 #ifdef HAVE_MOTIF
74 #include "io-motif.h"
75 #endif
76
77 #ifdef HAVE_LIBGTK
78 #include "gtk/gtk.h"
79 #endif
80
81 #include "list.h"
82 #include "sc.h"
83 #include "sylk.h"
84
85 #ifdef HAVE_PANIC_SAVE
86 #include "panic.h"
87 #endif
88
89 #if ENABLE_NLS
90 extern char *gettext(char *);
91 #endif
92
93 /*
94 * The ultimate global variable
95 */
96 #if 1
97 struct OleoGlobal *Global = NULL;
98 #else
99 struct OleoGlobal __tempGlobal,
100 *Global = &__tempGlobal;
101 #endif
102
103 /* These are the hooks used to do file-io. */
104 void (*read_file) (FILE *, int) = oleo_read_file;
105 void (*write_file) (FILE *, struct rng *) = oleo_write_file;
106 int (*set_file_opts) (int, char *) = oleo_set_options;
107 void (*show_file_opts) () = oleo_show_options;
108
109 static char option_separator = '\t';
110 static char *option_format = NULL;
111 int option_filter = 0;
112
113 static char short_options[] = "VqfxthsFSv";
114 static struct option long_options[] =
115 {
116 {"version", 0, NULL, 'V'},
117 {"quiet", 0, NULL, 'q'},
118 {"ignore-init-file", 0, NULL, 'f'},
119 {"nw", 0, NULL, 'x'},
120 {"no-toolkit", 0, NULL, 't'},
121 {"help", 0, NULL, 'h'},
122 {"separator", 1, NULL, 's'},
123 {"space", 0, NULL, 'S'},
124 {"format", 1, NULL, 'F'},
125 {"filter", 0, NULL, '-'},
126 {"version", 0, NULL, 'v'},
127 {NULL, 0, NULL, 0}
128 };
129
130 /* Avoid needless messages to stdout. */
131 int spread_quietly = 0;
132
133 /* Avoid using Displays no matter what else. (-x --no-x) */
134 int no_gtk = 0;
135 int no_x = 0;
136 int no_curses = 0;
137 int no_motif = 0;
138
139 /* What kind of display? */
140 int using_x = 0;
141 int using_curses = 0;
142 int using_gtk = 0;
143 int using_motif = 0;
144
145
146 /* Cell size paramaters. */
147 unsigned int default_width = 8;
148 unsigned int default_height = 1;
149
150 /* These values are used by clear_spreadsheet ()
151 * to restore the defaults.
152 */
153 unsigned int saved_default_width = 8;
154 unsigned int saved_default_height = 1;
155
156 /* Other cell defaults: */
157 int default_jst = JST_LFT;
158 int default_fmt = FMT_GEN;
159 int default_prc = 0x0F; /* FIX ME */
160 int default_lock = LCK_UNL;
161
162 /* Pointers to interesting cmd_func structures. */
163 struct cmd_func *end_macro_cmd;
164 struct cmd_func *digit_0_cmd;
165 struct cmd_func *digit_9_cmd;
166 struct cmd_func * break_cmd;
167 struct cmd_func * universal_arg_cmd;
168
169 /* A bland signal handler. */
170 static RETSIGTYPE
got_sig(int sig)171 got_sig (int sig)
172 {
173 }
174
175 /*
176 * Simple table of variables to set
177 * All these variables belong in a UserPreferences structure.
178 */
179
180 struct UserPreferences UserPreferences;
181
182 /*
183 * How to use this ?
184 *
185 * Set "name" to the string we'll find in the .oleorc.
186 * Put a pointer to the variable to assign to in "var".
187 *
188 * If a function needs to be called upon encountering this option,
189 * put its address in "trigger".
190 * If it's an integer, put the value to assign in "value".
191 * If it's a string, set "copynext" to 1. The string in the option will be
192 * copied to the variable.
193 *
194 * Set "write" to 1 if this needs to be saved in .oleorc.
195 * Even then, only saved to file if integer has the "value" from the table,
196 * or if the string is non-empty.
197 * Set cont to 1 if processing in do_set_option is to continue.
198 */
199 static struct pref {
200 char *name;
201 void *var;
202 int value;
203 void (*trigger)(char *);
204 int copynext;
205 int write;
206 int cont;
207 } Preferences [] = {
208 { "a0", &UserPreferences.a0, 1, NULL, 0, 1, 1},
209 { "noa0", &UserPreferences.a0, 0, NULL, 0, 1, 1},
210 { "bgcolor", &UserPreferences.bgcolor, 0, NULL, 1, 0, 1},
211 { "file", &UserPreferences.file_type, 0, NULL, 1, 1, 1},
212 { "encoding", &UserPreferences.encoding, 0, OleoUserPrefEncoding, 1, 1, 0},
213 { NULL, 0 }
214 };
215
216 /* An parser for the language grokked by option setting commands. */
217
218 static int
do_set_option(char * ptr)219 do_set_option (char *ptr)
220 {
221 int set_opt = 1;
222 int i, l;
223 int *tmp;
224 char *p;
225
226 while (*ptr == ' ')
227 ptr++;
228
229 for (l=0,p=ptr; *p && !isspace(*p); p++) l++;
230
231 for (i=0; Preferences[i].name; i++)
232 if (strncmp(ptr, Preferences[i].name, l) == 0) {
233 if (Preferences[i].trigger != NULL)
234 (Preferences[i].trigger)(ptr);
235
236 if (Preferences[i].copynext) {
237 ptr += strlen(Preferences[i].name) + 1;
238 Preferences[i].var = strdup(ptr);
239 } else if (Preferences[i].var) {
240 tmp = Preferences[i].var;
241 *tmp = Preferences[i].value;
242 }
243
244 if (Preferences[i].cont == 0)
245 return 1;
246 break;
247 }
248
249 if (!strincmp ("no", ptr, 2))
250 {
251 ptr += 2;
252 set_opt = 0;
253 while (*ptr == ' ')
254 ptr++;
255 }
256 if (!stricmp ("auto", ptr))
257 {
258 Global->auto_recalc = set_opt;
259 return 0;
260 }
261 if (!stricmp ("bkgrnd", ptr) || !stricmp ("background", ptr))
262 {
263 Global->bkgrnd_recalc = set_opt;
264 return 0;
265 }
266 if (!stricmp ("a0", ptr))
267 {
268 Global->a0 = set_opt;
269 io_repaint ();
270 return 0;
271 }
272 if (!stricmp ("backup", ptr))
273 {
274 __make_backups = set_opt;
275 return 0;
276 }
277 if (!stricmp ("bkup_copy", ptr))
278 {
279 __backup_by_copying = set_opt;
280 return 0;
281 }
282 if (set_opt && !strincmp ("ticks ", ptr, 6))
283 {
284 ptr += 6;
285 cell_timer_seconds = astol (&ptr);
286 return 0;
287 }
288 if (set_opt && !strincmp ("print ", ptr, 6))
289 {
290 ptr += 6;
291 print_width = astol (&ptr);
292 return 0;
293 }
294 if (set_opt && !strincmp ("file ", ptr, 5))
295 {
296 ptr += 5;
297 if (!stricmp ("oleo", ptr))
298 {
299 read_file = oleo_read_file;
300 write_file = oleo_write_file;
301 set_file_opts = oleo_set_options;
302 show_file_opts = oleo_show_options;
303 }
304 else if (!stricmp ("sylk", ptr))
305 {
306 Global->sylk_a0 = 1;
307 read_file = sylk_read_file;
308 write_file = sylk_write_file;
309 set_file_opts = sylk_set_options;
310 show_file_opts = sylk_show_options;
311 }
312 else if (!stricmp ("sylk-noa0", ptr))
313 {
314 Global->sylk_a0 = 0;
315 read_file = sylk_read_file;
316 write_file = sylk_write_file;
317 set_file_opts = sylk_set_options;
318 show_file_opts = sylk_show_options;
319 }
320 else if (!stricmp ("sc", ptr))
321 {
322 read_file = sc_read_file;
323 write_file = sc_write_file;
324 set_file_opts = sc_set_options;
325 show_file_opts = sc_show_options;
326 }
327 #ifdef HAVE_PANIC_SAVE
328 else if (!stricmp ("panic", ptr))
329 {
330 read_file = panic_read_file;
331 write_file = panic_write_file;
332 set_file_opts = panic_set_options;
333 show_file_opts = panic_show_options;
334 }
335 #endif
336 else if (!stricmp ("list", ptr))
337 {
338 read_file = list_read_file;
339 write_file = list_write_file;
340 set_file_opts = list_set_options;
341 show_file_opts = list_show_options;
342 /*if (ptr[4])
343 {
344 ptr+=4;
345 sl_sep=string_to_char(&ptr);
346 } */
347 }
348 else
349 io_error_msg ("Unknown file format %s", ptr);
350 return 0;
351 }
352 if (set_window_option (set_opt, ptr) == 0)
353 {
354 if ((*set_file_opts) (set_opt, ptr))
355 io_error_msg ("Unknown option '%s'", ptr);
356 return 0;
357 }
358 return 1;
359 }
360
361 void
save_preferences(void)362 save_preferences(void)
363 {
364 char *home = getenv("HOME");
365 char *rc, *rc2;
366 FILE *fp;
367 int i;
368
369 rc = malloc(strlen(home) + strlen(RCFILE) + 4);
370 rc2 = malloc(strlen(home) + strlen(RCFILE) + 4);
371
372 sprintf(rc, "%s/%s", home, RCFILE);
373 sprintf(rc2, "%s/%s.bak", home, RCFILE);
374
375 (void)unlink(rc2);
376 rename(rc, rc2);
377
378 free(rc2);
379
380 fp = fopen(rc, "w");
381 if (fp == NULL) {
382 io_info_msg("Couldn't save preferences in %s: %s",
383 rc, strerror(errno));
384 free(rc);
385 return;
386 }
387
388 for (i=0; Preferences[i].name; i++)
389 if (Preferences[i].write) {
390 if (Preferences[i].copynext) {
391 if (strlen((char *)Preferences[i].var) != 0)
392 fprintf(fp, "set-option %s %s\n",
393 Preferences[i].name,
394 (char *) Preferences[i].var);
395 } else if (Preferences[i].value == *(int *)Preferences[i].var)
396 fprintf(fp, "set-option %s\n",
397 Preferences[i].name);
398 }
399
400 fclose(fp);
401
402 io_info_msg("Saved preferences to %s", rc);
403
404 free(rc);
405 }
406
407 void
set_options(char * ptr)408 set_options (char * ptr)
409 {
410 if (do_set_option (ptr))
411 io_recenter_cur_win ();
412 }
413
414 void
show_options(void)415 show_options (void)
416 {
417 int n;
418 int fmts;
419 char *data_buf[9];
420
421 n = Global->auto_recalc;
422 io_text_start ();
423
424 io_text_line ("auto-recalculation: %s Recalculate in background: %s",
425 n ? " on" : "off", Global->bkgrnd_recalc ? "on" : "off");
426 io_text_line ("make backup files: %s Copy files into backups: %s",
427 __make_backups ? " on" : "off", __backup_by_copying ? "on" : "off");
428
429 io_text_line ("Asynchronous updates every %u ???",
430 cell_timer_seconds);
431
432 io_text_line ("Print width: %5u", print_width);
433
434 io_text_line ("");
435
436 (*show_file_opts) ();
437
438 io_text_line ("");
439 show_window_options ();
440 io_text_line ("");
441
442 fmts = usr_set_fmts ();
443 if (fmts)
444 {
445 io_text_line ("User-defined formats:");
446 io_text_line ("Fmt +Hdr -Hdr +Trlr -Trlr Zero Comma Decimal Prec Scale");
447 for (n = 0; n < 16; n++)
448 {
449 if (fmts & (1 << n))
450 {
451 get_usr_stats (n, data_buf);
452 io_text_line ("%3d %7s %7s %7s %7s %7s %7s %7s %5s %13s",
453 n + 1,
454 data_buf[0],
455 data_buf[1],
456 data_buf[2],
457 data_buf[3],
458 data_buf[4],
459 data_buf[5],
460 data_buf[6],
461 data_buf[7],
462 data_buf[8]);
463 }
464 }
465 }
466 else
467 io_text_line ("No user-defined formats have been defined");
468
469 io_text_finish ();
470 }
471
472
473 void
read_mp_usr_fmt(char * ptr)474 read_mp_usr_fmt (char *ptr)
475 {
476 int usr_n = -1;
477 int n_chrs = 0;
478 char *p;
479 char *buf[9];
480 int i;
481
482 for (i = 0; i < 9; i++)
483 buf[i] = "";
484 p = ptr;
485 while (*p == ';')
486 {
487 *p++ = '\0';
488 switch (*p++)
489 {
490 case 'N':
491 usr_n = astol (&p) - 1;
492 break;
493 case 'H':
494 switch (*p++)
495 {
496 case 'P':
497 i = 0;
498 break;
499 case 'N':
500 i = 1;
501 break;
502 default:
503 goto badline;
504 }
505 goto count_chars;
506 case 'T':
507 switch (*p++)
508 {
509 case 'P':
510 i = 2;
511 break;
512 case 'N':
513 i = 3;
514 break;
515 default:
516 goto badline;
517 }
518 goto count_chars;
519
520 case 'Z':
521 i = 4;
522 goto count_chars;
523
524 case 'C':
525 i = 5;
526 goto count_chars;
527
528 case 'D':
529 i = 6;
530 goto count_chars;
531
532 case 'P':
533 i = 7;
534 goto count_chars;
535
536 case 'S':
537 i = 8;
538 goto count_chars;
539
540 count_chars:
541 buf[i] = p;
542 n_chrs++;
543 while (*p && *p != ';')
544 {
545 p++;
546 n_chrs++;
547 }
548 break;
549
550 default:
551 badline:
552 io_error_msg ("Unknown OLEO line %s", ptr);
553 return;
554 }
555 }
556 if (*p || usr_n < 0 || usr_n > 15)
557 goto badline;
558
559 set_usr_stats (usr_n, buf);
560 }
561
562 /* Modify this to write out *all* the options */
563 void
write_mp_options(FILE * fp)564 write_mp_options (FILE *fp)
565 {
566 fprintf (fp, "O;%sauto;%sbackground;%sa0;ticks %d\n",
567 Global->auto_recalc ? "" : "no",
568 Global->bkgrnd_recalc ? "" : "no",
569 Global->a0 ? "" : "no",
570 cell_timer_seconds);
571 }
572
573 void
read_mp_options(char * str)574 read_mp_options (char *str)
575 {
576 char *np;
577
578 while ((np = (char *)index (str, ';')))
579 {
580 *np = '\0';
581 (void) do_set_option (str);
582 *np++ = ';';
583 str = np;
584 }
585 if ((np = (char *)rindex (str, '\n')))
586 *np = '\0';
587 (void) do_set_option (str);
588 }
589
590
591 /* Commands related to variables. */
592
593 void
set_var(struct rng * val,char * var)594 set_var (struct rng *val, char *var)
595 {
596 char *ret;
597
598 Global->modified = 1;
599 ret = new_var_value (var, strlen(var), val);
600
601 if (ret)
602 io_error_msg ("Can't set-var %s: %s\n", var, ret);
603 }
604
605 void
unset_var(char * var)606 unset_var (char *var)
607 {
608 struct rng tmp_rng;
609 struct var *v;
610
611 v = find_var(var, strlen(var));
612
613 if (!v || v->var_flags == VAR_UNDEF)
614 {
615 io_error_msg ("No variable named %s exists.", var);
616 }
617 else
618 {
619 tmp_rng.lr = tmp_rng.hr = NON_ROW;
620 tmp_rng.lc = tmp_rng.hc = NON_COL;
621 v = find_or_make_var(var, strlen(var));
622 v->v_rng = tmp_rng;
623 v->var_flags = VAR_UNDEF;
624 }
625 }
626
627 void
show_var(char * ptr)628 show_var (char *ptr)
629 {
630 struct var *v;
631 int num;
632
633 while (*ptr == ' ')
634 ptr++;
635 for (num = 0; ptr[num] && ptr[num] != ' '; num++)
636 ;
637
638 v = find_var (ptr, num);
639 if (!v || v->var_flags == VAR_UNDEF)
640 {
641 io_error_msg ("There is no '%s'", ptr);
642 return;
643 }
644 if (Global->a0)
645 {
646 if (v->v_rng.lr != v->v_rng.hr || v->v_rng.lc != v->v_rng.hc)
647 /* FOO */ sprintf (print_buf, "%s $%s$%u:$%s$%u", v->var_name, col_to_str (v->v_rng.lc), v->v_rng.lr, col_to_str (v->v_rng.hc), v->v_rng.hr);
648 else
649 /* FOO */ sprintf (print_buf, "%s $%s$%u", v->var_name, col_to_str (v->v_rng.lc), v->v_rng.lr);
650 }
651 else
652 sprintf (print_buf, "%s %s", v->var_name, range_name (&(v->v_rng)));
653 io_info_msg (print_buf);
654 }
655
656 static void
show_a_var(char * name,struct var * v)657 show_a_var (char *name, struct var *v)
658 {
659 if (v->var_flags == VAR_UNDEF)
660 return;
661 if (Global->a0)
662 {
663 if (v->v_rng.lr != v->v_rng.hr || v->v_rng.lc != v->v_rng.hc)
664 /* FOO */ io_text_line ("%-20s $%s$%u:$%s$%u", v->var_name, col_to_str (v->v_rng.lc), v->v_rng.lr, col_to_str (v->v_rng.hc), v->v_rng.hr);
665 else
666 /* FOO */ io_text_line ("%-20s $%s$%u", v->var_name, col_to_str (v->v_rng.lc), v->v_rng.lr);
667 }
668 else
669 io_text_line ("%-20s %s", v->var_name, range_name (&(v->v_rng)));
670 }
671
672 void
show_all_var(void)673 show_all_var (void)
674 {
675 io_text_start ();
676 io_text_line ("%-20s Current Value", "Variable Name");
677 for_all_vars (show_a_var);
678 io_text_finish ();
679 }
680
681 static FILE * write_variable_fp = 0;
682
683 static void
write_a_var(char * name,struct var * v)684 write_a_var (char *name, struct var *v)
685 {
686 CELLREF r, c;
687 if (v->var_flags == VAR_UNDEF)
688 return;
689 r = v->v_rng.lr;
690 c = v->v_rng.lc;
691 if (v->var_flags == VAR_CELL)
692 fprintf (write_variable_fp, "%s=%s\n",
693 v->var_name, cell_value_string (r, c, 1));
694 }
695
696 void
write_variables(FILE * fp)697 write_variables (FILE * fp)
698 {
699 if (write_variable_fp)
700 io_error_msg ("Can't re-enter write_variables.");
701 else
702 {
703 write_variable_fp = fp;
704 for_all_vars (write_a_var);
705 write_variable_fp = 0;
706 }
707 }
708
709 void
read_variables(FILE * fp)710 read_variables (FILE * fp)
711 {
712 char buf[1024];
713 int lineno = 0;
714 while (fgets (buf, 1024, fp))
715 {
716 char * ptr;
717 for (ptr = buf; *ptr && *ptr != '\n'; ++ptr)
718 ;
719 *ptr = '\0';
720 for (ptr = buf; isspace (*ptr); ptr++)
721 ;
722 if (!*ptr || (*ptr == '#'))
723 continue;
724 {
725 char * var_name = ptr;
726 int var_name_len;
727 char * value_string;
728 while (*ptr && *ptr != '=')
729 ++ptr;
730 if (!*ptr)
731 {
732 io_error_msg ("read-variables: format error near line %d.", lineno);
733 return;
734 }
735 var_name_len = ptr - var_name;
736 ++ptr;
737 value_string = ptr;
738 {
739 struct var * var = find_var (var_name, var_name_len);
740 if (var)
741 {
742 switch (var->var_flags)
743 {
744 case VAR_UNDEF:
745 break;
746 case VAR_CELL:
747 {
748 char * error = new_value (var->v_rng.lr, var->v_rng.lc,
749 value_string);
750 if (error)
751 {
752 io_error_msg (error);
753 return; /* actually, io_error_msg never returns. */
754 }
755 else
756 Global->modified = 1;
757 break;
758 }
759 case VAR_RANGE:
760 io_error_msg ("read-variables (line %d): ranges not supported.",
761 lineno);
762 return;
763 }
764 }
765 }
766 }
767 ++lineno;
768 }
769 if (!feof (fp))
770 {
771 io_error_msg ("read-variables: read error near line %d.", lineno);
772 return;
773 }
774 }
775
776 static void
init_maps(void)777 init_maps (void)
778 {
779 num_maps = 0;
780 the_maps = 0;
781 map_names = 0;
782 map_prompts = 0;
783
784 the_funcs = ck_malloc (sizeof (struct cmd_func *) * 2);
785 num_funcs = 1;
786 the_funcs[0] = &cmd_funcs[0];
787
788 find_func (0, &end_macro_cmd, "end-macro");
789 find_func (0, &digit_0_cmd, "digit-0");
790 find_func (0, &digit_9_cmd, "digit-9");
791 find_func (0, &break_cmd, "break");
792 find_func (0, &universal_arg_cmd, "universal-argument");
793
794 create_keymap ("universal", 0);
795 push_command_frame (0, 0, 0);
796 }
797
798 int
add_usr_cmds(struct cmd_func * new_cmds)799 add_usr_cmds (struct cmd_func *new_cmds)
800 {
801 num_funcs++;
802 the_funcs = ck_realloc (the_funcs, num_funcs * sizeof (struct cmd_func *));
803 the_funcs[num_funcs - 1] = new_cmds;
804 return num_funcs - 1;
805 }
806
807 /*
808 * The variable below makes it possible for the program "what" to identify
809 * which version of oleo this executable is.
810 */
811
812 static char *what_version = "@(#)" PACKAGE " " VERSION ;
813
814 static void
show_usage(void)815 show_usage (void)
816 {
817
818 printf(_("This is %s %s\n\n"), PACKAGE, VERSION);
819
820 printf(_("\
821 Usage: %s [OPTION]... [FILE]...\n\
822 "), PACKAGE);
823 printf(_("\
824 \n\
825 -h, --help display this help and exit\n\
826 -V, --version output version information and exit\n\
827 -q, --quiet do not display startup messages\n\
828 -f, --ignore-init-file ignore settings defined in init file\n\
829 -t, --no-toolkit disable X toolkit\n\
830 -x, --nw disable graphics and fallback to curses\n\
831 -s x, --separator x set separator for 'list' file type to x\n\
832 -S, --space set separator for 'list' file type to a space\n\
833 -F x, --format x set default file type to x (oleo, list, sc ...)\n\
834 --filter read file from stdin, write to stdout on exit\n\
835 \n\
836 Report bugs to <bug-oleo@gnu.org>.\n\
837 "));
838 }
839
840 static RETSIGTYPE
continue_oleo(int sig)841 continue_oleo (int sig)
842 {
843 io_repaint ();
844 if (using_curses)
845 cont_curses ();
846 }
847
InitializeGlobals(void)848 void InitializeGlobals(void)
849 {
850 Global->display_opened = 0;
851 Global->return_from_error = 0;
852
853 /* Initialize stuff that's now in Global */
854 Global->bkgrnd_recalc = 1;
855 Global->auto_recalc = 1;
856 Global->a0 = 0;
857 Global->topclear = 0;
858 Global->alarm_seconds = 1;
859 Global->alarm_active = 1;
860
861 /* From window.c */
862 Global->scr_lines = 24;
863 Global->scr_cols = 80;
864 user_input = 1;
865 user_status = 2;
866 Global->input = 0;
867 Global->status = 1;
868 input_rows = 1;
869 status_rows = 1;
870 default_right_border = 0;
871 default_bottom_border = 0;
872 nwin = 0;
873 cwin = 0;
874 wins = 0;
875 win_id = 1;
876
877 Global->sylk_a0 = 1;
878
879 Global->user_height_scale = 1.;
880 Global->user_width_scale = 1.;
881 Global->height_scale = 1.;
882 Global->width_scale = 1.;
883
884 Global->cell_font_point_size = 12;
885 Global->block_on_getch = 1;
886
887 Global->display_formula_mode = 0;
888 Global->auto_motion_direction = magic_down;
889 Global->sl_sep = '\t';
890
891 Global->CurrentPrintDriver = &PostScriptPrintDriver;
892 Global->zoom = 1.0;
893
894 Global->mouse_id = 0;
895
896 Global->oldLocale = NULL;
897
898 UserPreferences.run_load_hooks = 1;
899 /* End initialize */
900
901 __make_backups = 1;
902 }
903
904 void
oleo_catch_signals(void (* h)(int))905 oleo_catch_signals(void (*h)(int))
906 {
907 /*
908 * These probably don't all need to be ifdef, but
909 * it is harmless.
910 */
911 #ifdef SIGCONT
912 signal (SIGCONT, continue_oleo);
913 #endif
914 #ifdef SIGPIPE
915 signal (SIGPIPE, h);
916 #endif
917
918 /*
919 * It makes little sense to block all signals when using X
920 */
921 if ((! using_x) && (! using_gtk) && (! using_motif)) {
922 #ifdef SIGINT
923 signal (SIGINT, h);
924 #endif
925 #ifdef SIGQUIT
926 signal (SIGQUIT, h);
927 #endif
928 #ifdef SIGILL
929 signal (SIGILL, h);
930 #endif
931 #ifdef SIGEMT
932 signal (SIGEMT, h);
933 #endif
934 #ifdef SIGBUS
935 signal (SIGBUS, h);
936 #endif
937 #ifdef SIGSEGV
938 signal (SIGSEGV, h);
939 #endif
940 #ifdef SIGHUP
941 signal(SIGHUP, h);
942 #endif
943 #ifdef SIGTRAP
944 signal(SIGTRAP, h);
945 #endif
946 #ifdef SIGABRT
947 signal(SIGABRT, h);
948 #endif
949 #ifdef SIGFPE
950 signal(SIGFPE, h);
951 #endif
952 #ifdef SIGSYS
953 signal(SIGSYS, h);
954 #endif
955 #ifdef SIGALRM
956 signal(SIGALRM, h);
957 #endif
958 #ifdef SIGTERM
959 signal(SIGTERM, h);
960 #endif
961 #ifdef SIGXCPU
962 signal(SIGXCPU, h);
963 #endif
964 #ifdef SIGVTALRM
965 signal(SIGVTALRM, h);
966 #endif
967 #ifdef SIGPROF
968 signal(SIGPROF, h);
969 #endif
970 #ifdef SIGUSR1
971 signal(SIGUSR1, h);
972 #endif
973 #ifdef SIGUSR2
974 signal(SIGUSR2, h);
975 #endif
976 }
977 }
978
979 int
main(int argc,char ** argv)980 main (int argc, char **argv)
981 {
982 volatile int ignore_init_file = 0;
983 FILE * init_fp[2];
984 char * init_file_names[2];
985 volatile int init_fpc = 0;
986 int command_line_file = 0; /* was there one? */
987
988 #if 0
989 sleep(30);
990 #endif
991 #if 1 /* ENABLE_NLS */
992 setlocale(LC_ALL, "");
993 bindtextdomain(PACKAGE, LOCALEDIR);
994 textdomain(PACKAGE);
995 #endif
996
997 MdiInitialize(); /* Create initial Global structure */
998 PlotInit();
999 AllocateDatabaseGlobal();
1000 InitializeGlobals();
1001
1002 /* Set up the minimal io handler. */
1003 #if 0
1004 cmd_graphics ();
1005 #endif
1006
1007 {
1008 int opt;
1009
1010 while (1) {
1011 opt = getopt_long (argc, argv, short_options, long_options, (int *)0);
1012 if (opt == EOF)
1013 break;
1014
1015 #if 0
1016 if (opt)
1017 fprintf(stderr, PACKAGE " option %c\n", opt);
1018 else {
1019 fprintf(stderr, PACKAGE " optind %d option %s strange ...\n",
1020 optind, argv[optind]);
1021 }
1022 #endif
1023
1024 switch (opt)
1025 {
1026 case 'v':
1027 case 'V':
1028 printf(_("%s %s\n"), GNU_PACKAGE, VERSION);
1029 printf(_("Copyright 1992-2000 Free Software Foundation, Inc.\n"));
1030 printf(_("%s comes with ABSOLUTELY NO WARRANTY.\n"), GNU_PACKAGE);
1031 printf(_("You may redistribute copies of %s\n"), PACKAGE);
1032 printf(_("under the terms of the GNU General Public License.\n"));
1033 printf(_("For more information about these matters, "));
1034 printf(_("see the files named COPYING.\n"));
1035 exit (0);
1036 break;
1037 case 'q':
1038 spread_quietly = 1;
1039 break;
1040 case 'f':
1041 ignore_init_file = 1;
1042 break;
1043 case 'x':
1044 no_x = 1;
1045 break;
1046 case 't':
1047 no_gtk = 1;
1048 no_motif = 1;
1049 break;
1050 case 'h':
1051 show_usage ();
1052 exit (0);
1053 break;
1054 case 's':
1055 option_separator = argv[optind][0];
1056 #if 0
1057 fprintf(stderr, PACKAGE " set list file separator to %c\n", option_separator);
1058 #endif
1059 optind++;
1060 list_set_separator(option_separator);
1061 break;
1062 case 'S':
1063 option_separator = ' ';
1064 list_set_separator(option_separator);
1065 break;
1066 case 'F':
1067 #if 0
1068 fprintf(stderr, "F: optind %d argv[optind] '%s' optopt %d %c\n",
1069 optind, argv[optind], optopt, optopt);
1070 #endif
1071 option_format = argv[optind];
1072 file_set_default_format(option_format);
1073 optind++;
1074 break;
1075 case '-':
1076 option_filter = 1;
1077 break;
1078 }
1079 }
1080 }
1081
1082 if (argc - optind > 1)
1083 {
1084 if (no_motif)
1085 {
1086 show_usage ();
1087 exit (1);
1088 }
1089 }
1090
1091 init_infinity ();
1092 init_mem ();
1093 init_eval ();
1094 init_refs ();
1095 init_cells ();
1096 init_fonts ();
1097 init_info ();
1098
1099 /* Find the init files.
1100 * This is done even if ignore_init_file is true because
1101 * it effects whether the disclaimer will be shown.
1102 */
1103 {
1104 char *ptr, *home;
1105
1106 home = getenv ("HOME");
1107 if (home)
1108 {
1109 ptr = mk_sprintf ("%s/%s", home, RCFILE);
1110 init_fp[init_fpc] = fopen (ptr, "r");
1111 init_file_names[init_fpc] = ptr;
1112 if (init_fp[init_fpc])
1113 ++init_fpc;
1114 }
1115
1116 init_fp[init_fpc] = fopen (RCFILE, "r");
1117 if (init_fp[init_fpc])
1118 ++init_fpc;
1119 }
1120
1121 FD_ZERO (&read_fd_set);
1122 FD_ZERO (&read_pending_fd_set);
1123 FD_ZERO (&exception_fd_set);
1124 FD_ZERO (&exception_pending_fd_set);
1125
1126 #if defined(HAVE_LIBGTK) && !defined(HAVE_MOTIF)
1127 if ((!no_gtk)&&(!no_x)) {
1128
1129 gtk_init(&argc, &argv);
1130
1131 gtk_graphics ();
1132 using_gtk = TRUE;
1133 no_x = TRUE;
1134 no_curses = TRUE;
1135 }
1136 #endif
1137
1138 #ifdef HAVE_MOTIF
1139 if ((!no_motif)&&(!no_x)) {
1140
1141 motif_init(&argc, argv);
1142
1143 using_gtk = FALSE;
1144 using_motif = TRUE;
1145 no_x = TRUE;
1146 no_curses = TRUE;
1147 }
1148 #endif
1149
1150 #ifndef X_DISPLAY_MISSING
1151 if (!no_x) {
1152 get_x11_args (&argc, argv);
1153 if (Global->io_x11_display_name) {
1154 x11_graphics ();
1155 using_x = TRUE;
1156 no_curses = TRUE;
1157 }
1158 }
1159 #endif /* X_DISPLAY_MISSING */
1160
1161 if (!no_curses) {
1162 tty_graphics ();
1163 using_curses = TRUE;
1164 /* Allow the disclaimer to be read. */
1165 /* if (!init_fpc && !spread_quietly)
1166 sleep (5); */
1167 }
1168
1169 io_open_display ();
1170
1171 init_graphing ();
1172 PrintInit();
1173 OleoSetEncoding(OLEO_DEFAULT_ENCODING);
1174
1175 if (setjmp (Global->error_exception))
1176 {
1177 fprintf (stderr, _("Error in the builtin init scripts (a bug!).\n"));
1178 io_close_display(69);
1179 exit (69);
1180 }
1181 else
1182 {
1183 init_maps ();
1184 init_named_macro_strings ();
1185 run_init_cmds ();
1186 }
1187
1188 oleo_catch_signals(&got_sig);
1189
1190 /* Read the init file. */
1191 {
1192 volatile int x;
1193 for (x = 0; x < init_fpc; ++x)
1194 {
1195 if (setjmp (Global->error_exception))
1196 {
1197 fprintf (stderr, _(" error occured in init file %s near line %d."),
1198 init_file_names [x], Global->sneaky_linec);
1199 io_info_msg(_(" error occured in init file %s near line %d."),
1200 init_file_names [x], Global->sneaky_linec);
1201 }
1202 else
1203 if (!ignore_init_file)
1204 read_cmds_cmd (init_fp[x]);
1205 fclose (init_fp[x]);
1206 }
1207 }
1208
1209
1210 if (option_filter) {
1211 read_file_and_run_hooks(stdin, 0, "stdin");
1212 } else if (argc - optind == 1) {
1213 FILE * fp;
1214 /* fixme: record file name */
1215
1216 if ((fp = fopen (argv[optind], "r"))) {
1217 if (setjmp (Global->error_exception)) {
1218 fprintf (stderr, _(", error occured reading '%s'\n"), argv[optind]);
1219 io_info_msg(_(", error occured reading '%s'\n"), argv[optind]);
1220 } else
1221 read_file_and_run_hooks (fp, 0, argv[optind]);
1222 fclose (fp);
1223 command_line_file = 1;
1224 FileSetCurrentFileName(argv[optind]);
1225 } else {
1226 fprintf (stderr, _("Can't open %s: %s\n"), argv[optind], err_msg ());
1227 io_info_msg(_("Can't open %s: %s\n"), argv[optind], err_msg ());
1228 }
1229
1230 optind++;
1231 }
1232
1233 /* Force the command frame to be rebuilt now that the keymaps exist. */
1234 {
1235 struct command_frame * last_of_the_old = the_cmd_frame->next;
1236 while (the_cmd_frame != last_of_the_old)
1237 free_cmd_frame (the_cmd_frame);
1238 free_cmd_frame (last_of_the_old);
1239 }
1240
1241 io_recenter_cur_win ();
1242
1243 Global->display_opened = 1;
1244
1245 #if 0
1246 /* FIXME - Find better way of doing this */
1247 /* Display openning Copyright screen */
1248 if (!command_line_file)
1249 run_string_as_macro
1250 ("{pushback-keystroke}{builtin-help _NON_WARRANTY_}");
1251 #endif /* 0 */
1252
1253 #ifdef HAVE_MOTIF
1254 if (using_motif) {
1255 motif_build_gui();
1256 setjmp (Global->error_exception);
1257 motif_main_loop();
1258 } else {
1259 /* Compile with Motif but don't run with it. */
1260 while (1)
1261 {
1262 setjmp (Global->error_exception);
1263 command_loop (0, 0);
1264 }
1265 }
1266 #else
1267 while (1)
1268 {
1269 setjmp (Global->error_exception);
1270 command_loop (0, 0);
1271 }
1272 #endif
1273 return (0); /* Never Reached! */
1274 }
1275