File: | maprules.c |
Location: | line 189, column 25 |
Description: | Value stored to 'inComment' is never read |
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 | |
69 | typedef 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 | |
77 | static void |
78 | InitInputLine(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 | |
87 | static void |
88 | FreeInputLine(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 | |
99 | static int |
100 | InputLineAddChar(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 | |
129 | static Boolint |
130 | GetInputLine(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; |
Value stored to 'inComment' is never read | |
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 | |
225 | static const char *cname[MAX_WORDS10] = { |
226 | "model", "layout", "variant", "option", |
227 | "keycodes", "symbols", "types", "compat", "geometry", "keymap" |
228 | }; |
229 | |
230 | typedef struct _RemapSpec { |
231 | int number; |
232 | int num_remap; |
233 | struct { |
234 | int word; |
235 | int index; |
236 | } remap[MAX_WORDS10]; |
237 | } RemapSpec; |
238 | |
239 | typedef struct _FileSpec { |
240 | char *name[MAX_WORDS10]; |
241 | struct _FileSpec *pending; |
242 | } FileSpec; |
243 | |
244 | typedef 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 | |
255 | static char * |
256 | get_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 | |
282 | static void |
283 | SetUpRemap(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 | |
389 | static Boolint |
390 | MatchOneOf(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 | |
414 | static Boolint |
415 | CheckLine(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 | |
518 | static 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 | |
532 | static void |
533 | squeeze_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 | |
545 | static Boolint |
546 | MakeMultiDefs(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 | |
613 | static void |
614 | FreeMultiDefs(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 | |
624 | static void |
625 | Apply(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 | |
638 | static void |
639 | XkbRF_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 | |
651 | static Boolint |
652 | CheckGroup(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 | |
673 | static int |
674 | XkbRF_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 | |
753 | static void |
754 | XkbRF_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 | |
764 | static void |
765 | XkbRF_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 | |
777 | static void |
778 | XkbRF_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 | |
802 | static char * |
803 | XkbRF_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 | |
907 | Boolint |
908 | XkbRF_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 | |
943 | XkbRF_RulePtr |
944 | XkbRF_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 | |
967 | XkbRF_GroupPtr |
968 | XkbRF_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 | |
989 | Boolint |
990 | XkbRF_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 | |
1023 | Boolint |
1024 | XkbRF_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 | |
1064 | XkbRF_VarDescPtr |
1065 | XkbRF_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 | |
1087 | XkbRF_VarDescPtr |
1088 | XkbRF_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 | |
1099 | XkbRF_DescribeVarsPtr |
1100 | XkbRF_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 | |
1129 | Boolint |
1130 | XkbRF_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 | |
1228 | Boolint |
1229 | XkbRF_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 | |
1263 | XkbRF_RulesPtr |
1264 | XkbRF_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 | |
1283 | XkbRF_RulesPtr |
1284 | XkbRF_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 | |
1313 | static void |
1314 | XkbRF_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 | |
1331 | void |
1332 | XkbRF_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 | |
1398 | Boolint |
1399 | XkbRF_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; |
1455 | } |
1456 | |
1457 | XFree(data); |
1458 | return True1; |
1459 | } |
1460 | |
1461 | Boolint |
1462 | XkbRF_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 |