Bug Summary

File:keytypes.c
Location:line 600, column 40
Description:Access to field 'indexVMods' results in a dereference of a null pointer (loaded from variable 'old')

Annotated Source Code

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 "xkbcomp.h"
28#include "tokens.h"
29#include "expr.h"
30#include "vmod.h"
31#include "action.h"
32#include "misc.h"
33
34typedef struct _PreserveInfo
35{
36 CommonInfo defs;
37 short matchingMapIndex;
38 unsigned char indexMods;
39 unsigned char preMods;
40 unsigned short indexVMods;
41 unsigned short preVMods;
42} PreserveInfo;
43
44#define _KT_Name(1<<0) (1<<0)
45#define _KT_Mask(1<<1) (1<<1)
46#define _KT_Map(1<<2) (1<<2)
47#define _KT_Preserve(1<<3) (1<<3)
48#define _KT_LevelNames(1<<4) (1<<4)
49
50typedef struct _KeyTypeInfo
51{
52 CommonInfo defs;
53 Display *dpy;
54 Atom name;
55 int fileID;
56 unsigned mask;
57 unsigned vmask;
58 Boolint groupInfo;
59 int numLevels;
60 int nEntries;
61 int szEntries;
62 XkbKTMapEntryPtr entries;
63 PreserveInfo *preserve;
64 int szNames;
65 Atom *lvlNames;
66} KeyTypeInfo;
67
68typedef struct _KeyTypesInfo
69{
70 Display *dpy;
71 char *name;
72 int errorCount;
73 int fileID;
74 unsigned stdPresent;
75 int nTypes;
76 KeyTypeInfo *types;
77 KeyTypeInfo dflt;
78 VModInfo vmods;
79} KeyTypesInfo;
80
81Atom tok_ONE_LEVEL;
82Atom tok_TWO_LEVEL;
83Atom tok_ALPHABETIC;
84Atom tok_KEYPAD;
85
86/***====================================================================***/
87
88#define ReportTypeShouldBeArray(t,f)ReportShouldBeArray("key type",(f),XkbAtomText((t)->dpy,(t
)->name,3))
\
89 ReportShouldBeArray("key type",(f),TypeTxt(t)XkbAtomText((t)->dpy,(t)->name,3))
90#define ReportTypeBadType(t,f,w)ReportBadType("key type",(f),XkbAtomText((t)->dpy,(t)->
name,3),(w))
\
91 ReportBadType("key type",(f),TypeTxt(t)XkbAtomText((t)->dpy,(t)->name,3),(w))
92
93/***====================================================================***/
94
95extern Boolint AddMapEntry(XkbDescPtr /* xkb */ ,
96 KeyTypeInfo * /* type */ ,
97 XkbKTMapEntryPtr /* new */ ,
98 Boolint /* clobber */ ,
99 Boolint /* report */
100 );
101
102extern Boolint AddPreserve(XkbDescPtr /* xkb */ ,
103 KeyTypeInfo * /* type */ ,
104 PreserveInfo * /* new */ ,
105 Boolint /* clobber */ ,
106 Boolint /* report */
107 );
108
109extern Boolint AddLevelName(KeyTypeInfo * /* type */ ,
110 unsigned /* level */ ,
111 Atom /* name */ ,
112 Boolint /* clobber */ ,
113 Boolint /* report */
114 );
115
116#define MapEntryTxt(t,x,e)XkbVModMaskText((t)->dpy,(x),(e)->mods.real_mods,(e)->
mods.vmods,3)
\
117 XkbVModMaskText((t)->dpy,(x),(e)->mods.real_mods,(e)->mods.vmods,XkbMessage3)
118#define PreserveIndexTxt(t,x,p)XkbVModMaskText((t)->dpy,(x),(p)->indexMods,(p)->indexVMods
,3)
\
119 XkbVModMaskText((t)->dpy,(x),(p)->indexMods,(p)->indexVMods,XkbMessage3)
120#define PreserveTxt(t,x,p)XkbVModMaskText((t)->dpy,(x),(p)->preMods,(p)->preVMods
,3)
\
121 XkbVModMaskText((t)->dpy,(x),(p)->preMods,(p)->preVMods,XkbMessage3)
122#define TypeTxt(t)XkbAtomText((t)->dpy,(t)->name,3) XkbAtomText((t)->dpy,(t)->name,XkbMessage3)
123#define TypeMaskTxt(t,x)XkbVModMaskText((t)->dpy,(x),(t)->mask,(t)->vmask,3) \
124 XkbVModMaskText((t)->dpy,(x),(t)->mask,(t)->vmask,XkbMessage3)
125
126/***====================================================================***/
127
128static void
129InitKeyTypesInfo(KeyTypesInfo * info, XkbDescPtr xkb, KeyTypesInfo * from)
130{
131 tok_ONE_LEVEL = XkbInternAtom(NULL((void*)0), "ONE_LEVEL", False0);
132 tok_TWO_LEVEL = XkbInternAtom(NULL((void*)0), "TWO_LEVEL", False0);
133 tok_ALPHABETIC = XkbInternAtom(NULL((void*)0), "ALPHABETIC", False0);
134 tok_KEYPAD = XkbInternAtom(NULL((void*)0), "KEYPAD", False0);
135 info->dpy = NULL((void*)0);
136 info->name = uStringDup("default")(("default") ? strdup("default") : ((void*)0));
137 info->errorCount = 0;
138 info->stdPresent = 0;
139 info->nTypes = 0;
140 info->types = NULL((void*)0);
141 info->dflt.defs.defined = 0;
142 info->dflt.defs.fileID = 0;
143 info->dflt.defs.merge = MergeOverride2;
144 info->dflt.defs.next = NULL((void*)0);
145 info->dflt.name = None0L;
146 info->dflt.mask = 0;
147 info->dflt.vmask = 0;
148 info->dflt.groupInfo = False0;
149 info->dflt.numLevels = 1;
150 info->dflt.nEntries = info->dflt.szEntries = 0;
151 info->dflt.entries = NULL((void*)0);
152 info->dflt.szNames = 0;
153 info->dflt.lvlNames = NULL((void*)0);
154 info->dflt.preserve = NULL((void*)0);
155 InitVModInfo(&info->vmods, xkb);
156 if (from != NULL((void*)0))
157 {
158 info->dpy = from->dpy;
159 info->dflt = from->dflt;
160 if (from->dflt.entries)
161 {
162 info->dflt.entries = uTypedCalloc(from->dflt.szEntries,((XkbKTMapEntryRec *)uCalloc((unsigned)from->dflt.szEntries
,(unsigned)sizeof(XkbKTMapEntryRec)))
163 XkbKTMapEntryRec)((XkbKTMapEntryRec *)uCalloc((unsigned)from->dflt.szEntries
,(unsigned)sizeof(XkbKTMapEntryRec)))
;
164 if (info->dflt.entries)
165 {
166 unsigned sz = from->dflt.nEntries * sizeof(XkbKTMapEntryRec);
167 memcpy(info->dflt.entries, from->dflt.entries, sz);
168 }
169 }
170 if (from->dflt.lvlNames)
171 {
172 info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, Atom)((Atom *)uCalloc((unsigned)from->dflt.szNames,(unsigned)sizeof
(Atom)))
;
173 if (info->dflt.lvlNames)
174 {
175 register unsigned sz = from->dflt.szNames * sizeof(Atom);
176 memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz);
177 }
178 }
179 if (from->dflt.preserve)
180 {
181 PreserveInfo *old, *new, *last;
182 last = NULL((void*)0);
183 old = from->dflt.preserve;
184 for (; old; old = (PreserveInfo *) old->defs.next)
185 {
186 new = uTypedAlloc(PreserveInfo)((PreserveInfo *)uAlloc((unsigned)sizeof(PreserveInfo)));
187 if (!new)
188 return;
189 *new = *old;
190 new->defs.next = NULL((void*)0);
191 if (last)
192 last->defs.next = (CommonInfo *) new;
193 else
194 info->dflt.preserve = new;
195 last = new;
196 }
197 }
198 }
199 return;
200}
201
202static void
203FreeKeyTypeInfo(KeyTypeInfo * type)
204{
205 if (type->entries != NULL((void*)0))
206 {
207 uFree(type->entries);
208 type->entries = NULL((void*)0);
209 }
210 if (type->lvlNames != NULL((void*)0))
211 {
212 uFree(type->lvlNames);
213 type->lvlNames = NULL((void*)0);
214 }
215 if (type->preserve != NULL((void*)0))
216 {
217 ClearCommonInfo(&type->preserve->defs);
218 type->preserve = NULL((void*)0);
219 }
220 return;
221}
222
223static void
224FreeKeyTypesInfo(KeyTypesInfo * info)
225{
226 info->dpy = NULL((void*)0);
227 if (info->name)
228 uFree(info->name);
229 info->name = NULL((void*)0);
230 if (info->types)
231 {
232 register KeyTypeInfo *type;
233 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
234 {
235 FreeKeyTypeInfo(type);
236 }
237 info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
238 }
239 FreeKeyTypeInfo(&info->dflt);
240 return;
241}
242
243static KeyTypeInfo *
244NextKeyType(KeyTypesInfo * info)
245{
246 KeyTypeInfo *type;
247
248 type = uTypedAlloc(KeyTypeInfo)((KeyTypeInfo *)uAlloc((unsigned)sizeof(KeyTypeInfo)));
249 if (type != NULL((void*)0))
250 {
251 bzero(type, sizeof(KeyTypeInfo))memset(type,0,sizeof(KeyTypeInfo));
252 type->defs.fileID = info->fileID;
253 type->dpy = info->dpy;
254 info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
255 (CommonInfo *) type);
256 info->nTypes++;
257 }
258 return type;
259}
260
261static KeyTypeInfo *
262FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
263{
264 KeyTypeInfo *old;
265
266 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
267 {
268 if (old->name == new->name)
269 return old;
270 }
271 return NULL((void*)0);
272}
273
274static Boolint
275ReportTypeBadWidth(const char *type, int has, int needs)
276{
277 ERROR3uError("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
278 ACTIONuAction("Illegal type definition ignored\n");
279 return False0;
280}
281
282static Boolint
283AddKeyType(XkbDescPtr xkb, KeyTypesInfo * info, KeyTypeInfo * new)
284{
285 KeyTypeInfo *old;
286
287 if (new->name == tok_ONE_LEVEL)
288 {
289 if (new->numLevels > 1)
290 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
291 info->stdPresent |= XkbOneLevelMask(1<<0);
292 }
293 else if (new->name == tok_TWO_LEVEL)
294 {
295 if (new->numLevels > 2)
296 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
297 else if (new->numLevels < 2)
298 new->numLevels = 2;
299 info->stdPresent |= XkbTwoLevelMask(1<<1);
300 }
301 else if (new->name == tok_ALPHABETIC)
302 {
303 if (new->numLevels > 2)
304 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
305 else if (new->numLevels < 2)
306 new->numLevels = 2;
307 info->stdPresent |= XkbAlphabeticMask(1<<2);
308 }
309 else if (new->name == tok_KEYPAD)
310 {
311 if (new->numLevels > 2)
312 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
313 else if (new->numLevels < 2)
314 new->numLevels = 2;
315 info->stdPresent |= XkbKeypadMask(1<<3);
316 }
317
318 old = FindMatchingKeyType(info, new);
319 if (old != NULL((void*)0))
320 {
321 Boolint report;
322 if ((new->defs.merge == MergeReplace3)
323 || (new->defs.merge == MergeOverride2))
324 {
325 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
326 if (((old->defs.fileID == new->defs.fileID)
327 && (warningLevel > 0)) || (warningLevel > 9))
328 {
329 WARN1uWarning("Multiple definitions of the %s key type\n",
330 XkbAtomGetString(NULL((void*)0), new->name));
331 ACTIONuAction("Earlier definition ignored\n");
332 }
333 FreeKeyTypeInfo(old);
334 *old = *new;
335 new->szEntries = new->nEntries = 0;
336 new->entries = NULL((void*)0);
337 new->preserve = NULL((void*)0);
338 new->lvlNames = NULL((void*)0);
339 old->defs.next = &next->defs;
340 return True1;
341 }
342 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
343 if (report)
344 {
345 WARN1uWarning("Multiple definitions of the %s key type\n",
346 XkbAtomGetString(NULL((void*)0), new->name));
347 ACTIONuAction("Later definition ignored\n");
348 }
349 FreeKeyTypeInfo(new);
350 return True1;
351 }
352 old = NextKeyType(info);
353 if (old == NULL((void*)0))
354 return False0;
355 *old = *new;
356 old->defs.next = NULL((void*)0);
357 new->nEntries = new->szEntries = 0;
358 new->entries = NULL((void*)0);
359 new->szNames = 0;
360 new->lvlNames = NULL((void*)0);
361 new->preserve = NULL((void*)0);
362 return True1;
363}
364
365/***====================================================================***/
366
367static void
368MergeIncludedKeyTypes(KeyTypesInfo * into,
369 KeyTypesInfo * from, unsigned merge, XkbDescPtr xkb)
370{
371 KeyTypeInfo *type;
372
373 if (from->errorCount > 0)
374 {
375 into->errorCount += from->errorCount;
376 return;
377 }
378 if (into->name == NULL((void*)0))
379 {
380 into->name = from->name;
381 from->name = NULL((void*)0);
382 }
383 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
384 {
385 if (merge != MergeDefault0)
386 type->defs.merge = merge;
387 if (!AddKeyType(xkb, into, type))
388 into->errorCount++;
389 }
390 into->stdPresent |= from->stdPresent;
391 return;
392}
393
394typedef void (*FileHandler) (XkbFile * /* file */ ,
395 XkbDescPtr /* xkb */ ,
396 unsigned /* merge */ ,
397 KeyTypesInfo * /* included */
398 );
399
400static Boolint
401HandleIncludeKeyTypes(IncludeStmt * stmt,
402 XkbDescPtr xkb, KeyTypesInfo * info, FileHandler hndlr)
403{
404 unsigned newMerge;
405 XkbFile *rtrn;
406 KeyTypesInfo included;
407 Boolint haveSelf;
408
409 haveSelf = False0;
410 if ((stmt->file == NULL((void*)0)) && (stmt->map == NULL((void*)0)))
411 {
412 haveSelf = True1;
413 included = *info;
414 bzero(info, sizeof(KeyTypesInfo))memset(info,0,sizeof(KeyTypesInfo));
415 }
416 else if (ProcessIncludeFile(stmt, XkmTypesIndex0, &rtrn, &newMerge))
417 {
418 InitKeyTypesInfo(&included, xkb, info);
419 included.fileID = included.dflt.defs.fileID = rtrn->id;
420 included.dflt.defs.merge = newMerge;
421
422 (*hndlr) (rtrn, xkb, newMerge, &included);
423 if (stmt->stmt != NULL((void*)0))
424 {
425 if (included.name != NULL((void*)0))
426 uFree(included.name);
427 included.name = stmt->stmt;
428 stmt->stmt = NULL((void*)0);
429 }
430 }
431 else
432 {
433 info->errorCount += 10;
434 return False0;
435 }
436 if ((stmt->next != NULL((void*)0)) && (included.errorCount < 1))
437 {
438 IncludeStmt *next;
439 unsigned op;
440 KeyTypesInfo next_incl;
441
442 for (next = stmt->next; next != NULL((void*)0); next = next->next)
443 {
444 if ((next->file == NULL((void*)0)) && (next->map == NULL((void*)0)))
445 {
446 haveSelf = True1;
447 MergeIncludedKeyTypes(&included, info, next->merge, xkb);
448 FreeKeyTypesInfo(info);
449 }
450 else if (ProcessIncludeFile(next, XkmTypesIndex0, &rtrn, &op))
451 {
452 InitKeyTypesInfo(&next_incl, xkb, &included);
453 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
454 next_incl.dflt.defs.merge = op;
455 (*hndlr) (rtrn, xkb, op, &next_incl);
456 MergeIncludedKeyTypes(&included, &next_incl, op, xkb);
457 FreeKeyTypesInfo(&next_incl);
458 }
459 else
460 {
461 info->errorCount += 10;
462 return False0;
463 }
464 }
465 }
466 if (haveSelf)
467 *info = included;
468 else
469 {
470 MergeIncludedKeyTypes(info, &included, newMerge, xkb);
471 FreeKeyTypesInfo(&included);
472 }
473 return (info->errorCount == 0);
474}
475
476/***====================================================================***/
477
478static XkbKTMapEntryPtr
479FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
480{
481 register int i;
482 XkbKTMapEntryPtr entry;
483
484 for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
485 {
486 if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
487 return entry;
488 }
489 return NULL((void*)0);
490}
491
492static void
493DeleteLevel1MapEntries(KeyTypeInfo * type)
494{
495 register int i, n;
496
497 for (i = 0; i < type->nEntries; i++)
498 {
499 if (type->entries[i].level == 0)
500 {
501 for (n = i; n < type->nEntries - 1; n++)
502 {
503 type->entries[n] = type->entries[n + 1];
504 }
505 type->nEntries--;
506 }
507 }
508 return;
509}
510
511/**
512 * Return a pointer to the next free XkbKTMapEntry, reallocating space if
513 * necessary.
514 */
515static XkbKTMapEntryPtr
516NextMapEntry(KeyTypeInfo * type)
517{
518 if (type->entries == NULL((void*)0))
519 {
520 type->entries = uTypedCalloc(2, XkbKTMapEntryRec)((XkbKTMapEntryRec *)uCalloc((unsigned)2,(unsigned)sizeof(XkbKTMapEntryRec
)))
;
521 if (type->entries == NULL((void*)0))
522 {
523 ERROR1uError("Couldn't allocate map entries for %s\n", TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
524 ACTIONuAction("Map entries lost\n");
525 return NULL((void*)0);
526 }
527 type->szEntries = 2;
528 type->nEntries = 0;
529 }
530 else if (type->nEntries >= type->szEntries)
531 {
532 type->szEntries *= 2;
533 type->entries = uTypedRecalloc(type->entries,((XkbKTMapEntryRec *)uRecalloc((Opaque)type->entries,((unsigned
)type->nEntries),((unsigned)type->szEntries),sizeof(XkbKTMapEntryRec
)))
534 type->nEntries, type->szEntries,((XkbKTMapEntryRec *)uRecalloc((Opaque)type->entries,((unsigned
)type->nEntries),((unsigned)type->szEntries),sizeof(XkbKTMapEntryRec
)))
535 XkbKTMapEntryRec)((XkbKTMapEntryRec *)uRecalloc((Opaque)type->entries,((unsigned
)type->nEntries),((unsigned)type->szEntries),sizeof(XkbKTMapEntryRec
)))
;
536 if (type->entries == NULL((void*)0))
537 {
538 ERROR1uError("Couldn't reallocate map entries for %s\n", TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
539 ACTIONuAction("Map entries lost\n");
540 return NULL((void*)0);
541 }
542 }
543 return &type->entries[type->nEntries++];
544}
545
546Boolint
547AddPreserve(XkbDescPtr xkb,
548 KeyTypeInfo * type, PreserveInfo * new, Boolint clobber, Boolint report)
549{
550 PreserveInfo *old;
551
552 old = type->preserve;
553 while (old != NULL((void*)0))
1
Assuming 'old' is equal to null
2
Loop condition is false. Execution continues on line 596
554 {
555 if ((old->indexMods != new->indexMods) ||
556 (old->indexVMods != new->indexVMods))
557 {
558 old = (PreserveInfo *) old->defs.next;
559 continue;
560 }
561 if ((old->preMods == new->preMods)
562 && (old->preVMods == new->preVMods))
563 {
564 if (warningLevel > 9)
565 {
566 WARN2uWarning("Identical definitions for preserve[%s] in %s\n",
567 PreserveIndexTxt(type, xkb, old)XkbVModMaskText((type)->dpy,(xkb),(old)->indexMods,(old
)->indexVMods,3)
, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
568 ACTIONuAction("Ignored\n");
569 }
570 return True1;
571 }
572 if (report && (warningLevel > 0))
573 {
574 char *str;
575 WARN2uWarning("Multiple definitions for preserve[%s] in %s\n",
576 PreserveIndexTxt(type, xkb, old)XkbVModMaskText((type)->dpy,(xkb),(old)->indexMods,(old
)->indexVMods,3)
, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
577
578 if (clobber)
579 str = PreserveTxt(type, xkb, new)XkbVModMaskText((type)->dpy,(xkb),(new)->preMods,(new)->
preVMods,3)
;
580 else
581 str = PreserveTxt(type, xkb, old)XkbVModMaskText((type)->dpy,(xkb),(old)->preMods,(old)->
preVMods,3)
;
582 ACTION1uAction("Using %s, ", str);
583 if (clobber)
584 str = PreserveTxt(type, xkb, old)XkbVModMaskText((type)->dpy,(xkb),(old)->preMods,(old)->
preVMods,3)
;
585 else
586 str = PreserveTxt(type, xkb, new)XkbVModMaskText((type)->dpy,(xkb),(new)->preMods,(new)->
preVMods,3)
;
587 INFO1uInformation("ignoring %s\n", str);
588 }
589 if (clobber)
590 {
591 old->preMods = new->preMods;
592 old->preVMods = new->preVMods;
593 }
594 return True1;
595 }
596 old = uTypedAlloc(PreserveInfo)((PreserveInfo *)uAlloc((unsigned)sizeof(PreserveInfo)));
597 if (!old)
3
Assuming 'old' is null
4
Taking true branch
598 {
599 WSGO1uInternalError("Couldn't allocate preserve in %s\n", TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
600 ACTION1uAction("Preserve[%s] lost\n", PreserveIndexTxt(type, xkb, old)XkbVModMaskText((type)->dpy,(xkb),(old)->indexMods,(old
)->indexVMods,3)
);
5
Within the expansion of the macro 'PreserveIndexTxt':
a
Access to field 'indexVMods' results in a dereference of a null pointer (loaded from variable 'old')
601 return False0;
602 }
603 *old = *new;
604 old->matchingMapIndex = -1;
605 type->preserve =
606 (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
607 return True1;
608}
609
610/**
611 * Add a new KTMapEntry to the given key type. If an entry with the same mods
612 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
613 * entry is created.
614 *
615 * @param clobber Overwrite existing entry.
616 * @param report True if a warning is to be printed on.
617 */
618Boolint
619AddMapEntry(XkbDescPtr xkb,
620 KeyTypeInfo * type,
621 XkbKTMapEntryPtr new, Boolint clobber, Boolint report)
622{
623 XkbKTMapEntryPtr old;
624
625 if ((old =
626 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
627 {
628 if (report && (old->level != new->level))
629 {
630 unsigned use, ignore;
631 if (clobber)
632 {
633 use = new->level + 1;
634 ignore = old->level + 1;
635 }
636 else
637 {
638 use = old->level + 1;
639 ignore = new->level + 1;
640 }
641 WARN2uWarning("Multiple map entries for %s in %s\n",
642 MapEntryTxt(type, xkb, new)XkbVModMaskText((type)->dpy,(xkb),(new)->mods.real_mods
,(new)->mods.vmods,3)
, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
643 ACTION2uAction("Using %d, ignoring %d\n", use, ignore);
644 }
645 else if (warningLevel > 9)
646 {
647 WARN3uWarning("Multiple occurences of map[%s]= %d in %s\n",
648 MapEntryTxt(type, xkb, new)XkbVModMaskText((type)->dpy,(xkb),(new)->mods.real_mods
,(new)->mods.vmods,3)
, new->level + 1, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
649 ACTIONuAction("Ignored\n");
650 return True1;
651 }
652 if (clobber)
653 old->level = new->level;
654 return True1;
655 }
656 if ((old = NextMapEntry(type)) == NULL((void*)0))
657 return False0; /* allocation failure, already reported */
658 if (new->level >= type->numLevels)
659 type->numLevels = new->level + 1;
660 if (new->mods.vmods == 0)
661 old->active = True1;
662 else
663 old->active = False0;
664 old->mods.mask = new->mods.real_mods;
665 old->mods.real_mods = new->mods.real_mods;
666 old->mods.vmods = new->mods.vmods;
667 old->level = new->level;
668 return True1;
669}
670
671static LookupEntry lnames[] = {
672 {"level1", 1},
673 {"level2", 2},
674 {"level3", 3},
675 {"level4", 4},
676 {"level5", 5},
677 {"level6", 6},
678 {"level7", 7},
679 {"level8", 8},
680 {NULL((void*)0), 0}
681};
682
683static Boolint
684SetMapEntry(KeyTypeInfo * type,
685 XkbDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
686{
687 ExprResult rtrn;
688 XkbKTMapEntryRec entry;
689
690 if (arrayNdx == NULL((void*)0))
691 return ReportTypeShouldBeArray(type, "map entry")ReportShouldBeArray("key type",("map entry"),XkbAtomText((type
)->dpy,(type)->name,3))
;
692 if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (XPointer) xkb))
693 return ReportTypeBadType(type, "map entry", "modifier mask")ReportBadType("key type",("map entry"),XkbAtomText((type)->
dpy,(type)->name,3),("modifier mask"))
;
694 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
695 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
696 if ((entry.mods.real_mods & (~type->mask)) ||
697 ((entry.mods.vmods & (~type->vmask)) != 0))
698 {
699 if (warningLevel > 0)
700 {
701 WARN1uWarning("Map entry for unused modifiers in %s\n", TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
702 ACTION1uAction("Using %s instead of ",
703 XkbVModMaskText(type->dpy, xkb,
704 entry.mods.real_mods & type->mask,
705 entry.mods.vmods & type->vmask,
706 XkbMessage3));
707 INFO1uInformation("%s\n", MapEntryTxt(type, xkb, &entry)XkbVModMaskText((type)->dpy,(xkb),(&entry)->mods.real_mods
,(&entry)->mods.vmods,3)
);
708 }
709 entry.mods.real_mods &= type->mask;
710 entry.mods.vmods &= type->vmask;
711 }
712 if (!ExprResolveInteger(value, &rtrn, SimpleLookup, (XPointer) lnames))
713 {
714 ERRORuError("Level specifications in a key type must be integer\n");
715 ACTIONuAction("Ignoring malformed level specification\n");
716 return False0;
717 }
718 if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel63 + 1))
719 {
720 ERROR3uError("Shift level %d out of range (1..%d) in key type %s\n",
721 XkbMaxShiftLevel63 + 1, rtrn.ival, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
722 ACTION1uAction("Ignoring illegal definition of map[%s]\n",
723 MapEntryTxt(type, xkb, &entry)XkbVModMaskText((type)->dpy,(xkb),(&entry)->mods.real_mods
,(&entry)->mods.vmods,3)
);
724 return False0;
725 }
726 entry.level = rtrn.ival - 1;
727 return AddMapEntry(xkb, type, &entry, True1, True1);
728}
729
730static Boolint
731SetPreserve(KeyTypeInfo * type,
732 XkbDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
733{
734 ExprResult rtrn;
735 PreserveInfo new;
736
737 if (arrayNdx == NULL((void*)0))
738 return ReportTypeShouldBeArray(type, "preserve entry")ReportShouldBeArray("key type",("preserve entry"),XkbAtomText
((type)->dpy,(type)->name,3))
;
739 if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (XPointer) xkb))
740 return ReportTypeBadType(type, "preserve entry", "modifier mask")ReportBadType("key type",("preserve entry"),XkbAtomText((type
)->dpy,(type)->name,3),("modifier mask"))
;
741 new.defs = type->defs;
742 new.defs.next = NULL((void*)0);
743 new.indexMods = rtrn.uval & 0xff;
744 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
745 if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
746 {
747 if (warningLevel > 0)
748 {
749 WARN1uWarning("Preserve for modifiers not used by the %s type\n",
750 TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
751 ACTION1uAction("Index %s converted to ",
752 PreserveIndexTxt(type, xkb, &new)XkbVModMaskText((type)->dpy,(xkb),(&new)->indexMods
,(&new)->indexVMods,3)
);
753 }
754 new.indexMods &= type->mask;
755 new.indexVMods &= type->vmask;
756 if (warningLevel > 0)
757 INFO1uInformation("%s\n", PreserveIndexTxt(type, xkb, &new)XkbVModMaskText((type)->dpy,(xkb),(&new)->indexMods
,(&new)->indexVMods,3)
);
758 }
759 if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb))
760 {
761 ERRORuError("Preserve value in a key type is not a modifier mask\n");
762 ACTION2uAction("Ignoring preserve[%s] in type %s\n",
763 PreserveIndexTxt(type, xkb, &new)XkbVModMaskText((type)->dpy,(xkb),(&new)->indexMods
,(&new)->indexVMods,3)
, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
764 return False0;
765 }
766 new.preMods = rtrn.uval & 0xff;
767 new.preVMods = (rtrn.uval >> 16) & 0xffff;
768 if ((new.preMods & (~new.indexMods))
769 || (new.preVMods && (~new.indexVMods)))
770 {
771 if (warningLevel > 0)
772 {
773 WARN2uWarning("Illegal value for preserve[%s] in type %s\n",
774 PreserveTxt(type, xkb, &new)XkbVModMaskText((type)->dpy,(xkb),(&new)->preMods,(
&new)->preVMods,3)
, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
775 ACTION1uAction("Converted %s to ", PreserveIndexTxt(type, xkb, &new)XkbVModMaskText((type)->dpy,(xkb),(&new)->indexMods
,(&new)->indexVMods,3)
);
776 }
777 new.preMods &= new.indexMods;
778 new.preVMods &= new.indexVMods;
779 if (warningLevel > 0)
780 {
781 INFO1uInformation("%s\n", PreserveIndexTxt(type, xkb, &new)XkbVModMaskText((type)->dpy,(xkb),(&new)->indexMods
,(&new)->indexVMods,3)
);
782 }
783 }
784 return AddPreserve(xkb, type, &new, True1, True1);
785}
786
787/***====================================================================***/
788
789Boolint
790AddLevelName(KeyTypeInfo * type,
791 unsigned level, Atom name, Boolint clobber, Boolint report)
792{
793 if ((type->lvlNames == NULL((void*)0)) || (type->szNames <= level))
794 {
795 type->lvlNames =
796 uTypedRecalloc(type->lvlNames, type->szNames, level + 1, Atom)((Atom *)uRecalloc((Opaque)type->lvlNames,((unsigned)type->
szNames),((unsigned)level + 1),sizeof(Atom)))
;
797 if (type->lvlNames == NULL((void*)0))
798 {
799 ERROR1uError("Couldn't allocate level names for type %s\n",
800 TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
801 ACTIONuAction("Level names lost\n");
802 type->szNames = 0;
803 return False0;
804 }
805 type->szNames = level + 1;
806 }
807 else if (type->lvlNames[level] == name)
808 {
809 if (warningLevel > 9)
810 {
811 WARN2uWarning("Duplicate names for level %d of key type %s\n",
812 level + 1, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
813 ACTIONuAction("Ignored\n");
814 }
815 return True1;
816 }
817 else if (type->lvlNames[level] != None0L)
818 {
819 if (warningLevel > 0)
820 {
821 char *old, *new;
822 old = XkbAtomText(type->dpy, type->lvlNames[level], XkbMessage3);
823 new = XkbAtomText(type->dpy, name, XkbMessage3);
824 WARN2uWarning("Multiple names for level %d of key type %s\n",
825 level + 1, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
826 if (clobber)
827 ACTION2uAction("Using %s, ignoring %s\n", new, old);
828 else
829 ACTION2uAction("Using %s, ignoring %s\n", old, new);
830 }
831 if (!clobber)
832 return True1;
833 }
834 if (level >= type->numLevels)
835 type->numLevels = level + 1;
836 type->lvlNames[level] = name;
837 return True1;
838}
839
840static Boolint
841SetLevelName(KeyTypeInfo * type, ExprDef * arrayNdx, ExprDef * value)
842{
843 ExprResult rtrn;
844 unsigned level;
845
846 if (arrayNdx == NULL((void*)0))
847 return ReportTypeShouldBeArray(type, "level name")ReportShouldBeArray("key type",("level name"),XkbAtomText((type
)->dpy,(type)->name,3))
;
848 if (!ExprResolveInteger(arrayNdx, &rtrn, SimpleLookup, (XPointer) lnames))
849 return ReportTypeBadType(type, "level name", "integer")ReportBadType("key type",("level name"),XkbAtomText((type)->
dpy,(type)->name,3),("integer"))
;
850 if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel63 + 1))
851 {
852 ERROR3uError("Level name %d out of range (1..%d) in key type %s\n",
853 rtrn.ival,
854 XkbMaxShiftLevel63 + 1,
855 XkbAtomText(type->dpy, type->name, XkbMessage3));
856 ACTIONuAction("Ignoring illegal level name definition\n");
857 return False0;
858 }
859 level = rtrn.ival - 1;
860 if (!ExprResolveString(value, &rtrn, NULL((void*)0), NULL((void*)0)))
861 {
862 ERROR2uError("Non-string name for level %d in key type %s\n", level + 1,
863 XkbAtomText(type->dpy, type->name, XkbMessage3));
864 ACTIONuAction("Ignoring illegal level name definition\n");
865 return False0;
866 }
867 return
868 AddLevelName(type, level, XkbInternAtom(NULL((void*)0), rtrn.str, False0), True1,
869 True1);
870}
871
872/***====================================================================***/
873
874/**
875 * Parses the fields in a type "..." { } description.
876 *
877 * @param field The field to parse (e.g. modifiers, map, level_name)
878 */
879static Boolint
880SetKeyTypeField(KeyTypeInfo * type,
881 XkbDescPtr xkb,
882 char *field,
883 ExprDef * arrayNdx, ExprDef * value, KeyTypesInfo * info)
884{
885 ExprResult tmp;
886
887 if (uStrCaseCmp(field, "modifiers")(strcasecmp(field,"modifiers")) == 0)
888 {
889 unsigned mods, vmods;
890 if (arrayNdx != NULL((void*)0))
891 {
892 WARNuWarning("The modifiers field of a key type is not an array\n");
893 ACTIONuAction("Illegal array subscript ignored\n");
894 }
895 /* get modifier mask for current type */
896 if (!ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb))
897 {
898 ERRORuError("Key type mask field must be a modifier mask\n");
899 ACTIONuAction("Key type definition ignored\n");
900 return False0;
901 }
902 mods = tmp.uval & 0xff; /* core mods */
903 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
904 if (type->defs.defined & _KT_Mask(1<<1))
905 {
906 WARN1uWarning("Multiple modifier mask definitions for key type %s\n",
907 XkbAtomText(type->dpy, type->name, XkbMessage3));
908 ACTION1uAction("Using %s, ", TypeMaskTxt(type, xkb)XkbVModMaskText((type)->dpy,(xkb),(type)->mask,(type)->
vmask,3)
);
909 INFO1uInformation("ignoring %s\n", XkbVModMaskText(type->dpy, xkb, mods,
910 vmods, XkbMessage3));
911 return False0;
912 }
913 type->mask = mods;
914 type->vmask = vmods;
915 type->defs.defined |= _KT_Mask(1<<1);
916 return True1;
917 }
918 else if (uStrCaseCmp(field, "map")(strcasecmp(field,"map")) == 0)
919 {
920 type->defs.defined |= _KT_Map(1<<2);
921 return SetMapEntry(type, xkb, arrayNdx, value);
922 }
923 else if (uStrCaseCmp(field, "preserve")(strcasecmp(field,"preserve")) == 0)
924 {
925 type->defs.defined |= _KT_Preserve(1<<3);
926 return SetPreserve(type, xkb, arrayNdx, value);
927 }
928 else if ((uStrCaseCmp(field, "levelname")(strcasecmp(field,"levelname")) == 0) ||
929 (uStrCaseCmp(field, "level_name")(strcasecmp(field,"level_name")) == 0))
930 {
931 type->defs.defined |= _KT_LevelNames(1<<4);
932 return SetLevelName(type, arrayNdx, value);
933 }
934 ERROR2uError("Unknown field %s in key type %s\n", field, TypeTxt(type)XkbAtomText((type)->dpy,(type)->name,3));
935 ACTIONuAction("Definition ignored\n");
936 return False0;
937}
938
939static Boolint
940HandleKeyTypeVar(VarDef * stmt, XkbDescPtr xkb, KeyTypesInfo * info)
941{
942 ExprResult elem, field;
943 ExprDef *arrayNdx;
944
945 if (!ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx))
946 return False0; /* internal error, already reported */
947 if (elem.str && (uStrCaseCmp(elem.str, "type")(strcasecmp(elem.str,"type")) == 0))
948 return SetKeyTypeField(&info->dflt, xkb, field.str, arrayNdx,
949 stmt->value, info);
950 if (elem.str != NULL((void*)0))
951 {
952 ERROR1uError("Default for unknown element %s\n", uStringText(elem.str)((elem.str)==((char *)((void*)0))?"<NullString>":(elem.
str))
);
953 ACTION1uAction("Value for field %s ignored\n", uStringText(field.str)((field.str)==((char *)((void*)0))?"<NullString>":(field
.str))
);
954 }
955 else if (field.str != NULL((void*)0))
956 {
957 ERROR1uError("Default defined for unknown field %s\n",
958 uStringText(field.str)((field.str)==((char *)((void*)0))?"<NullString>":(field
.str))
);
959 ACTIONuAction("Ignored\n");
960 }
961 return False0;
962}
963
964static int
965HandleKeyTypeBody(VarDef * def,
966 XkbDescPtr xkb, KeyTypeInfo * type, KeyTypesInfo * info)
967{
968 int ok = 1;
969 ExprResult tmp, field;
970 ExprDef *arrayNdx;
971
972 for (; def != NULL((void*)0); def = (VarDef *) def->common.next)
973 {
974 if ((def->name) && (def->name->type == ExprFieldRef3))
975 {
976 ok = HandleKeyTypeVar(def, xkb, info);
977 continue;
978 }
979 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
980 if (ok)
981 ok = SetKeyTypeField(type, xkb, field.str, arrayNdx, def->value,
982 info);
983 }
984 return ok;
985}
986
987/**
988 * Process a type "XYZ" { } specification in the xkb_types section.
989 *
990 */
991static int
992HandleKeyTypeDef(KeyTypeDef * def,
993 XkbDescPtr xkb, unsigned merge, KeyTypesInfo * info)
994{
995 register int i;
996 KeyTypeInfo type;
997
998 if (def->merge != MergeDefault0)
999 merge = def->merge;
1000
1001 type.defs.defined = 0;
1002 type.defs.fileID = info->fileID;
1003 type.defs.merge = merge;
1004 type.defs.next = NULL((void*)0);
1005 type.dpy = info->dpy;
1006 type.name = def->name;
1007 type.mask = info->dflt.mask;
1008 type.vmask = info->dflt.vmask;
1009 type.groupInfo = info->dflt.groupInfo;
1010 type.numLevels = 1;
1011 type.nEntries = type.szEntries = 0;
1012 type.entries = NULL((void*)0);
1013 type.szNames = 0;
1014 type.lvlNames = NULL((void*)0);
1015 type.preserve = NULL((void*)0);
1016
1017 /* Parse the actual content. */
1018 if (!HandleKeyTypeBody(def->body, xkb, &type, info))
1019 {
1020 info->errorCount++;
1021 return False0;
1022 }
1023
1024 /* now copy any appropriate map, preserve or level names from the */
1025 /* default type */
1026 for (i = 0; i < info->dflt.nEntries; i++)
1027 {
1028 XkbKTMapEntryPtr dflt;
1029 dflt = &info->dflt.entries[i];
1030 if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
1031 ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
1032 {
1033 AddMapEntry(xkb, &type, dflt, False0, False0);
1034 }
1035 }
1036 if (info->dflt.preserve)
1037 {
1038 PreserveInfo *dflt = info->dflt.preserve;
1039 while (dflt)
1040 {
1041 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
1042 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
1043 {
1044 AddPreserve(xkb, &type, dflt, False0, False0);
1045 }
1046 dflt = (PreserveInfo *) dflt->defs.next;
1047 }
1048 }
1049 for (i = 0; i < info->dflt.szNames; i++)
1050 {
1051 if ((i < type.numLevels) && (info->dflt.lvlNames[i] != None0L))
1052 {
1053 AddLevelName(&type, i, info->dflt.lvlNames[i], False0, False0);
1054 }
1055 }
1056 /* Now add the new keytype to the info struct */
1057 if (!AddKeyType(xkb, info, &type))
1058 {
1059 info->errorCount++;
1060 return False0;
1061 }
1062 return True1;
1063}
1064
1065/**
1066 * Process an xkb_types section.
1067 *
1068 * @param file The parsed xkb_types section.
1069 * @param merge Merge Strategy (e.g. MergeOverride)
1070 * @param info Pointer to memory where the outcome will be stored.
1071 */
1072static void
1073HandleKeyTypesFile(XkbFile * file,
1074 XkbDescPtr xkb, unsigned merge, KeyTypesInfo * info)
1075{
1076 ParseCommon *stmt;
1077
1078 info->name = uStringDup(file->name)((file->name) ? strdup(file->name) : ((void*)0));
1079 stmt = file->defs;
1080 while (stmt)
1081 {
1082 switch (stmt->stmtType)
1083 {
1084 case StmtInclude1:
1085 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, xkb, info,
1086 HandleKeyTypesFile))
1087 info->errorCount++;
1088 break;
1089 case StmtKeyTypeDef6: /* e.g. type "ONE_LEVEL" */
1090 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, xkb, merge, info))
1091 info->errorCount++;
1092 break;
1093 case StmtVarDef5:
1094 if (!HandleKeyTypeVar((VarDef *) stmt, xkb, info))
1095 info->errorCount++;
1096 break;
1097 case StmtVModDef8: /* virtual_modifiers NumLock, ... */
1098 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1099 info->errorCount++;
1100 break;
1101 case StmtKeyAliasDef3:
1102 ERRORuError("Key type files may not include other declarations\n");
1103 ACTIONuAction("Ignoring definition of key alias\n");
1104 info->errorCount++;
1105 break;
1106 case StmtKeycodeDef2:
1107 ERRORuError("Key type files may not include other declarations\n");
1108 ACTIONuAction("Ignoring definition of key name\n");
1109 info->errorCount++;
1110 break;
1111 case StmtInterpDef7:
1112 ERRORuError("Key type files may not include other declarations\n");
1113 ACTIONuAction("Ignoring definition of symbol interpretation\n");
1114 info->errorCount++;
1115 break;
1116 default:
1117 WSGO1uInternalError("Unexpected statement type %d in HandleKeyTypesFile\n",
1118 stmt->stmtType);
1119 break;
1120 }
1121 stmt = stmt->next;
1122 if (info->errorCount > 10)
1123 {
1124#ifdef NOISY
1125 ERRORuError("Too many errors\n");
1126#endif
1127 ACTION1uAction("Abandoning keytypes file \"%s\"\n", file->topName);
1128 break;
1129 }
1130 }
1131 return;
1132}
1133
1134static Boolint
1135CopyDefToKeyType(XkbDescPtr xkb, XkbKeyTypePtr type, KeyTypeInfo * def)
1136{
1137 register int i;
1138 PreserveInfo *pre;
1139
1140 for (pre = def->preserve; pre != NULL((void*)0);
1141 pre = (PreserveInfo *) pre->defs.next)
1142 {
1143 XkbKTMapEntryPtr match;
1144 XkbKTMapEntryRec tmp;
1145 tmp.mods.real_mods = pre->indexMods;
1146 tmp.mods.vmods = pre->indexVMods;
1147 tmp.level = 0;
1148 AddMapEntry(xkb, def, &tmp, False0, False0);
1149 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1150 if (!match)
1151 {
1152 WSGOuInternalError("Couldn't find matching entry for preserve\n");
1153 ACTIONuAction("Aborting\n");
1154 return False0;
1155 }
1156 pre->matchingMapIndex = match - def->entries;
1157 }
1158 type->mods.real_mods = def->mask;
1159 type->mods.vmods = def->vmask;
1160 type->num_levels = def->numLevels;
1161 type->map_count = def->nEntries;
1162 type->map = def->entries;
1163 if (def->preserve)
1164 {
1165 type->preserve = uTypedCalloc(type->map_count, XkbModsRec)((XkbModsRec *)uCalloc((unsigned)type->map_count,(unsigned
)sizeof(XkbModsRec)))
;
1166 if (!type->preserve)
1167 {
1168 WARNuWarning("Couldn't allocate preserve array in CopyDefToKeyType\n");
1169 ACTION1uAction("Preserve setting for type %s lost\n",
1170 XkbAtomText(def->dpy, def->name, XkbMessage3));
1171 }
1172 else
1173 {
1174 pre = def->preserve;
1175 for (; pre != NULL((void*)0); pre = (PreserveInfo *) pre->defs.next)
1176 {
1177 int ndx = pre->matchingMapIndex;
1178 type->preserve[ndx].mask = pre->preMods;
1179 type->preserve[ndx].real_mods = pre->preMods;
1180 type->preserve[ndx].vmods = pre->preVMods;
1181 }
1182 }
1183 }
1184 else
1185 type->preserve = NULL((void*)0);
1186 type->name = (Atom) def->name;
1187 if (def->szNames > 0)
1188 {
1189 type->level_names = uTypedCalloc(def->numLevels, Atom)((Atom *)uCalloc((unsigned)def->numLevels,(unsigned)sizeof
(Atom)))
;
1190
1191 /* assert def->szNames<=def->numLevels */
1192 for (i = 0; i < def->szNames; i++)
1193 {
1194 type->level_names[i] = (Atom) def->lvlNames[i];
1195 }
1196 }
1197 else
1198 {
1199 type->level_names = NULL((void*)0);
1200 }
1201
1202 def->nEntries = def->szEntries = 0;
1203 def->entries = NULL((void*)0);
1204 return XkbComputeEffectiveMap(xkb, type, NULL((void*)0));
1205}
1206
1207Boolint
1208CompileKeyTypes(XkbFile * file, XkbFileInfo * result, unsigned merge)
1209{
1210 KeyTypesInfo info;
1211 XkbDescPtr xkb;
1212
1213 xkb = result->xkb;
1214 InitKeyTypesInfo(&info, xkb, NULL((void*)0));
1215 info.fileID = file->id;
1216 HandleKeyTypesFile(file, xkb, merge, &info);
1217
1218 if (info.errorCount == 0)
1219 {
1220 register int i;
1221 register KeyTypeInfo *def;
1222 register XkbKeyTypePtr type, next;
1223
1224 if (info.name != NULL((void*)0))
1225 {
1226 if (XkbAllocNames(xkb, XkbTypesNameMask(1<<4), 0, 0) == Success0)
1227 xkb->names->types = XkbInternAtom(xkb->dpy, info.name, False0);
1228 else
1229 {
1230 WSGOuInternalError("Couldn't allocate space for types name\n");
1231 ACTION2uAction("Name \"%s\" (from %s) NOT assigned\n",
1232 scanFile, info.name);
1233 }
1234 }
1235 i = info.nTypes;
1236 if ((info.stdPresent & XkbOneLevelMask(1<<0)) == 0)
1237 i++;
1238 if ((info.stdPresent & XkbTwoLevelMask(1<<1)) == 0)
1239 i++;
1240 if ((info.stdPresent & XkbKeypadMask(1<<3)) == 0)
1241 i++;
1242 if ((info.stdPresent & XkbAlphabeticMask(1<<2)) == 0)
1243 i++;
1244 if (XkbAllocClientMap(xkb, XkbKeyTypesMask(1<<0), i) != Success0)
1245 {
1246 WSGOuInternalError("Couldn't allocate client map\n");
1247 ACTIONuAction("Exiting\n");
1248 return False0;
1249 }
1250 xkb->map->num_types = i;
1251 if (XkbAllRequiredTypes(0xf) & (~info.stdPresent))
1252 {
1253 unsigned missing, keypadVMod;
1254
1255 missing = XkbAllRequiredTypes(0xf) & (~info.stdPresent);
1256 keypadVMod = FindKeypadVMod(xkb);
1257 if (XkbInitCanonicalKeyTypes(xkb, missing, keypadVMod) != Success0)
1258 {
1259 WSGOuInternalError("Couldn't initialize canonical key types\n");
1260 ACTIONuAction("Exiting\n");
1261 return False0;
1262 }
1263 if (missing & XkbOneLevelMask(1<<0))
1264 xkb->map->types[XkbOneLevelIndex0].name = tok_ONE_LEVEL;
1265 if (missing & XkbTwoLevelMask(1<<1))
1266 xkb->map->types[XkbTwoLevelIndex1].name = tok_TWO_LEVEL;
1267 if (missing & XkbAlphabeticMask(1<<2))
1268 xkb->map->types[XkbAlphabeticIndex2].name = tok_ALPHABETIC;
1269 if (missing & XkbKeypadMask(1<<3))
1270 xkb->map->types[XkbKeypadIndex3].name = tok_KEYPAD;
1271 }
1272 next = &xkb->map->types[XkbLastRequiredType3 + 1];
1273 for (i = 0, def = info.types; i < info.nTypes; i++)
1274 {
1275 if (def->name == tok_ONE_LEVEL)
1276 type = &xkb->map->types[XkbOneLevelIndex0];
1277 else if (def->name == tok_TWO_LEVEL)
1278 type = &xkb->map->types[XkbTwoLevelIndex1];
1279 else if (def->name == tok_ALPHABETIC)
1280 type = &xkb->map->types[XkbAlphabeticIndex2];
1281 else if (def->name == tok_KEYPAD)
1282 type = &xkb->map->types[XkbKeypadIndex3];
1283 else
1284 type = next++;
1285 DeleteLevel1MapEntries(def);
1286 if (!CopyDefToKeyType(xkb, type, def))
1287 return False0;
1288 def = (KeyTypeInfo *) def->defs.next;
1289 }
1290 return True1;
1291 }
1292 return False0;
1293}