1 /************************************************************
2 Copyright 1996 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
26 /***********************************************************
28 Copyright 1988, 1998 The Open Group
30 Permission to use, copy, modify, distribute, and sell this software and its
31 documentation for any purpose is hereby granted without fee, provided that
32 the above copyright notice appear in all copies and that both that
33 copyright notice and this permission notice appear in supporting
36 The above copyright notice and this permission notice shall be included in
37 all copies or substantial portions of the Software.
39 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
43 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
44 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46 Except as contained in this notice, the name of The Open Group shall not be
47 used in advertising or otherwise to promote the sale, use or other dealings
48 in this Software without prior written authorization from The Open Group.
51 Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
55 Permission to use, copy, modify, and distribute this software and its
56 documentation for any purpose and without fee is hereby granted,
57 provided that the above copyright notice appear in all copies and that
58 both that copyright notice and this permission notice appear in
59 supporting documentation, and that the name of Digital not be
60 used in advertising or publicity pertaining to distribution of the
61 software without specific, written prior permission.
63 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
64 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
65 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
66 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
67 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
68 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
71 ******************************************************************/
75 #include <sys/types.h>
77 #include <X11/keysym.h>
83 #define DEBUG_VAR listingDebug
90 # define _POSIX_SOURCE
99 #include <sys/param.h>
103 #define PATH_MAX MAXPATHLEN
105 #define PATH_MAX 1024
111 # include <windows.h>
112 # define FileName(file) file.cFileName
117 # define FileName(file) file->d_name
122 #include "parseutils.h"
126 #ifndef DFLT_XKB_CONFIG_ROOT
127 #define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
130 unsigned int listingDebug;
132 typedef struct _CompPair {
136 XkbComponentNamePtr comp;
139 /***====================================================================***/
142 AddComponent(CompPair *cp, char *fileName, XkbFile *map, unsigned dirsToStrip)
144 if (!cp || !fileName || !map)
147 if (cp->num >= cp->sz) {
148 int orig_sz = cp->sz;
149 XkbComponentNamePtr orig_comp = cp->comp;
156 cp->comp = _XkbRealloc(cp->comp,
157 cp->sz * sizeof(XkbComponentNameRec));
159 ERROR("Failed reallocating component name list\n");
161 cp->comp = orig_comp;
166 /* Strip off leading directories of component */
167 if (dirsToStrip > 0) {
171 for (i = 0, tmp = last = fileName; (i <= dirsToStrip) && tmp; i++) {
173 tmp = strchr(tmp, '/');
178 fileName = (tmp ? tmp : last);
182 size_t len = strlen(fileName) + strlen(map->name) + 3;
184 cp->comp[cp->num].name = _XkbAlloc(len * sizeof(char));
185 if (!cp->comp[cp->num].name) {
186 ERROR("Could not allocate space for component name\n");
189 sprintf(cp->comp[cp->num].name, "%s(%s)", fileName, map->name);
192 cp->comp[cp->num].name = strdup(fileName);
193 if (!cp->comp[cp->num].name) {
194 ERROR("Could not duplicate component name\n");
199 cp->comp[cp->num].flags = map->flags;
206 MapMatches(char *mapToConsider, char *ptrn)
208 return ptrn ? XkbcNameMatchesPattern(mapToConsider, ptrn) : True;
212 ParseComponents(CompPair *cp, char *path, char *map, int *max, unsigned strip)
216 XkbFile *rtrn, *mapToUse;
217 unsigned oldWarningLevel;
219 if (!cp || !path || !max)
223 if (warningLevel > 9)
224 fprintf(stderr, "should list:\n");
227 oldWarningLevel = warningLevel;
231 if (oldWarningLevel > 9)
232 fprintf(stderr, "%s(%s)\n", path ? path : "*", map ? map : "*");
235 inputFile = fopen(path, "r");
237 if (oldWarningLevel > 5)
238 WARN("Couldn't open \"%s\"\n", path);
242 setScanState(path, 1);
243 if (!XKBParseFile(inputFile, &rtrn) || !rtrn) {
244 if (oldWarningLevel > 5)
245 WARN("Couldn't parse file \"%s\"\n", path);
251 for (; mapToUse; mapToUse = (XkbFile *)mapToUse->common.next) {
252 if (!MapMatches(mapToUse->name, map))
258 if (AddComponent(cp, path, mapToUse, strip))
262 warningLevel = oldWarningLevel;
270 /***====================================================================***/
273 AddDirectory(CompPair *cp, char *head, char *ptrn, char *rest, char *map,
274 int *max, unsigned strip)
278 WIN32_FIND_DATA file;
288 ERROR("Must specify directory name\n");
292 strncpy(path, head, sizeof(path));
293 path[PATH_MAX - 1] = '\0';
294 baselen = strlen(path);
299 if (!rest && ptrn && !strchr(ptrn, '/')) {
301 map = strchr(ptrn, '(');
303 else if (!rest && !ptrn && !strchr(head, '/')) {
305 map = strchr(head, '(');
309 tmp = strchr(tmp, ')');
310 if (!tmp || tmp[1] != '\0') {
311 ERROR("File and map must have the format file(map)\n");
321 if ((dirh = FindFirstFile("*.*", &file)) == INVALID_HANDLE_VALUE)
324 if (!(dirp = opendir(head))) {
325 ERROR("Could not open directory \"%s\"\n", head ? head : ".");
333 while ((file = readdir(dirp)) != NULL)
339 filename = FileName(file);
340 if (!filename || filename[0] == '.')
342 if (ptrn && (!XkbcNameMatchesPattern(filename, ptrn)))
345 snprintf(&path[baselen], sizeof(path) - baselen, "/%s", filename);
346 if (stat(path, &sbuf) < 0) {
347 ERROR("Could not read file \"%s\"\n", path);
351 if ((rest && !S_ISDIR(sbuf.st_mode)) ||
352 (map && S_ISDIR(sbuf.st_mode)))
355 if (S_ISDIR(sbuf.st_mode))
356 nMatch += AddDirectory(cp, path, rest, NULL, map, max, strip);
358 nMatch += ParseComponents(cp, path, map, max, strip);
361 while (FindNextFile(dirh, &file));
366 /***====================================================================***/
369 GenerateComponent(XkbComponentListPtr complist, unsigned type, char *head_in,
370 char *base, int *max)
372 char *str, *head, *ptrn = NULL, *rest = NULL;
376 unsigned dirsToStrip;
379 if (!complist || !head_in || !max)
383 for (str = head_in; (*str != '\0') && (*str != '?') && (*str != '*');
386 if ((str != head_in) && (*str == '/'))
395 /* no slash before the first wildcard */
400 /* slash followed by wildcard */
407 rest = strchr(ptrn, '/');
414 if ((rest && ptrn && (strchr(ptrn, '(') || strchr(ptrn, ')'))) ||
415 (head && (strchr(head, '(') || strchr(head, ')')))) {
416 ERROR("Files/maps to list must have the form file(map)\n");
420 /* Prepend XKB directory */
421 snprintf(buf, sizeof(buf), "%s%s%s", base ? base : "", base ? "/" : "",
422 XkbDirectoryForInclude(type));
425 /* Figure out directory stripping */
428 while ((str = strchr(str, '/')) != NULL) {
434 snprintf(&buf[len], PATH_MAX - len, "/%s", head);
437 memset(&cp, 0, sizeof(CompPair));
438 extra = AddDirectory(&cp, head, ptrn, rest, NULL, max, dirsToStrip);
440 /* Trim excess component slots */
441 if (cp.sz > 0 && cp.sz > cp.num) {
442 if (_XkbRealloc(cp.comp, cp.num * sizeof(XkbComponentNameRec)))
445 WARN("Could not reallocate component name list\n");
450 complist->num_keymaps = cp.num;
451 complist->keymaps = cp.comp;
453 case XkmKeyNamesIndex:
454 complist->num_keycodes = cp.num;
455 complist->keycodes = cp.comp;
458 complist->num_types = cp.num;
459 complist->types = cp.comp;
461 case XkmCompatMapIndex:
462 complist->num_compat = cp.num;
463 complist->compat = cp.comp;
465 case XkmSymbolsIndex:
466 complist->num_symbols = cp.num;
467 complist->symbols = cp.comp;
469 case XkmGeometryIndex:
470 complist->num_geometry = cp.num;
471 complist->geometry = cp.comp;
478 /***====================================================================***/
481 XkbcListComponents(XkbComponentNamesPtr ptrns, int *maxMatch)
483 XkbComponentListPtr complist = NULL;
486 complist = _XkbTypedCalloc(1, XkbComponentListRec);
488 ERROR("could not allocate space for listing\n");
492 if (!maxMatch || *maxMatch <= 0)
495 if (ptrns->keymap && *ptrns->keymap != '\0')
496 extra += GenerateComponent(complist, XkmKeymapFile, ptrns->keycodes,
497 DFLT_XKB_CONFIG_ROOT, maxMatch);
499 if (ptrns->keycodes && *ptrns->keycodes != '\0')
500 extra += GenerateComponent(complist, XkmKeyNamesIndex, ptrns->keycodes,
501 DFLT_XKB_CONFIG_ROOT, maxMatch);
503 if (ptrns->types && *ptrns->types != '\0')
504 extra += GenerateComponent(complist, XkmTypesIndex, ptrns->types,
505 DFLT_XKB_CONFIG_ROOT, maxMatch);
507 if (ptrns->compat && *ptrns->compat != '\0')
508 extra += GenerateComponent(complist, XkmCompatMapIndex, ptrns->compat,
509 DFLT_XKB_CONFIG_ROOT, maxMatch);
511 if (ptrns->symbols && *ptrns->symbols != '\0')
512 extra += GenerateComponent(complist, XkmSymbolsIndex, ptrns->symbols,
513 DFLT_XKB_CONFIG_ROOT, maxMatch);
515 if (ptrns->geometry && *ptrns->geometry != '\0')
516 extra += GenerateComponent(complist, XkmGeometryIndex, ptrns->geometry,
517 DFLT_XKB_CONFIG_ROOT, maxMatch);