home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / beav1402.zip / symbol.c < prev    next >
Text File  |  1993-04-16  |  18KB  |  521 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 char ctrlg ();        /* Abort out of things      */
  118. extern char quit ();        /* Quit             */
  119. extern char ctlxlp ();        /* Begin macro          */
  120. extern char ctlxrp ();        /* End macro            */
  121. extern char ctlxe ();        /* Execute macro        */
  122. extern char showversion ();    /* Show version numbers, etc.   */
  123. extern char flushnquit ();    /* Flush buffers & exit (fitz)  */
  124. extern char flush_all ();    /* Flush buffers (jam)      */
  125. extern char autosave ();    /* autosave function (jam)  */
  126.  
  127. /*
  128. * Defined by "search.c".
  129. */
  130. extern char forwsearch ();    /* Search forward       */
  131. extern char backsearch ();    /* Search backwards     */
  132. extern char searchagain ();    /* Repeat last search command   */
  133. extern char queryrepl ();    /* Query replace        */
  134. extern char compare ();        /* Compare two windows  */
  135. extern char recall ();        /* Recall last search string  */
  136.  
  137. /*
  138. * Defined by "basic.c".
  139. */
  140. extern char backchar ();    /* Move backward by characters  */
  141. extern char forwchar ();    /* Move forward by characters   */
  142. extern char gotobob ();        /* Move to start of buffer  */
  143. extern char gotoeob ();        /* Move to end of buffer    */
  144. extern char forwline ();    /* Move forward by lines    */
  145. extern char backline ();    /* Move backward by lines   */
  146. extern char forwpage ();    /* Move forward by pages    */
  147. extern char backpage ();    /* Move backward by pages   */
  148. extern char setmark ();        /* Set mark         */
  149. extern char swapmark ();    /* Swap "." and mark        */
  150. extern char gotoline ();    /* Go to a specified line.  */
  151.  
  152. /*
  153. * Defined by "buffer.c".
  154. */
  155. extern char listbuffers ();    /* Display list of buffers  */
  156. extern char showsavebuf ();    /* Show the save buffer contents */
  157. extern char usebuffer ();    /* Switch a window to a buffer  */
  158. extern char use_buffer ();    /* ditto, plus window split */
  159. extern char killbuffer ();    /* Make a buffer go away.   */
  160. extern char next_buf ();    /* goto next buffer     */
  161. extern char prev_buf ();    /* goto prev buffer     */
  162. extern char yank_buffer ();    /* yank buffer by name      */
  163. extern char buffername ();    /* change buffer name       */
  164. extern char bufsizlock ();    /* lock buffer size         */
  165.  
  166. /*
  167. * Defined by "file."
  168. */
  169. extern char fileread ();    /* Get a file, read only    */
  170. extern char filevisit ();    /* Get a file, read write   */
  171. extern char file_visit ();    /* ditto , plus window split    */
  172. extern char filewrite ();    /* Write a file         */
  173. extern char filesave ();    /* Save current file        */
  174. extern char filename ();    /* Adjust file name     */
  175. extern char fileinsert ();    /* insert file to cursor (jam ) */
  176. extern char viewfile ();    /* readonly file visit (jam)    */
  177.  
  178. /*
  179. * Defined by "random.c".
  180. */
  181.  
  182. extern char dispshift ();    /* Increment display shift   */
  183. extern char selfinsert ();    /* Insert character  */
  184. extern char insert_toggle ();    /* toggle insert mode  (jam)    */
  185. extern char insertunit ();    /* insert unit  (pvr)    */
  186. extern char showcpos ();    /* Show the cursor position */
  187. extern char twiddle ();        /* Twiddle units        */
  188. extern char forwdel ();        /* Forward delete       */
  189. extern char backdel ();        /* Backward delete      */
  190. extern char quote ();        /* Insert literal       */
  191. extern char asciimode ();    /* display ASCII data   */
  192. extern char ebcdicmode ();    /* display EBCDIC data   */
  193. extern char decimalmode ();    /* display DECIMAL data   */
  194. #if    FLOAT_DISP
  195. extern char floatmode ();    /* display FLOATING POINT data   */
  196. #endif
  197. extern char hexmode ();        /* display HEX data   */
  198. extern char octalmode ();    /* display OCTAL data   */
  199. extern char binarymode ();    /* display BINARY data   */
  200. extern char dispsize1 ();    /* display in BYTE format */
  201. extern char dispsize2 ();    /* display in WORD format */
  202. extern char dispsize4 ();    /* display in DWORD format*/
  203. extern char dispswapbyte ();    /* Display swaped bytes    pvr   */
  204. extern char yank ();        /* Yank back from killbuffer.   */
  205. extern char linkwind ();    /* Link all windows on one buffer. */
  206. extern char n_way_split ();    /* Split buffer into n buffers. */
  207. extern char n_way_combine ();    /* Combine n buffers into one. */
  208.  
  209. /*
  210. * Defined by "region.c".
  211. */
  212. extern char killregion ();    /* Kill region.         */
  213. extern char copyregion ();    /* Copy region to kill buffer.  */
  214. extern char save_region ();    /* Save region in named buffer. */
  215.  
  216. /*
  217. * Defined by "spawn.c".
  218. */
  219. extern char spawncli ();    /* Run CLI in a subjob.     */
  220. extern char clock ();        /* display time in modeline */
  221.  
  222. /*
  223. * Defined by "window.c".
  224. */
  225. extern char reposition ();    /* Reposition window        */
  226. extern char refresh ();        /* Refresh the screen       */
  227. extern char nextwind ();    /* Move to the next window  */
  228. extern char prevwind ();    /* Move to the previous window  */
  229. extern char mvdnwind ();    /* Move window down     */
  230. extern char mvupwind ();    /* Move window up       */
  231. extern char onlywind ();    /* Make current window only one */
  232. extern char delwind ();        /* Delete current window */
  233. extern char splitwind ();    /* Split current window     */
  234. extern char enlargewind ();    /* Enlarge display window.  */
  235. extern char shrinkwind ();    /* Shrink window.       */
  236. extern char screen_rows ();    /* Set the screen size  */
  237.  
  238. /*
  239. * Defined by "word.c".
  240. */
  241. extern char backunit ();    /* Backup by units      */
  242. extern char forwunit ();    /* Advance by units     */
  243. extern char delfunit ();    /* Delete forward unit. */
  244. extern char delbunit ();    /* Delete backward unit.    */
  245.  
  246. /*
  247. * Defined by "extend.c".
  248. */
  249. extern char extend ();        /* Extended commands.       */
  250. extern char help ();        /* Help key.            */
  251. extern char bindtokey ();    /* Modify key bindings.     */
  252. extern char wallchart ();    /* Make wall chart.     */
  253. extern void check_extend ();    /* load extended key file   */
  254. extern char load_extend ();    /* load extended file by name   */
  255.  
  256. /*
  257. * Defined by "display.c
  258. */
  259. extern char print ();        /* print window from mark to dot */
  260.  
  261. typedef struct
  262. {
  263.     short k_key;        /* Key to bind.                 */
  264.     char (*k_funcp) ();        /* Function.            */
  265.     char *k_name;        /* Function name string.        */
  266.     char 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, 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. #ifdef    NOPROTO
  472. bool (*funcp) ();
  473. #else
  474. bool (*funcp) (void);
  475. #endif
  476.     char *name;
  477.     int modify;
  478. {
  479.     register SYMBOL *sp;
  480.     register int hash;
  481.  
  482.     if ((sp = (SYMBOL *) malloc (sizeof (SYMBOL))) == NULL)
  483.     abort ();
  484.     hash = symhash (name);
  485.     sp->s_symp = symbol[hash];
  486.     symbol[hash] = sp;
  487.     sp->s_nkey = 0;
  488.     sp->s_name = name;
  489.     sp->s_funcp = funcp;
  490.     sp->s_modify = modify;
  491.     if (new >= 0)
  492.     {
  493.     /* Bind this key.       */
  494.     if (binding[new] != NULL)
  495.         abort ();
  496.     binding[new] = sp;
  497.     ++sp->s_nkey;
  498.     }
  499. }
  500.  
  501. /*
  502. * Bind key "new" to the existing
  503. * routine "name". If the name cannot be found,
  504. * or the key is already bound, abort.
  505. */
  506. void
  507. keydup (new, name)
  508.     register int new;
  509.     char *name;
  510. {
  511.     register SYMBOL *sp;
  512.  
  513.     if (binding[new] != NULL || (sp = symlookup (name)) == NULL)
  514.     {
  515.     printf (MSG_no_f_tb, name);
  516.     abort ();
  517.     }
  518.     binding[new] = sp;
  519.     ++sp->s_nkey;
  520. }
  521.