home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1821.lha / XDME / keytables.c < prev    next >
C/C++ Source or Header  |  1993-03-25  |  25KB  |  1,278 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     keytables.c
  5.  
  6.     DESCRIPTION
  7.     Management for Key-Hashing tables
  8.  
  9.     NOTES
  10.     original from M.Dillon
  11.  
  12.     for the first(!) call of any function of that module,
  13.     the corresponding HASH-table must be clean (setmem(...,0))
  14.  
  15.     BUGS
  16.     thousands - but where
  17.     there may be some inconsistencies
  18.  
  19.     TODO
  20.     new method for management of hashes
  21.     resolve the references to av[]
  22.  
  23.     EXAMPLES
  24.  
  25.     SEE ALSO
  26.     keycodes.c keycom.c keycontrol.c
  27.  
  28.     INDEX
  29.  
  30.     HISTORY
  31.     14-Dec-92  b_null created
  32.     15-Dez-92  b_null modified
  33.     15-Dez-92  b_null docs updated, some checks added
  34.     16-Dez-92  b_null documented
  35.  
  36. ******************************************************************************/
  37.  
  38. /**************************************
  39.         Includes
  40. **************************************/
  41. #include "defs.h"
  42. #include <devices/keymap.h>
  43. #include <devices/console.h>
  44. #include "keyhashes.h"
  45.  
  46.  
  47. /**************************************
  48.         Globale Variable
  49. **************************************/
  50.  
  51. Prototype void     keyload    (KEYTABLE * kt, char * name);
  52. Prototype void     keysave    (KEYTABLE * kt, char * name);
  53. Prototype int     loadkeys    (KEYTABLE * kt, FILE * fi, int * lineno);
  54. Prototype int     savekeys    (KEYTABLE * kt, FILE * fo);
  55. Prototype HASH * findhash    (KEYTABLE * kt, UBYTE code, USHORT qual);
  56. Prototype APTR     keyspec2macro    (KEYTABLE * kt, char * str);
  57. Prototype int     resethash    (KEYTABLE * kt);
  58. Prototype int     unmapkey    (KEYTABLE * kt, char * key);
  59. Prototype int     mapkey     (KEYTABLE * kt, char * key, char * value);
  60. Prototype int     remhash    (KEYTABLE * kt, UBYTE code, USHORT mask, USHORT qual);
  61. Prototype int     addhash    (KEYTABLE * kt, UBYTE code, USHORT mask, USHORT qual, const UBYTE * comm, const UBYTE * help);
  62. Prototype void     dealloc_hash    (KEYTABLE * kt);
  63.  
  64. Prototype KEYTABLE * get_keytable    (char * name);
  65. Prototype KEYTABLE * new_keytable    (char * name, int defaults);
  66. Prototype void         delete_keytable (KEYTABLE * kt, int force);
  67.  
  68. Prototype void         exit_keytables (void);
  69.  
  70. /**************************************
  71.       Interne Defines & Strukturen
  72. **************************************/
  73.  
  74. #define HASHMASK  (HASHSIZE-1)
  75. #define QUALMASK  0x3ff
  76.  
  77.  
  78. /**************************************
  79.         Interne Variable
  80. **************************************/
  81. /* extern TWOSTRINGS defmap[]; */
  82. #include "defmap.h"
  83.  
  84.  
  85. /* this is the list of all keytables */
  86. static struct MinList KeyTables = { &KeyTables.mlh_Tail, NULL, &KeyTables.mlh_Head };
  87.  
  88. /**************************************
  89.        Interne Prototypes
  90. **************************************/
  91.  
  92.  
  93.  
  94. /*****************************************************************************
  95.  
  96.     NAME
  97.     freehash
  98.  
  99.     PARAMETER
  100.     HASH * hash
  101.  
  102.     RESULT
  103.     the hash->next entry if existing
  104.     NULL if hash == NULL
  105.  
  106.     RETURN
  107.     HASH *
  108.  
  109.     DESCRIPTION
  110.     free a hash-entry and all associated data
  111.  
  112.     NOTES
  113.     the free'd hash must not be entry in a hashtable,
  114.     as we do not take care of any refernces, but only
  115.     of hash, comm and help
  116.  
  117.     BUGS
  118.  
  119.     EXAMPLES
  120.  
  121.     SEE ALSO
  122.  
  123.     INTERNALS
  124.  
  125.     HISTORY
  126.     23 Jan 1993 b_null created
  127.  
  128. ******************************************************************************/
  129.  
  130. HASH * freehash (HASH * hash)
  131. {
  132.     HASH * next = NULL;
  133.  
  134.     if (hash) {
  135.     next = hash->next;
  136.     if (hash->comm) {
  137.         DeallocFunc (hash->comm);
  138.     } /* if */
  139.     if (hash->help) {
  140.         DeallocFunc (hash->help);
  141.     } /* if */
  142.     FreeFunc(hash, sizeof(HASH));
  143.     } /* if */
  144.  
  145.     return (next);
  146. } /* freehash */
  147.  
  148.  
  149.  
  150. /*****************************************************************************
  151.  
  152.     NAME
  153.     addhash
  154.  
  155.     PARAMETER
  156.     KEYTABLE * kt
  157.     UBYTE    code
  158.     USHORT    mask
  159.     USHORT    qual
  160.     char  * comm
  161.     char  * help
  162.  
  163.     RESULT
  164.     success: RET_SUCC == ok; RET_FAIL == failure
  165.  
  166.     RETURN
  167.     int
  168.  
  169.     DESCRIPTION
  170.     create a new hash-entry for a known hash
  171.     if there is already an existing one with the same code/qual
  172.     simply change its command
  173.  
  174.     NOTES
  175.     that function is called by mapkey
  176.  
  177.     BUGS
  178.     WARNING : WE DO NOT LOOK FOR A SETTING OF help YET !!!
  179.  
  180.     EXAMPLES
  181.  
  182.     SEE ALSO
  183.  
  184.     INTERNALS
  185.     finde den hash-slot
  186.     falls der eintrag schon existiert, ersetze den comm
  187.     sonst erstelle einen neuen eintrag
  188.     falls nicht alles funktionierte, stelle den alten zustand wieder her
  189.  
  190.     HISTORY
  191.     14-Dec-92  b_null included & modified
  192.     16-Dec-92  b_null added handling of "nolink"
  193.  
  194. ******************************************************************************/
  195.  
  196. int addhash (KEYTABLE * kt, UBYTE code, USHORT mask, USHORT qual, const UBYTE * comm, const UBYTE * help)
  197. {
  198.     HASH ** p,
  199.       * hash;
  200.     APTR    oldcomm = NULL;
  201.  
  202.     if (kt == NULL) {
  203.     return (RET_FAIL);
  204.     } /* if empty or missing table */
  205.  
  206.     hash = *(p = &kt->hash[code&HASHMASK]);
  207.  
  208.     while (hash) {
  209.     if (hash->code == code && hash->qual == qual && hash->mask == mask) {
  210.         goto newstr;
  211.     } /* if found old */
  212.     hash = *(p = &hash->next);
  213.     } /* while entries left */
  214.  
  215.     hash  = (HASH *)AllocFunc (sizeof (HASH), MEMF_ANY);
  216.     clrmem (hash, sizeof (HASH));
  217.  
  218.     if (hash == NULL) {
  219.     globalflags.Abortcommand = 1;
  220.     return (RET_FAIL);
  221.     } /* if nomemory */
  222.  
  223.     hash->next = NULL;
  224.     hash->code = code;
  225.     hash->mask = mask;
  226.     hash->qual = qual;
  227.  
  228. newstr:
  229.     /* oldcomm = hash->comm; */
  230.     DeallocFunc (hash->comm);
  231.     DeallocFunc (hash->help);
  232.  
  233.     hash->comm = DupFunc (comm, 0);
  234.     hash->help = DupFunc (help, 0);
  235.  
  236.     if ((!hash->comm) /* || (!hash->help) */ /* || (oldcomm == hash->comm) */) {
  237.     *p = freehash (hash);
  238.     return (RET_FAIL);
  239.     } /* if something went wrong */
  240.  
  241.     /* everything worked fine - insert it into the table */
  242.     *p = hash;
  243.     return (RET_SUCC);
  244. } /* addhash */
  245.  
  246.  
  247.  
  248. /*****************************************************************************
  249.  
  250.     NAME
  251.     remhash
  252.  
  253.     PARAMETER
  254.     KEYTABLE * kt
  255.     UBYTE    code
  256.     USHORT    mask
  257.     USHORT    qual
  258.  
  259.     RESULT
  260.     success:
  261.         RET_SUCC == ok;
  262.         RET_FAIL == failure or not found
  263.  
  264.     RETURN
  265.     int
  266.  
  267.     DESCRIPTION
  268.     delete an existing hashentry
  269.  
  270.     NOTES
  271.     that function is called by unmapkey
  272.  
  273.     BUGS
  274.  
  275.     EXAMPLES
  276.  
  277.     SEE ALSO
  278.  
  279.     INTERNALS
  280.     finde den hash-slot
  281.     falls der eintrag existiert, loesche ihn und seinen link
  282.     sonst mache gar nichts
  283.  
  284.     HISTORY
  285.     14-Dec-92  b_null included & modified
  286.     23-Jan-93  b_null used freehash
  287.  
  288. ******************************************************************************/
  289.  
  290. int remhash (KEYTABLE * kt, UBYTE code, USHORT mask, USHORT qual)
  291. {
  292.     HASH *  hash, /* current */
  293.      ** p;      /* previous */
  294.  
  295.     if (kt == NULL) {
  296.     return (RET_FAIL);
  297.     } /* if empty or missing table */
  298.  
  299.     hash = *(p = &kt->hash[code&HASHMASK]);
  300.     while (hash) {
  301.     if (hash->code == code && hash->qual == qual && hash->mask == mask) {
  302.         *p = freehash (hash);
  303.         return   (RET_SUCC);
  304.     } /* if found */
  305.     hash = *(p = &hash->next);
  306.     } /* while searching */
  307.  
  308.     /* not found: */
  309.     return (RET_FAIL);
  310. } /* remhash */
  311.  
  312.  
  313.  
  314. /*****************************************************************************
  315.  
  316.     NAME
  317.     mapkey
  318.  
  319.     PARAMETER
  320.     KEYTABLE * kt
  321.     char *    key
  322.     char *    value
  323.  
  324.     RESULT
  325.     success:
  326.         RET_FAIL == error
  327.         RET_OK   == everything ok
  328.  
  329.     RETURN
  330.     int
  331.  
  332.     DESCRIPTION
  333.     first abstraction for addhash
  334.     which uses an ascii-name
  335.  
  336.     NOTES
  337.     this function might call error()
  338.  
  339.     BUGS
  340.  
  341.     EXAMPLES
  342.  
  343.     SEE ALSO
  344.     addhash, unmapkey
  345.  
  346.     INTERNALS
  347.     falls es sich um einen gueltigen map handelt
  348.         belege ihn (neu)
  349.     sonst gebe eine fehlermeldung aus
  350.  
  351.     HISTORY
  352.     14-Dec-92  b_null included & modified
  353.     23-Jan-93  b_null void -> int
  354.  
  355. ******************************************************************************/
  356.  
  357. int mapkey (KEYTABLE * kt, char * key, char * value)
  358. /* char * help */
  359. {
  360.     UBYTE  code;
  361.     USHORT qual;
  362.  
  363.     if (get_codequal (key, &code, &qual)) {
  364.     return (addhash (kt, code, QUALMASK, qual, value, NULL)); /* help)); */
  365.     } else {
  366.     error ("%s:\nUnknown Key '%s'", CommandName(), key);
  367.     }
  368.     return (RET_FAIL);
  369. } /* mapkey */
  370.  
  371.  
  372.  
  373. /*****************************************************************************
  374.  
  375.     NAME
  376.     unmapkey
  377.  
  378.     PARAMETER
  379.     KEYTABLE * kt
  380.     char *    key
  381.  
  382.     RESULT
  383.     success:
  384.         RET_FAIL == error
  385.         RET_OK   == everything ok
  386.  
  387.     RETURN
  388.     int
  389.  
  390.     DESCRIPTION
  391.     first abstraction for remhash
  392.     which uses an ascii-name
  393.  
  394.     NOTES
  395.     this function might call error()
  396.  
  397.     BUGS
  398.  
  399.     EXAMPLES
  400.  
  401.     SEE ALSO
  402.     remhash, mapkey
  403.  
  404.     INTERNALS
  405.     falls es sich um einen gueltigen map handelt
  406.         loesche seine belegung
  407.     sonst gebe eine fehlermeldung aus
  408.  
  409.     HISTORY
  410.     14-Dec-92  b_null included & modified
  411.     23-Jan-93  b_null void -> int
  412.  
  413. ******************************************************************************/
  414.  
  415. int unmapkey (KEYTABLE * kt, char * key)
  416. {
  417.     UBYTE  code;
  418.     USHORT qual;
  419.  
  420.     if (get_codequal(key, &code, &qual)) {
  421.     return (remhash (kt, code, QUALMASK, qual));
  422.     } else {
  423.     error ("%s:\nUnknown Key '%s'", CommandName(), key);
  424.     }
  425.     return (RET_FAIL);
  426. } /* unmapkey */
  427.  
  428.  
  429.  
  430. /*****************************************************************************
  431.  
  432.     NAME
  433.     dealloc_hash
  434.  
  435.     PARAMETER
  436.     KEYTABLE * kt
  437.  
  438.     RESULT
  439.     -/-
  440.  
  441.     RETURN
  442.     void
  443.  
  444.     DESCRIPTION
  445.     frees all Hash-entries in a key-table
  446.  
  447.     NOTES
  448.  
  449.     BUGS
  450.  
  451.     EXAMPLES
  452.  
  453.     SEE ALSO
  454.  
  455.     INTERNALS
  456.     ueber allen hash-slots
  457.         loesche jeden eintrag des hash-slots
  458.  
  459.     HISTORY
  460.     14-Dec-92  b_null included & modified
  461.  
  462. ******************************************************************************/
  463.  
  464. void dealloc_hash ( KEYTABLE * kt )
  465. {
  466.     HASH * hash,
  467.      * hnext = NULL;  /* save ptr to the next entry when freeing the current */
  468.     short  i;
  469.  
  470.     if (kt == NULL) {
  471.     return ();
  472.     } /* if empty or missing table */
  473.  
  474.     for (i = 0; i < HASHSIZE; i++) {
  475.     for (hash = kt->hash[i]; hash; hash = hnext) {
  476.         hnext = freehash (hash);
  477.     } /* for */
  478.     kt->hash[i] = NULL;
  479.     } /* for */
  480. } /* dealloc_hash */
  481.  
  482.  
  483.  
  484. /*****************************************************************************
  485.  
  486.     NAME
  487.     resethash
  488.  
  489.     PARAMETER
  490.     KEYTABLE * kt
  491.  
  492.     RESULT
  493.     success:
  494.         RET_FAIL == error (might have worked partially)
  495.         RET_OK   == everything ok
  496.  
  497.     RETURN
  498.     int
  499.  
  500.     DESCRIPTION
  501.     dealloc all entries of a hashtable and then
  502.     set its contents to default-values
  503.  
  504.     NOTES
  505.     the defaults are stored in an array
  506.     called defmap
  507.  
  508.     BUGS
  509.  
  510.     EXAMPLES
  511.  
  512.     SEE ALSO
  513.     mapkey, dealloc_hash
  514.  
  515.     INTERNALS
  516.     loesche die tabelle
  517.     solange noch ein gueltiger eintrag in defmap ist (und alles gutging)
  518.         erzeuge eine map fuer ihn
  519.  
  520.     HISTORY
  521.     14-Dec-92  b_null included
  522.     16-Dec-92  b_null documented
  523.  
  524. ******************************************************************************/
  525.  
  526. int resethash (KEYTABLE * kt)
  527. {
  528.     short i;
  529.  
  530.     if (kt == NULL) {
  531.     return (RET_FAIL);
  532.     } /* if empty or missing table */
  533.  
  534.     dealloc_hash (kt);
  535.  
  536.     for (i = 0; defmap[i].from; ++i) {
  537.     if (!mapkey (kt, defmap[i].from, defmap[i].to)) { /* ,defmap[i].help)) */
  538.         return (RET_FAIL);
  539.     } /* if error */
  540.     } /* for defmap-entries */
  541.  
  542.     return (RET_SUCC);
  543. } /* resethash */
  544.  
  545.  
  546.  
  547. /*****************************************************************************
  548.  
  549.     NAME
  550.     findhash
  551.  
  552.     PARAMETER
  553.     KEYTABLE * kt
  554.     UBYTE    code
  555.     USHORT    qual
  556.  
  557.     RESULT
  558.     the hash-entry associated with code and qual
  559.  
  560.     RETURN
  561.     HASH *
  562.  
  563.     DESCRIPTION
  564.     simple searching
  565.  
  566.     NOTES
  567.     this routine is part of keyspec2macro
  568.  
  569.     BUGS
  570.  
  571.     EXAMPLES
  572.  
  573.     SEE ALSO
  574.     keyspec2macro
  575.  
  576.     INTERNALS
  577.     finde den richtigen slot
  578.     solange es noch eintraege in dem slot gibe, und der richtige nicht
  579.         gefunden ist,
  580.         gehe zum naechsten eintrag
  581.     wenn du was gefunden hast, gib es aus, sonst NULL
  582.  
  583.     HISTORY
  584.     16-Dec-92  b_null created
  585.  
  586. ******************************************************************************/
  587.  
  588. HASH * findhash (KEYTABLE * kt, UBYTE code, USHORT qual)
  589. {
  590.     HASH * hash;
  591.  
  592.     if (kt == NULL) {
  593.     return (NULL);
  594.     } /* if empty or missing table */
  595.  
  596.     for (hash = kt->hash[code&HASHMASK]; hash; hash = hash->next) {
  597.     if (hash->code == code) {
  598.         if (hash->qual == (qual & hash->mask)) {
  599.         return (hash);
  600.         }
  601.     }
  602.     }
  603.     return (NULL);
  604. } /* findhash */
  605.  
  606.  
  607.  
  608. /*****************************************************************************
  609.  
  610.     NAME
  611.     keyspectohash
  612.  
  613.     PARAMETER
  614.     KEYTABLE * kt
  615.     char *    str
  616.  
  617.     RESULT
  618.     the Hashentry associated with
  619.     the name str
  620.  
  621.     RETURN
  622.     HASH *
  623.  
  624.     DESCRIPTION
  625.     transform str into a Hash-value and search for its entry
  626.  
  627.     NOTES
  628.     this routine uses findhash
  629.  
  630.     BUGS
  631.  
  632.     EXAMPLES
  633.  
  634.     SEE ALSO
  635.     findhash
  636.  
  637.     INTERNALS
  638.     falls es sich um einen gueltigen schluessel handelt,
  639.         finde eine passenden eintrag und
  640.         gib ihn aus
  641.     sonst gib NULL aus
  642.  
  643.     HISTORY
  644.     23-Jan-93  b_null created
  645.  
  646. ******************************************************************************/
  647.  
  648. HASH * keyspectohash (KEYTABLE * kt, char * str)
  649. {
  650.     UBYTE  code;
  651.     USHORT qual;
  652.  
  653.     if (get_codequal(str, &code, &qual)) {
  654.     return (findhash (kt, code, qual));
  655.     } /* if is key */
  656.     return (NULL);
  657. } /* keyspectohash */
  658.  
  659.  
  660.  
  661. /*****************************************************************************
  662.  
  663.     NAME
  664.     keyspec2macro
  665.  
  666.     PARAMETER
  667.     KEYTABLE * kt
  668.     char *    str
  669.  
  670.     RESULT
  671.     the macro-field of the Hashentry associated with
  672.     the name str
  673.  
  674.     RETURN
  675.     APTR
  676.  
  677.     DESCRIPTION
  678.     transform str into a Hash-value and search for its entry
  679.     then return its command-entry
  680.  
  681.     NOTES
  682.     this routine is splitted into
  683.     two minor ones by putting the searching
  684.     into another routine called findhash&keyspectohash
  685.  
  686.     BUGS
  687.  
  688.     EXAMPLES
  689.  
  690.     SEE ALSO
  691.     findhash
  692.  
  693.     INTERNALS
  694.     finde den passendedn eintrag
  695.         und gib dessen comm aus
  696.  
  697.     HISTORY
  698.     14-Dec-92  b_null included
  699.     16-Dec-92  b_null splitted & documented
  700.  
  701. ******************************************************************************/
  702.  
  703. APTR keyspec2macro (KEYTABLE * kt, char * str)
  704. {
  705.     HASH *hash;
  706.  
  707.     hash = keyspectohash (kt, str);
  708.     if (hash) {
  709.     return (hash->comm);
  710.     } /* if */
  711.     return (NULL);
  712. } /* keyspec2macro */
  713.  
  714.  
  715. /*****************************************************************************
  716.  
  717.     NAME
  718.     savekeys
  719.  
  720.     PARAMETER
  721.     KEYTABLE * kt
  722.     FILE *    fi
  723.  
  724.     RESULT
  725.     success:
  726.         RET_FAIL == error
  727.         RET_OK   == everything ok
  728.  
  729.     RETURN
  730.     int
  731.  
  732.     DESCRIPTION
  733.     write a special keymap file
  734.     or the keymap section of a file
  735.     such a section can be read with loadkeys
  736.  
  737.     NOTES
  738.     currently the keymap-section is in ascii
  739.     format - this may be changed to IFF
  740.     this function is separated from keysave for use in packages
  741.  
  742.     BUGS
  743.  
  744.     EXAMPLES
  745.  
  746.     SEE ALSO
  747.     loadkeys
  748.  
  749.     INTERNALS
  750.     schreibe einen header
  751.     gehe alle slots entlang und
  752.         schreibe alle eintraege der slots
  753.     schreibe einen footer
  754.  
  755.     HISTORY
  756.     14-Dec-92  b_null included
  757.     16-Dec-92  b_null documented
  758.  
  759. ******************************************************************************/
  760.  
  761. int savekeys (KEYTABLE * kt, FILE * fo)
  762. {
  763.     HASH * hash;
  764.     int    i;
  765.  
  766.     if (kt == NULL) {
  767.     return (RET_FAIL);
  768.     } /* if empty or missing table */
  769.  
  770.     fprintf(fo, "KEYLIST START\n");
  771.     for (i = 0; i < HASHSIZE; i++) {
  772.     for (hash = kt->hash[i]; hash; hash = hash->next) {
  773.         fprintf (fo, "\tKEY   %s\n", cqtoa (hash->code, hash->qual));
  774. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  775.      /* fprintf (fo, "\t HELP %s\n", hash->help); */
  776.         fprintf (fo, "\t COM  %s\n", hash->comm);
  777. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  778.     } /* for keys */
  779.     } /* for hashes */
  780.     fprintf(fo, "KEYLIST END\n");
  781.     return (RET_SUCC);
  782. } /* savekeys */
  783.  
  784.  
  785.  
  786. /*****************************************************************************
  787.  
  788.     NAME
  789.     loadkeys
  790.  
  791.     PARAMETER
  792.     KEYTABLE * kt
  793.     FILE *    fi
  794.     int  *    lineno
  795.  
  796.     RESULT
  797.     success:
  798.         RET_FAIL == error
  799.         RET_OK   == everything ok
  800.  
  801.     RETURN
  802.     int
  803.  
  804.     DESCRIPTION
  805.     read a special Keymap-File
  806.     or the Keymap-section of a file
  807.     which was created with savekeys
  808.  
  809.     NOTES
  810.     this function might call error()
  811.     this function is separated from keyload for use in packages
  812.     can not support "help" yet
  813.  
  814.     BUGS
  815.  
  816.     EXAMPLES
  817.  
  818.     SEE ALSO
  819.     savekeys
  820.  
  821.     INTERNALS
  822.     lese den header
  823.     solange alles gutging und der footer nicht erreicht wurde
  824.         lese nacheinander schluessel
  825.         und macro
  826.         falls eine Zeile nicht in diese Sequenz passt ABBRUCH
  827.  
  828.     das muss geaendert werden:
  829.     lese den header
  830.     solange alles gutging und der footer nicht erreicht wurde
  831.     lese  schluessel und
  832.     danach macro (und evtl help)
  833.         da die reihenfolge von macro und help variieren kann,
  834.            darf der naechste addhash erst durchgefuehrt werden beim naechsten KEY oder bei KEYLIST END
  835.  
  836.     HISTORY
  837.     14-Dec-92  b_null included
  838.     16-Dec-92  b_null documented
  839.  
  840. ******************************************************************************/
  841.  
  842. #define next_nonblank(buf) {while (*buf && *buf<33) buf++; }
  843.  
  844. int loadkeys (KEYTABLE * kt, FILE * fi, int * lineno)
  845. {
  846.     char * buf;
  847.     char   nkey   [128];
  848.     char   help   [128];
  849.     char   body   [LINE_LENGTH];
  850.  
  851.     if (kt == NULL) {
  852.     return (RET_FAIL);
  853.     } /* if empty or missing table */
  854.  
  855.     buf = getnextcomline (fi, lineno);
  856.  
  857.     if (!buf) {
  858.     globalflags.Abortcommand = 1;
  859.     return (RET_FAIL);
  860.     } /* if */
  861.     if (strncmp(buf, "KEYLIST START", 13) != 0) {
  862.     error  ("No Keystart header");
  863.     return (RET_FAIL);
  864.     } /* if */
  865.  
  866.     nkey  [0] = 0;
  867.     help  [0] = 0;
  868.     body  [0] = 0;
  869.  
  870.     while (globalflags.Abortcommand == 0) {
  871.     buf = getnextcomline(fi, lineno);
  872. /* printf("read %s\n", buf); */
  873.     if (!buf) {
  874.         globalflags.Abortcommand = 1;
  875.         return (RET_FAIL);
  876.     } /* if */
  877.  
  878.     if (strncmp(buf, "KEYLIST END", 11) == 0) {
  879.         return (RET_SUCC);
  880.     } else if (strncmp(buf, "KEY ", 4) == 0) {
  881.         buf += 3;
  882.         next_nonblank(buf);
  883.         if (nkey[0] != 0) {
  884.         error  ("<%s:\nDeclared Key w/out Body '%s'", CommandName(), buf);
  885.         return (RET_FAIL);
  886.         } /* if */
  887.         strncpy(nkey, buf, 128);
  888. #ifdef NOT_DEF
  889.     } else if (strncmp(buf, "HELP", 4) == 0) {
  890.         buf += 4;
  891.         next_nonblank(buf);
  892.         if (nkey[0] == 0) {
  893.         error  ("<%s:\nDeclared Help w/out a Key", CommandName(), buf);
  894.         return (RET_FAIL);
  895.         } /* if */
  896.         strncpy(help, buf, 128);
  897. #endif
  898.     } else if (strncmp (buf, "COM", 3) == 0) {
  899.         buf += 3;
  900.         next_nonblank(buf);
  901.         if (nkey[0] == 0) {
  902.         error  ("<%s:\nDeclared Body w/out a Key", CommandName());
  903.         return (RET_FAIL);
  904.         } /* if */
  905.         strncpy (body, buf, LINE_LENGTH);
  906.         mapkey  (kt, nkey, body); /* ,help */
  907.         help[0] = 0;
  908.         nkey[0] = 0;
  909.     } else {
  910.         error  ("%s:\nunknown identifier '%s'", CommandName(), buf);
  911.         return (RET_FAIL);
  912.     } /* if types */
  913.     } /* while not ready */
  914.     return (RET_FAIL);
  915. } /* loadkeys */
  916.  
  917.  
  918. /*****************************************************************************
  919.  
  920.     NAME
  921.     keysave
  922.  
  923.     PARAMETER
  924.     KEYTABLE * kt
  925.     char *    name
  926.  
  927.     RESULT
  928.     -/-
  929.  
  930.     RETURN
  931.     void
  932.  
  933.     DESCRIPTION
  934.     first abstraction of savekeys to single files:
  935.     handling of open&close
  936.  
  937.     NOTES
  938.  
  939.     BUGS
  940.  
  941.     EXAMPLES
  942.  
  943.     SEE ALSO
  944.     savekeys
  945.  
  946.     INTERNALS
  947.     oeffne ein file
  948.     falls das ging,
  949.         lese die enthaltenen mappings
  950.         und schliesse es
  951.     sonst gib einen Fehler aus
  952.  
  953.     HISTORY
  954.     14-Dec-92  b_null included
  955.     16-Dec-92  b_null renamed & documented
  956.  
  957. ******************************************************************************/
  958.  
  959. void keysave (KEYTABLE * kt, char * name)
  960. {
  961.     FILE * fo = NULL;
  962.  
  963.     if (fo = fopen (name, "w")) {
  964.     savekeys (kt, fo);
  965.     fclose (fo);
  966.     } else {
  967.     error ("%s:\nCan't open file %s for output", CommandName(), name);
  968.     } /* if */
  969. } /* keysave */
  970.  
  971.  
  972. /*****************************************************************************
  973.  
  974.     NAME
  975.     keyload
  976.  
  977.     PARAMETER
  978.     KEYTABLE * kt
  979.     char *    name
  980.  
  981.     RESULT
  982.     -/-
  983.  
  984.     RETURN
  985.     void
  986.  
  987.     DESCRIPTION
  988.     first abstraction of loadkeys to single files:
  989.     handling of open & close
  990.  
  991.     NOTES
  992.  
  993.     BUGS
  994.  
  995.     EXAMPLES
  996.  
  997.     SEE ALSO
  998.     loadkeys
  999.  
  1000.     INTERNALS
  1001.     oeffne ein file
  1002.     falls das ging,
  1003.         schreibe die aktuellen mappings hinein
  1004.         und schliesse es
  1005.     sonst gib einen Fehler aus
  1006.  
  1007.     HISTORY
  1008.     14-Dec-92  b_null included
  1009.     16-Dec-92  b_null renamed & documented
  1010.  
  1011. ******************************************************************************/
  1012.  
  1013. void keyload (KEYTABLE * kt, char * name)
  1014. {
  1015.     FILE * fi      = NULL;
  1016.     int    lineno = 0;
  1017.  
  1018.     if (fi = fopen (name, "r")) {
  1019.     dealloc_hash (kt);
  1020.     loadkeys (kt, fi, &lineno);
  1021.     fclose (fi);
  1022.     } else {
  1023.     error ("%s:\nCan't open file %s for input", CommandName(), name);
  1024.     } /* if */
  1025. } /* keyload */
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031. /*****************************************************************************
  1032.  
  1033.     BASIC FUNCTIONS ON KEYTABLES :
  1034.  
  1035.     get, new, delete
  1036.  
  1037.     all keytables created with new_keytable are deleted at program termination
  1038.  
  1039. *****************************************************************************/
  1040.  
  1041. /*****************************************************************************
  1042.  
  1043.     NAME
  1044.     get_keytable
  1045.  
  1046.     PARAMETER
  1047.     char * name
  1048.  
  1049.     RESULT
  1050.     the keytable with the name name, if it is already existing
  1051.     else NULL
  1052.  
  1053.     RETURN
  1054.     KEYTABLE *
  1055.  
  1056.     DESCRIPTION
  1057.     search function on the hidden list of keytables
  1058.  
  1059.     NOTES
  1060.     useful only, if we are using multiple keytables
  1061.  
  1062.     BUGS
  1063.  
  1064.     EXAMPLES
  1065.  
  1066.     SEE ALSO
  1067.  
  1068.     INTERNALS
  1069.  
  1070.     HISTORY
  1071.     27 Jan 1993 b_null created
  1072.  
  1073. ******************************************************************************/
  1074.  
  1075. KEYTABLE * get_keytable (char * name)
  1076. {
  1077.     KEYTABLE * kt;
  1078.  
  1079.     if (name == NULL) {
  1080.     return (GetHead (&KeyTables));
  1081.     } /* if wanted default */
  1082.  
  1083.     for (kt = GetHead(&KeyTables); kt; kt = GetSucc(kt)) {
  1084.     if (strcmp (kt->node.ln_Name, name) == 0) {
  1085.         return (kt);
  1086.     } /* if */
  1087.     } /* for */
  1088.     return (NULL);
  1089. } /* get_keytable */
  1090.  
  1091.  
  1092.  
  1093. /*****************************************************************************
  1094.  
  1095.     NAME
  1096.     delete_keytable
  1097.  
  1098.     PARAMETER
  1099.     KEYTABLE * kt
  1100.     int       force
  1101.  
  1102.     RESULT
  1103.     -/-
  1104.  
  1105.     RETURN
  1106.     void
  1107.  
  1108.     DESCRIPTION
  1109.     delete a full keytable
  1110.     that function does NOT dlete the last keytable,
  1111.     unless force is set to 1
  1112.  
  1113.     NOTES
  1114.     useful only, if we are using multiple keytables
  1115.  
  1116.     that function does NOT take care of any references to a keytable
  1117.     You must do that job on a higher abstraction-level
  1118.         (e.g. in keycom.c - for all ED's if )
  1119.  
  1120.     BUGS
  1121.  
  1122.     EXAMPLES
  1123.  
  1124.     SEE ALSO
  1125.  
  1126.     INTERNALS
  1127.     ausklinken aus der keytable-liste
  1128.     loeschen der hash-entries
  1129.     loeschen des namens
  1130.     loeschen des bodies
  1131.  
  1132.     HISTORY
  1133.     27 Jan 1993 b_null created
  1134.  
  1135. ******************************************************************************/
  1136.  
  1137. void delete_keytable (KEYTABLE * kt, int force)
  1138. {
  1139.     if (kt) {
  1140.     Remove        (&kt->node);
  1141.     if ((!force) && (!GetHead (&KeyTables))) {
  1142.         AddHead ((struct List *)&KeyTables, &kt->node);
  1143.         return;
  1144.     } /* if */
  1145.  
  1146.     dealloc_hash (kt);
  1147.     DeallocFunc  (kt->node.ln_Name);
  1148.     FreeFunc     (kt, sizeof(KEYTABLE));
  1149.     } /* if */
  1150. } /* delete_keytable */
  1151.  
  1152.  
  1153.  
  1154. /*****************************************************************************
  1155.  
  1156.     NAME
  1157.     new_keytable
  1158.  
  1159.     PARAMETER
  1160.     char * name
  1161.     int    defaults
  1162.  
  1163.     RESULT
  1164.     either a new keytable, if there is not already one with that name
  1165.     or the first keytable, that matches that name
  1166.     if we have to create a new one, we can set defaults to 1 to
  1167.     fill in the default-keytable
  1168.  
  1169.     RETURN
  1170.     KEYTABLE *
  1171.  
  1172.     DESCRIPTION
  1173.  
  1174.     NOTES
  1175.     useful only, if we are using multiple keytables
  1176.  
  1177.     if we can fill in only parts of the deafult-information,
  1178.     we do NOT fail
  1179.  
  1180.     BUGS
  1181.  
  1182.     EXAMPLES
  1183.  
  1184.     SEE ALSO
  1185.  
  1186.     INTERNALS
  1187.  
  1188.     HISTORY
  1189.     27 Jan 1993 b_null created
  1190.  
  1191. ******************************************************************************/
  1192.  
  1193. KEYTABLE * new_keytable (char * name, int defaults)
  1194. {
  1195.     KEYTABLE * kt;
  1196.  
  1197.     if (kt = get_keytable(name)) {
  1198.     return (kt);
  1199.     } /* if */
  1200.  
  1201.     kt = AllocFunc (sizeof(KEYTABLE), MEMF_ANY);
  1202.     if (kt == NULL) {
  1203.     return (NULL);
  1204.     } /* if */
  1205.  
  1206.     setmem (kt, sizeof(KEYTABLE), 0);
  1207.     kt->node.ln_Name = DupFunc (name, MEMF_ANY);
  1208.     if (kt->node.ln_Name == NULL) {
  1209.     FreeFunc (kt, sizeof (KEYTABLE));
  1210.     return (NULL);
  1211.     } /* if */
  1212.  
  1213.     if (defaults) {
  1214.     resethash (kt);
  1215.     } /* if */
  1216.  
  1217.     AddTail ((struct List *)&KeyTables, &kt->node);
  1218.  
  1219.     return (kt);
  1220. } /* new_keytable */
  1221.  
  1222.  
  1223.  
  1224. /*****************************************************************************
  1225.  
  1226.     NAME
  1227.     exit_keytables
  1228.  
  1229.     PARAMETER
  1230.     void
  1231.  
  1232.     RESULT
  1233.     -/-
  1234.  
  1235.     RETURN
  1236.     void
  1237.  
  1238.     DESCRIPTION
  1239.     exit function for keytables
  1240.  
  1241.     NOTES
  1242.     useful only, if we are using multiple keytables
  1243.  
  1244.     THIS is an __AUTOEXIT - function !!!!
  1245.  
  1246.     BUGS
  1247.  
  1248.     EXAMPLES
  1249.  
  1250.     SEE ALSO
  1251.  
  1252.     INTERNALS
  1253.  
  1254.     HISTORY
  1255.     27 Jan 1993 b_null created
  1256.  
  1257. ******************************************************************************/
  1258.  
  1259. __autoexit
  1260. void exit_keytables (void)
  1261. {
  1262.     KEYTABLE * kt;
  1263.  
  1264. /* PutStr ("key_exiting\n"); */
  1265.     while (kt = GetHead (&KeyTables)) {
  1266.     delete_keytable (kt, 1);
  1267.     } /* while */
  1268. /* PutStr ("key_exited\n"); */
  1269. } /* exit_keytables */
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275. /******************************************************************************
  1276. *****  ENDE keytables.c
  1277. ******************************************************************************/
  1278.