makekeys.c revision 2e9c7c8c
1/* $Xorg: makekeys.c,v 1.5 2001/02/09 02:03:40 $ */ 2/* $XdotOrg: lib/X11/src/util/makekeys.c,v 1.5 2005-07-03 07:00:56 daniels Exp $ */ 3/* 4 5Copyright 1990, 1998 The Open Group 6 7Permission to use, copy, modify, distribute, and sell this software and its 8documentation for any purpose is hereby granted without fee, provided that 9the above copyright notice appear in all copies and that both that 10copyright notice and this permission notice appear in supporting 11documentation. 12 13The above copyright notice and this permission notice shall be included 14in all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 20OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22OTHER DEALINGS IN THE SOFTWARE. 23 24Except as contained in this notice, the name of The Open Group shall 25not be used in advertising or otherwise to promote the sale, use or 26other dealings in this Software without prior written authorization 27from The Open Group. 28 29*/ 30/* $XFree86: $ */ 31 32/* Constructs hash tables for XStringToKeysym and XKeysymToString. */ 33 34#include <X11/X.h> 35#include <X11/Xos.h> 36#include <X11/keysymdef.h> 37#include <stdio.h> 38#include <stdlib.h> 39 40typedef unsigned long Signature; 41 42#define KTNUM 4000 43 44static struct info { 45 char *name; 46 KeySym val; 47} info[KTNUM]; 48 49#define MIN_REHASH 15 50#define MATCHES 10 51 52static char tab[KTNUM]; 53static unsigned short offsets[KTNUM]; 54static unsigned short indexes[KTNUM]; 55static KeySym values[KTNUM]; 56static char buf[1024]; 57 58int 59main(int argc, char *argv[]) 60{ 61 int ksnum = 0; 62 int max_rehash; 63 Signature sig; 64 register int i, j, k, z; 65 register char *name; 66 register char c; 67 int first; 68 int best_max_rehash; 69 int best_z = 0; 70 int num_found; 71 KeySym val; 72 char key[128]; 73 char alias[128]; 74 75 76 while (fgets(buf, sizeof(buf), stdin)) { 77 i = sscanf(buf, "#define XK_%127s 0x%lx", key, &info[ksnum].val); 78 if (i != 2) { 79 i = sscanf(buf, "#define XK_%127s XK_%127s", key, alias); 80 if (i != 2) 81 continue; 82 for (i = ksnum - 1; i >= 0; i--) { 83 if (strcmp(info[i].name, alias) == 0) { 84 info[ksnum].val = info[i].val; 85 break; 86 } 87 } 88 if (i < 0) { /* Didn't find a match */ 89 fprintf(stderr, 90 "can't find matching definition %s for keysym %s\n", 91 alias, key); 92 continue; 93 } 94 } 95 if (info[ksnum].val == XK_VoidSymbol) 96 info[ksnum].val = 0; 97 if (info[ksnum].val > 0x1fffffff) { 98 fprintf(stderr, 99 "ignoring illegal keysym (%s), remove it from .h file!\n", 100 key); 101 continue; 102 } 103 name = strdup(key); 104 if (!name) { 105 fprintf(stderr, "makekeys: out of memory!\n"); 106 exit(1); 107 } 108 info[ksnum].name = name; 109 ksnum++; 110 if (ksnum == KTNUM) { 111 fprintf(stderr, "makekeys: too many keysyms!\n"); 112 exit(1); 113 } 114 } 115 116 printf("/* This file is generated from keysymdef.h. */\n"); 117 printf("/* Do not edit. */\n"); 118 printf("\n"); 119 120 best_max_rehash = ksnum; 121 num_found = 0; 122 for (z = ksnum; z < KTNUM; z++) { 123 max_rehash = 0; 124 for (name = tab, i = z; --i >= 0;) 125 *name++ = 0; 126 for (i = 0; i < ksnum; i++) { 127 name = info[i].name; 128 sig = 0; 129 while ((c = *name++)) 130 sig = (sig << 1) + c; 131 first = j = sig % z; 132 for (k = 0; tab[j]; k++) { 133 j += first + 1; 134 if (j >= z) 135 j -= z; 136 if (j == first) 137 goto next1; 138 } 139 tab[j] = 1; 140 if (k > max_rehash) 141 max_rehash = k; 142 } 143 if (max_rehash < MIN_REHASH) { 144 if (max_rehash < best_max_rehash) { 145 best_max_rehash = max_rehash; 146 best_z = z; 147 } 148 num_found++; 149 if (num_found >= MATCHES) 150 break; 151 } 152next1: ; 153 } 154 155 z = best_z; 156 if (z == 0) { 157 fprintf(stderr, "makekeys: failed to find small enough hash!\n" 158 "Try increasing KTNUM in makekeys.c\n"); 159 exit(1); 160 } 161 printf("#ifdef NEEDKTABLE\n"); 162 printf("const unsigned char _XkeyTable[] = {\n"); 163 printf("0,\n"); 164 k = 1; 165 for (i = 0; i < ksnum; i++) { 166 name = info[i].name; 167 sig = 0; 168 while ((c = *name++)) 169 sig = (sig << 1) + c; 170 first = j = sig % z; 171 while (offsets[j]) { 172 j += first + 1; 173 if (j >= z) 174 j -= z; 175 } 176 offsets[j] = k; 177 indexes[i] = k; 178 val = info[i].val; 179 printf("0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, ", 180 (sig >> 8) & 0xff, sig & 0xff, 181 (val >> 24) & 0xff, (val >> 16) & 0xff, 182 (val >> 8) & 0xff, val & 0xff); 183 for (name = info[i].name, k += 7; (c = *name++); k++) 184 printf("'%c',", c); 185 printf((i == (ksnum-1)) ? "0\n" : "0,\n"); 186 } 187 printf("};\n"); 188 printf("\n"); 189 printf("#define KTABLESIZE %d\n", z); 190 printf("#define KMAXHASH %d\n", best_max_rehash + 1); 191 printf("\n"); 192 printf("static const unsigned short hashString[KTABLESIZE] = {\n"); 193 for (i = 0; i < z;) { 194 printf("0x%.4x", offsets[i]); 195 i++; 196 if (i == z) 197 break; 198 printf((i & 7) ? ", " : ",\n"); 199 } 200 printf("\n"); 201 printf("};\n"); 202 printf("#endif /* NEEDKTABLE */\n"); 203 204 best_max_rehash = ksnum; 205 num_found = 0; 206 for (z = ksnum; z < KTNUM; z++) { 207 max_rehash = 0; 208 for (name = tab, i = z; --i >= 0;) 209 *name++ = 0; 210 for (i = 0; i < ksnum; i++) { 211 val = info[i].val; 212 first = j = val % z; 213 for (k = 0; tab[j]; k++) { 214 if (values[j] == val) 215 goto skip1; 216 j += first + 1; 217 if (j >= z) 218 j -= z; 219 if (j == first) 220 goto next2; 221 } 222 tab[j] = 1; 223 values[j] = val; 224 if (k > max_rehash) 225 max_rehash = k; 226skip1: ; 227 } 228 if (max_rehash < MIN_REHASH) { 229 if (max_rehash < best_max_rehash) { 230 best_max_rehash = max_rehash; 231 best_z = z; 232 } 233 num_found++; 234 if (num_found >= MATCHES) 235 break; 236 } 237next2: ; 238 } 239 240 z = best_z; 241 if (z == 0) { 242 fprintf(stderr, "makekeys: failed to find small enough hash!\n" 243 "Try increasing KTNUM in makekeys.c\n"); 244 exit(1); 245 } 246 for (i = z; --i >= 0;) 247 offsets[i] = 0; 248 for (i = 0; i < ksnum; i++) { 249 val = info[i].val; 250 first = j = val % z; 251 while (offsets[j]) { 252 if (values[j] == val) 253 goto skip2; 254 j += first + 1; 255 if (j >= z) 256 j -= z; 257 } 258 offsets[j] = indexes[i] + 2; 259 values[j] = val; 260skip2: ; 261 } 262 printf("\n"); 263 printf("#ifdef NEEDVTABLE\n"); 264 printf("#define VTABLESIZE %d\n", z); 265 printf("#define VMAXHASH %d\n", best_max_rehash + 1); 266 printf("\n"); 267 printf("static const unsigned short hashKeysym[VTABLESIZE] = {\n"); 268 for (i = 0; i < z;) { 269 printf("0x%.4x", offsets[i]); 270 i++; 271 if (i == z) 272 break; 273 printf((i & 7) ? ", " : ",\n"); 274 } 275 printf("\n"); 276 printf("};\n"); 277 printf("#endif /* NEEDVTABLE */\n"); 278 279 exit(0); 280} 281