home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / OLEO130S.ZIP / oleo130s.tar / oleo-1.3 / io-term.c < prev    next >
C/C++ Source or Header  |  1993-03-30  |  26KB  |  1,226 lines

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