File: | maprules.c |
Location: | line 1431, column 12 |
Description: | Null pointer argument in call to string length function |
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; | |||
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 |