makekeys.c revision 61b2299d
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#if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */ 40char *malloc(); 41#endif /* macII */ 42 43typedef unsigned long Signature; 44 45#define KTNUM 4000 46 47static struct info { 48 char *name; 49 KeySym val; 50} info[KTNUM]; 51 52#define MIN_REHASH 15 53#define MATCHES 10 54 55static char tab[KTNUM]; 56static unsigned short offsets[KTNUM]; 57static unsigned short indexes[KTNUM]; 58static KeySym values[KTNUM]; 59static char buf[1024]; 60 61int 62main(int argc, char *argv[]) 63{ 64 int ksnum = 0; 65 int max_rehash; 66 Signature sig; 67 register int i, j, k, z; 68 register char *name; 69 register char c; 70 int first; 71 int best_max_rehash; 72 int best_z = 0; 73 int num_found; 74 KeySym val; 75 char key[128]; 76 char alias[128]; 77 78 79 while (fgets(buf, sizeof(buf), stdin)) { 80 i = sscanf(buf, "#define XK_%127s 0x%lx", key, &info[ksnum].val); 81 if (i != 2) { 82 i = sscanf(buf, "#define XK_%127s XK_%127s", key, alias); 83 if (i != 2) 84 continue; 85 for (i = ksnum - 1; i >= 0; i--) { 86 if (strcmp(info[i].name, alias) == 0) { 87 info[ksnum].val = info[i].val; 88 break; 89 } 90 } 91 if (i < 0) { /* Didn't find a match */ 92 fprintf(stderr, 93 "can't find matching definition %s for keysym %s\n", 94 alias, key); 95 continue; 96 } 97 } 98 if (info[ksnum].val == XK_VoidSymbol) 99 info[ksnum].val = 0; 100 if (info[ksnum].val > 0x1fffffff) { 101 fprintf(stderr, 102 "ignoring illegal keysym (%s), remove it from .h file!\n", 103 key); 104 continue; 105 } 106 name = malloc((unsigned)strlen(key)+1); 107 if (!name) { 108 fprintf(stderr, "makekeys: out of memory!\n"); 109 exit(1); 110 } 111 (void)strcpy(name, key); 112 info[ksnum].name = name; 113 ksnum++; 114 if (ksnum == KTNUM) { 115 fprintf(stderr, "makekeys: too many keysyms!\n"); 116 exit(1); 117 } 118 } 119 120 printf("/* This file is generated from keysymdef.h. */\n"); 121 printf("/* Do not edit. */\n"); 122 printf("\n"); 123 124 best_max_rehash = ksnum; 125 num_found = 0; 126 for (z = ksnum; z < KTNUM; z++) { 127 max_rehash = 0; 128 for (name = tab, i = z; --i >= 0;) 129 *name++ = 0; 130 for (i = 0; i < ksnum; i++) { 131 name = info[i].name; 132 sig = 0; 133 while ((c = *name++)) 134 sig = (sig << 1) + c; 135 first = j = sig % z; 136 for (k = 0; tab[j]; k++) { 137 j += first + 1; 138 if (j >= z) 139 j -= z; 140 if (j == first) 141 goto next1; 142 } 143 tab[j] = 1; 144 if (k > max_rehash) 145 max_rehash = k; 146 } 147 if (max_rehash < MIN_REHASH) { 148 if (max_rehash < best_max_rehash) { 149 best_max_rehash = max_rehash; 150 best_z = z; 151 } 152 num_found++; 153 if (num_found >= MATCHES) 154 break; 155 } 156next1: ; 157 } 158 159 z = best_z; 160 printf("#ifdef NEEDKTABLE\n"); 161 printf("const unsigned char _XkeyTable[] = {\n"); 162 printf("0,\n"); 163 k = 1; 164 for (i = 0; i < ksnum; i++) { 165 name = info[i].name; 166 sig = 0; 167 while ((c = *name++)) 168 sig = (sig << 1) + c; 169 first = j = sig % z; 170 while (offsets[j]) { 171 j += first + 1; 172 if (j >= z) 173 j -= z; 174 } 175 offsets[j] = k; 176 indexes[i] = k; 177 val = info[i].val; 178 printf("0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, ", 179 (sig >> 8) & 0xff, sig & 0xff, 180 (val >> 24) & 0xff, (val >> 16) & 0xff, 181 (val >> 8) & 0xff, val & 0xff); 182 for (name = info[i].name, k += 7; (c = *name++); k++) 183 printf("'%c',", c); 184 printf((i == (ksnum-1)) ? "0\n" : "0,\n"); 185 } 186 printf("};\n"); 187 printf("\n"); 188 printf("#define KTABLESIZE %d\n", z); 189 printf("#define KMAXHASH %d\n", best_max_rehash + 1); 190 printf("\n"); 191 printf("static const unsigned short hashString[KTABLESIZE] = {\n"); 192 for (i = 0; i < z;) { 193 printf("0x%.4x", offsets[i]); 194 i++; 195 if (i == z) 196 break; 197 printf((i & 7) ? ", " : ",\n"); 198 } 199 printf("\n"); 200 printf("};\n"); 201 printf("#endif /* NEEDKTABLE */\n"); 202 203 best_max_rehash = ksnum; 204 num_found = 0; 205 for (z = ksnum; z < KTNUM; z++) { 206 max_rehash = 0; 207 for (name = tab, i = z; --i >= 0;) 208 *name++ = 0; 209 for (i = 0; i < ksnum; i++) { 210 val = info[i].val; 211 first = j = val % z; 212 for (k = 0; tab[j]; k++) { 213 if (values[j] == val) 214 goto skip1; 215 j += first + 1; 216 if (j >= z) 217 j -= z; 218 if (j == first) 219 goto next2; 220 } 221 tab[j] = 1; 222 values[j] = val; 223 if (k > max_rehash) 224 max_rehash = k; 225skip1: ; 226 } 227 if (max_rehash < MIN_REHASH) { 228 if (max_rehash < best_max_rehash) { 229 best_max_rehash = max_rehash; 230 best_z = z; 231 } 232 num_found++; 233 if (num_found >= MATCHES) 234 break; 235 } 236next2: ; 237 } 238 239 z = best_z; 240 for (i = z; --i >= 0;) 241 offsets[i] = 0; 242 for (i = 0; i < ksnum; i++) { 243 val = info[i].val; 244 first = j = val % z; 245 while (offsets[j]) { 246 if (values[j] == val) 247 goto skip2; 248 j += first + 1; 249 if (j >= z) 250 j -= z; 251 } 252 offsets[j] = indexes[i] + 2; 253 values[j] = val; 254skip2: ; 255 } 256 printf("\n"); 257 printf("#ifdef NEEDVTABLE\n"); 258 printf("#define VTABLESIZE %d\n", z); 259 printf("#define VMAXHASH %d\n", best_max_rehash + 1); 260 printf("\n"); 261 printf("static const unsigned short hashKeysym[VTABLESIZE] = {\n"); 262 for (i = 0; i < z;) { 263 printf("0x%.4x", offsets[i]); 264 i++; 265 if (i == z) 266 break; 267 printf((i & 7) ? ", " : ",\n"); 268 } 269 printf("\n"); 270 printf("};\n"); 271 printf("#endif /* NEEDVTABLE */\n"); 272 273 exit(0); 274} 275