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