Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / parser / Flags.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright (c) 1997 Metro Link Incorporated
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 * Except as contained in this notice, the name of the Metro Link shall not be
23 * used in advertising or otherwise to promote the sale, use or other dealings
24 * in this Software without prior written authorization from Metro Link.
25 *
26 */
27/*
28 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
29 *
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
36 *
37 * The above copyright notice and this permission notice shall be included in
38 * all copies or substantial portions of the Software.
39 *
40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
44 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 * OTHER DEALINGS IN THE SOFTWARE.
47 *
48 * Except as contained in this notice, the name of the copyright holder(s)
49 * and author(s) shall not be used in advertising or otherwise to promote
50 * the sale, use or other dealings in this Software without prior written
51 * authorization from the copyright holder(s) and author(s).
52 */
53
54#ifdef HAVE_XORG_CONFIG_H
55#include <xorg-config.h>
56#endif
57
58#include "xf86Parser.h"
59#include "xf86tokens.h"
60#include "Configint.h"
61#include <X11/Xfuncproto.h>
62#include "Xprintf.h"
63#include "optionstr.h"
64
65extern LexRec val;
66
67static xf86ConfigSymTabRec ServerFlagsTab[] = {
68 {ENDSECTION, "endsection"},
69 {NOTRAPSIGNALS, "notrapsignals"},
70 {DONTZAP, "dontzap"},
71 {DONTZOOM, "dontzoom"},
72 {DISABLEVIDMODE, "disablevidmodeextension"},
73 {ALLOWNONLOCAL, "allownonlocalxvidtune"},
74 {DISABLEMODINDEV, "disablemodindev"},
75 {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"},
76 {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"},
77 {OPTION, "option"},
78 {BLANKTIME, "blanktime"},
79 {STANDBYTIME, "standbytime"},
80 {SUSPENDTIME, "suspendtime"},
81 {OFFTIME, "offtime"},
82 {DEFAULTLAYOUT, "defaultserverlayout"},
83 {-1, ""},
84};
85
86#define CLEANUP xf86freeFlags
87
88XF86ConfFlagsPtr
89xf86parseFlagsSection(void)
90{
91 int token;
92
93 parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec)
94
95 while ((token = xf86getToken(ServerFlagsTab)) != ENDSECTION) {
96 int hasvalue = FALSE;
97 int strvalue = FALSE;
98 int tokentype;
99
100 switch (token) {
101 case COMMENT:
102 ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str);
103 break;
104 /*
105 * these old keywords are turned into standard generic options.
106 * we fall through here on purpose
107 */
108 case DEFAULTLAYOUT:
109 strvalue = TRUE;
110 case BLANKTIME:
111 case STANDBYTIME:
112 case SUSPENDTIME:
113 case OFFTIME:
114 hasvalue = TRUE;
115 case NOTRAPSIGNALS:
116 case DONTZAP:
117 case DONTZOOM:
118 case DISABLEVIDMODE:
119 case ALLOWNONLOCAL:
120 case DISABLEMODINDEV:
121 case MODINDEVALLOWNONLOCAL:
122 case ALLOWMOUSEOPENFAIL:
123 {
124 int i = 0;
125
126 while (ServerFlagsTab[i].token != -1) {
127 char *tmp;
128
129 if (ServerFlagsTab[i].token == token) {
130 char *valstr = NULL;
131
132 tmp = strdup(ServerFlagsTab[i].name);
133 if (hasvalue) {
134 tokentype = xf86getSubToken(&(ptr->flg_comment));
135 if (strvalue) {
136 if (tokentype != STRING)
137 Error(QUOTE_MSG, tmp);
138 valstr = val.str;
139 }
140 else {
141 if (tokentype != NUMBER)
142 Error(NUMBER_MSG, tmp);
143 if (asprintf(&valstr, "%d", val.num) == -1)
144 valstr = NULL;
145 }
146 }
147 ptr->flg_option_lst = xf86addNewOption
148 (ptr->flg_option_lst, tmp, valstr);
149 }
150 i++;
151 }
152 }
153 break;
154 case OPTION:
155 ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst);
156 break;
157
158 case EOF_TOKEN:
159 Error(UNEXPECTED_EOF_MSG);
160 break;
161 default:
162 Error(INVALID_KEYWORD_MSG, xf86tokenString());
163 break;
164 }
165 }
166
167#ifdef DEBUG
168 printf("Flags section parsed\n");
169#endif
170
171 return ptr;
172}
173
174#undef CLEANUP
175
176void
177xf86printServerFlagsSection(FILE * f, XF86ConfFlagsPtr flags)
178{
179 XF86OptionPtr p;
180
181 if ((!flags) || (!flags->flg_option_lst))
182 return;
183 p = flags->flg_option_lst;
184 fprintf(f, "Section \"ServerFlags\"\n");
185 if (flags->flg_comment)
186 fprintf(f, "%s", flags->flg_comment);
187 xf86printOptionList(f, p, 1);
188 fprintf(f, "EndSection\n\n");
189}
190
191static XF86OptionPtr
192addNewOption2(XF86OptionPtr head, char *name, char *val, int used)
193{
194 XF86OptionPtr new, old = NULL;
195
196 /* Don't allow duplicates, free old strings */
197 if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
198 new = old;
199 free(new->opt_name);
200 free(new->opt_val);
201 }
202 else
203 new = calloc(1, sizeof(*new));
204 new->opt_name = name;
205 new->opt_val = val;
206 new->opt_used = used;
207
208 if (old)
209 return head;
210 return ((XF86OptionPtr) xf86addListItem((glp) head, (glp) new));
211}
212
213XF86OptionPtr
214xf86addNewOption(XF86OptionPtr head, char *name, char *val)
215{
216 return addNewOption2(head, name, val, 0);
217}
218
219void
220xf86freeFlags(XF86ConfFlagsPtr flags)
221{
222 if (flags == NULL)
223 return;
224 xf86optionListFree(flags->flg_option_lst);
225 TestFree(flags->flg_comment);
226 free(flags);
227}
228
229XF86OptionPtr
230xf86optionListDup(XF86OptionPtr opt)
231{
232 XF86OptionPtr newopt = NULL;
233 char *val;
234
235 while (opt) {
236 val = opt->opt_val ? strdup(opt->opt_val) : NULL;
237 newopt = xf86addNewOption(newopt, strdup(opt->opt_name), val);
238 newopt->opt_used = opt->opt_used;
239 if (opt->opt_comment)
240 newopt->opt_comment = strdup(opt->opt_comment);
241 opt = opt->list.next;
242 }
243 return newopt;
244}
245
246void
247xf86optionListFree(XF86OptionPtr opt)
248{
249 XF86OptionPtr prev;
250
251 while (opt) {
252 TestFree(opt->opt_name);
253 TestFree(opt->opt_val);
254 TestFree(opt->opt_comment);
255 prev = opt;
256 opt = opt->list.next;
257 free(prev);
258 }
259}
260
261char *
262xf86optionName(XF86OptionPtr opt)
263{
264 if (opt)
265 return opt->opt_name;
266 return 0;
267}
268
269char *
270xf86optionValue(XF86OptionPtr opt)
271{
272 if (opt)
273 return opt->opt_val;
274 return 0;
275}
276
277XF86OptionPtr
278xf86newOption(char *name, char *value)
279{
280 XF86OptionPtr opt;
281
282 opt = calloc(1, sizeof(*opt));
283 if (!opt)
284 return NULL;
285
286 opt->opt_used = 0;
287 opt->list.next = 0;
288 opt->opt_name = name;
289 opt->opt_val = value;
290
291 return opt;
292}
293
294XF86OptionPtr
295xf86nextOption(XF86OptionPtr list)
296{
297 if (!list)
298 return NULL;
299 return list->list.next;
300}
301
302/*
303 * this function searches the given option list for the named option and
304 * returns a pointer to the option rec if found. If not found, it returns
305 * NULL
306 */
307
308XF86OptionPtr
309xf86findOption(XF86OptionPtr list, const char *name)
310{
311 while (list) {
312 if (xf86nameCompare(list->opt_name, name) == 0)
313 return list;
314 list = list->list.next;
315 }
316 return NULL;
317}
318
319/*
320 * this function searches the given option list for the named option. If
321 * found and the option has a parameter, a pointer to the parameter is
322 * returned. If the option does not have a parameter an empty string is
323 * returned. If the option is not found, a NULL is returned.
324 */
325
326const char *
327xf86findOptionValue(XF86OptionPtr list, const char *name)
328{
329 XF86OptionPtr p = xf86findOption(list, name);
330
331 if (p) {
332 if (p->opt_val)
333 return p->opt_val;
334 else
335 return "";
336 }
337 return NULL;
338}
339
340XF86OptionPtr
341xf86optionListCreate(const char **options, int count, int used)
342{
343 XF86OptionPtr p = NULL;
344 char *t1, *t2;
345 int i;
346
347 if (count == -1) {
348 for (count = 0; options[count]; count++);
349 }
350 if ((count % 2) != 0) {
351 fprintf(stderr,
352 "xf86optionListCreate: count must be an even number.\n");
353 return NULL;
354 }
355 for (i = 0; i < count; i += 2) {
356 t1 = strdup(options[i]);
357 t2 = strdup(options[i + 1]);
358 p = addNewOption2(p, t1, t2, used);
359 }
360
361 return p;
362}
363
364/* the 2 given lists are merged. If an option with the same name is present in
365 * both, the option from the user list - specified in the second argument -
366 * is used. The end result is a single valid list of options. Duplicates
367 * are freed, and the original lists are no longer guaranteed to be complete.
368 */
369XF86OptionPtr
370xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail)
371{
372 XF86OptionPtr a, b, ap = NULL, bp = NULL;
373
374 a = tail;
375 b = head;
376 while (tail && b) {
377 if (xf86nameCompare(a->opt_name, b->opt_name) == 0) {
378 if (b == head)
379 head = a;
380 else
381 bp->list.next = a;
382 if (a == tail)
383 tail = a->list.next;
384 else
385 ap->list.next = a->list.next;
386 a->list.next = b->list.next;
387 b->list.next = NULL;
388 xf86optionListFree(b);
389 b = a->list.next;
390 bp = a;
391 a = tail;
392 ap = NULL;
393 }
394 else {
395 ap = a;
396 if (!(a = a->list.next)) {
397 a = tail;
398 bp = b;
399 b = b->list.next;
400 ap = NULL;
401 }
402 }
403 }
404
405 if (head) {
406 for (a = head; a->list.next; a = a->list.next);
407 a->list.next = tail;
408 }
409 else
410 head = tail;
411
412 return head;
413}
414
415char *
416xf86uLongToString(unsigned long i)
417{
418 char *s;
419
420 if (asprintf(&s, "%lu", i) == -1)
421 return NULL;
422 return s;
423}
424
425XF86OptionPtr
426xf86parseOption(XF86OptionPtr head)
427{
428 XF86OptionPtr option, cnew, old;
429 char *name, *comment = NULL;
430 int token;
431
432 if ((token = xf86getSubToken(&comment)) != STRING) {
433 xf86parseError(BAD_OPTION_MSG);
434 free(comment);
435 return head;
436 }
437
438 name = val.str;
439 if ((token = xf86getSubToken(&comment)) == STRING) {
440 option = xf86newOption(name, val.str);
441 option->opt_comment = comment;
442 if ((token = xf86getToken(NULL)) == COMMENT)
443 option->opt_comment = xf86addComment(option->opt_comment, val.str);
444 else
445 xf86unGetToken(token);
446 }
447 else {
448 option = xf86newOption(name, NULL);
449 option->opt_comment = comment;
450 if (token == COMMENT)
451 option->opt_comment = xf86addComment(option->opt_comment, val.str);
452 else
453 xf86unGetToken(token);
454 }
455
456 old = NULL;
457
458 /* Don't allow duplicates */
459 if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
460 cnew = old;
461 free(option->opt_name);
462 TestFree(option->opt_val);
463 TestFree(option->opt_comment);
464 free(option);
465 }
466 else
467 cnew = option;
468
469 if (old == NULL)
470 return ((XF86OptionPtr) xf86addListItem((glp) head, (glp) cnew));
471
472 return head;
473}
474
475void
476xf86printOptionList(FILE * fp, XF86OptionPtr list, int tabs)
477{
478 int i;
479
480 if (!list)
481 return;
482 while (list) {
483 for (i = 0; i < tabs; i++)
484 fputc('\t', fp);
485 if (list->opt_val)
486 fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name,
487 list->opt_val);
488 else
489 fprintf(fp, "Option \"%s\"", list->opt_name);
490 if (list->opt_comment)
491 fprintf(fp, "%s", list->opt_comment);
492 else
493 fputc('\n', fp);
494 list = list->list.next;
495 }
496}