Bug Summary

File:maprules.c
Location:line 1454, column 9
Description:Value stored to 'out' is never read

Annotated Source Code

1/************************************************************
2 Copyright (c) 1996 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#ifdef HAVE_DIX_CONFIG_H
28#include <dix-config.h>
29#elif defined(HAVE_CONFIG_H1)
30#include <config.h>
31#endif
32
33#include <stdio.h>
34#include <ctype.h>
35#include <stdlib.h>
36
37#define X_INCLUDE_STRING_H
38#define XOS_USE_NO_LOCKING
39#include <X11/Xos_r.h>
40
41
42#include <X11/Xproto.h>
43#include <X11/Xlib.h>
44#include <X11/Xos.h>
45#include <X11/Xfuncs.h>
46#include <X11/Xatom.h>
47#include <X11/keysym.h>
48#include <X11/XKBlib.h>
49#include <X11/extensions/XKBgeom.h>
50#include "XKMformat.h"
51#include "XKBfileInt.h"
52#include "XKBrules.h"
53
54
55#ifdef DEBUG
56#define PR_DEBUG(s) fprintf(stderr__stderrp,s)
57#define PR_DEBUG1(s,a) fprintf(stderr__stderrp,s,a)
58#define PR_DEBUG2(s,a,b) fprintf(stderr__stderrp,s,a,b)
59#else
60#define PR_DEBUG(s)
61#define PR_DEBUG1(s,a)
62#define PR_DEBUG2(s,a,b)
63#endif
64
65/***====================================================================***/
66
67#define DFLT_LINE_SIZE128 128
68
69typedef struct {
70 int line_num;
71 int sz_line;
72 int num_line;
73 char buf[DFLT_LINE_SIZE128];
74 char * line;
75} InputLine;
76
77static void
78InitInputLine(InputLine *line)
79{
80 line->line_num = 1;
81 line->num_line = 0;
82 line->sz_line = DFLT_LINE_SIZE128;
83 line->line = line->buf;
84 return;
85}
86
87static void
88FreeInputLine(InputLine *line)
89{
90 if (line->line != line->buf)
91 _XkbFree(line->line)free(line->line);
92 line->line_num = 1;
93 line->num_line = 0;
94 line->sz_line = DFLT_LINE_SIZE128;
95 line->line = line->buf;
96 return;
97}
98
99static int
100InputLineAddChar(InputLine *line, int ch)
101{
102 if (line->num_line >= line->sz_line) {
103 if (line->line == line->buf) {
104 line->line = (char *) _XkbAlloc(line->sz_line * 2)malloc((line->sz_line * 2));
105 memcpy(line->line, line->buf, line->sz_line)__builtin___memcpy_chk (line->line, line->buf, line->
sz_line, __builtin_object_size (line->line, 0))
;
106 }
107 else {
108 line->line =
109 (char *) _XkbRealloc((char *) line->line, line->sz_line * 2)realloc(((char *) line->line),(line->sz_line * 2));
110 }
111 line->sz_line *= 2;
112 }
113 line->line[line->num_line++] = ch;
114 return ch;
115}
116
117#define ADD_CHAR(l,c)((l)->num_line<(l)->sz_line? (int)((l)->line[(l)->
num_line++]= (c)): InputLineAddChar(l,c))
((l)->num_line<(l)->sz_line?\
118 (int)((l)->line[(l)->num_line++]= (c)):\
119 InputLineAddChar(l,c))
120
121#ifdef HAVE_UNLOCKED_STDIO1
122#undef getc
123#define getc(x)(--(x)->_r < 0 ? __srget(x) : (int)(*(x)->_p++)) getc_unlocked(x)(--(x)->_r < 0 ? __srget(x) : (int)(*(x)->_p++))
124#else
125#define flockfile(x) do {} while (0)
126#define funlockfile(x) do {} while (0)
127#endif
128
129static Boolint
130GetInputLine(FILE *file, InputLine *line, Boolint checkbang)
131{
132 int ch;
133 Boolint endOfFile, spacePending, slashPending, inComment;
134
135 endOfFile = False0;
136 flockfile(file);
137 while ((!endOfFile) && (line->num_line == 0)) {
138 spacePending = slashPending = inComment = False0;
139 while (((ch = getc(file)(--(file)->_r < 0 ? __srget(file) : (int)(*(file)->_p
++))
) != '\n') && (ch != EOF(-1))) {
140 if (ch == '\\') {
141 if ((ch = getc(file)(--(file)->_r < 0 ? __srget(file) : (int)(*(file)->_p
++))
) == EOF(-1))
142 break;
143 if (ch == '\n') {
144 inComment = False0;
145 ch = ' ';
146 line->line_num++;
147 }
148 }
149 if (inComment)
150 continue;
151 if (ch == '/') {
152 if (slashPending) {
153 inComment = True1;
154 slashPending = False0;
155 }
156 else {
157 slashPending = True1;
158 }
159 continue;
160 }
161 else if (slashPending) {
162 if (spacePending) {
163 ADD_CHAR(line, ' ')((line)->num_line<(line)->sz_line? (int)((line)->
line[(line)->num_line++]= (' ')): InputLineAddChar(line,' '
))
;
164 spacePending = False0;
165 }
166 ADD_CHAR(line, '/')((line)->num_line<(line)->sz_line? (int)((line)->
line[(line)->num_line++]= ('/')): InputLineAddChar(line,'/'
))
;
167 slashPending = False0;
168 }
169 if (isspace(ch)) {
170 while (isspace(ch) && (ch != '\n') && (ch != EOF(-1))) {
171 ch = getc(file)(--(file)->_r < 0 ? __srget(file) : (int)(*(file)->_p
++))
;
172 }
173 if (ch == EOF(-1))
174 break;
175 if ((ch != '\n') && (line->num_line > 0))
176 spacePending = True1;
177 ungetc(ch, file);
178 }
179 else {
180 if (spacePending) {
181 ADD_CHAR(line, ' ')((line)->num_line<(line)->sz_line? (int)((line)->
line[(line)->num_line++]= (' ')): InputLineAddChar(line,' '
))
;
182 spacePending = False0;
183 }
184 if (checkbang && ch == '!') {
185 if (line->num_line != 0) {
186 PR_DEBUG("The '!' legal only at start of line\n");
187 PR_DEBUG("Line containing '!' ignored\n");
188 line->num_line = 0;
189 inComment = 0;
190 break;
191 }
192
193 }
194 ADD_CHAR(line, ch)((line)->num_line<(line)->sz_line? (int)((line)->
line[(line)->num_line++]= (ch)): InputLineAddChar(line,ch)
)
;
195 }
196 }
197 if (ch == EOF(-1))
198 endOfFile = True1;
199/* else line->num_line++;*/
200 }
201 funlockfile(file);
202 if ((line->num_line == 0) && (endOfFile))
203 return False0;
204 ADD_CHAR(line, '\0')((line)->num_line<(line)->sz_line? (int)((line)->
line[(line)->num_line++]= ('\0')): InputLineAddChar(line,'\0'
))
;
205 return True1;
206}
207
208/***====================================================================***/
209
210#define MODEL0 0
211#define LAYOUT1 1
212#define VARIANT2 2
213#define OPTION3 3
214#define KEYCODES4 4
215#define SYMBOLS5 5
216#define TYPES6 6
217#define COMPAT7 7
218#define GEOMETRY8 8
219#define KEYMAP9 9
220#define MAX_WORDS10 10
221
222#define PART_MASK0x000F 0x000F
223#define COMPONENT_MASK0x03F0 0x03F0
224
225static const char *cname[MAX_WORDS10] = {
226 "model", "layout", "variant", "option",
227 "keycodes", "symbols", "types", "compat", "geometry", "keymap"
228};
229
230typedef struct _RemapSpec {
231 int number;
232 int num_remap;
233 struct {
234 int word;
235 int index;
236 } remap[MAX_WORDS10];
237} RemapSpec;
238
239typedef struct _FileSpec {
240 char *name[MAX_WORDS10];
241 struct _FileSpec *pending;
242} FileSpec;
243
244typedef struct {
245 char *model;
246 char *layout[XkbNumKbdGroups4 + 1];
247 char *variant[XkbNumKbdGroups4 + 1];
248 char *options;
249} XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr;
250
251#define NDX_BUFF_SIZE4 4
252
253/***====================================================================***/
254
255static char *
256get_index(char *str, int *ndx)
257{
258 char ndx_buf[NDX_BUFF_SIZE4];
259
260 char *end;
261
262 if (*str != '[') {
263 *ndx = 0;
264 return str;
265 }
266 str++;
267 end = strchr(str, ']');
268 if (end == NULL((void*)0)) {
269 *ndx = -1;
270 return str - 1;
271 }
272 if ((end - str) >= NDX_BUFF_SIZE4) {
273 *ndx = -1;
274 return end + 1;
275 }
276 strncpy(ndx_buf, str, end - str)__builtin___strncpy_chk (ndx_buf, str, end - str, __builtin_object_size
(ndx_buf, 2 > 1 ? 1 : 0))
;
277 ndx_buf[end - str] = '\0';
278 *ndx = atoi(ndx_buf);
279 return end + 1;
280}
281
282static void
283SetUpRemap(InputLine *line, RemapSpec *remap)
284{
285 char *tok, *str;
286 unsigned present, l_ndx_present, v_ndx_present;
287 register int i;
288 int len, ndx;
289 _Xstrtokparams strtok_buf;
290
291#ifdef DEBUG
292 Boolint found;
293#endif
294
295 l_ndx_present = v_ndx_present = present = 0;
296 str = &line->line[1];
297 len = remap->number;
298 bzero((char *) remap, sizeof(RemapSpec))__builtin___memset_chk ((char *) remap, 0, sizeof(RemapSpec),
__builtin_object_size ((char *) remap, 0))
;
299 remap->number = len;
300 while ((tok = _XStrtok(str, " ", strtok_buf)( strtok_buf = 0, (void)strtok_buf, strtok((str),(" ")) )) != NULL((void*)0)) {
301#ifdef DEBUG
302 found = False0;
303#endif
304 str = NULL((void*)0);
305 if (strcmp(tok, "=") == 0)
306 continue;
307 for (i = 0; i < MAX_WORDS10; i++) {
308 len = strlen(cname[i]);
309 if (strncmp(cname[i], tok, len) == 0) {
310 if (strlen(tok) > len) {
311 char *end = get_index(tok + len, &ndx);
312
313 if ((i != LAYOUT1 && i != VARIANT2) ||
314 *end != '\0' || ndx == -1)
315 break;
316 if (ndx < 1 || ndx > XkbNumKbdGroups4) {
317 PR_DEBUG2("Illegal %s index: %d\n", cname[i], ndx);
318 PR_DEBUG1("Index must be in range 1..%d\n",
319 XkbNumKbdGroups);
320 break;
321 }
322 }
323 else {
324 ndx = 0;
325 }
326#ifdef DEBUG
327 found = True1;
328#endif
329 if (present & (1 << i)) {
330 if ((i == LAYOUT1 && l_ndx_present & (1 << ndx)) ||
331 (i == VARIANT2 && v_ndx_present & (1 << ndx))) {
332 PR_DEBUG1("Component \"%s\" listed twice\n", tok);
333 PR_DEBUG("Second definition ignored\n");
334 break;
335 }
336 }
337 present |= (1 << i);
338 if (i == LAYOUT1)
339 l_ndx_present |= 1 << ndx;
340 if (i == VARIANT2)
341 v_ndx_present |= 1 << ndx;
342 remap->remap[remap->num_remap].word = i;
343 remap->remap[remap->num_remap++].index = ndx;
344 break;
345 }
346 }
347#ifdef DEBUG
348 if (!found) {
349 fprintf(stderr__stderrp, "Unknown component \"%s\" ignored\n", tok);
350 }
351#endif
352 }
353 if ((present & PART_MASK0x000F) == 0) {
354#ifdef DEBUG
355 unsigned mask = PART_MASK0x000F;
356
357 fprintf(stderr__stderrp, "Mapping needs at least one of ");
358 for (i = 0; (i < MAX_WORDS10); i++) {
359 if ((1L << i) & mask) {
360 mask &= ~(1L << i);
361 if (mask)
362 fprintf(stderr__stderrp, "\"%s,\" ", cname[i]);
363 else
364 fprintf(stderr__stderrp, "or \"%s\"\n", cname[i]);
365 }
366 }
367 fprintf(stderr__stderrp, "Illegal mapping ignored\n");
368#endif
369 remap->num_remap = 0;
370 return;
371 }
372 if ((present & COMPONENT_MASK0x03F0) == 0) {
373 PR_DEBUG("Mapping needs at least one component\n");
374 PR_DEBUG("Illegal mapping ignored\n");
375 remap->num_remap = 0;
376 return;
377 }
378 if (((present & COMPONENT_MASK0x03F0) & (1 << KEYMAP9)) &&
379 ((present & COMPONENT_MASK0x03F0) != (1 << KEYMAP9))) {
380 PR_DEBUG("Keymap cannot appear with other components\n");
381 PR_DEBUG("Illegal mapping ignored\n");
382 remap->num_remap = 0;
383 return;
384 }
385 remap->number++;
386 return;
387}
388
389static Boolint
390MatchOneOf(char *wanted, char *vals_defined)
391{
392 char *str, *next;
393 int want_len = strlen(wanted);
394
395 for (str = vals_defined, next = NULL((void*)0); str != NULL((void*)0); str = next) {
396 int len;
397
398 next = strchr(str, ',');
399 if (next) {
400 len = next - str;
401 next++;
402 }
403 else {
404 len = strlen(str);
405 }
406 if ((len == want_len) && (strncmp(wanted, str, len) == 0))
407 return True1;
408 }
409 return False0;
410}
411
412/***====================================================================***/
413
414static Boolint
415CheckLine(InputLine * line,
416 RemapSpec * remap,
417 XkbRF_RulePtr rule,
418 XkbRF_GroupPtr group)
419{
420 char *str, *tok;
421 register int nread, i;
422 FileSpec tmp;
423 _Xstrtokparams strtok_buf;
424 Boolint append = False0;
425
426 if (line->line[0] == '!') {
427 if (line->line[1] == '$' ||
428 (line->line[1] == ' ' && line->line[2] == '$')) {
429 char *gname = strchr(line->line, '$');
430 char *words = strchr(gname, ' ');
431
432 if (!words)
433 return False0;
434 *words++ = '\0';
435 for (; *words; words++) {
436 if (*words != '=' && *words != ' ')
437 break;
438 }
439 if (*words == '\0')
440 return False0;
441 group->name = _XkbDupString(gname);
442 group->words = _XkbDupString(words);
443 for (i = 1, words = group->words; *words; words++) {
444 if (*words == ' ') {
445 *words++ = '\0';
446 i++;
447 }
448 }
449 group->number = i;
450 return True1;
451 }
452 else {
453 SetUpRemap(line, remap);
454 return False0;
455 }
456 }
457
458 if (remap->num_remap == 0) {
459 PR_DEBUG("Must have a mapping before first line of data\n");
460 PR_DEBUG("Illegal line of data ignored\n");
461 return False0;
462 }
463 bzero((char *) &tmp, sizeof(FileSpec))__builtin___memset_chk ((char *) &tmp, 0, sizeof(FileSpec
), __builtin_object_size ((char *) &tmp, 0))
;
464 str = line->line;
465 for (nread = 0; (tok = _XStrtok(str, " ", strtok_buf)( strtok_buf = 0, (void)strtok_buf, strtok((str),(" ")) )) != NULL((void*)0); nread++) {
466 str = NULL((void*)0);
467 if (strcmp(tok, "=") == 0) {
468 nread--;
469 continue;
470 }
471 if (nread > remap->num_remap) {
472 PR_DEBUG("Too many words on a line\n");
473 PR_DEBUG1("Extra word \"%s\" ignored\n", tok);
474 continue;
475 }
476 tmp.name[remap->remap[nread].word] = tok;
477 if (*tok == '+' || *tok == '|')
478 append = True1;
479 }
480 if (nread < remap->num_remap) {
481 PR_DEBUG1("Too few words on a line: %s\n", line->line);
482 PR_DEBUG("line ignored\n");
483 return False0;
484 }
485
486 rule->flags = 0;
487 rule->number = remap->number;
488 if (tmp.name[OPTION3])
489 rule->flags |= XkbRF_Option(1L<<2);
490 else if (append)
491 rule->flags |= XkbRF_Append(1L<<3);
492 else
493 rule->flags |= XkbRF_Normal(1L<<4);
494 rule->model = _XkbDupString(tmp.name[MODEL0]);
495 rule->layout = _XkbDupString(tmp.name[LAYOUT1]);
496 rule->variant = _XkbDupString(tmp.name[VARIANT2]);
497 rule->option = _XkbDupString(tmp.name[OPTION3]);
498
499 rule->keycodes = _XkbDupString(tmp.name[KEYCODES4]);
500 rule->symbols = _XkbDupString(tmp.name[SYMBOLS5]);
501 rule->types = _XkbDupString(tmp.name[TYPES6]);
502 rule->compat = _XkbDupString(tmp.name[COMPAT7]);
503 rule->geometry = _XkbDupString(tmp.name[GEOMETRY8]);
504 rule->keymap = _XkbDupString(tmp.name[KEYMAP9]);
505
506 rule->layout_num = rule->variant_num = 0;
507 for (i = 0; i < nread; i++) {
508 if (remap->remap[i].index) {
509 if (remap->remap[i].word == LAYOUT1)
510 rule->layout_num = remap->remap[i].index;
511 if (remap->remap[i].word == VARIANT2)
512 rule->variant_num = remap->remap[i].index;
513 }
514 }
515 return True1;
516}
517
518static char *
519_Concat(char *str1, char *str2)
520{
521 int len;
522
523 if ((!str1) || (!str2))
524 return str1;
525 len = strlen(str1) + strlen(str2) + 1;
526 str1 = _XkbTypedRealloc(str1, len, char)((str1)?(char *)realloc((str1),(len)*sizeof(char)):((char *)calloc
((len),sizeof(char))))
;
527 if (str1)
528 strcat(str1, str2)__builtin___strcat_chk (str1, str2, __builtin_object_size (str1
, 2 > 1 ? 1 : 0))
;
529 return str1;
530}
531
532static void
533squeeze_spaces(char *p1)
534{
535 char *p2;
536
537 for (p2 = p1; *p2; p2++) {
538 *p1 = *p2;
539 if (*p1 != ' ')
540 p1++;
541 }
542 *p1 = '\0';
543}
544
545static Boolint
546MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
547{
548
549 bzero((char *) mdefs, sizeof(XkbRF_MultiDefsRec))__builtin___memset_chk ((char *) mdefs, 0, sizeof(XkbRF_MultiDefsRec
), __builtin_object_size ((char *) mdefs, 0))
;
550 mdefs->model = defs->model;
551 mdefs->options = _XkbDupString(defs->options);
552 if (mdefs->options)
553 squeeze_spaces(mdefs->options);
554
555 if (defs->layout) {
556 if (!strchr(defs->layout, ',')) {
557 mdefs->layout[0] = defs->layout;
558 }
559 else {
560 char *p;
561
562 int i;
563
564 mdefs->layout[1] = _XkbDupString(defs->layout);
565 if (mdefs->layout[1] == NULL((void*)0))
566 return False0;
567 squeeze_spaces(mdefs->layout[1]);
568 p = mdefs->layout[1];
569 for (i = 2; i <= XkbNumKbdGroups4; i++) {
570 if ((p = strchr(p, ','))) {
571 *p++ = '\0';
572 mdefs->layout[i] = p;
573 }
574 else {
575 break;
576 }
577 }
578 if (p && (p = strchr(p, ',')))
579 *p = '\0';
580 }
581 }
582
583 if (defs->variant) {
584 if (!strchr(defs->variant, ',')) {
585 mdefs->variant[0] = defs->variant;
586 }
587 else {
588 char *p;
589
590 int i;
591
592 mdefs->variant[1] = _XkbDupString(defs->variant);
593 if (mdefs->variant[1] == NULL((void*)0))
594 return False0;
595 squeeze_spaces(mdefs->variant[1]);
596 p = mdefs->variant[1];
597 for (i = 2; i <= XkbNumKbdGroups4; i++) {
598 if ((p = strchr(p, ','))) {
599 *p++ = '\0';
600 mdefs->variant[i] = p;
601 }
602 else {
603 break;
604 }
605 }
606 if (p && (p = strchr(p, ',')))
607 *p = '\0';
608 }
609 }
610 return True1;
611}
612
613static void
614FreeMultiDefs(XkbRF_MultiDefsPtr defs)
615{
616 if (defs->options)
617 _XkbFree(defs->options)free(defs->options);
618 if (defs->layout[1])
619 _XkbFree(defs->layout[1])free(defs->layout[1]);
620 if (defs->variant[1])
621 _XkbFree(defs->variant[1])free(defs->variant[1]);
622}
623
624static void
625Apply(char *src, char **dst)
626{
627 if (src) {
628 if (*src == '+' || *src == '!') {
629 *dst = _Concat(*dst, src);
630 }
631 else {
632 if (*dst == NULL((void*)0))
633 *dst = _XkbDupString(src);
634 }
635 }
636}
637
638static void
639XkbRF_ApplyRule(XkbRF_RulePtr rule, XkbComponentNamesPtr names)
640{
641 rule->flags &= ~XkbRF_PendingMatch(1L<<1); /* clear the flag because it's applied */
642
643 Apply(rule->keycodes, &names->keycodes);
644 Apply(rule->symbols, &names->symbols);
645 Apply(rule->types, &names->types);
646 Apply(rule->compat, &names->compat);
647 Apply(rule->geometry, &names->geometry);
648 Apply(rule->keymap, &names->keymap);
649}
650
651static Boolint
652CheckGroup(XkbRF_RulesPtr rules, char *group_name, char *name)
653{
654 int i;
655 char *p;
656 XkbRF_GroupPtr group;
657
658 for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
659 if (!strcmp(group->name, group_name)) {
660 break;
661 }
662 }
663 if (i == rules->num_groups)
664 return False0;
665 for (i = 0, p = group->words; i < group->number; i++, p += strlen(p) + 1) {
666 if (!strcmp(p, name)) {
667 return True1;
668 }
669 }
670 return False0;
671}
672
673static int
674XkbRF_CheckApplyRule(XkbRF_RulePtr rule,
675 XkbRF_MultiDefsPtr mdefs,
676 XkbComponentNamesPtr names,
677 XkbRF_RulesPtr rules)
678{
679 Boolint pending = False0;
680
681 if (rule->model != NULL((void*)0)) {
682 if (mdefs->model == NULL((void*)0))
683 return 0;
684 if (strcmp(rule->model, "*") == 0) {
685 pending = True1;
686 }
687 else {
688 if (rule->model[0] == '$') {
689 if (!CheckGroup(rules, rule->model, mdefs->model))
690 return 0;
691 }
692 else {
693 if (strcmp(rule->model, mdefs->model) != 0)
694 return 0;
695 }
696 }
697 }
698 if (rule->option != NULL((void*)0)) {
699 if (mdefs->options == NULL((void*)0))
700 return 0;
701 if ((!MatchOneOf(rule->option, mdefs->options)))
702 return 0;
703 }
704
705 if (rule->layout != NULL((void*)0)) {
706 if (mdefs->layout[rule->layout_num] == NULL((void*)0) ||
707 *mdefs->layout[rule->layout_num] == '\0')
708 return 0;
709 if (strcmp(rule->layout, "*") == 0) {
710 pending = True1;
711 }
712 else {
713 if (rule->layout[0] == '$') {
714 if (!CheckGroup(rules, rule->layout,
715 mdefs->layout[rule->layout_num]))
716 return 0;
717 }
718 else {
719 if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0)
720 return 0;
721 }
722 }
723 }
724 if (rule->variant != NULL((void*)0)) {
725 if (mdefs->variant[rule->variant_num] == NULL((void*)0) ||
726 *mdefs->variant[rule->variant_num] == '\0')
727 return 0;
728 if (strcmp(rule->variant, "*") == 0) {
729 pending = True1;
730 }
731 else {
732 if (rule->variant[0] == '$') {
733 if (!CheckGroup(rules, rule->variant,
734 mdefs->variant[rule->variant_num]))
735 return 0;
736 }
737 else {
738 if (strcmp(rule->variant,
739 mdefs->variant[rule->variant_num]) != 0)
740 return 0;
741 }
742 }
743 }
744 if (pending) {
745 rule->flags |= XkbRF_PendingMatch(1L<<1);
746 return rule->number;
747 }
748 /* exact match, apply it now */
749 XkbRF_ApplyRule(rule, names);
750 return rule->number;
751}
752
753static void
754XkbRF_ClearPartialMatches(XkbRF_RulesPtr rules)
755{
756 register int i;
757 XkbRF_RulePtr rule;
758
759 for (i = 0, rule = rules->rules; i < rules->num_rules; i++, rule++) {
760 rule->flags &= ~XkbRF_PendingMatch(1L<<1);
761 }
762}
763
764static void
765XkbRF_ApplyPartialMatches(XkbRF_RulesPtr rules, XkbComponentNamesPtr names)
766{
767 int i;
768 XkbRF_RulePtr rule;
769
770 for (rule = rules->rules, i = 0; i < rules->num_rules; i++, rule++) {
771 if ((rule->flags & XkbRF_PendingMatch(1L<<1)) == 0)
772 continue;
773 XkbRF_ApplyRule(rule, names);
774 }
775}
776
777static void
778XkbRF_CheckApplyRules(XkbRF_RulesPtr rules,
779 XkbRF_MultiDefsPtr mdefs,
780 XkbComponentNamesPtr names,
781 int flags)
782{
783 int i;
784 XkbRF_RulePtr rule;
785 int skip;
786
787 for (rule = rules->rules, i = 0; i < rules->num_rules; rule++, i++) {
788 if ((rule->flags & flags) != flags)
789 continue;
790 skip = XkbRF_CheckApplyRule(rule, mdefs, names, rules);
791 if (skip && !(flags & XkbRF_Option(1L<<2))) {
792 for (; (i < rules->num_rules) && (rule->number == skip);
793 rule++, i++);
794 rule--;
795 i--;
796 }
797 }
798}
799
800/***====================================================================***/
801
802static char *
803XkbRF_SubstituteVars(char *name, XkbRF_MultiDefsPtr mdefs)
804{
805 char *str, *outstr, *orig, *var;
806 int len, ndx;
807
808 orig = name;
809 str = index(name, '%');
810 if (str == NULL((void*)0))
811 return name;
812 len = strlen(name);
813 while (str != NULL((void*)0)) {
814 char pfx = str[1];
815 int extra_len = 0;
816
817 if ((pfx == '+') || (pfx == '|') || (pfx == '_') || (pfx == '-')) {
818 extra_len = 1;
819 str++;
820 }
821 else if (pfx == '(') {
822 extra_len = 2;
823 str++;
824 }
825 var = str + 1;
826 str = get_index(var + 1, &ndx);
827 if (ndx == -1) {
828 str = index(str, '%');
829 continue;
830 }
831 if ((*var == 'l') && mdefs->layout[ndx] && *mdefs->layout[ndx])
832 len += strlen(mdefs->layout[ndx]) + extra_len;
833 else if ((*var == 'm') && mdefs->model)
834 len += strlen(mdefs->model) + extra_len;
835 else if ((*var == 'v') && mdefs->variant[ndx] && *mdefs->variant[ndx])
836 len += strlen(mdefs->variant[ndx]) + extra_len;
837 if ((pfx == '(') && (*str == ')')) {
838 str++;
839 }
840 str = index(&str[0], '%');
841 }
842 name = (char *) _XkbAlloc(len + 1)malloc((len + 1));
843 str = orig;
844 outstr = name;
845 while (*str != '\0') {
846 if (str[0] == '%') {
847 char pfx, sfx;
848
849 str++;
850 pfx = str[0];
851 sfx = '\0';
852 if ((pfx == '+') || (pfx == '|') || (pfx == '_') || (pfx == '-')) {
853 str++;
854 }
855 else if (pfx == '(') {
856 sfx = ')';
857 str++;
858 }
859 else
860 pfx = '\0';
861
862 var = str;
863 str = get_index(var + 1, &ndx);
864 if (ndx == -1) {
865 continue;
866 }
867 if ((*var == 'l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) {
868 if (pfx)
869 *outstr++ = pfx;
870 strcpy(outstr, mdefs->layout[ndx])__builtin___strcpy_chk (outstr, mdefs->layout[ndx], __builtin_object_size
(outstr, 2 > 1 ? 1 : 0))
;
871 outstr += strlen(mdefs->layout[ndx]);
872 if (sfx)
873 *outstr++ = sfx;
874 }
875 else if ((*var == 'm') && (mdefs->model)) {
876 if (pfx)
877 *outstr++ = pfx;
878 strcpy(outstr, mdefs->model)__builtin___strcpy_chk (outstr, mdefs->model, __builtin_object_size
(outstr, 2 > 1 ? 1 : 0))
;
879 outstr += strlen(mdefs->model);
880 if (sfx)
881 *outstr++ = sfx;
882 }
883 else if ((*var == 'v') && mdefs->variant[ndx] &&
884 *mdefs->variant[ndx]) {
885 if (pfx)
886 *outstr++ = pfx;
887 strcpy(outstr, mdefs->variant[ndx])__builtin___strcpy_chk (outstr, mdefs->variant[ndx], __builtin_object_size
(outstr, 2 > 1 ? 1 : 0))
;
888 outstr += strlen(mdefs->variant[ndx]);
889 if (sfx)
890 *outstr++ = sfx;
891 }
892 if ((pfx == '(') && (*str == ')'))
893 str++;
894 }
895 else {
896 *outstr++ = *str++;
897 }
898 }
899 *outstr++ = '\0';
900 if (orig != name)
901 _XkbFree(orig)free(orig);
902 return name;
903}
904
905/***====================================================================***/
906
907Boolint
908XkbRF_GetComponents(XkbRF_RulesPtr rules,
909 XkbRF_VarDefsPtr defs,
910 XkbComponentNamesPtr names)
911{
912 XkbRF_MultiDefsRec mdefs;
913
914 MakeMultiDefs(&mdefs, defs);
915
916 bzero((char *) names, sizeof(XkbComponentNamesRec))__builtin___memset_chk ((char *) names, 0, sizeof(XkbComponentNamesRec
), __builtin_object_size ((char *) names, 0))
;
917 XkbRF_ClearPartialMatches(rules);
918 XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Normal(1L<<4));
919 XkbRF_ApplyPartialMatches(rules, names);
920 XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append(1L<<3));
921 XkbRF_ApplyPartialMatches(rules, names);
922 XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option(1L<<2));
923 XkbRF_ApplyPartialMatches(rules, names);
924
925 if (names->keycodes)
926 names->keycodes = XkbRF_SubstituteVars(names->keycodes, &mdefs);
927 if (names->symbols)
928 names->symbols = XkbRF_SubstituteVars(names->symbols, &mdefs);
929 if (names->types)
930 names->types = XkbRF_SubstituteVars(names->types, &mdefs);
931 if (names->compat)
932 names->compat = XkbRF_SubstituteVars(names->compat, &mdefs);
933 if (names->geometry)
934 names->geometry = XkbRF_SubstituteVars(names->geometry, &mdefs);
935 if (names->keymap)
936 names->keymap = XkbRF_SubstituteVars(names->keymap, &mdefs);
937
938 FreeMultiDefs(&mdefs);
939 return (names->keycodes && names->symbols && names->types &&
940 names->compat && names->geometry) || names->keymap;
941}
942
943XkbRF_RulePtr
944XkbRF_AddRule(XkbRF_RulesPtr rules)
945{
946 if (rules->sz_rules < 1) {
947 rules->sz_rules = 16;
948 rules->num_rules = 0;
949 rules->rules = _XkbTypedCalloc(rules->sz_rules, XkbRF_RuleRec)((XkbRF_RuleRec *)calloc((rules->sz_rules),sizeof(XkbRF_RuleRec
)))
;
950 }
951 else if (rules->num_rules >= rules->sz_rules) {
952 rules->sz_rules *= 2;
953 rules->rules = _XkbTypedRealloc(rules->rules, rules->sz_rules,((rules->rules)?(XkbRF_RuleRec *)realloc((rules->rules)
,(rules->sz_rules)*sizeof(XkbRF_RuleRec)):((XkbRF_RuleRec *
)calloc((rules->sz_rules),sizeof(XkbRF_RuleRec))))
954 XkbRF_RuleRec)((rules->rules)?(XkbRF_RuleRec *)realloc((rules->rules)
,(rules->sz_rules)*sizeof(XkbRF_RuleRec)):((XkbRF_RuleRec *
)calloc((rules->sz_rules),sizeof(XkbRF_RuleRec))))
;
955 }
956 if (!rules->rules) {
957 rules->sz_rules = rules->num_rules = 0;
958#ifdef DEBUG
959 fprintf(stderr__stderrp, "Allocation failure in XkbRF_AddRule\n");
960#endif
961 return NULL((void*)0);
962 }
963 bzero((char *) &rules->rules[rules->num_rules], sizeof(XkbRF_RuleRec))__builtin___memset_chk ((char *) &rules->rules[rules->
num_rules], 0, sizeof(XkbRF_RuleRec), __builtin_object_size (
(char *) &rules->rules[rules->num_rules], 0))
;
964 return &rules->rules[rules->num_rules++];
965}
966
967XkbRF_GroupPtr
968XkbRF_AddGroup(XkbRF_RulesPtr rules)
969{
970 if (rules->sz_groups < 1) {
971 rules->sz_groups = 16;
972 rules->num_groups = 0;
973 rules->groups = _XkbTypedCalloc(rules->sz_groups, XkbRF_GroupRec)((XkbRF_GroupRec *)calloc((rules->sz_groups),sizeof(XkbRF_GroupRec
)))
;
974 }
975 else if (rules->num_groups >= rules->sz_groups) {
976 rules->sz_groups *= 2;
977 rules->groups = _XkbTypedRealloc(rules->groups, rules->sz_groups,((rules->groups)?(XkbRF_GroupRec *)realloc((rules->groups
),(rules->sz_groups)*sizeof(XkbRF_GroupRec)):((XkbRF_GroupRec
*)calloc((rules->sz_groups),sizeof(XkbRF_GroupRec))))
978 XkbRF_GroupRec)((rules->groups)?(XkbRF_GroupRec *)realloc((rules->groups
),(rules->sz_groups)*sizeof(XkbRF_GroupRec)):((XkbRF_GroupRec
*)calloc((rules->sz_groups),sizeof(XkbRF_GroupRec))))
;
979 }
980 if (!rules->groups) {
981 rules->sz_groups = rules->num_groups = 0;
982 return NULL((void*)0);
983 }
984
985 bzero((char *) &rules->groups[rules->num_groups], sizeof(XkbRF_GroupRec))__builtin___memset_chk ((char *) &rules->groups[rules->
num_groups], 0, sizeof(XkbRF_GroupRec), __builtin_object_size
((char *) &rules->groups[rules->num_groups], 0))
;
986 return &rules->groups[rules->num_groups++];
987}
988
989Boolint
990XkbRF_LoadRules(FILE *file, XkbRF_RulesPtr rules)
991{
992 InputLine line;
993 RemapSpec remap;
994 XkbRF_RuleRec trule, *rule;
995 XkbRF_GroupRec tgroup, *group;
996
997 if (!(rules && file))
998 return False0;
999 bzero((char *) &remap, sizeof(RemapSpec))__builtin___memset_chk ((char *) &remap, 0, sizeof(RemapSpec
), __builtin_object_size ((char *) &remap, 0))
;
1000 bzero((char *) &tgroup, sizeof(XkbRF_GroupRec))__builtin___memset_chk ((char *) &tgroup, 0, sizeof(XkbRF_GroupRec
), __builtin_object_size ((char *) &tgroup, 0))
;
1001 InitInputLine(&line);
1002 while (GetInputLine(file, &line, True1)) {
1003 if (CheckLine(&line, &remap, &trule, &tgroup)) {
1004 if (tgroup.number) {
1005 if ((group = XkbRF_AddGroup(rules)) != NULL((void*)0)) {
1006 *group = tgroup;
1007 bzero((char *) &tgroup, sizeof(XkbRF_GroupRec))__builtin___memset_chk ((char *) &tgroup, 0, sizeof(XkbRF_GroupRec
), __builtin_object_size ((char *) &tgroup, 0))
;
1008 }
1009 }
1010 else {
1011 if ((rule = XkbRF_AddRule(rules)) != NULL((void*)0)) {
1012 *rule = trule;
1013 bzero((char *) &trule, sizeof(XkbRF_RuleRec))__builtin___memset_chk ((char *) &trule, 0, sizeof(XkbRF_RuleRec
), __builtin_object_size ((char *) &trule, 0))
;
1014 }
1015 }
1016 }
1017 line.num_line = 0;
1018 }
1019 FreeInputLine(&line);
1020 return True1;
1021}
1022
1023Boolint
1024XkbRF_LoadRulesByName(char *base, char *locale, XkbRF_RulesPtr rules)
1025{
1026 FILE *file;
1027 char buf[PATH_MAX1024];
1028 Boolint ok;
1029
1030 if ((!base) || (!rules))
1031 return False0;
1032 if (locale) {
1033 if (strlen(base) + strlen(locale) + 2 > PATH_MAX1024)
1034 return False0;
1035 snprintf(buf, sizeof(buf), "%s-%s", base, locale)__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), "%s-%s", base, locale)
;
1036 }
1037 else {
1038 if (strlen(base) + 1 > PATH_MAX1024)
1039 return False0;
1040 strcpy(buf, base)__builtin___strcpy_chk (buf, base, __builtin_object_size (buf
, 2 > 1 ? 1 : 0))
;
1041 }
1042
1043 file = fopen(buf, "r");
1044 if ((!file) && (locale)) { /* fallback if locale was specified */
1045 strcpy(buf, base)__builtin___strcpy_chk (buf, base, __builtin_object_size (buf
, 2 > 1 ? 1 : 0))
;
1046 file = fopen(buf, "r");
1047 }
1048 if (!file)
1049 return False0;
1050 ok = XkbRF_LoadRules(file, rules);
1051 fclose(file);
1052 return ok;
1053}
1054
1055/***====================================================================***/
1056
1057#define HEAD_NONE0 0
1058#define HEAD_MODEL1 1
1059#define HEAD_LAYOUT2 2
1060#define HEAD_VARIANT3 3
1061#define HEAD_OPTION4 4
1062#define HEAD_EXTRA5 5
1063
1064XkbRF_VarDescPtr
1065XkbRF_AddVarDesc(XkbRF_DescribeVarsPtr vars)
1066{
1067 if (vars->sz_desc < 1) {
1068 vars->sz_desc = 16;
1069 vars->num_desc = 0;
1070 vars->desc = _XkbTypedCalloc(vars->sz_desc, XkbRF_VarDescRec)((XkbRF_VarDescRec *)calloc((vars->sz_desc),sizeof(XkbRF_VarDescRec
)))
;
1071 }
1072 else if (vars->num_desc >= vars->sz_desc) {
1073 vars->sz_desc *= 2;
1074 vars->desc =
1075 _XkbTypedRealloc(vars->desc, vars->sz_desc, XkbRF_VarDescRec)((vars->desc)?(XkbRF_VarDescRec *)realloc((vars->desc),
(vars->sz_desc)*sizeof(XkbRF_VarDescRec)):((XkbRF_VarDescRec
*)calloc((vars->sz_desc),sizeof(XkbRF_VarDescRec))))
;
1076 }
1077 if (!vars->desc) {
1078 vars->sz_desc = vars->num_desc = 0;
1079 PR_DEBUG("Allocation failure in XkbRF_AddVarDesc\n");
1080 return NULL((void*)0);
1081 }
1082 vars->desc[vars->num_desc].name = NULL((void*)0);
1083 vars->desc[vars->num_desc].desc = NULL((void*)0);
1084 return &vars->desc[vars->num_desc++];
1085}
1086
1087XkbRF_VarDescPtr
1088XkbRF_AddVarDescCopy(XkbRF_DescribeVarsPtr vars, XkbRF_VarDescPtr from)
1089{
1090 XkbRF_VarDescPtr nd;
1091
1092 if ((nd = XkbRF_AddVarDesc(vars)) != NULL((void*)0)) {
1093 nd->name = _XkbDupString(from->name);
1094 nd->desc = _XkbDupString(from->desc);
1095 }
1096 return nd;
1097}
1098
1099XkbRF_DescribeVarsPtr
1100XkbRF_AddVarToDescribe(XkbRF_RulesPtr rules, char *name)
1101{
1102 if (rules->sz_extra < 1) {
1103 rules->num_extra = 0;
1104 rules->sz_extra = 1;
1105 rules->extra_names = _XkbTypedCalloc(rules->sz_extra, char *)((char * *)calloc((rules->sz_extra),sizeof(char *)));
1106
1107 rules->extra = _XkbTypedCalloc(rules->sz_extra, XkbRF_DescribeVarsRec)((XkbRF_DescribeVarsRec *)calloc((rules->sz_extra),sizeof(
XkbRF_DescribeVarsRec)))
;
1108 }
1109 else if (rules->num_extra >= rules->sz_extra) {
1110 rules->sz_extra *= 2;
1111 rules->extra_names =
1112 _XkbTypedRealloc(rules->extra_names, rules->sz_extra, char *)((rules->extra_names)?(char * *)realloc((rules->extra_names
),(rules->sz_extra)*sizeof(char *)):((char * *)calloc((rules
->sz_extra),sizeof(char *))))
;
1113 rules->extra =
1114 _XkbTypedRealloc(rules->extra, rules->sz_extra,((rules->extra)?(XkbRF_DescribeVarsRec *)realloc((rules->
extra),(rules->sz_extra)*sizeof(XkbRF_DescribeVarsRec)):((
XkbRF_DescribeVarsRec *)calloc((rules->sz_extra),sizeof(XkbRF_DescribeVarsRec
))))
1115 XkbRF_DescribeVarsRec)((rules->extra)?(XkbRF_DescribeVarsRec *)realloc((rules->
extra),(rules->sz_extra)*sizeof(XkbRF_DescribeVarsRec)):((
XkbRF_DescribeVarsRec *)calloc((rules->sz_extra),sizeof(XkbRF_DescribeVarsRec
))))
;
1116 }
1117 if ((!rules->extra_names) || (!rules->extra)) {
1118 PR_DEBUG("allocation error in extra parts\n");
1119 rules->sz_extra = rules->num_extra = 0;
1120 rules->extra_names = NULL((void*)0);
1121 rules->extra = NULL((void*)0);
1122 return NULL((void*)0);
1123 }
1124 rules->extra_names[rules->num_extra] = _XkbDupString(name);
1125 bzero(&rules->extra[rules->num_extra], sizeof(XkbRF_DescribeVarsRec))__builtin___memset_chk (&rules->extra[rules->num_extra
], 0, sizeof(XkbRF_DescribeVarsRec), __builtin_object_size (&
rules->extra[rules->num_extra], 0))
;
1126 return &rules->extra[rules->num_extra++];
1127}
1128
1129Boolint
1130XkbRF_LoadDescriptions(FILE *file, XkbRF_RulesPtr rules)
1131{
1132 InputLine line;
1133 XkbRF_VarDescRec tmp;
1134 char *tok;
1135 int len, headingtype, extra_ndx = 0;
1136
1137 bzero((char *) &tmp, sizeof(XkbRF_VarDescRec))__builtin___memset_chk ((char *) &tmp, 0, sizeof(XkbRF_VarDescRec
), __builtin_object_size ((char *) &tmp, 0))
;
1138 headingtype = HEAD_NONE0;
1139 InitInputLine(&line);
1140 for (; GetInputLine(file, &line, False0); line.num_line = 0) {
1141 if (line.line[0] == '!') {
1142 tok = strtok(&(line.line[1]), " \t");
1143 if (strcmp(tok, "model") == 0)
1144 headingtype = HEAD_MODEL1;
1145 else if (_XkbStrCaseCmpstrcasecmp(tok, "layout") == 0)
1146 headingtype = HEAD_LAYOUT2;
1147 else if (_XkbStrCaseCmpstrcasecmp(tok, "variant") == 0)
1148 headingtype = HEAD_VARIANT3;
1149 else if (_XkbStrCaseCmpstrcasecmp(tok, "option") == 0)
1150 headingtype = HEAD_OPTION4;
1151 else {
1152 int i;
1153
1154 headingtype = HEAD_EXTRA5;
1155 extra_ndx = -1;
1156 for (i = 0; (i < rules->num_extra) && (extra_ndx < 0); i++) {
1157 if (_XkbStrCaseCmpstrcasecmp(tok, rules->extra_names[i]))
1158 extra_ndx = i;
1159 }
1160 if (extra_ndx < 0) {
1161 XkbRF_DescribeVarsPtr var;
1162
1163 PR_DEBUG1("Extra heading \"%s\" encountered\n", tok);
1164 var = XkbRF_AddVarToDescribe(rules, tok);
1165 if (var)
1166 extra_ndx = var - rules->extra;
1167 else
1168 headingtype = HEAD_NONE0;
1169 }
1170 }
1171 continue;
1172 }
1173
1174 if (headingtype == HEAD_NONE0) {
1175 PR_DEBUG("Must have a heading before first line of data\n");
1176 PR_DEBUG("Illegal line of data ignored\n");
1177 continue;
1178 }
1179
1180 len = strlen(line.line);
1181 if ((tmp.name = strtok(line.line, " \t")) == NULL((void*)0)) {
1182 PR_DEBUG("Huh? No token on line\n");
1183 PR_DEBUG("Illegal line of data ignored\n");
1184 continue;
1185 }
1186 if (strlen(tmp.name) == len) {
1187 PR_DEBUG("No description found\n");
1188 PR_DEBUG("Illegal line of data ignored\n");
1189 continue;
1190 }
1191
1192 tok = line.line + strlen(tmp.name) + 1;
1193 while ((*tok != '\n') && isspace(*tok))
1194 tok++;
1195 if (*tok == '\0') {
1196 PR_DEBUG("No description found\n");
1197 PR_DEBUG("Illegal line of data ignored\n");
1198 continue;
1199 }
1200 tmp.desc = tok;
1201 switch (headingtype) {
1202 case HEAD_MODEL1:
1203 XkbRF_AddVarDescCopy(&rules->models, &tmp);
1204 break;
1205 case HEAD_LAYOUT2:
1206 XkbRF_AddVarDescCopy(&rules->layouts, &tmp);
1207 break;
1208 case HEAD_VARIANT3:
1209 XkbRF_AddVarDescCopy(&rules->variants, &tmp);
1210 break;
1211 case HEAD_OPTION4:
1212 XkbRF_AddVarDescCopy(&rules->options, &tmp);
1213 break;
1214 case HEAD_EXTRA5:
1215 XkbRF_AddVarDescCopy(&rules->extra[extra_ndx], &tmp);
1216 break;
1217 }
1218 }
1219 FreeInputLine(&line);
1220 if ((rules->models.num_desc == 0) && (rules->layouts.num_desc == 0) &&
1221 (rules->variants.num_desc == 0) && (rules->options.num_desc == 0) &&
1222 (rules->num_extra == 0)) {
1223 return False0;
1224 }
1225 return True1;
1226}
1227
1228Boolint
1229XkbRF_LoadDescriptionsByName(char *base, char *locale, XkbRF_RulesPtr rules)
1230{
1231 FILE *file;
1232 char buf[PATH_MAX1024];
1233 Boolint ok;
1234
1235 if ((!base) || (!rules))
1236 return False0;
1237 if (locale) {
1238 if (strlen(base) + strlen(locale) + 6 > PATH_MAX1024)
1239 return False0;
1240 snprintf(buf, sizeof(buf), "%s-%s.lst", base, locale)__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), "%s-%s.lst", base, locale)
;
1241 }
1242 else {
1243 if (strlen(base) + 5 > PATH_MAX1024)
1244 return False0;
1245 snprintf(buf, sizeof(buf), "%s.lst", base)__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), "%s.lst", base)
;
1246 }
1247
1248 file = fopen(buf, "r");
1249 if ((!file) && (locale)) { /* fallback if locale was specified */
1250 snprintf(buf, sizeof(buf), "%s.lst", base)__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), "%s.lst", base)
;
1251
1252 file = fopen(buf, "r");
1253 }
1254 if (!file)
1255 return False0;
1256 ok = XkbRF_LoadDescriptions(file, rules);
1257 fclose(file);
1258 return ok;
1259}
1260
1261/***====================================================================***/
1262
1263XkbRF_RulesPtr
1264XkbRF_Load(char *base, char *locale, Boolint wantDesc, Boolint wantRules)
1265{
1266 XkbRF_RulesPtr rules;
1267
1268 if ((!base) || ((!wantDesc) && (!wantRules)))
1269 return NULL((void*)0);
1270 if ((rules = _XkbTypedCalloc(1, XkbRF_RulesRec)((XkbRF_RulesRec *)calloc((1),sizeof(XkbRF_RulesRec)))) == NULL((void*)0))
1271 return NULL((void*)0);
1272 if (wantDesc && (!XkbRF_LoadDescriptionsByName(base, locale, rules))) {
1273 XkbRF_Free(rules, True1);
1274 return NULL((void*)0);
1275 }
1276 if (wantRules && (!XkbRF_LoadRulesByName(base, locale, rules))) {
1277 XkbRF_Free(rules, True1);
1278 return NULL((void*)0);
1279 }
1280 return rules;
1281}
1282
1283XkbRF_RulesPtr
1284XkbRF_Create(int szRules, int szExtra)
1285{
1286 XkbRF_RulesPtr rules;
1287
1288 if ((rules = _XkbTypedCalloc(1, XkbRF_RulesRec)((XkbRF_RulesRec *)calloc((1),sizeof(XkbRF_RulesRec)))) == NULL((void*)0))
1289 return NULL((void*)0);
1290 if (szRules > 0) {
1291 rules->sz_rules = szRules;
1292 rules->rules = _XkbTypedCalloc(rules->sz_rules, XkbRF_RuleRec)((XkbRF_RuleRec *)calloc((rules->sz_rules),sizeof(XkbRF_RuleRec
)))
;
1293 if (!rules->rules) {
1294 _XkbFree(rules)free(rules);
1295 return NULL((void*)0);
1296 }
1297 }
1298 if (szExtra > 0) {
1299 rules->sz_extra = szExtra;
1300 rules->extra = _XkbTypedCalloc(rules->sz_extra, XkbRF_DescribeVarsRec)((XkbRF_DescribeVarsRec *)calloc((rules->sz_extra),sizeof(
XkbRF_DescribeVarsRec)))
;
1301 if (!rules->extra) {
1302 if (rules->rules)
1303 _XkbFree(rules->rules)free(rules->rules);
1304 _XkbFree(rules)free(rules);
1305 return NULL((void*)0);
1306 }
1307 }
1308 return rules;
1309}
1310
1311/***====================================================================***/
1312
1313static void
1314XkbRF_ClearVarDescriptions(XkbRF_DescribeVarsPtr var)
1315{
1316 register int i;
1317
1318 for (i = 0; i < var->num_desc; i++) {
1319 if (var->desc[i].name)
1320 _XkbFree(var->desc[i].name)free(var->desc[i].name);
1321 if (var->desc[i].desc)
1322 _XkbFree(var->desc[i].desc)free(var->desc[i].desc);
1323 var->desc[i].name = var->desc[i].desc = NULL((void*)0);
1324 }
1325 if (var->desc)
1326 _XkbFree(var->desc)free(var->desc);
1327 var->desc = NULL((void*)0);
1328 return;
1329}
1330
1331void
1332XkbRF_Free(XkbRF_RulesPtr rules, Boolint freeRules)
1333{
1334 int i;
1335 XkbRF_RulePtr rule;
1336 XkbRF_GroupPtr group;
1337
1338 if (!rules)
1339 return;
1340 XkbRF_ClearVarDescriptions(&rules->models);
1341 XkbRF_ClearVarDescriptions(&rules->layouts);
1342 XkbRF_ClearVarDescriptions(&rules->variants);
1343 XkbRF_ClearVarDescriptions(&rules->options);
1344 if (rules->extra) {
1345 for (i = 0; i < rules->num_extra; i++) {
1346 XkbRF_ClearVarDescriptions(&rules->extra[i]);
1347 }
1348 _XkbFree(rules->extra)free(rules->extra);
1349 rules->num_extra = rules->sz_extra = 0;
1350 rules->extra = NULL((void*)0);
1351 }
1352 if (rules->rules) {
1353 for (i = 0, rule = rules->rules; i < rules->num_rules; i++, rule++) {
1354 if (rule->model)
1355 _XkbFree(rule->model)free(rule->model);
1356 if (rule->layout)
1357 _XkbFree(rule->layout)free(rule->layout);
1358 if (rule->variant)
1359 _XkbFree(rule->variant)free(rule->variant);
1360 if (rule->option)
1361 _XkbFree(rule->option)free(rule->option);
1362 if (rule->keycodes)
1363 _XkbFree(rule->keycodes)free(rule->keycodes);
1364 if (rule->symbols)
1365 _XkbFree(rule->symbols)free(rule->symbols);
1366 if (rule->types)
1367 _XkbFree(rule->types)free(rule->types);
1368 if (rule->compat)
1369 _XkbFree(rule->compat)free(rule->compat);
1370 if (rule->geometry)
1371 _XkbFree(rule->geometry)free(rule->geometry);
1372 if (rule->keymap)
1373 _XkbFree(rule->keymap)free(rule->keymap);
1374 bzero((char *) rule, sizeof(XkbRF_RuleRec))__builtin___memset_chk ((char *) rule, 0, sizeof(XkbRF_RuleRec
), __builtin_object_size ((char *) rule, 0))
;
1375 }
1376 _XkbFree(rules->rules)free(rules->rules);
1377 rules->num_rules = rules->sz_rules = 0;
1378 rules->rules = NULL((void*)0);
1379 }
1380
1381 if (rules->groups) {
1382 for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
1383 if (group->name)
1384 _XkbFree(group->name)free(group->name);
1385 if (group->words)
1386 _XkbFree(group->words)free(group->words);
1387 }
1388 _XkbFree(rules->groups)free(rules->groups);
1389 rules->num_groups = 0;
1390 rules->groups = NULL((void*)0);
1391 }
1392 if (freeRules)
1393 _XkbFree(rules)free(rules);
1394 return;
1395}
1396
1397
1398Boolint
1399XkbRF_GetNamesProp(Display * dpy, char **rf_rtrn, XkbRF_VarDefsPtr vd_rtrn)
1400{
1401 Atom rules_atom, actual_type;
1402 int fmt;
1403 unsigned long nitems, bytes_after;
1404 unsigned char *data;
1405 char *out, *end;
1406 Statusint rtrn;
1407
1408 rules_atom = XInternAtom(dpy, _XKB_RF_NAMES_PROP_ATOM"_XKB_RULES_NAMES", True1);
1409 if (rules_atom == None0L) /* property cannot exist */
1410 return False0;
1411 rtrn = XGetWindowProperty(dpy, DefaultRootWindow(dpy)((&((_XPrivDisplay)(dpy))->screens[(((_XPrivDisplay)(dpy
))->default_screen)])->root)
, rules_atom,
1412 0L, _XKB_RF_NAMES_PROP_MAXLEN1024, False0,
1413 XA_STRING((Atom) 31), &actual_type,
1414 &fmt, &nitems, &bytes_after,
1415 (unsigned char **) &data);
1416 if (rtrn != Success0)
1417 return False0;
1418 if (rf_rtrn)
1419 *rf_rtrn = NULL((void*)0);
1420 (void) bzero((char *) vd_rtrn, sizeof(XkbRF_VarDefsRec))__builtin___memset_chk ((char *) vd_rtrn, 0, sizeof(XkbRF_VarDefsRec
), __builtin_object_size ((char *) vd_rtrn, 0))
;
1421 if ((bytes_after > 0) || (actual_type != XA_STRING((Atom) 31)) || (fmt != 8)) {
1422 if (data)
1423 XFree(data);
1424 return (fmt == 0 ? True1 : False0);
1425 }
1426
1427 out = (char *) data;
1428 end = out + nitems;
1429 if (out && (*out) && rf_rtrn)
1430 *rf_rtrn = _XkbDupString(out);
1431 out += strlen(out) + 1;
1432
1433 if (out < end) {
1434 if (*out)
1435 vd_rtrn->model = _XkbDupString(out);
1436 out += strlen(out) + 1;
1437 }
1438
1439 if (out < end) {
1440 if (*out)
1441 vd_rtrn->layout = _XkbDupString(out);
1442 out += strlen(out) + 1;
1443 }
1444
1445 if (out < end) {
1446 if (*out)
1447 vd_rtrn->variant = _XkbDupString(out);
1448 out += strlen(out) + 1;
1449 }
1450
1451 if (out < end) {
1452 if (*out)
1453 vd_rtrn->options = _XkbDupString(out);
1454 out += strlen(out) + 1;
Value stored to 'out' is never read
1455 }
1456
1457 XFree(data);
1458 return True1;
1459}
1460
1461Boolint
1462XkbRF_SetNamesProp(Display *dpy, char *rules_file, XkbRF_VarDefsPtr var_defs)
1463{
1464 int len, out;
1465 Atom name;
1466 char *pval;
1467
1468 len = (rules_file ? strlen(rules_file) : 0);
1469 len += (var_defs->model ? strlen(var_defs->model) : 0);
1470 len += (var_defs->layout ? strlen(var_defs->layout) : 0);
1471 len += (var_defs->variant ? strlen(var_defs->variant) : 0);
1472 len += (var_defs->options ? strlen(var_defs->options) : 0);
1473 if (len < 1)
1474 return True1;
1475
1476 len += 5; /* trailing NULs */
1477
1478 name = XInternAtom(dpy, _XKB_RF_NAMES_PROP_ATOM"_XKB_RULES_NAMES", False0);
1479 if (name == None0L) { /* should never happen */
1480 _XkbLibError(_XkbErrXReqFailure, "XkbRF_SetNamesProp", X_InternAtom){ _XkbErrCode= (25); _XkbErrLocation= ("XkbRF_SetNamesProp");
_XkbErrData= (16); }
;
1481 return False0;
1482 }
1483 pval = (char *) _XkbAlloc(len)malloc((len));
1484 if (!pval) {
1485 _XkbLibError(_XkbErrBadAlloc, "XkbRF_SetNamesProp", len){ _XkbErrCode= (23); _XkbErrLocation= ("XkbRF_SetNamesProp");
_XkbErrData= (len); }
;
1486 return False0;
1487 }
1488 out = 0;
1489 if (rules_file) {
1490 strcpy(&pval[out], rules_file)__builtin___strcpy_chk (&pval[out], rules_file, __builtin_object_size
(&pval[out], 2 > 1 ? 1 : 0))
;
1491 out += strlen(rules_file);
1492 }
1493 pval[out++] = '\0';
1494 if (var_defs->model) {
1495 strcpy(&pval[out], var_defs->model)__builtin___strcpy_chk (&pval[out], var_defs->model, __builtin_object_size
(&pval[out], 2 > 1 ? 1 : 0))
;
1496 out += strlen(var_defs->model);
1497 }
1498 pval[out++] = '\0';
1499 if (var_defs->layout) {
1500 strcpy(&pval[out], var_defs->layout)__builtin___strcpy_chk (&pval[out], var_defs->layout, __builtin_object_size
(&pval[out], 2 > 1 ? 1 : 0))
;
1501 out += strlen(var_defs->layout);
1502 }
1503 pval[out++] = '\0';
1504 if (var_defs->variant) {
1505 strcpy(&pval[out], var_defs->variant)__builtin___strcpy_chk (&pval[out], var_defs->variant,
__builtin_object_size (&pval[out], 2 > 1 ? 1 : 0))
;
1506 out += strlen(var_defs->variant);
1507 }
1508 pval[out++] = '\0';
1509 if (var_defs->options) {
1510 strcpy(&pval[out], var_defs->options)__builtin___strcpy_chk (&pval[out], var_defs->options,
__builtin_object_size (&pval[out], 2 > 1 ? 1 : 0))
;
1511 out += strlen(var_defs->options);
1512 }
1513 pval[out++] = '\0';
1514 if (out != len) {
1515 _XkbLibError(_XkbErrBadLength, "XkbRF_SetNamesProp", out){ _XkbErrCode= (24); _XkbErrLocation= ("XkbRF_SetNamesProp");
_XkbErrData= (out); }
;
1516 _XkbFree(pval)free(pval);
1517 return False0;
1518 }
1519
1520 XChangeProperty(dpy, DefaultRootWindow(dpy)((&((_XPrivDisplay)(dpy))->screens[(((_XPrivDisplay)(dpy
))->default_screen)])->root)
, name, XA_STRING((Atom) 31), 8,
1521 PropModeReplace0, (unsigned char *) pval, len);
1522 _XkbFree(pval)free(pval);
1523 return True1;
1524}
1525