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