| File: | xkbcomp.c |
| Location: | line 1061, column 37 |
| Description: | Access to field 'device_spec' results in a dereference of a null pointer (loaded from field 'xkb') |
| 1 | /************************************************************ | |||
| 2 | Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. | |||
| 3 | ||||
| 4 | Permission to use, copy, modify, and distribute this | |||
| 5 | software and its documentation for any purpose and without | |||
| 6 | fee is hereby granted, provided that the above copyright | |||
| 7 | notice appear in all copies and that both that copyright | |||
| 8 | notice and this permission notice appear in supporting | |||
| 9 | documentation, and that the name of Silicon Graphics not be | |||
| 10 | used in advertising or publicity pertaining to distribution | |||
| 11 | of the software without specific prior written permission. | |||
| 12 | Silicon Graphics makes no representation about the suitability | |||
| 13 | of this software for any purpose. It is provided "as is" | |||
| 14 | without any express or implied warranty. | |||
| 15 | ||||
| 16 | SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS | |||
| 17 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | |||
| 18 | AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON | |||
| 19 | GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | |||
| 20 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |||
| 21 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | |||
| 22 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH | |||
| 23 | THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| 24 | ||||
| 25 | ********************************************************/ | |||
| 26 | ||||
| 27 | #include <stdio.h> | |||
| 28 | #include <ctype.h> | |||
| 29 | #include <X11/keysym.h> | |||
| 30 | ||||
| 31 | /* for symlink attack security fix -- Branden Robinson */ | |||
| 32 | #include <sys/stat.h> | |||
| 33 | #include <sys/types.h> | |||
| 34 | #include <unistd.h> | |||
| 35 | /* end BR */ | |||
| 36 | ||||
| 37 | #if defined(sgi) | |||
| 38 | #include <malloc.h> | |||
| 39 | #endif | |||
| 40 | ||||
| 41 | #define DEBUG_VARdebugFlags debugFlags | |||
| 42 | #include "xkbcomp.h" | |||
| 43 | #include <stdlib.h> | |||
| 44 | #include "xkbpath.h" | |||
| 45 | #include "parseutils.h" | |||
| 46 | #include "misc.h" | |||
| 47 | #include "tokens.h" | |||
| 48 | #include <X11/extensions/XKBgeom.h> | |||
| 49 | ||||
| 50 | ||||
| 51 | #ifdef WIN32 | |||
| 52 | #define S_IRGRP0000040 0 | |||
| 53 | #define S_IWGRP0000020 0 | |||
| 54 | #define S_IROTH0000004 0 | |||
| 55 | #define S_IWOTH0000002 0 | |||
| 56 | #endif | |||
| 57 | ||||
| 58 | #define lowbit(x)((x) & (-(x))) ((x) & (-(x))) | |||
| 59 | ||||
| 60 | /***====================================================================***/ | |||
| 61 | ||||
| 62 | #define WANT_DEFAULT0 0 | |||
| 63 | #define WANT_XKM_FILE1 1 | |||
| 64 | #define WANT_C_HDR2 2 | |||
| 65 | #define WANT_XKB_FILE3 3 | |||
| 66 | #define WANT_X_SERVER4 4 | |||
| 67 | #define WANT_LISTING5 5 | |||
| 68 | ||||
| 69 | #define INPUT_UNKNOWN0 0 | |||
| 70 | #define INPUT_XKB1 1 | |||
| 71 | #define INPUT_XKM2 2 | |||
| 72 | ||||
| 73 | unsigned int debugFlags; | |||
| 74 | ||||
| 75 | static const char *fileTypeExt[] = { | |||
| 76 | "XXX", | |||
| 77 | "xkm", | |||
| 78 | "h", | |||
| 79 | "xkb", | |||
| 80 | "dir" | |||
| 81 | }; | |||
| 82 | ||||
| 83 | static unsigned inputFormat, outputFormat; | |||
| 84 | char *rootDir; | |||
| 85 | static char *inputFile; | |||
| 86 | static char *inputMap; | |||
| 87 | static char *outputFile; | |||
| 88 | static char *inDpyName; | |||
| 89 | static char *outDpyName; | |||
| 90 | static Display *inDpy; | |||
| 91 | static Display *outDpy; | |||
| 92 | static Boolint showImplicit = False0; | |||
| 93 | static Boolint synch = False0; | |||
| 94 | static Boolint computeDflts = False0; | |||
| 95 | static Boolint xkblist = False0; | |||
| 96 | unsigned warningLevel = 5; | |||
| 97 | unsigned verboseLevel = 0; | |||
| 98 | unsigned dirsToStrip = 0; | |||
| 99 | unsigned optionalParts = 0; | |||
| 100 | static char *preErrorMsg = NULL((void*)0); | |||
| 101 | static char *postErrorMsg = NULL((void*)0); | |||
| 102 | static char *errorPrefix = NULL((void*)0); | |||
| 103 | static unsigned int device_id = XkbUseCoreKbd0x0100; | |||
| 104 | ||||
| 105 | /***====================================================================***/ | |||
| 106 | ||||
| 107 | #define M(m)fprintf(__stderrp,(m)) fprintf(stderr__stderrp,(m)) | |||
| 108 | #define M1(m,a)fprintf(__stderrp,(m),(a)) fprintf(stderr__stderrp,(m),(a)) | |||
| 109 | ||||
| 110 | static void | |||
| 111 | Usage(int argc, char *argv[]) | |||
| 112 | { | |||
| 113 | if (!xkblist) | |||
| 114 | M1("Usage: %s [options] input-file [ output-file ]\n", argv[0])fprintf(__stderrp,("Usage: %s [options] input-file [ output-file ]\n" ),(argv[0])); | |||
| 115 | else | |||
| 116 | M1("Usage: %s [options] file[(map)] ...\n", argv[0])fprintf(__stderrp,("Usage: %s [options] file[(map)] ...\n"),( argv[0])); | |||
| 117 | M("Legal options:\n")fprintf(__stderrp,("Legal options:\n")); | |||
| 118 | M("-?,-help Print this message\n")fprintf(__stderrp,("-?,-help Print this message\n" )); | |||
| 119 | M("-version Print the version number\n")fprintf(__stderrp,("-version Print the version number\n" )); | |||
| 120 | if (!xkblist) | |||
| 121 | { | |||
| 122 | M("-a Show all actions\n")fprintf(__stderrp,("-a Show all actions\n") ); | |||
| 123 | M("-C Create a C header file\n")fprintf(__stderrp,("-C Create a C header file\n" )); | |||
| 124 | } | |||
| 125 | #ifdef DEBUG | |||
| 126 | M("-d [flags] Report debugging information\n")fprintf(__stderrp,("-d [flags] Report debugging information\n" )); | |||
| 127 | #endif | |||
| 128 | M("-em1 <msg> Print <msg> before printing first error message\n")fprintf(__stderrp,("-em1 <msg> Print <msg> before printing first error message\n" )); | |||
| 129 | M("-emp <msg> Print <msg> at the start of each message line\n")fprintf(__stderrp,("-emp <msg> Print <msg> at the start of each message line\n" )); | |||
| 130 | M("-eml <msg> If there were any errors, print <msg> before exiting\n")fprintf(__stderrp,("-eml <msg> If there were any errors, print <msg> before exiting\n" )); | |||
| 131 | if (!xkblist) | |||
| 132 | { | |||
| 133 | M("-dflts Compute defaults for missing parts\n")fprintf(__stderrp,("-dflts Compute defaults for missing parts\n" )); | |||
| 134 | M("-I[<dir>] Specifies a top level directory for include\n")fprintf(__stderrp,("-I[<dir>] Specifies a top level directory for include\n" )); | |||
| 135 | M(" directives. Multiple directories are legal.\n")fprintf(__stderrp,(" directives. Multiple directories are legal.\n" )); | |||
| 136 | M("-l [flags] List matching maps in the specified files\n")fprintf(__stderrp,("-l [flags] List matching maps in the specified files\n" )); | |||
| 137 | M(" f: list fully specified names\n")fprintf(__stderrp,(" f: list fully specified names\n" )); | |||
| 138 | M(" h: also list hidden maps\n")fprintf(__stderrp,(" h: also list hidden maps\n" )); | |||
| 139 | M(" l: long listing (show flags)\n")fprintf(__stderrp,(" l: long listing (show flags)\n" )); | |||
| 140 | M(" p: also list partial maps\n")fprintf(__stderrp,(" p: also list partial maps\n" )); | |||
| 141 | M(" R: recursively list subdirectories\n")fprintf(__stderrp,(" R: recursively list subdirectories\n" )); | |||
| 142 | M(" default is all options off\n")fprintf(__stderrp,(" default is all options off\n" )); | |||
| 143 | } | |||
| 144 | M("-i <deviceid> Specifies device ID (not name) to compile for\n")fprintf(__stderrp,("-i <deviceid> Specifies device ID (not name) to compile for\n" )); | |||
| 145 | M("-m[ap] <map> Specifies map to compile\n")fprintf(__stderrp,("-m[ap] <map> Specifies map to compile\n" )); | |||
| 146 | M("-o <file> Specifies output file name\n")fprintf(__stderrp,("-o <file> Specifies output file name\n" )); | |||
| 147 | if (!xkblist) | |||
| 148 | { | |||
| 149 | M("-opt[ional] <parts> Specifies optional components of keymap\n")fprintf(__stderrp,("-opt[ional] <parts> Specifies optional components of keymap\n" )); | |||
| 150 | M(" Errors in optional parts are not fatal\n")fprintf(__stderrp,(" Errors in optional parts are not fatal\n" )); | |||
| 151 | M(" <parts> can be any combination of:\n")fprintf(__stderrp,(" <parts> can be any combination of:\n" )); | |||
| 152 | M(" c: compat map g: geometry\n")fprintf(__stderrp,(" c: compat map g: geometry\n" )); | |||
| 153 | M(" k: keycodes s: symbols\n")fprintf(__stderrp,(" k: keycodes s: symbols\n" )); | |||
| 154 | M(" t: types\n")fprintf(__stderrp,(" t: types\n")); | |||
| 155 | } | |||
| 156 | if (xkblist) | |||
| 157 | { | |||
| 158 | M("-p <count> Specifies the number of slashes to be stripped\n")fprintf(__stderrp,("-p <count> Specifies the number of slashes to be stripped\n" )); | |||
| 159 | M(" from the front of the map name on output\n")fprintf(__stderrp,(" from the front of the map name on output\n" )); | |||
| 160 | } | |||
| 161 | M("-R[<DIR>] Specifies the root directory for\n")fprintf(__stderrp,("-R[<DIR>] Specifies the root directory for\n" )); | |||
| 162 | M(" relative path names\n")fprintf(__stderrp,(" relative path names\n" )); | |||
| 163 | M("-synch Force synchronization\n")fprintf(__stderrp,("-synch Force synchronization\n" )); | |||
| 164 | if (xkblist) | |||
| 165 | { | |||
| 166 | M("-v [<flags>] Set level of detail for listing.\n")fprintf(__stderrp,("-v [<flags>] Set level of detail for listing.\n" )); | |||
| 167 | M(" flags are as for the -l option\n")fprintf(__stderrp,(" flags are as for the -l option\n" )); | |||
| 168 | } | |||
| 169 | M("-w [<lvl>] Set warning level (0=none, 10=all)\n")fprintf(__stderrp,("-w [<lvl>] Set warning level (0=none, 10=all)\n" )); | |||
| 170 | if (!xkblist) | |||
| 171 | { | |||
| 172 | M("-xkb Create an XKB source (.xkb) file\n")fprintf(__stderrp,("-xkb Create an XKB source (.xkb) file\n" )); | |||
| 173 | M("-xkm Create a compiled key map (.xkm) file\n")fprintf(__stderrp,("-xkm Create a compiled key map (.xkm) file\n" )); | |||
| 174 | } | |||
| 175 | return; | |||
| 176 | } | |||
| 177 | ||||
| 178 | /***====================================================================***/ | |||
| 179 | ||||
| 180 | static void | |||
| 181 | setVerboseFlags(char *str) | |||
| 182 | { | |||
| 183 | for (; *str; str++) | |||
| 184 | { | |||
| 185 | switch (*str) | |||
| 186 | { | |||
| 187 | case 'f': | |||
| 188 | verboseLevel |= WantFullNames(1<<3); | |||
| 189 | break; | |||
| 190 | case 'h': | |||
| 191 | verboseLevel |= WantHiddenMaps(1<<2); | |||
| 192 | break; | |||
| 193 | case 'l': | |||
| 194 | verboseLevel |= WantLongListing(1<<0); | |||
| 195 | break; | |||
| 196 | case 'p': | |||
| 197 | verboseLevel |= WantPartialMaps(1<<1); | |||
| 198 | break; | |||
| 199 | case 'R': | |||
| 200 | verboseLevel |= ListRecursive(1<<4); | |||
| 201 | break; | |||
| 202 | default: | |||
| 203 | if (warningLevel > 4) | |||
| 204 | { | |||
| 205 | WARN1uWarning("Unknown verbose option \"%c\"\n", (unsigned int) *str); | |||
| 206 | ACTIONuAction("Ignored\n"); | |||
| 207 | } | |||
| 208 | break; | |||
| 209 | } | |||
| 210 | } | |||
| 211 | return; | |||
| 212 | } | |||
| 213 | ||||
| 214 | static Boolint | |||
| 215 | parseArgs(int argc, char *argv[]) | |||
| 216 | { | |||
| 217 | register int i, tmp; | |||
| 218 | ||||
| 219 | i = strlen(argv[0]); | |||
| 220 | tmp = strlen("xkblist"); | |||
| 221 | if ((i >= tmp) && (strcmp(&argv[0][i - tmp], "xkblist") == 0)) | |||
| 222 | { | |||
| 223 | xkblist = True1; | |||
| 224 | } | |||
| 225 | for (i = 1; i < argc; i++) | |||
| 226 | { | |||
| 227 | int itmp; | |||
| 228 | if ((argv[i][0] != '-') || (uStringEqual(argv[i], "-")((((argv[i])==((char *)((void*)0))||("-")==((char *)((void*)0 )))? (argv[i])!=("-"):strcmp(argv[i],"-"))==((Comparison)0)))) | |||
| 229 | { | |||
| 230 | if (!xkblist) | |||
| 231 | { | |||
| 232 | if (inputFile == NULL((void*)0)) | |||
| 233 | inputFile = argv[i]; | |||
| 234 | else if (outputFile == NULL((void*)0)) | |||
| 235 | outputFile = argv[i]; | |||
| 236 | else if (warningLevel > 0) | |||
| 237 | { | |||
| 238 | WARNuWarning("Too many file names on command line\n"); | |||
| 239 | ACTION3uAction | |||
| 240 | ("Compiling %s, writing to %s, ignoring %s\n", | |||
| 241 | inputFile, outputFile, argv[i]); | |||
| 242 | } | |||
| 243 | } | |||
| 244 | else if (!AddMatchingFiles(argv[i])) | |||
| 245 | return False0; | |||
| 246 | } | |||
| 247 | else if ((strcmp(argv[i], "-?") == 0) | |||
| 248 | || (strcmp(argv[i], "-help") == 0)) | |||
| 249 | { | |||
| 250 | Usage(argc, argv); | |||
| 251 | exit(0); | |||
| 252 | } | |||
| 253 | else if (strcmp(argv[i], "-version") == 0) | |||
| 254 | { | |||
| 255 | printf("xkbcomp %s\n", PACKAGE_VERSION"1.3.1"); | |||
| 256 | exit(0); | |||
| 257 | } else if ((strcmp(argv[i], "-a") == 0) && (!xkblist)) | |||
| 258 | { | |||
| 259 | showImplicit = True1; | |||
| 260 | } | |||
| 261 | else if ((strcmp(argv[i], "-C") == 0) && (!xkblist)) | |||
| 262 | { | |||
| 263 | if ((outputFormat != WANT_DEFAULT0) | |||
| 264 | && (outputFormat != WANT_C_HDR2)) | |||
| 265 | { | |||
| 266 | if (warningLevel > 0) | |||
| 267 | { | |||
| 268 | WARNuWarning("Multiple output file formats specified\n"); | |||
| 269 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
| 270 | } | |||
| 271 | } | |||
| 272 | else | |||
| 273 | outputFormat = WANT_C_HDR2; | |||
| 274 | } | |||
| 275 | #ifdef DEBUG | |||
| 276 | else if (strcmp(argv[i], "-d") == 0) | |||
| 277 | { | |||
| 278 | if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) | |||
| 279 | { | |||
| 280 | debugFlags = 1; | |||
| 281 | } | |||
| 282 | else | |||
| 283 | { | |||
| 284 | if (sscanf(argv[++i], "%i", &itmp) == 1) | |||
| 285 | debugFlags = itmp; | |||
| 286 | } | |||
| 287 | INFO1uInformation("Setting debug flags to %d\n", debugFlags); | |||
| 288 | } | |||
| 289 | #endif | |||
| 290 | else if ((strcmp(argv[i], "-dflts") == 0) && (!xkblist)) | |||
| 291 | { | |||
| 292 | computeDflts = True1; | |||
| 293 | } | |||
| 294 | else if (strcmp(argv[i], "-em1") == 0) | |||
| 295 | { | |||
| 296 | if (++i >= argc) | |||
| 297 | { | |||
| 298 | if (warningLevel > 0) | |||
| 299 | { | |||
| 300 | WARNuWarning("No pre-error message specified\n"); | |||
| 301 | ACTIONuAction("Trailing \"-em1\" option ignored\n"); | |||
| 302 | } | |||
| 303 | } | |||
| 304 | else if (preErrorMsg != NULL((void*)0)) | |||
| 305 | { | |||
| 306 | if (warningLevel > 0) | |||
| 307 | { | |||
| 308 | WARNuWarning("Multiple pre-error messsages specified\n"); | |||
| 309 | ACTION2uAction("Compiling %s, ignoring %s\n", | |||
| 310 | preErrorMsg, argv[i]); | |||
| 311 | } | |||
| 312 | } | |||
| 313 | else | |||
| 314 | preErrorMsg = argv[i]; | |||
| 315 | } | |||
| 316 | else if (strcmp(argv[i], "-emp") == 0) | |||
| 317 | { | |||
| 318 | if (++i >= argc) | |||
| 319 | { | |||
| 320 | if (warningLevel > 0) | |||
| 321 | { | |||
| 322 | WARNuWarning("No error prefix specified\n"); | |||
| 323 | ACTIONuAction("Trailing \"-emp\" option ignored\n"); | |||
| 324 | } | |||
| 325 | } | |||
| 326 | else if (errorPrefix != NULL((void*)0)) | |||
| 327 | { | |||
| 328 | if (warningLevel > 0) | |||
| 329 | { | |||
| 330 | WARNuWarning("Multiple error prefixes specified\n"); | |||
| 331 | ACTION2uAction("Compiling %s, ignoring %s\n", | |||
| 332 | errorPrefix, argv[i]); | |||
| 333 | } | |||
| 334 | } | |||
| 335 | else | |||
| 336 | errorPrefix = argv[i]; | |||
| 337 | } | |||
| 338 | else if (strcmp(argv[i], "-eml") == 0) | |||
| 339 | { | |||
| 340 | if (++i >= argc) | |||
| 341 | { | |||
| 342 | if (warningLevel > 0) | |||
| 343 | { | |||
| 344 | WARNuWarning("No post-error message specified\n"); | |||
| 345 | ACTIONuAction("Trailing \"-eml\" option ignored\n"); | |||
| 346 | } | |||
| 347 | } | |||
| 348 | else if (postErrorMsg != NULL((void*)0)) | |||
| 349 | { | |||
| 350 | if (warningLevel > 0) | |||
| 351 | { | |||
| 352 | WARNuWarning("Multiple post-error messages specified\n"); | |||
| 353 | ACTION2uAction("Compiling %s, ignoring %s\n", | |||
| 354 | postErrorMsg, argv[i]); | |||
| 355 | } | |||
| 356 | } | |||
| 357 | else | |||
| 358 | postErrorMsg = argv[i]; | |||
| 359 | } | |||
| 360 | else if ((strncmp(argv[i], "-I", 2) == 0) && (!xkblist)) | |||
| 361 | { | |||
| 362 | if (!XkbAddDirectoryToPath(&argv[i][2])) | |||
| 363 | { | |||
| 364 | ACTIONuAction("Exiting\n"); | |||
| 365 | exit(1); | |||
| 366 | } | |||
| 367 | } | |||
| 368 | else if ((strncmp(argv[i], "-i", 2) == 0) && (!xkblist)) | |||
| 369 | { | |||
| 370 | if (++i >= argc) | |||
| 371 | { | |||
| 372 | if (warningLevel > 0) | |||
| 373 | WARNuWarning("No device ID specified\n"); | |||
| 374 | } | |||
| 375 | device_id = atoi(argv[i]); | |||
| 376 | } | |||
| 377 | else if ((strncmp(argv[i], "-l", 2) == 0) && (!xkblist)) | |||
| 378 | { | |||
| 379 | if (outputFormat != WANT_DEFAULT0) | |||
| 380 | { | |||
| 381 | if (warningLevel > 0) | |||
| 382 | { | |||
| 383 | WARNuWarning("Multiple output file formats specified\n"); | |||
| 384 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
| 385 | } | |||
| 386 | } | |||
| 387 | else | |||
| 388 | { | |||
| 389 | if (argv[i][2] != '\0') | |||
| 390 | setVerboseFlags(&argv[i][2]); | |||
| 391 | xkblist = True1; | |||
| 392 | if ((inputFile) && (!AddMatchingFiles(inputFile))) | |||
| 393 | return False0; | |||
| 394 | else | |||
| 395 | inputFile = NULL((void*)0); | |||
| 396 | if ((outputFile) && (!AddMatchingFiles(outputFile))) | |||
| 397 | return False0; | |||
| 398 | else | |||
| 399 | outputFile = NULL((void*)0); | |||
| 400 | } | |||
| 401 | } | |||
| 402 | else if ((strcmp(argv[i], "-m") == 0) | |||
| 403 | || (strcmp(argv[i], "-map") == 0)) | |||
| 404 | { | |||
| 405 | if (++i >= argc) | |||
| 406 | { | |||
| 407 | if (warningLevel > 0) | |||
| 408 | { | |||
| 409 | WARNuWarning("No map name specified\n"); | |||
| 410 | ACTION1uAction("Trailing \"%s\" option ignored\n", argv[i - 1]); | |||
| 411 | } | |||
| 412 | } | |||
| 413 | else if (xkblist) | |||
| 414 | { | |||
| 415 | if (!AddMapOnly(argv[i])) | |||
| 416 | return False0; | |||
| 417 | } | |||
| 418 | else if (inputMap != NULL((void*)0)) | |||
| 419 | { | |||
| 420 | if (warningLevel > 0) | |||
| 421 | { | |||
| 422 | WARNuWarning("Multiple map names specified\n"); | |||
| 423 | ACTION2uAction("Compiling %s, ignoring %s\n", inputMap, argv[i]); | |||
| 424 | } | |||
| 425 | } | |||
| 426 | else | |||
| 427 | inputMap = argv[i]; | |||
| 428 | } | |||
| 429 | else if ((strcmp(argv[i], "-merge") == 0) && (!xkblist)) | |||
| 430 | { | |||
| 431 | /* Ignored */ | |||
| 432 | } | |||
| 433 | else if (strcmp(argv[i], "-o") == 0) | |||
| 434 | { | |||
| 435 | if (++i >= argc) | |||
| 436 | { | |||
| 437 | if (warningLevel > 0) | |||
| 438 | { | |||
| 439 | WARNuWarning("No output file specified\n"); | |||
| 440 | ACTIONuAction("Trailing \"-o\" option ignored\n"); | |||
| 441 | } | |||
| 442 | } | |||
| 443 | else if (outputFile != NULL((void*)0)) | |||
| 444 | { | |||
| 445 | if (warningLevel > 0) | |||
| 446 | { | |||
| 447 | WARNuWarning("Multiple output files specified\n"); | |||
| 448 | ACTION2uAction("Compiling %s, ignoring %s\n", outputFile, | |||
| 449 | argv[i]); | |||
| 450 | } | |||
| 451 | } | |||
| 452 | else | |||
| 453 | outputFile = argv[i]; | |||
| 454 | } | |||
| 455 | else if (((strcmp(argv[i], "-opt") == 0) | |||
| 456 | || (strcmp(argv[i], "optional") == 0)) && (!xkblist)) | |||
| 457 | { | |||
| 458 | if (++i >= argc) | |||
| 459 | { | |||
| 460 | if (warningLevel > 0) | |||
| 461 | { | |||
| 462 | WARNuWarning("No optional components specified\n"); | |||
| 463 | ACTION1uAction("Trailing \"%s\" option ignored\n", argv[i - 1]); | |||
| 464 | } | |||
| 465 | } | |||
| 466 | else | |||
| 467 | { | |||
| 468 | char *tmp2; | |||
| 469 | for (tmp2 = argv[i]; (*tmp2 != '\0'); tmp2++) | |||
| 470 | { | |||
| 471 | switch (*tmp2) | |||
| 472 | { | |||
| 473 | case 'c': | |||
| 474 | case 'C': | |||
| 475 | optionalParts |= XkmCompatMapMask(1<<1); | |||
| 476 | break; | |||
| 477 | case 'g': | |||
| 478 | case 'G': | |||
| 479 | optionalParts |= XkmGeometryMask(1<<5); | |||
| 480 | break; | |||
| 481 | case 'k': | |||
| 482 | case 'K': | |||
| 483 | optionalParts |= XkmKeyNamesMask(1<<4); | |||
| 484 | break; | |||
| 485 | case 's': | |||
| 486 | case 'S': | |||
| 487 | optionalParts |= XkmSymbolsMask(1<<2); | |||
| 488 | break; | |||
| 489 | case 't': | |||
| 490 | case 'T': | |||
| 491 | optionalParts |= XkmTypesMask(1<<0); | |||
| 492 | break; | |||
| 493 | default: | |||
| 494 | if (warningLevel > 0) | |||
| 495 | { | |||
| 496 | WARN1uWarning | |||
| 497 | ("Illegal component for %s option\n", | |||
| 498 | argv[i - 1]); | |||
| 499 | ACTION1uAction | |||
| 500 | ("Ignoring unknown specifier \"%c\"\n", | |||
| 501 | (unsigned int) *tmp2); | |||
| 502 | } | |||
| 503 | break; | |||
| 504 | } | |||
| 505 | } | |||
| 506 | } | |||
| 507 | } | |||
| 508 | else if (strncmp(argv[i], "-p", 2) == 0) | |||
| 509 | { | |||
| 510 | if (isdigit(argv[i][2])) | |||
| 511 | { | |||
| 512 | if (sscanf(&argv[i][2], "%i", &itmp) == 1) | |||
| 513 | dirsToStrip = itmp; | |||
| 514 | } | |||
| 515 | else if ((i < (argc - 1)) && (isdigit(argv[i + 1][0]))) | |||
| 516 | { | |||
| 517 | if (sscanf(argv[++i], "%i", &itmp) == 1) | |||
| 518 | dirsToStrip = itmp; | |||
| 519 | } | |||
| 520 | else | |||
| 521 | { | |||
| 522 | dirsToStrip = 0; | |||
| 523 | } | |||
| 524 | if (warningLevel > 5) | |||
| 525 | INFO1uInformation("Setting path count to %d\n", dirsToStrip); | |||
| 526 | } | |||
| 527 | else if (strncmp(argv[i], "-R", 2) == 0) | |||
| 528 | { | |||
| 529 | if (argv[i][2] == '\0') | |||
| 530 | { | |||
| 531 | if (warningLevel > 0) | |||
| 532 | { | |||
| 533 | WARNuWarning("No root directory specified\n"); | |||
| 534 | ACTIONuAction("Ignoring -R option\n"); | |||
| 535 | } | |||
| 536 | } | |||
| 537 | else if (rootDir != NULL((void*)0)) | |||
| 538 | { | |||
| 539 | if (warningLevel > 0) | |||
| 540 | { | |||
| 541 | WARNuWarning("Multiple root directories specified\n"); | |||
| 542 | ACTION2uAction("Using %s, ignoring %s\n", rootDir, argv[i]); | |||
| 543 | } | |||
| 544 | } | |||
| 545 | else | |||
| 546 | { | |||
| 547 | rootDir = &argv[i][2]; | |||
| 548 | if (warningLevel > 8) | |||
| 549 | { | |||
| 550 | WARN1uWarning("Changing root directory to \"%s\"\n", rootDir); | |||
| 551 | } | |||
| 552 | if ((chdir(rootDir) < 0) && (warningLevel > 0)) | |||
| 553 | { | |||
| 554 | WARN1uWarning("Couldn't change directory to \"%s\"\n", rootDir); | |||
| 555 | ACTIONuAction("Root directory (-R) option ignored\n"); | |||
| 556 | rootDir = NULL((void*)0); | |||
| 557 | } | |||
| 558 | } | |||
| 559 | } | |||
| 560 | else if ((strcmp(argv[i], "-synch") == 0) | |||
| 561 | || (strcmp(argv[i], "-s") == 0)) | |||
| 562 | { | |||
| 563 | synch = True1; | |||
| 564 | } | |||
| 565 | else if (strncmp(argv[i], "-v", 2) == 0) | |||
| 566 | { | |||
| 567 | char *str; | |||
| 568 | if (argv[i][2] != '\0') | |||
| 569 | str = &argv[i][2]; | |||
| 570 | else if ((i < (argc - 1)) && (argv[i + 1][0] != '-')) | |||
| 571 | str = argv[++i]; | |||
| 572 | else | |||
| 573 | str = NULL((void*)0); | |||
| 574 | if (str) | |||
| 575 | setVerboseFlags(str); | |||
| 576 | } | |||
| 577 | else if (strncmp(argv[i], "-w", 2) == 0) | |||
| 578 | { | |||
| 579 | unsigned long utmp; | |||
| 580 | char *tmp2; | |||
| 581 | /* If text is just after "-w" in the same word, then it must | |||
| 582 | * be a number and it is the warning level. Otherwise, if the | |||
| 583 | * next argument is a number, then it is the warning level, | |||
| 584 | * else the warning level is assumed to be 0. | |||
| 585 | */ | |||
| 586 | if (argv[i][2] == '\0') | |||
| 587 | { | |||
| 588 | warningLevel = 0; | |||
| 589 | if (i < argc - 1) | |||
| 590 | { | |||
| 591 | utmp = strtoul(argv[i+1], &tmp2, 10); | |||
| 592 | if (argv[i+1][0] != '\0' && *tmp2 == '\0') | |||
| 593 | { | |||
| 594 | warningLevel = utmp > 10 ? 10 : utmp; | |||
| 595 | i++; | |||
| 596 | } | |||
| 597 | } | |||
| 598 | } | |||
| 599 | else | |||
| 600 | { | |||
| 601 | utmp = strtoul(&argv[i][2], &tmp2, 10); | |||
| 602 | if (*tmp2 == '\0') | |||
| 603 | warningLevel = utmp > 10 ? 10 : utmp; | |||
| 604 | else | |||
| 605 | { | |||
| 606 | ERROR1uError("Unknown flag \"%s\" on command line\n", argv[i]); | |||
| 607 | Usage(argc, argv); | |||
| 608 | return False0; | |||
| 609 | } | |||
| 610 | } | |||
| 611 | } | |||
| 612 | else if ((strcmp(argv[i], "-xkb") == 0) && (!xkblist)) | |||
| 613 | { | |||
| 614 | if ((outputFormat != WANT_DEFAULT0) | |||
| 615 | && (outputFormat != WANT_XKB_FILE3)) | |||
| 616 | { | |||
| 617 | if (warningLevel > 0) | |||
| 618 | { | |||
| 619 | WARNuWarning("Multiple output file formats specified\n"); | |||
| 620 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
| 621 | } | |||
| 622 | } | |||
| 623 | else | |||
| 624 | outputFormat = WANT_XKB_FILE3; | |||
| 625 | } | |||
| 626 | else if ((strcmp(argv[i], "-xkm") == 0) && (!xkblist)) | |||
| 627 | { | |||
| 628 | if ((outputFormat != WANT_DEFAULT0) | |||
| 629 | && (outputFormat != WANT_XKM_FILE1)) | |||
| 630 | { | |||
| 631 | if (warningLevel > 0) | |||
| 632 | { | |||
| 633 | WARNuWarning("Multiple output file formats specified\n"); | |||
| 634 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
| 635 | } | |||
| 636 | } | |||
| 637 | else | |||
| 638 | outputFormat = WANT_XKM_FILE1; | |||
| 639 | } | |||
| 640 | else | |||
| 641 | { | |||
| 642 | ERROR1uError("Unknown flag \"%s\" on command line\n", argv[i]); | |||
| 643 | Usage(argc, argv); | |||
| 644 | return False0; | |||
| 645 | } | |||
| 646 | } | |||
| 647 | if (xkblist) | |||
| 648 | inputFormat = INPUT_XKB1; | |||
| 649 | else if (inputFile == NULL((void*)0)) | |||
| 650 | { | |||
| 651 | ERRORuError("No input file specified\n"); | |||
| 652 | return False0; | |||
| 653 | } | |||
| 654 | else if (uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void* )0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison )0))) | |||
| 655 | { | |||
| 656 | inputFormat = INPUT_XKB1; | |||
| 657 | } | |||
| 658 | #ifndef WIN32 | |||
| 659 | else if (strchr(inputFile, ':') == NULL((void*)0)) | |||
| 660 | { | |||
| 661 | #else | |||
| 662 | else if ((strchr(inputFile, ':') == NULL((void*)0)) || (strlen(inputFile) > 2 && | |||
| 663 | isalpha(inputFile[0]) && | |||
| 664 | inputFile[1] == ':' | |||
| 665 | && strchr(inputFile + 2, | |||
| 666 | ':') == NULL((void*)0))) | |||
| 667 | { | |||
| 668 | #endif | |||
| 669 | int len; | |||
| 670 | len = strlen(inputFile); | |||
| 671 | if (inputFile[len - 1] == ')') | |||
| 672 | { | |||
| 673 | char *tmpstr; | |||
| 674 | if ((tmpstr = strchr(inputFile, '(')) != NULL((void*)0)) | |||
| 675 | { | |||
| 676 | *tmpstr = '\0'; | |||
| 677 | inputFile[len - 1] = '\0'; | |||
| 678 | tmpstr++; | |||
| 679 | if (*tmpstr == '\0') | |||
| 680 | { | |||
| 681 | WARNuWarning("Empty map in filename\n"); | |||
| 682 | ACTIONuAction("Ignored\n"); | |||
| 683 | } | |||
| 684 | else if (inputMap == NULL((void*)0)) | |||
| 685 | { | |||
| 686 | inputMap = uStringDup(tmpstr)((tmpstr) ? strdup(tmpstr) : ((void*)0)); | |||
| 687 | } | |||
| 688 | else | |||
| 689 | { | |||
| 690 | WARNuWarning("Map specified in filename and with -m flag\n"); | |||
| 691 | ACTION1uAction("map from name (\"%s\") ignored\n", tmpstr); | |||
| 692 | } | |||
| 693 | } | |||
| 694 | else | |||
| 695 | { | |||
| 696 | ERROR1uError("Illegal name \"%s\" for input file\n", inputFile); | |||
| 697 | return False0; | |||
| 698 | } | |||
| 699 | } | |||
| 700 | if ((len > 4) && (strcmp(&inputFile[len - 4], ".xkm") == 0)) | |||
| 701 | { | |||
| 702 | inputFormat = INPUT_XKM2; | |||
| 703 | } | |||
| 704 | else | |||
| 705 | { | |||
| 706 | FILE *file; | |||
| 707 | file = fopen(inputFile, "r"); | |||
| 708 | if (file) | |||
| 709 | { | |||
| 710 | if (XkmProbe(file)) | |||
| 711 | inputFormat = INPUT_XKM2; | |||
| 712 | else | |||
| 713 | inputFormat = INPUT_XKB1; | |||
| 714 | fclose(file); | |||
| 715 | } | |||
| 716 | else | |||
| 717 | { | |||
| 718 | fprintf(stderr__stderrp, "Cannot open \"%s\" for reading\n", | |||
| 719 | inputFile); | |||
| 720 | return False0; | |||
| 721 | } | |||
| 722 | } | |||
| 723 | } | |||
| 724 | else | |||
| 725 | { | |||
| 726 | inDpyName = inputFile; | |||
| 727 | inputFile = NULL((void*)0); | |||
| 728 | inputFormat = INPUT_XKM2; | |||
| 729 | } | |||
| 730 | ||||
| 731 | if (outputFormat == WANT_DEFAULT0) | |||
| 732 | { | |||
| 733 | if (xkblist) | |||
| 734 | outputFormat = WANT_LISTING5; | |||
| 735 | else if (inputFormat == INPUT_XKB1) | |||
| 736 | outputFormat = WANT_XKM_FILE1; | |||
| 737 | else | |||
| 738 | outputFormat = WANT_XKB_FILE3; | |||
| 739 | } | |||
| 740 | if ((outputFormat == WANT_LISTING5) && (inputFormat != INPUT_XKB1)) | |||
| 741 | { | |||
| 742 | if (inputFile) | |||
| 743 | ERRORuError("Cannot generate a listing from a .xkm file (yet)\n"); | |||
| 744 | else | |||
| 745 | ERRORuError("Cannot generate a listing from an X connection (yet)\n"); | |||
| 746 | return False0; | |||
| 747 | } | |||
| 748 | if (xkblist) | |||
| 749 | { | |||
| 750 | if (outputFile == NULL((void*)0)) | |||
| 751 | outputFile = uStringDup("-")(("-") ? strdup("-") : ((void*)0)); | |||
| 752 | else if (strchr(outputFile, ':') != NULL((void*)0)) | |||
| 753 | { | |||
| 754 | ERRORuError("Cannot write a listing to an X connection\n"); | |||
| 755 | return False0; | |||
| 756 | } | |||
| 757 | } | |||
| 758 | else if ((!outputFile) && (inputFile) && uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void* )0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison )0))) | |||
| 759 | { | |||
| 760 | int len = strlen("stdin") + strlen(fileTypeExt[outputFormat]) + 2; | |||
| 761 | outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char))); | |||
| 762 | if (outputFile == NULL((void*)0)) | |||
| 763 | { | |||
| 764 | WSGOuInternalError("Cannot allocate space for output file name\n"); | |||
| 765 | ACTIONuAction("Exiting\n"); | |||
| 766 | exit(1); | |||
| 767 | } | |||
| 768 | snprintf(outputFile, len, "stdin.%s", fileTypeExt[outputFormat])__builtin___snprintf_chk (outputFile, len, 0, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0), "stdin.%s", fileTypeExt[outputFormat ]); | |||
| 769 | } | |||
| 770 | else if ((outputFile == NULL((void*)0)) && (inputFile != NULL((void*)0))) | |||
| 771 | { | |||
| 772 | int len; | |||
| 773 | char *base, *ext; | |||
| 774 | ||||
| 775 | if (inputMap == NULL((void*)0)) | |||
| 776 | { | |||
| 777 | base = strrchr(inputFile, '/'); | |||
| 778 | if (base == NULL((void*)0)) | |||
| 779 | base = inputFile; | |||
| 780 | else | |||
| 781 | base++; | |||
| 782 | } | |||
| 783 | else | |||
| 784 | base = inputMap; | |||
| 785 | ||||
| 786 | len = strlen(base) + strlen(fileTypeExt[outputFormat]) + 2; | |||
| 787 | outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char))); | |||
| 788 | if (outputFile == NULL((void*)0)) | |||
| 789 | { | |||
| 790 | WSGOuInternalError("Cannot allocate space for output file name\n"); | |||
| 791 | ACTIONuAction("Exiting\n"); | |||
| 792 | exit(1); | |||
| 793 | } | |||
| 794 | ext = strrchr(base, '.'); | |||
| 795 | if (ext == NULL((void*)0)) | |||
| 796 | snprintf(outputFile, len, "%s.%s", base, fileTypeExt[outputFormat])__builtin___snprintf_chk (outputFile, len, 0, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0), "%s.%s", base, fileTypeExt[outputFormat ]); | |||
| 797 | else | |||
| 798 | { | |||
| 799 | strcpy(outputFile, base)__builtin___strcpy_chk (outputFile, base, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0)); | |||
| 800 | strcpy(&outputFile[ext - base + 1], fileTypeExt[outputFormat])__builtin___strcpy_chk (&outputFile[ext - base + 1], fileTypeExt [outputFormat], __builtin_object_size (&outputFile[ext - base + 1], 2 > 1 ? 1 : 0)); | |||
| 801 | } | |||
| 802 | } | |||
| 803 | else if (outputFile == NULL((void*)0)) | |||
| 804 | { | |||
| 805 | int len; | |||
| 806 | char *ch, *name, buf[128]; | |||
| 807 | if (inDpyName[0] == ':') | |||
| 808 | snprintf(name = buf, sizeof(buf), "server%s", inDpyName)__builtin___snprintf_chk (name = buf, sizeof(buf), 0, __builtin_object_size (name = buf, 2 > 1 ? 1 : 0), "server%s", inDpyName); | |||
| 809 | else | |||
| 810 | name = inDpyName; | |||
| 811 | ||||
| 812 | len = strlen(name) + strlen(fileTypeExt[outputFormat]) + 2; | |||
| 813 | outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char))); | |||
| 814 | if (outputFile == NULL((void*)0)) | |||
| 815 | { | |||
| 816 | WSGOuInternalError("Cannot allocate space for output file name\n"); | |||
| 817 | ACTIONuAction("Exiting\n"); | |||
| 818 | exit(1); | |||
| 819 | } | |||
| 820 | strcpy(outputFile, name)__builtin___strcpy_chk (outputFile, name, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0)); | |||
| 821 | for (ch = outputFile; (*ch) != '\0'; ch++) | |||
| 822 | { | |||
| 823 | if (*ch == ':') | |||
| 824 | *ch = '-'; | |||
| 825 | else if (*ch == '.') | |||
| 826 | *ch = '_'; | |||
| 827 | } | |||
| 828 | *ch++ = '.'; | |||
| 829 | strcpy(ch, fileTypeExt[outputFormat])__builtin___strcpy_chk (ch, fileTypeExt[outputFormat], __builtin_object_size (ch, 2 > 1 ? 1 : 0)); | |||
| 830 | } | |||
| 831 | #ifdef WIN32 | |||
| 832 | else if (strlen(outputFile) > 2 && | |||
| 833 | isalpha(outputFile[0]) && | |||
| 834 | outputFile[1] == ':' && strchr(outputFile + 2, ':') == NULL((void*)0)) | |||
| 835 | { | |||
| 836 | } | |||
| 837 | #endif | |||
| 838 | else if (strchr(outputFile, ':') != NULL((void*)0)) | |||
| 839 | { | |||
| 840 | outDpyName = outputFile; | |||
| 841 | outputFile = NULL((void*)0); | |||
| 842 | outputFormat = WANT_X_SERVER4; | |||
| 843 | } | |||
| 844 | return True1; | |||
| 845 | } | |||
| 846 | ||||
| 847 | static Display * | |||
| 848 | GetDisplay(char *program, char *dpyName) | |||
| 849 | { | |||
| 850 | int mjr, mnr, error; | |||
| 851 | Display *dpy; | |||
| 852 | ||||
| 853 | mjr = XkbMajorVersion1; | |||
| 854 | mnr = XkbMinorVersion0; | |||
| 855 | dpy = XkbOpenDisplay(dpyName, NULL((void*)0), NULL((void*)0), &mjr, &mnr, &error); | |||
| 856 | if (dpy == NULL((void*)0)) | |||
| 857 | { | |||
| 858 | switch (error) | |||
| 859 | { | |||
| 860 | case XkbOD_BadLibraryVersion1: | |||
| 861 | INFO3uInformation("%s was compiled with XKB version %d.%02d\n", | |||
| 862 | program, XkbMajorVersion1, XkbMinorVersion0); | |||
| 863 | ERROR2uError("X library supports incompatible version %d.%02d\n", | |||
| 864 | mjr, mnr); | |||
| 865 | break; | |||
| 866 | case XkbOD_ConnectionRefused2: | |||
| 867 | ERROR1uError("Cannot open display \"%s\"\n", dpyName); | |||
| 868 | break; | |||
| 869 | case XkbOD_NonXkbServer3: | |||
| 870 | ERROR1uError("XKB extension not present on %s\n", dpyName); | |||
| 871 | break; | |||
| 872 | case XkbOD_BadServerVersion4: | |||
| 873 | INFO3uInformation("%s was compiled with XKB version %d.%02d\n", | |||
| 874 | program, XkbMajorVersion1, XkbMinorVersion0); | |||
| 875 | ERROR3uError("Server %s uses incompatible version %d.%02d\n", | |||
| 876 | dpyName, mjr, mnr); | |||
| 877 | break; | |||
| 878 | default: | |||
| 879 | WSGO1uInternalError("Unknown error %d from XkbOpenDisplay\n", error); | |||
| 880 | } | |||
| 881 | } | |||
| 882 | else if (synch) | |||
| 883 | XSynchronize(dpy, True1); | |||
| 884 | return dpy; | |||
| 885 | } | |||
| 886 | ||||
| 887 | /***====================================================================***/ | |||
| 888 | ||||
| 889 | #ifdef DEBUG | |||
| 890 | extern int yydebug; | |||
| 891 | #endif | |||
| 892 | ||||
| 893 | int | |||
| 894 | main(int argc, char *argv[]) | |||
| 895 | { | |||
| 896 | FILE *file; /* input file (or stdin) */ | |||
| 897 | XkbFile *rtrn; | |||
| 898 | XkbFile *mapToUse; | |||
| 899 | int ok; | |||
| 900 | XkbFileInfo result; | |||
| 901 | Statusint status; | |||
| 902 | ||||
| 903 | scan_set_file(stdin__stdinp); | |||
| 904 | uSetDebugFile(NullString((char *)((void*)0))); | |||
| 905 | uSetErrorFile(NullString((char *)((void*)0))); | |||
| 906 | ||||
| 907 | XkbInitIncludePath(); | |||
| 908 | if (!parseArgs(argc, argv)) | |||
| ||||
| 909 | exit(1); | |||
| 910 | #ifdef DEBUG | |||
| 911 | if (debugFlags & 0x2) | |||
| 912 | yydebug = 1; | |||
| 913 | #endif | |||
| 914 | if (preErrorMsg) | |||
| 915 | uSetPreErrorMessage(preErrorMsg); | |||
| 916 | if (errorPrefix) | |||
| 917 | uSetErrorPrefix(errorPrefix); | |||
| 918 | if (postErrorMsg) | |||
| 919 | uSetPostErrorMessage(postErrorMsg); | |||
| 920 | file = NULL((void*)0); | |||
| 921 | XkbInitAtoms(NULL((void*)0)); | |||
| 922 | XkbAddDefaultDirectoriesToPath(); | |||
| 923 | if (xkblist) | |||
| 924 | { | |||
| 925 | Boolint gotSome; | |||
| 926 | gotSome = GenerateListing(outputFile); | |||
| 927 | if ((warningLevel > 7) && (!gotSome)) | |||
| 928 | return -1; | |||
| 929 | return 0; | |||
| 930 | } | |||
| 931 | if (inputFile != NULL((void*)0)) | |||
| 932 | { | |||
| 933 | if (uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void* )0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison )0))) | |||
| 934 | { | |||
| 935 | file = stdin__stdinp; | |||
| 936 | inputFile = "stdin"; | |||
| 937 | } | |||
| 938 | else | |||
| 939 | { | |||
| 940 | file = fopen(inputFile, "r"); | |||
| 941 | } | |||
| 942 | } | |||
| 943 | else if (inDpyName != NULL((void*)0)) | |||
| 944 | { | |||
| 945 | inDpy = GetDisplay(argv[0], inDpyName); | |||
| 946 | if (!inDpy) | |||
| 947 | { | |||
| 948 | ACTIONuAction("Exiting\n"); | |||
| 949 | exit(1); | |||
| 950 | } | |||
| 951 | } | |||
| 952 | if (outDpyName != NULL((void*)0)) | |||
| 953 | { | |||
| 954 | outDpy = GetDisplay(argv[0], outDpyName); | |||
| 955 | if (!outDpy) | |||
| 956 | { | |||
| 957 | ACTIONuAction("Exiting\n"); | |||
| 958 | exit(1); | |||
| 959 | } | |||
| 960 | } | |||
| 961 | if ((inDpy == NULL((void*)0)) && (outDpy == NULL((void*)0))) | |||
| 962 | { | |||
| 963 | int mjr, mnr; | |||
| 964 | mjr = XkbMajorVersion1; | |||
| 965 | mnr = XkbMinorVersion0; | |||
| 966 | if (!XkbLibraryVersion(&mjr, &mnr)) | |||
| 967 | { | |||
| 968 | INFO3uInformation("%s was compiled with XKB version %d.%02d\n", | |||
| 969 | argv[0], XkbMajorVersion1, XkbMinorVersion0); | |||
| 970 | ERROR2uError("X library supports incompatible version %d.%02d\n", | |||
| 971 | mjr, mnr); | |||
| 972 | ACTIONuAction("Exiting\n"); | |||
| 973 | exit(1); | |||
| 974 | } | |||
| 975 | } | |||
| 976 | if (file) | |||
| 977 | { | |||
| 978 | ok = True1; | |||
| 979 | setScanState(inputFile, 1); | |||
| 980 | if ((inputFormat == INPUT_XKB1) /* parse .xkb file */ | |||
| 981 | && (XKBParseFile(file, &rtrn) && (rtrn != NULL((void*)0)))) | |||
| 982 | { | |||
| 983 | fclose(file); | |||
| 984 | mapToUse = rtrn; | |||
| 985 | if (inputMap != NULL((void*)0)) /* map specified on cmdline? */ | |||
| 986 | { | |||
| 987 | while ((mapToUse) | |||
| 988 | && (!uStringEqual(mapToUse->name, inputMap)((((mapToUse->name)==((char *)((void*)0))||(inputMap)==((char *)((void*)0)))? (mapToUse->name)!=(inputMap):strcmp(mapToUse ->name,inputMap))==((Comparison)0)))) | |||
| 989 | { | |||
| 990 | mapToUse = (XkbFile *) mapToUse->common.next; | |||
| 991 | } | |||
| 992 | if (!mapToUse) | |||
| 993 | { | |||
| 994 | FATAL2uFatalError("No map named \"%s\" in \"%s\"\n", | |||
| 995 | inputMap, inputFile); | |||
| 996 | /* NOTREACHED */ | |||
| 997 | } | |||
| 998 | } | |||
| 999 | else if (rtrn->common.next != NULL((void*)0)) | |||
| 1000 | { | |||
| 1001 | /* look for map with XkbLC_Default flag. */ | |||
| 1002 | mapToUse = rtrn; | |||
| 1003 | for (; mapToUse; mapToUse = (XkbFile *) mapToUse->common.next) | |||
| 1004 | { | |||
| 1005 | if (mapToUse->flags & XkbLC_Default(1L << 1)) | |||
| 1006 | break; | |||
| 1007 | } | |||
| 1008 | if (!mapToUse) | |||
| 1009 | { | |||
| 1010 | mapToUse = rtrn; | |||
| 1011 | if (warningLevel > 4) | |||
| 1012 | { | |||
| 1013 | WARN1uWarning | |||
| 1014 | ("No map specified, but \"%s\" has several\n", | |||
| 1015 | inputFile); | |||
| 1016 | ACTION1uAction | |||
| 1017 | ("Using the first defined map, \"%s\"\n", | |||
| 1018 | mapToUse->name); | |||
| 1019 | } | |||
| 1020 | } | |||
| 1021 | } | |||
| 1022 | bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result ), __builtin_object_size ((char *) &result, 0)); | |||
| 1023 | result.type = mapToUse->type; | |||
| 1024 | if ((result.xkb = XkbAllocKeyboard()) == NULL((void*)0)) | |||
| 1025 | { | |||
| 1026 | WSGOuInternalError("Cannot allocate keyboard description\n"); | |||
| 1027 | /* NOTREACHED */ | |||
| 1028 | } | |||
| 1029 | switch (mapToUse->type) | |||
| 1030 | { | |||
| 1031 | case XkmSemanticsFile20: | |||
| 1032 | case XkmLayoutFile21: | |||
| 1033 | case XkmKeymapFile22: | |||
| 1034 | ok = CompileKeymap(mapToUse, &result, MergeReplace3); | |||
| 1035 | break; | |||
| 1036 | case XkmKeyNamesIndex4: | |||
| 1037 | ok = CompileKeycodes(mapToUse, &result, MergeReplace3); | |||
| 1038 | break; | |||
| 1039 | case XkmTypesIndex0: | |||
| 1040 | ok = CompileKeyTypes(mapToUse, &result, MergeReplace3); | |||
| 1041 | break; | |||
| 1042 | case XkmSymbolsIndex2: | |||
| 1043 | /* if it's just symbols, invent key names */ | |||
| 1044 | result.xkb->flags |= AutoKeyNames(1L << 0); | |||
| 1045 | ok = False0; | |||
| 1046 | break; | |||
| 1047 | case XkmCompatMapIndex1: | |||
| 1048 | ok = CompileCompatMap(mapToUse, &result, MergeReplace3, NULL((void*)0)); | |||
| 1049 | break; | |||
| 1050 | case XkmGeometryFile23: | |||
| 1051 | case XkmGeometryIndex5: | |||
| 1052 | /* if it's just a geometry, invent key names */ | |||
| 1053 | result.xkb->flags |= AutoKeyNames(1L << 0); | |||
| 1054 | ok = CompileGeometry(mapToUse, &result, MergeReplace3); | |||
| 1055 | break; | |||
| 1056 | default: | |||
| 1057 | WSGO1uInternalError("Unknown file type %d\n", mapToUse->type); | |||
| 1058 | ok = False0; | |||
| 1059 | break; | |||
| 1060 | } | |||
| 1061 | result.xkb->device_spec = device_id; | |||
| ||||
| 1062 | } | |||
| 1063 | else if (inputFormat == INPUT_XKM2) /* parse xkm file */ | |||
| 1064 | { | |||
| 1065 | unsigned tmp; | |||
| 1066 | bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result ), __builtin_object_size ((char *) &result, 0)); | |||
| 1067 | if ((result.xkb = XkbAllocKeyboard()) == NULL((void*)0)) | |||
| 1068 | { | |||
| 1069 | WSGOuInternalError("Cannot allocate keyboard description\n"); | |||
| 1070 | /* NOTREACHED */ | |||
| 1071 | } | |||
| 1072 | tmp = XkmReadFile(file, 0, XkmKeymapLegal((((1<<1))|((1<<4)|(1<<2)|(1<<0)))|(( ((1<<0)|(1<<6)|(1<<3))|((1<<6)|(1<< 5)))&(~(((1<<1))|((1<<4)|(1<<2)|(1<< 0)))))), &result); | |||
| 1073 | if (tmp == XkmKeymapLegal((((1<<1))|((1<<4)|(1<<2)|(1<<0)))|(( ((1<<0)|(1<<6)|(1<<3))|((1<<6)|(1<< 5)))&(~(((1<<1))|((1<<4)|(1<<2)|(1<< 0))))))) | |||
| 1074 | { | |||
| 1075 | ERROR1uError("Cannot read XKM file \"%s\"\n", inputFile); | |||
| 1076 | ok = False0; | |||
| 1077 | } | |||
| 1078 | result.xkb->device_spec = device_id; | |||
| 1079 | } | |||
| 1080 | else | |||
| 1081 | { | |||
| 1082 | INFO1uInformation("Errors encountered in %s; not compiled.\n", inputFile); | |||
| 1083 | ok = False0; | |||
| 1084 | } | |||
| 1085 | } | |||
| 1086 | else if (inDpy != NULL((void*)0)) | |||
| 1087 | { | |||
| 1088 | bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result ), __builtin_object_size ((char *) &result, 0)); | |||
| 1089 | result.type = XkmKeymapFile22; | |||
| 1090 | result.xkb = XkbGetMap(inDpy, XkbAllMapComponentsMask(((1<<0)|(1<<1)|(1<<2))|((1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7))), device_id); | |||
| 1091 | if (result.xkb == NULL((void*)0)) | |||
| 1092 | WSGOuInternalError("Cannot load keyboard description\n"); | |||
| 1093 | if (XkbGetIndicatorMap(inDpy, ~0, result.xkb) != Success0) | |||
| 1094 | WSGOuInternalError("Could not load indicator map\n"); | |||
| 1095 | if (XkbGetControls(inDpy, XkbAllControlsMask(0xF8001FFF), result.xkb) != Success0) | |||
| 1096 | WSGOuInternalError("Could not load keyboard controls\n"); | |||
| 1097 | if (XkbGetCompatMap(inDpy, XkbAllCompatMask(0x3), result.xkb) != Success0) | |||
| 1098 | WSGOuInternalError("Could not load compatibility map\n"); | |||
| 1099 | if (XkbGetNames(inDpy, XkbAllNamesMask(0x3fff), result.xkb) != Success0) | |||
| 1100 | WSGOuInternalError("Could not load names\n"); | |||
| 1101 | if ((status = XkbGetGeometry(inDpy, result.xkb)) != Success0) | |||
| 1102 | { | |||
| 1103 | if (warningLevel > 3) | |||
| 1104 | { | |||
| 1105 | char buf[100]; | |||
| 1106 | buf[0] = '\0'; | |||
| 1107 | XGetErrorText(inDpy, status, buf, 100); | |||
| 1108 | WARN1uWarning("Could not load keyboard geometry for %s\n", inDpyName); | |||
| 1109 | ACTION1uAction("%s\n", buf); | |||
| 1110 | ACTIONuAction("Resulting keymap file will not describe geometry\n"); | |||
| 1111 | } | |||
| 1112 | } | |||
| 1113 | if (computeDflts) | |||
| 1114 | ok = (ComputeKbdDefaults(result.xkb) == Success0); | |||
| 1115 | else | |||
| 1116 | ok = True1; | |||
| 1117 | } | |||
| 1118 | else | |||
| 1119 | { | |||
| 1120 | fprintf(stderr__stderrp, "Cannot open \"%s\" to compile\n", inputFile); | |||
| 1121 | ok = 0; | |||
| 1122 | } | |||
| 1123 | if (ok) | |||
| 1124 | { | |||
| 1125 | FILE *out = stdout__stdoutp; | |||
| 1126 | if ((inDpy != outDpy) && | |||
| 1127 | (XkbChangeKbdDisplay(outDpy, &result) != Success0)) | |||
| 1128 | { | |||
| 1129 | WSGO2uInternalError("Error converting keyboard display from %s to %s\n", | |||
| 1130 | inDpyName, outDpyName); | |||
| 1131 | exit(1); | |||
| 1132 | } | |||
| 1133 | if (outputFile != NULL((void*)0)) | |||
| 1134 | { | |||
| 1135 | if (uStringEqual(outputFile, "-")((((outputFile)==((char *)((void*)0))||("-")==((char *)((void *)0)))? (outputFile)!=("-"):strcmp(outputFile,"-"))==((Comparison )0))) | |||
| 1136 | outputFile = "stdout"; | |||
| 1137 | else | |||
| 1138 | { | |||
| 1139 | /* | |||
| 1140 | * fix to prevent symlink attack (e.g., | |||
| 1141 | * ln -s /etc/passwd /var/tmp/server-0.xkm) | |||
| 1142 | */ | |||
| 1143 | /* | |||
| 1144 | * this patch may have POSIX, Linux, or GNU libc bias | |||
| 1145 | * -- Branden Robinson | |||
| 1146 | */ | |||
| 1147 | int outputFileFd; | |||
| 1148 | int binMode = 0; | |||
| 1149 | const char *openMode = "w"; | |||
| 1150 | unlink(outputFile); | |||
| 1151 | #ifdef O_BINARY | |||
| 1152 | switch (outputFormat) | |||
| 1153 | { | |||
| 1154 | case WANT_XKM_FILE1: | |||
| 1155 | binMode = O_BINARY; | |||
| 1156 | openMode = "wb"; | |||
| 1157 | break; | |||
| 1158 | default: | |||
| 1159 | binMode = 0; | |||
| 1160 | break; | |||
| 1161 | } | |||
| 1162 | #endif | |||
| 1163 | outputFileFd = | |||
| 1164 | open(outputFile, O_WRONLY0x0001 | O_CREAT0x0200 | O_EXCL0x0800, | |||
| 1165 | S_IRUSR0000400 | S_IWUSR0000200 | S_IRGRP0000040 | S_IWGRP0000020 | S_IROTH0000004 | |||
| 1166 | | S_IWOTH0000002 | binMode); | |||
| 1167 | if (outputFileFd < 0) | |||
| 1168 | { | |||
| 1169 | ERROR1uError | |||
| 1170 | ("Cannot open \"%s\" to write keyboard description\n", | |||
| 1171 | outputFile); | |||
| 1172 | ACTIONuAction("Exiting\n"); | |||
| 1173 | exit(1); | |||
| 1174 | } | |||
| 1175 | #ifndef WIN32 | |||
| 1176 | out = fdopen(outputFileFd, openMode); | |||
| 1177 | #else | |||
| 1178 | close(outputFileFd); | |||
| 1179 | out = fopen(outputFile, "wb"); | |||
| 1180 | #endif | |||
| 1181 | /* end BR */ | |||
| 1182 | if (out == NULL((void*)0)) | |||
| 1183 | { | |||
| 1184 | ERROR1uError | |||
| 1185 | ("Cannot open \"%s\" to write keyboard description\n", | |||
| 1186 | outputFile); | |||
| 1187 | ACTIONuAction("Exiting\n"); | |||
| 1188 | exit(1); | |||
| 1189 | } | |||
| 1190 | } | |||
| 1191 | } | |||
| 1192 | switch (outputFormat) | |||
| 1193 | { | |||
| 1194 | case WANT_XKM_FILE1: | |||
| 1195 | ok = XkbWriteXKMFile(out, &result); | |||
| 1196 | break; | |||
| 1197 | case WANT_XKB_FILE3: | |||
| 1198 | ok = XkbWriteXKBFile(out, &result, showImplicit, NULL((void*)0), NULL((void*)0)); | |||
| 1199 | break; | |||
| 1200 | case WANT_C_HDR2: | |||
| 1201 | ok = XkbWriteCFile(out, outputFile, &result); | |||
| 1202 | break; | |||
| 1203 | case WANT_X_SERVER4: | |||
| 1204 | if (!(ok = XkbWriteToServer(&result))) | |||
| 1205 | { | |||
| 1206 | ERROR2uError("%s in %s\n", _XkbErrMessages[_XkbErrCode], | |||
| 1207 | _XkbErrLocation ? _XkbErrLocation : "unknown"); | |||
| 1208 | ACTION1uAction("Couldn't write keyboard description to %s\n", | |||
| 1209 | outDpyName); | |||
| 1210 | } | |||
| 1211 | break; | |||
| 1212 | default: | |||
| 1213 | WSGO1uInternalError("Unknown output format %d\n", outputFormat); | |||
| 1214 | ACTIONuAction("No output file created\n"); | |||
| 1215 | ok = False0; | |||
| 1216 | break; | |||
| 1217 | } | |||
| 1218 | if (outputFormat != WANT_X_SERVER4) | |||
| 1219 | { | |||
| 1220 | if (fclose(out)) | |||
| 1221 | { | |||
| 1222 | ERROR1uError("Cannot close \"%s\" properly (not enough space?)\n", | |||
| 1223 | outputFile); | |||
| 1224 | ok= False0; | |||
| 1225 | } | |||
| 1226 | else if (!ok) | |||
| 1227 | { | |||
| 1228 | ERROR2uError("%s in %s\n", _XkbErrMessages[_XkbErrCode], | |||
| 1229 | _XkbErrLocation ? _XkbErrLocation : "unknown"); | |||
| 1230 | } | |||
| 1231 | if (!ok) | |||
| 1232 | { | |||
| 1233 | ACTION1uAction("Output file \"%s\" removed\n", outputFile); | |||
| 1234 | unlink(outputFile); | |||
| 1235 | } | |||
| 1236 | } | |||
| 1237 | } | |||
| 1238 | if (inDpy) | |||
| 1239 | XCloseDisplay(inDpy); | |||
| 1240 | inDpy = NULL((void*)0); | |||
| 1241 | if (outDpy) | |||
| 1242 | XCloseDisplay(outDpy); | |||
| 1243 | uFinishUp(); | |||
| 1244 | return (ok == 0); | |||
| 1245 | } |