home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / editor / beav / symbol.c < prev    next >
C/C++ Source or Header  |  1994-01-30  |  18KB  |  517 lines

  1. /*
  2. *              Symbol table stuff.
  3. * Symbol tables, and keymap setup.
  4. * The terminal specific parts of building the
  5. * keymap has been moved to a better place.
  6. */
  7. #include        "def.h"
  8.  
  9. void keyadd ();
  10. void keydup ();
  11.  
  12.  
  13. extern char MSG_byte_shift[];
  14. extern char MSG_back_char[];
  15. extern char MSG_quit[];
  16. extern char MSG_forw_del_char[];
  17. extern char MSG_toggle_swap[];
  18. extern char MSG_forw_char[];
  19. extern char MSG_abort[];
  20. extern char MSG_ins_self[];
  21. extern char MSG_back_del_char[];
  22. extern char MSG_refresh[];
  23. extern char MSG_forw_line[];
  24. extern char MSG_back_line[];
  25. extern char MSG_quote[];
  26. extern char MSG_recall[];
  27. extern char MSG_twiddle[];
  28. extern char MSG_forw_page[];
  29. extern char MSG_kill_region[];
  30. extern char MSG_yank[];
  31. extern char MSG_down_window[];
  32. extern char MSG_ins_toggle[];
  33. extern char MSG_display_buffers[];
  34. extern char MSG_quit[];
  35. extern char MSG_exit_flush_all[];
  36. extern char MSG_set_file_name[];
  37. extern char MSG_file_insert[];
  38. extern char MSG_buf_size_lock[];
  39. extern char MSG_flush_all[];
  40. extern char MSG_down_window[];
  41. extern char MSG_up_window[];
  42. extern char MSG_file_read[];
  43. extern char MSG_file_save[];
  44. extern char MSG_file_visit[];
  45. extern char MSG_file_write[];
  46. extern char MSG_swap_dot_and_mark[];
  47. extern char MSG_shrink_window[];
  48. extern char MSG_display_position[];
  49. extern char MSG_start_macro[];
  50. extern char MSG_end_macro[];
  51. extern char MSG_help[];
  52. extern char MSG_only_window[];
  53. extern char MSG_del_window[];
  54. extern char MSG_split_window[];
  55. extern char MSG_use_buffer[];
  56. extern char MSG_spawn_cli[];
  57. extern char MSG_execute_macro[];
  58. extern char MSG_goto_line[];
  59. extern char MSG_ins_unit[];
  60. extern char MSG_kill_buffer[];
  61. extern char MSG_load_bindings[];
  62. extern char MSG_forw_window[];
  63. extern char MSG_back_window[];
  64. extern char MSG_view_file[];
  65. extern char MSG_enlarge_window[];
  66. extern char MSG_ascii_mode[];
  67. extern char MSG_binary_mode[];
  68. extern char MSG_buffer_name[];
  69. extern char MSG_decimal_mode[];
  70. extern char MSG_ebcdic_mode[];
  71. #if    FLOAT_DISP
  72. extern char MSG_float_mode[];
  73. #endif
  74. extern char MSG_hex_mode[];
  75. extern char MSG_back_del_unit[];
  76. extern char MSG_octal_mode[];
  77. extern char MSG_display_version[];
  78. extern char MSG_unit_size1[];
  79. extern char MSG_unit_size2[];
  80. extern char MSG_unit_size4[];
  81. extern char MSG_reposition_window[];
  82. extern char MSG_set_mark[];
  83. extern char MSG_goto_eob[];
  84. extern char MSG_goto_bob[];
  85. extern char MSG_next_buff[];
  86. extern char MSG_prev_buff[];
  87. extern char MSG_query_replace[];
  88. extern char MSG_display_bindings[];
  89. extern char MSG_auto_save[];
  90. extern char MSG_back_unit[];
  91. extern char MSG_compare[];
  92. extern char MSG_forw_del_unit[];
  93. extern char MSG_forw_unit[];
  94. extern char MSG_link_windows[];
  95. extern char MSG_print[];
  96. extern char MSG_back_search[];
  97. extern char MSG_forw_search[];
  98. extern char MSG_back_page[];
  99. extern char MSG_copy_region[];
  100. extern char MSG_extended_command[];
  101. extern char MSG_up_window[];
  102. extern char MSG_search_again[];
  103. extern char MSG_bind_to_key[];
  104. extern char MSG_file_visit_split[];
  105. extern char MSG_yank_buffer[];
  106. extern char MSG_save_region[];
  107. extern char MSG_use_buffer_split[];
  108. extern char MSG_no_f_tb[];
  109. extern char MSG_n_split[];
  110. extern char MSG_n_combine[];
  111. extern char MSG_show_save_buf[];
  112. extern char MSG_scr_row[];
  113.  
  114. /*
  115. * Defined by "main.c".
  116. */
  117. extern bool ctrlg ();        /* Abort out of things      */
  118. extern bool quit ();        /* Quit             */
  119. extern bool ctlxlp ();        /* Begin macro          */
  120. extern bool ctlxrp ();        /* End macro            */
  121. extern bool ctlxe ();        /* Execute macro        */
  122. extern bool showversion ();    /* Show version numbers, etc.   */
  123. extern bool flushnquit ();    /* Flush buffers & exit (fitz)  */
  124. extern bool flush_all ();    /* Flush buffers (jam)      */
  125. extern bool autosave ();    /* autosave function (jam)  */
  126.  
  127. /*
  128. * Defined by "search.c".
  129. */
  130. extern bool forwsearch ();    /* Search forward       */
  131. extern bool backsearch ();    /* Search backwards     */
  132. extern bool searchagain ();    /* Repeat last search command   */
  133. extern bool queryrepl ();    /* Query replace        */
  134. extern bool compare ();        /* Compare two windows  */
  135. extern bool recall ();        /* Recall last search string  */
  136.  
  137. /*
  138. * Defined by "basic.c".
  139. */
  140. extern bool backchar ();    /* Move backward by characters  */
  141. extern bool forwchar ();    /* Move forward by characters   */
  142. extern bool gotobob ();        /* Move to start of buffer  */
  143. extern bool gotoeob ();        /* Move to end of buffer    */
  144. extern bool forwline ();    /* Move forward by lines    */
  145. extern bool backline ();    /* Move backward by lines   */
  146. extern bool forwpage ();    /* Move forward by pages    */
  147. extern bool backpage ();    /* Move backward by pages   */
  148. extern bool setmark ();        /* Set mark         */
  149. extern bool swapmark ();    /* Swap "." and mark        */
  150. extern bool gotoline ();    /* Go to a specified line.  */
  151.  
  152. /*
  153. * Defined by "buffer.c".
  154. */
  155. extern bool listbuffers ();    /* Display list of buffers  */
  156. extern bool showsavebuf ();    /* Show the save buffer contents */
  157. extern bool usebuffer ();    /* Switch a window to a buffer  */
  158. extern bool use_buffer ();    /* ditto, plus window split */
  159. extern bool killbuffer ();    /* Make a buffer go away.   */
  160. extern bool next_buf ();    /* goto next buffer     */
  161. extern bool prev_buf ();    /* goto prev buffer     */
  162. extern bool yank_buffer ();    /* yank buffer by name      */
  163. extern bool buffername ();    /* change buffer name       */
  164. extern bool bufsizlock ();    /* lock buffer size         */
  165.  
  166. /*
  167. * Defined by "file."
  168. */
  169. extern bool fileread ();    /* Get a file, read only    */
  170. extern bool filevisit ();    /* Get a file, read write   */
  171. extern bool file_visit ();    /* ditto , plus window split    */
  172. extern bool filewrite ();    /* Write a file         */
  173. extern bool filesave ();    /* Save current file        */
  174. extern bool filename ();    /* Adjust file name     */
  175. extern bool fileinsert ();    /* insert file to cursor (jam ) */
  176. extern bool viewfile ();    /* readonly file visit (jam)    */
  177.  
  178. /*
  179. * Defined by "random.c".
  180. */
  181.  
  182. extern bool dispshift ();    /* Increment display shift   */
  183. extern bool selfinsert ();    /* Insert character  */
  184. extern bool insert_toggle ();    /* toggle insert mode  (jam)    */
  185. extern bool insertunit ();    /* insert unit  (pvr)    */
  186. extern bool showcpos ();    /* Show the cursor position */
  187. extern bool twiddle ();        /* Twiddle units        */
  188. extern bool forwdel ();        /* Forward delete       */
  189. extern bool backdel ();        /* Backward delete      */
  190. extern bool quote ();        /* Insert literal       */
  191. extern bool asciimode ();    /* display ASCII data   */
  192. extern bool ebcdicmode ();    /* display EBCDIC data   */
  193. extern bool decimalmode ();    /* display DECIMAL data   */
  194. #if    FLOAT_DISP
  195. extern bool floatmode ();    /* display FLOATING POINT data   */
  196. #endif
  197. extern bool hexmode ();        /* display HEX data   */
  198. extern bool octalmode ();    /* display OCTAL data   */
  199. extern bool binarymode ();    /* display BINARY data   */
  200. extern bool dispsize1 ();    /* display in BYTE format */
  201. extern bool dispsize2 ();    /* display in WORD format */
  202. extern bool dispsize4 ();    /* display in DWORD format*/
  203. extern bool dispswapbyte ();    /* Display swaped bytes    pvr   */
  204. extern bool yank ();        /* Yank back from killbuffer.   */
  205. extern bool linkwind ();    /* Link all windows on one buffer. */
  206. extern bool n_way_split ();    /* Split buffer into n buffers. */
  207. extern bool n_way_combine ();    /* Combine n buffers into one. */
  208.  
  209. /*
  210. * Defined by "region.c".
  211. */
  212. extern bool killregion ();    /* Kill region.         */
  213. extern bool copyregion ();    /* Copy region to kill buffer.  */
  214. extern bool save_region ();    /* Save region in named buffer. */
  215.  
  216. /*
  217. * Defined by "spawn.c".
  218. */
  219. extern bool spawncli ();    /* Run CLI in a subjob.     */
  220. extern bool clock ();        /* display time in modeline */
  221.  
  222. /*
  223. * Defined by "window.c".
  224. */
  225. extern bool reposition ();    /* Reposition window        */
  226. extern bool refresh ();        /* Refresh the screen       */
  227. extern bool nextwind ();    /* Move to the next window  */
  228. extern bool prevwind ();    /* Move to the previous window  */
  229. extern bool mvdnwind ();    /* Move window down     */
  230. extern bool mvupwind ();    /* Move window up       */
  231. extern bool onlywind ();    /* Make current window only one */
  232. extern bool delwind ();        /* Delete current window */
  233. extern bool splitwind ();    /* Split current window     */
  234. extern bool enlargewind ();    /* Enlarge display window.  */
  235. extern bool shrinkwind ();    /* Shrink window.       */
  236. extern bool screen_rows ();    /* Set the screen size  */
  237.  
  238. /*
  239. * Defined by "word.c".
  240. */
  241. extern bool backunit ();    /* Backup by units      */
  242. extern bool forwunit ();    /* Advance by units     */
  243. extern bool delfunit ();    /* Delete forward unit. */
  244. extern bool delbunit ();    /* Delete backward unit.    */
  245.  
  246. /*
  247. * Defined by "extend.c".
  248. */
  249. extern bool extend ();        /* Extended commands.       */
  250. extern bool help ();        /* Help key.            */
  251. extern bool bindtokey ();    /* Modify key bindings.     */
  252. extern bool wallchart ();    /* Make wall chart.     */
  253. extern void check_extend ();    /* load extended key file   */
  254. extern bool load_extend ();    /* load extended file by name   */
  255.  
  256. /*
  257. * Defined by "display.c
  258. */
  259. extern bool print ();        /* print window from mark to dot */
  260.  
  261. typedef struct
  262. {
  263.     short k_key;        /* Key to bind.                 */
  264.     bool (*k_funcp) ();        /* Function.            */
  265.     char *k_name;        /* Function name string.        */
  266.     bool k_modify;        /* modify bit */
  267. } KEY;
  268.  
  269. /*
  270. * Default key binding table. This contains
  271. * the function names, the symbol table name, and (possibly)
  272. * a key binding for the builtin functions. There are no
  273. * bindings for C-U or C-X. These are done with special
  274. * code, but should be done normally.
  275. */
  276. KEY key[] =
  277. {
  278.     KCTRL | 'A', dispshift, MSG_byte_shift, 0,
  279.     KCTRL | 'B', backchar, MSG_back_char, SSRCH | SRPLC,
  280.     KCTRL | 'C', quit, MSG_quit, 0,    /* pvr */
  281.     KCTRL | 'D', forwdel, MSG_forw_del_char, SMOD | SSIZE | SSRCH | SRPLC,
  282.     KCTRL | 'E', dispswapbyte, MSG_toggle_swap, SSRCH | SRPLC,    /* pvr */
  283.     KCTRL | 'F', forwchar, MSG_forw_char, SSRCH | SRPLC,
  284.     KCTRL | 'G', ctrlg, MSG_abort, SSRCH | SRPLC,
  285.     KCTRL | 'I', selfinsert, MSG_ins_self, SMOD | SSRCH | SRPLC,
  286.     KCTRL | 'H', backdel, MSG_back_del_char, SMOD | SSIZE | SSRCH | SRPLC,
  287.     KCTRL | 'L', refresh, MSG_refresh, SSRCH | SRPLC,
  288.     KCTRL | 'N', forwline, MSG_forw_line, SSRCH | SRPLC,
  289.     KCTRL | 'P', backline, MSG_back_line, SSRCH | SRPLC,
  290.     KCTRL | 'Q', quote, MSG_quote, 0,
  291.     KCTRL | 'R', recall, MSG_recall, SSRCH | SRPLC,
  292.     KCTRL | 'T', twiddle, MSG_twiddle, SMOD | SSRCH | SRPLC,
  293.     KCTRL | 'V', forwpage, MSG_forw_page, SRPLC,
  294.     KCTRL | 'W', killregion, MSG_kill_region, SMOD | SSIZE,
  295.     KCTRL | 'Y', yank, MSG_yank, SMOD | SSIZE,
  296.     KCTRL | 'Z', mvdnwind, MSG_down_window, 0,    /* fitz */
  297.     KCTLX | KCTRL | 'A', insert_toggle, MSG_ins_toggle, SSRCH | SRPLC,
  298.     KCTLX | KCTRL | 'B', listbuffers, MSG_display_buffers, 0,
  299.     KCTLX | KCTRL | 'C', quit, MSG_quit, 0,
  300.     KCTLX | KCTRL | 'E', flushnquit, MSG_exit_flush_all, 0,    /* fitz */
  301.     KCTLX | KCTRL | 'F', filename, MSG_set_file_name, SMOD,    /* jam */
  302.     KCTLX | KCTRL | 'I', fileinsert, MSG_file_insert, SMOD | SSIZE,
  303.     KCTLX | KCTRL | 'L', bufsizlock, MSG_buf_size_lock, 0,
  304.     KCTLX | KCTRL | 'M', flush_all, MSG_flush_all, 0,
  305.     KCTLX | KCTRL | 'N', mvdnwind, MSG_down_window, 0,
  306.     KCTLX | KCTRL | 'P', mvupwind, MSG_up_window, 0,
  307.     KCTLX | KCTRL | 'R', fileread, MSG_file_read, 0,
  308.     KCTLX | KCTRL | 'S', filesave, MSG_file_save, 0,
  309.     KCTLX | KCTRL | 'V', filevisit, MSG_file_visit, 0,
  310.     KCTLX | KCTRL | 'W', filewrite, MSG_file_write, 0,
  311.     KCTLX | KCTRL | 'X', swapmark, MSG_swap_dot_and_mark, 0,
  312.     KCTLX | KCTRL | 'Z', shrinkwind, MSG_shrink_window, 0,
  313.     KCTLX | '=', showcpos, MSG_display_position, 0,
  314.     KCTLX | '(', ctlxlp, MSG_start_macro, 0,
  315.     KCTLX | ')', ctlxrp, MSG_end_macro, 0,
  316.     KCTLX | '?', help, MSG_help, 0,
  317.     KCTLX | '0', delwind, MSG_del_window, 0,
  318.     KCTLX | '1', onlywind, MSG_only_window, 0,
  319.     KCTLX | '2', splitwind, MSG_split_window, 0,
  320.     KCTLX | 'B', usebuffer, MSG_use_buffer, 0,
  321.     KCTLX | 'C', spawncli, MSG_spawn_cli, 0,    /* fitz */
  322.     KCTLX | 'E', ctlxe, MSG_execute_macro, 0,
  323.     KCTLX | 'G', gotoline, MSG_goto_line, 0,
  324.     KCTLX | 'I', insertunit, MSG_ins_unit, SMOD | SSIZE | SSRCH | SRPLC,
  325.     KCTLX | 'K', killbuffer, MSG_kill_buffer, 0,
  326.     KCTLX | 'L', load_extend, MSG_load_bindings, 0,
  327.     KCTLX | 'N', nextwind, MSG_forw_window, 0,
  328.     KCTLX | 'P', prevwind, MSG_back_window, 0,
  329.     KCTLX | 'V', viewfile, MSG_view_file, 0,    /* jam */
  330.     KCTLX | 'Z', enlargewind, MSG_enlarge_window, 0,
  331.     KMETA | KCTRL | 'A', asciimode, MSG_ascii_mode, SSRCH | SRPLC,    /* pvr */
  332.     KMETA | KCTRL | 'B', binarymode, MSG_binary_mode, SSRCH | SRPLC,    /* pvr */
  333.     KMETA | KCTRL | 'D', decimalmode, MSG_decimal_mode, SSRCH | SRPLC,    /* pvr */
  334.     KMETA | KCTRL | 'E', ebcdicmode, MSG_ebcdic_mode, SSRCH | SRPLC,    /* pvr */
  335. #if    FLOAT_DISP
  336.     KMETA | KCTRL | 'F', floatmode, MSG_float_mode, SSRCH | SRPLC,    /* pvr */
  337. #endif
  338.     KMETA | KCTRL | 'H', hexmode, MSG_hex_mode, SSRCH | SRPLC,    /* pvr */
  339.     KMETA | KCTRL | 'K', delbunit, MSG_back_del_unit, SMOD | SSIZE | SSRCH | SRPLC,
  340.     KMETA | KCTRL | 'N', buffername, MSG_buffer_name, 0,
  341.     KMETA | KCTRL | 'O', octalmode, MSG_octal_mode, SSRCH | SRPLC,    /* pvr */
  342.     KMETA | KCTRL | 'P', n_way_combine, MSG_n_combine, SSIZE | SMOD,    /* pvr */
  343.     KMETA | KCTRL | 'R', screen_rows, MSG_scr_row, 0,    /* pvr */
  344.     KMETA | KCTRL | 'S', n_way_split, MSG_n_split, 0,    /* pvr */
  345.     KMETA | KCTRL | 'V', showversion, MSG_display_version, 0,
  346.     KMETA | KCTRL | 'W', showsavebuf, MSG_show_save_buf, 0,
  347.     KMETA | '1', dispsize1, MSG_unit_size1, SSRCH | SRPLC,    /* pvr */
  348.     KMETA | '2', dispsize2, MSG_unit_size2, SSRCH | SRPLC,    /* pvr */
  349.     KMETA | '4', dispsize4, MSG_unit_size4, SSRCH | SRPLC,    /* pvr */
  350.     KMETA | '!', reposition, MSG_reposition_window, 0,
  351.     KMETA | '.', setmark, MSG_set_mark, 0,
  352.     KMETA | '>', gotoeob, MSG_goto_eob, SSRCH | SRPLC,
  353.     KMETA | '<', gotobob, MSG_goto_bob, SSRCH | SRPLC,
  354.     KMETA | '+', next_buf, MSG_next_buff, 0,
  355.     KMETA | '-', prev_buf, MSG_prev_buff, 0,
  356.     KMETA | '%', queryrepl, MSG_query_replace, SMOD,
  357.     KMETA | '?', wallchart, MSG_display_bindings, 0,
  358.     KMETA | 'A', autosave, MSG_auto_save, 0,
  359.     KMETA | 'B', backunit, MSG_back_unit, SSRCH | SRPLC,
  360.     KMETA | 'C', compare, MSG_compare, 0,
  361.     KMETA | 'D', delfunit, MSG_forw_del_unit, SMOD | SSIZE | SSRCH | SRPLC,
  362.     KMETA | 'F', forwunit, MSG_forw_unit, SSRCH | SRPLC,
  363.     KMETA | 'G', use_buffer, MSG_use_buffer_split, 0,
  364.     KMETA | 'K', bindtokey, MSG_bind_to_key, 0,
  365.     KMETA | 'L', linkwind, MSG_link_windows, 0,
  366.     KMETA | 'O', save_region, MSG_save_region, 0,
  367.     KMETA | 'P', print, MSG_print, 0,
  368.     KMETA | 'R', backsearch, MSG_back_search, 0,
  369.     KMETA | 'S', forwsearch, MSG_forw_search, 0,
  370.     KMETA | 'T', searchagain, MSG_search_again, 0,
  371.     KMETA | 'U', file_visit, MSG_file_visit_split, 0,
  372.     KMETA | 'V', backpage, MSG_back_page, SRPLC,
  373.     KMETA | 'W', copyregion, MSG_copy_region, 0,
  374.     KMETA | 'X', extend, MSG_extended_command, 0,
  375.     KMETA | 'Y', yank_buffer, MSG_yank_buffer, SMOD | SSIZE,
  376.     KMETA | 'Z', mvupwind, MSG_up_window, 0
  377. };
  378.  
  379. #define NKEY    (sizeof(key) / sizeof(key[0]))
  380.  
  381. /*
  382. * Symbol table lookup.
  383. * Return a pointer to the SYMBOL node, or NULL if
  384. * the symbol is not found.
  385. */
  386. SYMBOL *
  387. symlookup (cp)
  388.     register char *cp;
  389. {
  390.     register SYMBOL *sp;
  391.  
  392.     sp = symbol[symhash (cp)];
  393.     while (sp != NULL)
  394.     {
  395.     if (strcmp (cp, sp->s_name) == 0)
  396.         return (sp);
  397.     sp = sp->s_symp;
  398.     }
  399.     return (NULL);
  400. }
  401.  
  402. /*
  403. * Take a string, and compute the symbol table
  404. * bucket number. This is done by adding all of the characters
  405. * together, and taking the sum mod NSHASH. The string probably
  406. * should not contain any GR characters; if it does the "*cp"
  407. * may get a nagative number on some machines, and the "%"
  408. * will return a negative number!
  409. */
  410. int
  411. symhash (cp)
  412.     register char *cp;
  413. {
  414.     register int c;
  415.     register int n;
  416.  
  417.     n = 0;
  418.     while ((c = *cp++) != 0)
  419.     n += c;
  420.     return (n % NSHASH);
  421. }
  422.  
  423. /*
  424. * Build initial keymap. The funny keys
  425. * (commands, odd control characters) are mapped using
  426. * a big table and calls to "keyadd". The printing characters
  427. * are done with some do-it-yourself handwaving. The terminal
  428. * specific keymap initialization code is called at the
  429. * very end to finish up. All errors are fatal.
  430. */
  431. void
  432. keymapinit ()
  433. {
  434.     register SYMBOL *sp;
  435.     register KEY *kp;
  436.     register int i;
  437.  
  438.     for (i = 0; i < NKEYS; ++i)
  439.     binding[i] = NULL;
  440.     for (kp = &key[0]; kp < &key[NKEY]; ++kp)
  441.         keyadd (kp->k_key, (bool (*)()) kp->k_funcp, kp->k_name, kp->k_modify);
  442.     keydup (KCTLX | KCTRL | 'G', MSG_abort);
  443.     keydup (KMETA | KCTRL | 'G', MSG_abort);
  444.     keydup (0x7F, MSG_back_del_char);
  445.     keydup (KMETA | 'Q', MSG_quote);
  446.     keydup (KMETA | 0x7F, MSG_back_del_unit);
  447.     /*
  448.   * Should be bound by "tab" already.
  449.   */
  450.     if ((sp = symlookup (MSG_ins_self)) == NULL)
  451.     abort ();
  452.     for (i = 0x20; i < 0x7F; ++i)
  453.     {
  454.     if (binding[i] != NULL)
  455.         abort ();
  456.     binding[i] = sp;
  457.     ++sp->s_nkey;
  458.     }
  459.     ttykeymapinit ();
  460. }
  461.  
  462. /*
  463. * Create a new builtin function "name"
  464. * with function "funcp". If the "new" is a real
  465. * key, bind it as a side effect. All errors
  466. * are fatal.
  467. */
  468. void
  469. keyadd (new, funcp, name, modify)
  470.     short new;
  471. bool (*funcp) (void);
  472.     char *name;
  473.     int modify;
  474. {
  475.     register SYMBOL *sp;
  476.     register int hash;
  477.  
  478.     if ((sp = (SYMBOL *) malloc (sizeof (SYMBOL))) == NULL)
  479.     abort ();
  480.     hash = symhash (name);
  481.     sp->s_symp = symbol[hash];
  482.     symbol[hash] = sp;
  483.     sp->s_nkey = 0;
  484.     sp->s_name = name;
  485.     sp->s_funcp = funcp;
  486.     sp->s_modify = modify;
  487.     if (new >= 0)
  488.     {
  489.     /* Bind this key.       */
  490.     if (binding[new] != NULL)
  491.         abort ();
  492.     binding[new] = sp;
  493.     ++sp->s_nkey;
  494.     }
  495. }
  496.  
  497. /*
  498. * Bind key "new" to the existing
  499. * routine "name". If the name cannot be found,
  500. * or the key is already bound, abort.
  501. */
  502. void
  503. keydup (new, name)
  504.     register int new;
  505.     char *name;
  506. {
  507.     register SYMBOL *sp;
  508.  
  509.     if (binding[new] != NULL || (sp = symlookup (name)) == NULL)
  510.     {
  511.     printf (MSG_no_f_tb, name);
  512.     abort ();
  513.     }
  514.     binding[new] = sp;
  515.     ++sp->s_nkey;
  516. }
  517.