Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / gtx / keymap.c
blob0cc8beb17dc847f52b76ab10f65dcef3992ec15d
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <afsconfig.h>
11 #include <afs/param.h>
14 #include <string.h>
15 #include <stdlib.h>
17 #include "gtxkeymap.h"
19 struct keymap_map *
20 keymap_Create(void)
22 struct keymap_map *tmap;
24 tmap = (struct keymap_map *)malloc(sizeof(struct keymap_map));
25 if (tmap != (struct keymap_map *)0)
26 memset(tmap, 0, sizeof(*tmap));
27 return (tmap);
30 /* make a copy of a string; generic utility */
31 char *
32 gtx_CopyString(char *aval)
34 char *tp;
36 if (!aval)
37 return NULL; /* propagate null strings around */
38 tp = (char *)malloc(strlen(aval) + 1);
39 if (tp != NULL)
40 strcpy(tp, aval);
41 return (tp);
44 static int
45 BindIt(struct keymap_map *amap, int aslot, int atype, void *aproc, char *aname, void *arock)
47 char *tp;
48 struct keymap_entry *tentry;
50 if (aslot < 0 || aslot >= KEYMAP_NENTRIES)
51 return -1;
52 tentry = &amap->entries[aslot];
53 tentry->type = atype;
54 if ((tp = tentry->name))
55 free(tp);
56 if (atype == KEYMAP_EMPTY) {
57 tentry->u.generic = NULL;
58 tentry->name = NULL;
59 } else {
60 tentry->name = gtx_CopyString(aname);
61 tentry->u.generic = aproc;
63 tentry->rock = arock;
64 return 0;
67 int
68 keymap_BindToString(struct keymap_map *amap, char *astring,
69 int (*aproc)(void *, void *),
70 char *aname, void *arock)
72 char *cptr;
73 int tc;
74 afs_int32 code;
75 struct keymap_map *tmap;
77 cptr = astring;
78 /* walk down string, building submaps if possible, until we get to function
79 * at the end */
80 while ((tc = *cptr++)) {
81 /* see if we should do submap or final function */
82 if (*cptr == 0) { /* we're peeking: already skipped command char */
83 /* last character, do final function */
84 if (!aproc) /* delete the entry */
85 code = BindIt(amap, tc, KEYMAP_EMPTY, NULL, NULL, NULL);
86 else
87 code =
88 BindIt(amap, tc, KEYMAP_PROC, aproc, aname, arock);
89 if (code)
90 return code;
91 } else {
92 /* more characters after this; do submap */
93 if (amap->entries[tc].type != KEYMAP_SUBMAP) {
94 tmap = keymap_Create();
95 code =
96 BindIt(amap, tc, KEYMAP_SUBMAP, tmap, NULL, NULL);
97 } else {
98 tmap = amap->entries[tc].u.submap;
99 code = 0;
101 if (code)
102 return code;
103 amap = tmap; /* continue processing this map */
105 } /* while loop */
106 /* here when all characters are gone */
107 return 0;
110 /* delete a keymap and all of its recursively-included maps */
112 keymap_Delete(struct keymap_map *amap)
114 int i;
115 struct keymap_entry *tentry;
117 for (i = 0; i < KEYMAP_NENTRIES; i++) {
118 tentry = &amap->entries[i];
119 if (tentry->name)
120 free(tentry->name);
121 if (tentry->type == KEYMAP_SUBMAP)
122 keymap_Delete(tentry->u.submap);
124 free(amap);
125 return 0;
129 keymap_InitState(struct keymap_state *astate, struct keymap_map *amap)
131 memset(astate, 0, sizeof(*astate));
132 astate->initMap = amap;
133 astate->currentMap = amap;
134 return 0;
138 keymap_ProcessKey(struct keymap_state *astate, int akey, void *arock)
140 struct keymap_entry *tentry;
141 afs_int32 code;
143 if (akey < 0 || akey >= KEYMAP_NENTRIES)
144 return -1;
145 tentry = &astate->currentMap->entries[akey];
146 code = 0;
147 switch (tentry->type) {
148 case KEYMAP_EMPTY:
149 keymap_ResetState(astate);
150 return -1;
151 /* break; */
152 /* break commented out because of return above causing compiler warnings */
154 case KEYMAP_SUBMAP:
155 astate->currentMap = tentry->u.submap;
156 break;
158 case KEYMAP_PROC:
159 code = (*tentry->u.proc) (arock, tentry->rock);
160 keymap_ResetState(astate);
161 break;
163 return code;
167 keymap_ResetState(struct keymap_state *astate)
169 return keymap_InitState(astate, astate->initMap);