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