Imported Upstream version 1.11.4
[ubuntu-omap:xserver.git] / hw / xfree86 / parser / Flags.c
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
55 /* View/edit this file with tab stops set to 4 */
56
57 #ifdef HAVE_XORG_CONFIG_H
58 #include <xorg-config.h>
59 #endif
60
61 #include "xf86Parser.h"
62 #include "xf86tokens.h"
63 #include "Configint.h"
64 #include <X11/Xfuncproto.h>
65 #include "Xprintf.h"
66
67 extern LexRec val;
68
69 static xf86ConfigSymTabRec ServerFlagsTab[] =
70 {
71         {ENDSECTION, "endsection"},
72         {NOTRAPSIGNALS, "notrapsignals"},
73         {DONTZAP, "dontzap"},
74         {DONTZOOM, "dontzoom"},
75         {DISABLEVIDMODE, "disablevidmodeextension"},
76         {ALLOWNONLOCAL, "allownonlocalxvidtune"},
77         {DISABLEMODINDEV, "disablemodindev"},
78         {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"},
79         {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"},
80         {OPTION, "option"},
81         {BLANKTIME, "blanktime"},
82         {STANDBYTIME, "standbytime"},
83         {SUSPENDTIME, "suspendtime"},
84         {OFFTIME, "offtime"},
85         {DEFAULTLAYOUT, "defaultserverlayout"},
86         {-1, ""},
87 };
88
89 #define CLEANUP xf86freeFlags
90
91 XF86ConfFlagsPtr
92 xf86parseFlagsSection (void)
93 {
94         int token;
95         parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
96
97         while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION)
98         {
99                 int hasvalue = FALSE;
100                 int strvalue = FALSE;
101                 int tokentype;
102                 switch (token)
103                 {
104                 case COMMENT:
105                         ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str);
106                         break;
107                         /* 
108                          * these old keywords are turned into standard generic options.
109                          * we fall through here on purpose
110                          */
111                 case DEFAULTLAYOUT:
112                         strvalue = TRUE;
113                 case BLANKTIME:
114                 case STANDBYTIME:
115                 case SUSPENDTIME:
116                 case OFFTIME:
117                         hasvalue = TRUE;
118                 case NOTRAPSIGNALS:
119                 case DONTZAP:
120                 case DONTZOOM:
121                 case DISABLEVIDMODE:
122                 case ALLOWNONLOCAL:
123                 case DISABLEMODINDEV:
124                 case MODINDEVALLOWNONLOCAL:
125                 case ALLOWMOUSEOPENFAIL:
126                         {
127                                 int i = 0;
128                                 while (ServerFlagsTab[i].token != -1)
129                                 {
130                                         char *tmp;
131
132                                         if (ServerFlagsTab[i].token == token)
133                                         {
134                                                 char *valstr = NULL;
135                                                 tmp = strdup (ServerFlagsTab[i].name);
136                                                 if (hasvalue)
137                                                 {
138                                                         tokentype = xf86getSubToken(&(ptr->flg_comment));
139                                                         if (strvalue) {
140                                                                 if (tokentype != STRING)
141                                                                         Error (QUOTE_MSG, tmp);
142                                                                 valstr = val.str;
143                                                         } else {
144                                                                 if (tokentype != NUMBER)
145                                                                         Error (NUMBER_MSG, tmp);
146                                                                 if (asprintf(&valstr, "%d", val.num) == -1)
147                                                                         valstr = NULL;
148                                                         }
149                                                 }
150                                                 ptr->flg_option_lst = xf86addNewOption
151                                                         (ptr->flg_option_lst, tmp, valstr);
152                                         }
153                                         i++;
154                                 }
155                         }
156                         break;
157                 case OPTION:
158                         ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst);
159                         break;
160
161                 case EOF_TOKEN:
162                         Error (UNEXPECTED_EOF_MSG, NULL);
163                         break;
164                 default:
165                         Error (INVALID_KEYWORD_MSG, xf86tokenString ());
166                         break;
167                 }
168         }
169
170 #ifdef DEBUG
171         printf ("Flags section parsed\n");
172 #endif
173
174         return ptr;
175 }
176
177 #undef CLEANUP
178
179 void
180 xf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags)
181 {
182         XF86OptionPtr p;
183
184         if ((!flags) || (!flags->flg_option_lst))
185                 return;
186         p = flags->flg_option_lst;
187         fprintf (f, "Section \"ServerFlags\"\n");
188         if (flags->flg_comment)
189                 fprintf (f, "%s", flags->flg_comment);
190         xf86printOptionList(f, p, 1);
191         fprintf (f, "EndSection\n\n");
192 }
193
194 static XF86OptionPtr
195 addNewOption2 (XF86OptionPtr head, char *name, char *val, int used)
196 {
197         XF86OptionPtr new, old = NULL;
198
199         /* Don't allow duplicates, free old strings */
200         if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
201                 new = old;
202                 free(new->opt_name);
203                 free(new->opt_val);
204         }
205         else
206                 new = calloc (1, sizeof (XF86OptionRec));
207         new->opt_name = name;
208         new->opt_val = val;
209         new->opt_used = used;
210
211         if (old)
212                 return head;
213         return ((XF86OptionPtr) xf86addListItem ((glp) head, (glp) new));
214 }
215
216 XF86OptionPtr
217 xf86addNewOption (XF86OptionPtr head, char *name, char *val)
218 {
219         return addNewOption2(head, name, val, 0);
220 }
221
222 void
223 xf86freeFlags (XF86ConfFlagsPtr flags)
224 {
225         if (flags == NULL)
226                 return;
227         xf86optionListFree (flags->flg_option_lst);
228         TestFree(flags->flg_comment);
229         free (flags);
230 }
231
232 XF86OptionPtr
233 xf86optionListDup (XF86OptionPtr opt)
234 {
235         XF86OptionPtr newopt = NULL;
236         char *val;
237
238         while (opt)
239         {
240                 val = opt->opt_val ? strdup(opt->opt_val) : NULL;
241                 newopt = xf86addNewOption(newopt, strdup(opt->opt_name), val);
242                 newopt->opt_used = opt->opt_used;
243                 if (opt->opt_comment)
244                         newopt->opt_comment = strdup(opt->opt_comment);
245                 opt = opt->list.next;
246         }
247         return newopt;
248 }
249
250 void
251 xf86optionListFree (XF86OptionPtr opt)
252 {
253         XF86OptionPtr prev;
254
255         while (opt)
256         {
257                 TestFree (opt->opt_name);
258                 TestFree (opt->opt_val);
259                 TestFree (opt->opt_comment);
260                 prev = opt;
261                 opt = opt->list.next;
262                 free (prev);
263         }
264 }
265
266 char *
267 xf86optionName(XF86OptionPtr opt)
268 {
269         if (opt)
270                 return opt->opt_name;
271         return 0;
272 }
273
274 char *
275 xf86optionValue(XF86OptionPtr opt)
276 {
277         if (opt)
278                 return opt->opt_val;
279         return 0;
280 }
281
282 XF86OptionPtr
283 xf86newOption(char *name, char *value)
284 {
285         XF86OptionPtr opt;
286
287         opt = calloc(1, sizeof (XF86OptionRec));
288         if (!opt)
289                 return NULL;
290
291         opt->opt_used = 0;
292         opt->list.next = 0;
293         opt->opt_name = name;
294         opt->opt_val = value;
295
296         return opt;
297 }
298
299 XF86OptionPtr
300 xf86nextOption(XF86OptionPtr list)
301 {
302         if (!list)
303                 return NULL;
304         return list->list.next;
305 }
306
307 /*
308  * this function searches the given option list for the named option and
309  * returns a pointer to the option rec if found. If not found, it returns
310  * NULL
311  */
312
313 XF86OptionPtr
314 xf86findOption (XF86OptionPtr list, const char *name)
315 {
316         while (list)
317         {
318                 if (xf86nameCompare (list->opt_name, name) == 0)
319                         return list;
320                 list = list->list.next;
321         }
322         return NULL;
323 }
324
325 /*
326  * this function searches the given option list for the named option. If
327  * found and the option has a parameter, a pointer to the parameter is
328  * returned.  If the option does not have a parameter an empty string is
329  * returned.  If the option is not found, a NULL is returned.
330  */
331
332 char *
333 xf86findOptionValue (XF86OptionPtr list, const char *name)
334 {
335         XF86OptionPtr p = xf86findOption (list, name);
336
337         if (p)
338         {
339                 if (p->opt_val)
340                         return p->opt_val;
341                 else
342                         return "";
343         }
344         return NULL;
345 }
346
347 XF86OptionPtr
348 xf86optionListCreate( const char **options, int count, int used )
349 {
350         XF86OptionPtr p = NULL;
351         char *t1, *t2;
352         int i;
353
354         if (count == -1)
355         {
356                 for (count = 0; options[count]; count++)
357                         ;
358         }
359         if( (count % 2) != 0 )
360         {
361                 fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" );
362                 return NULL;
363         }
364         for (i = 0; i < count; i += 2)
365         {
366                 t1 = strdup(options[i]);
367                 t2 = strdup(options[i + 1]);
368                 p = addNewOption2 (p, t1, t2, used);
369         }
370
371         return p;
372 }
373
374 /* the 2 given lists are merged. If an option with the same name is present in
375  * both, the option from the user list - specified in the second argument -
376  * is used. The end result is a single valid list of options. Duplicates
377  * are freed, and the original lists are no longer guaranteed to be complete.
378  */
379 XF86OptionPtr
380 xf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail)
381 {
382         XF86OptionPtr a, b, ap = NULL, bp = NULL;
383
384         a = tail;
385         b = head;
386         while (tail && b) {
387                 if (xf86nameCompare (a->opt_name, b->opt_name) == 0) {
388                         if (b == head)
389                                 head = a;
390                         else
391                                 bp->list.next = a;
392                         if (a == tail)
393                                 tail = a->list.next;
394                         else
395                                 ap->list.next = a->list.next;
396                         a->list.next = b->list.next;
397                         b->list.next = NULL;
398                         xf86optionListFree (b);
399                         b = a->list.next;
400                         bp = a;
401                         a = tail;
402                         ap = NULL;
403                 } else {
404                         ap = a;
405                         if (!(a = a->list.next)) {
406                                 a = tail;
407                                 bp = b;
408                                 b = b->list.next;
409                                 ap = NULL;
410                         }
411                 }
412         }
413
414         if (head) {
415                 for (a = head; a->list.next; a = a->list.next)
416                         ;
417                 a->list.next = tail;
418         } else 
419                 head = tail;
420
421         return head;
422 }
423
424 char *
425 xf86uLongToString(unsigned long i)
426 {
427         char *s;
428
429         if (asprintf(&s, "%lu", i) == -1)
430                 return NULL;
431         return s;
432 }
433
434 XF86OptionPtr
435 xf86parseOption(XF86OptionPtr head)
436 {
437         XF86OptionPtr option, cnew, old;
438         char *name, *comment = NULL;
439         int token;
440
441         if ((token = xf86getSubToken(&comment)) != STRING) {
442                 xf86parseError(BAD_OPTION_MSG, NULL);
443                 free(comment);
444                 return head;
445         }
446
447         name = val.str;
448         if ((token = xf86getSubToken(&comment)) == STRING) {
449                 option = xf86newOption(name, val.str);
450                 option->opt_comment = comment;
451                 if ((token = xf86getToken(NULL)) == COMMENT)
452                         option->opt_comment = xf86addComment(option->opt_comment, val.str);
453                 else
454                         xf86unGetToken(token);
455         }
456         else {
457                 option = xf86newOption(name, NULL);
458                 option->opt_comment = comment;
459                 if (token == COMMENT)
460                         option->opt_comment = xf86addComment(option->opt_comment, val.str);
461                 else
462                         xf86unGetToken(token);
463         }
464
465         old = NULL;
466
467         /* Don't allow duplicates */
468         if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
469                 cnew = old;
470                 free(option->opt_name);
471                 TestFree(option->opt_val);
472                 TestFree(option->opt_comment);
473                 free(option);
474         }
475         else
476                 cnew = option;
477         
478         if (old == NULL)
479                 return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)cnew));
480
481         return head;
482 }
483
484 void
485 xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs)
486 {
487         int i;
488
489         if (!list)
490                 return;
491         while (list) {
492                 for (i = 0; i < tabs; i++)
493                         fputc('\t', fp);
494                 if (list->opt_val)
495                         fprintf(fp, "Option         \"%s\" \"%s\"", list->opt_name, list->opt_val);
496                 else
497                         fprintf(fp, "Option         \"%s\"", list->opt_name);
498                 if (list->opt_comment)
499                         fprintf(fp, "%s", list->opt_comment);
500                 else
501                         fputc('\n', fp);
502                 list = list->list.next;
503         }
504 }