1706f2543Smrg/*
2706f2543Smrg *
3706f2543Smrg * Copyright (c) 1997  Metro Link Incorporated
4706f2543Smrg *
5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6706f2543Smrg * copy of this software and associated documentation files (the "Software"),
7706f2543Smrg * to deal in the Software without restriction, including without limitation
8706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
10706f2543Smrg * Software is furnished to do so, subject to the following conditions:
11706f2543Smrg *
12706f2543Smrg * The above copyright notice and this permission notice shall be included in
13706f2543Smrg * all copies or substantial portions of the Software.
14706f2543Smrg *
15706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18706f2543Smrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21706f2543Smrg * SOFTWARE.
22706f2543Smrg *
23706f2543Smrg * Except as contained in this notice, the name of the Metro Link shall not be
24706f2543Smrg * used in advertising or otherwise to promote the sale, use or other dealings
25706f2543Smrg * in this Software without prior written authorization from Metro Link.
26706f2543Smrg *
27706f2543Smrg */
28706f2543Smrg/*
29706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
30706f2543Smrg *
31706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
32706f2543Smrg * copy of this software and associated documentation files (the "Software"),
33706f2543Smrg * to deal in the Software without restriction, including without limitation
34706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
36706f2543Smrg * Software is furnished to do so, subject to the following conditions:
37706f2543Smrg *
38706f2543Smrg * The above copyright notice and this permission notice shall be included in
39706f2543Smrg * all copies or substantial portions of the Software.
40706f2543Smrg *
41706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
44706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
45706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
48706f2543Smrg *
49706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
50706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
51706f2543Smrg * the sale, use or other dealings in this Software without prior written
52706f2543Smrg * authorization from the copyright holder(s) and author(s).
53706f2543Smrg */
54706f2543Smrg
55706f2543Smrg
56706f2543Smrg/* View/edit this file with tab stops set to 4 */
57706f2543Smrg
58706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
59706f2543Smrg#include <xorg-config.h>
60706f2543Smrg#endif
61706f2543Smrg
62706f2543Smrg#include "xf86Parser.h"
63706f2543Smrg#include "xf86tokens.h"
64706f2543Smrg#include "Configint.h"
65706f2543Smrg
66706f2543Smrgextern LexRec val;
67706f2543Smrg
68706f2543Smrgstatic xf86ConfigSymTabRec TopLevelTab[] =
69706f2543Smrg{
70706f2543Smrg	{SECTION, "section"},
71706f2543Smrg	{-1, ""},
72706f2543Smrg};
73706f2543Smrg
74706f2543Smrg#define CLEANUP xf86freeConfig
75706f2543Smrg
76706f2543Smrg/*
77706f2543Smrg * This function resolves name references and reports errors if the named
78706f2543Smrg * objects cannot be found.
79706f2543Smrg */
80706f2543Smrgstatic int
81706f2543Smrgxf86validateConfig (XF86ConfigPtr p)
82706f2543Smrg{
83706f2543Smrg	if (!xf86validateScreen (p))
84706f2543Smrg		return FALSE;
85706f2543Smrg	if (!xf86validateInput (p))
86706f2543Smrg		return FALSE;
87706f2543Smrg	if (!xf86validateLayout (p))
88706f2543Smrg		return FALSE;
89706f2543Smrg
90706f2543Smrg	return TRUE;
91706f2543Smrg}
92706f2543Smrg
93706f2543SmrgXF86ConfigPtr
94706f2543Smrgxf86readConfigFile (void)
95706f2543Smrg{
96706f2543Smrg	int token;
97706f2543Smrg	XF86ConfigPtr ptr = NULL;
98706f2543Smrg
99706f2543Smrg	if ((ptr = calloc (1, sizeof (XF86ConfigRec))) == NULL)
100706f2543Smrg	{
101706f2543Smrg		return NULL;
102706f2543Smrg	}
103706f2543Smrg
104706f2543Smrg	while ((token = xf86getToken (TopLevelTab)) != EOF_TOKEN)
105706f2543Smrg	{
106706f2543Smrg		switch (token)
107706f2543Smrg		{
108706f2543Smrg		case COMMENT:
109706f2543Smrg			ptr->conf_comment = xf86addComment(ptr->conf_comment, val.str);
110706f2543Smrg			break;
111706f2543Smrg		case SECTION:
112706f2543Smrg			if (xf86getSubToken (&(ptr->conf_comment)) != STRING)
113706f2543Smrg			{
114706f2543Smrg				xf86parseError (QUOTE_MSG, "Section");
115706f2543Smrg				CLEANUP (ptr);
116706f2543Smrg				return NULL;
117706f2543Smrg			}
118706f2543Smrg			xf86setSection (val.str);
119706f2543Smrg			if (xf86nameCompare (val.str, "files") == 0)
120706f2543Smrg			{
121706f2543Smrg				free(val.str);
122706f2543Smrg				val.str = NULL;
123706f2543Smrg				HANDLE_RETURN (conf_files, xf86parseFilesSection ());
124706f2543Smrg			}
125706f2543Smrg			else if (xf86nameCompare (val.str, "serverflags") == 0)
126706f2543Smrg			{
127706f2543Smrg				free(val.str);
128706f2543Smrg				val.str = NULL;
129706f2543Smrg				HANDLE_RETURN (conf_flags, xf86parseFlagsSection ());
130706f2543Smrg			}
131706f2543Smrg			else if (xf86nameCompare (val.str, "pointer") == 0)
132706f2543Smrg			{
133706f2543Smrg				free(val.str);
134706f2543Smrg				val.str = NULL;
135706f2543Smrg				HANDLE_LIST (conf_input_lst, xf86parsePointerSection,
136706f2543Smrg							 XF86ConfInputPtr);
137706f2543Smrg			}
138706f2543Smrg			else if (xf86nameCompare (val.str, "videoadaptor") == 0)
139706f2543Smrg			{
140706f2543Smrg				free(val.str);
141706f2543Smrg				val.str = NULL;
142706f2543Smrg				HANDLE_LIST (conf_videoadaptor_lst, xf86parseVideoAdaptorSection,
143706f2543Smrg							 XF86ConfVideoAdaptorPtr);
144706f2543Smrg			}
145706f2543Smrg			else if (xf86nameCompare (val.str, "device") == 0)
146706f2543Smrg			{
147706f2543Smrg				free(val.str);
148706f2543Smrg				val.str = NULL;
149706f2543Smrg				HANDLE_LIST (conf_device_lst, xf86parseDeviceSection,
150706f2543Smrg							 XF86ConfDevicePtr);
151706f2543Smrg			}
152706f2543Smrg			else if (xf86nameCompare (val.str, "monitor") == 0)
153706f2543Smrg			{
154706f2543Smrg				free(val.str);
155706f2543Smrg				val.str = NULL;
156706f2543Smrg				HANDLE_LIST (conf_monitor_lst, xf86parseMonitorSection,
157706f2543Smrg							 XF86ConfMonitorPtr);
158706f2543Smrg			}
159706f2543Smrg			else if (xf86nameCompare (val.str, "modes") == 0)
160706f2543Smrg			{
161706f2543Smrg				free(val.str);
162706f2543Smrg				val.str = NULL;
163706f2543Smrg				HANDLE_LIST (conf_modes_lst, xf86parseModesSection,
164706f2543Smrg							 XF86ConfModesPtr);
165706f2543Smrg			}
166706f2543Smrg			else if (xf86nameCompare (val.str, "screen") == 0)
167706f2543Smrg			{
168706f2543Smrg				free(val.str);
169706f2543Smrg				val.str = NULL;
170706f2543Smrg				HANDLE_LIST (conf_screen_lst, xf86parseScreenSection,
171706f2543Smrg							 XF86ConfScreenPtr);
172706f2543Smrg			}
173706f2543Smrg			else if (xf86nameCompare(val.str, "inputdevice") == 0)
174706f2543Smrg			{
175706f2543Smrg				free(val.str);
176706f2543Smrg				val.str = NULL;
177706f2543Smrg				HANDLE_LIST (conf_input_lst, xf86parseInputSection,
178706f2543Smrg							 XF86ConfInputPtr);
179706f2543Smrg			}
180706f2543Smrg			else if (xf86nameCompare(val.str, "inputclass") == 0)
181706f2543Smrg			{
182706f2543Smrg				free(val.str);
183706f2543Smrg				val.str = NULL;
184706f2543Smrg				HANDLE_LIST (conf_inputclass_lst,
185706f2543Smrg						xf86parseInputClassSection,
186706f2543Smrg						XF86ConfInputClassPtr);
187706f2543Smrg			}
188706f2543Smrg			else if (xf86nameCompare (val.str, "module") == 0)
189706f2543Smrg			{
190706f2543Smrg				free(val.str);
191706f2543Smrg				val.str = NULL;
192706f2543Smrg				HANDLE_RETURN (conf_modules, xf86parseModuleSection ());
193706f2543Smrg			}
194706f2543Smrg			else if (xf86nameCompare (val.str, "serverlayout") == 0)
195706f2543Smrg			{
196706f2543Smrg				free(val.str);
197706f2543Smrg				val.str = NULL;
198706f2543Smrg				HANDLE_LIST (conf_layout_lst, xf86parseLayoutSection,
199706f2543Smrg							 XF86ConfLayoutPtr);
200706f2543Smrg			}
201706f2543Smrg			else if (xf86nameCompare (val.str, "vendor") == 0)
202706f2543Smrg			{
203706f2543Smrg				free(val.str);
204706f2543Smrg				val.str = NULL;
205706f2543Smrg				HANDLE_LIST (conf_vendor_lst, xf86parseVendorSection,
206706f2543Smrg							 XF86ConfVendorPtr);
207706f2543Smrg			}
208706f2543Smrg			else if (xf86nameCompare (val.str, "dri") == 0)
209706f2543Smrg			{
210706f2543Smrg				free(val.str);
211706f2543Smrg				val.str = NULL;
212706f2543Smrg				HANDLE_RETURN (conf_dri, xf86parseDRISection ());
213706f2543Smrg			}
214706f2543Smrg			else if (xf86nameCompare (val.str, "extensions") == 0)
215706f2543Smrg			{
216706f2543Smrg				free(val.str);
217706f2543Smrg				val.str = NULL;
218706f2543Smrg				HANDLE_RETURN (conf_extensions, xf86parseExtensionsSection ());
219706f2543Smrg			}
220706f2543Smrg			else
221706f2543Smrg			{
222706f2543Smrg				free(val.str);
223706f2543Smrg				val.str = NULL;
224706f2543Smrg				Error (INVALID_SECTION_MSG, xf86tokenString ());
225706f2543Smrg			}
226706f2543Smrg			break;
227706f2543Smrg		default:
228706f2543Smrg			free(val.str);
229706f2543Smrg			val.str = NULL;
230706f2543Smrg			Error (INVALID_KEYWORD_MSG, xf86tokenString ());
231706f2543Smrg		}
232706f2543Smrg	}
233706f2543Smrg
234706f2543Smrg	if (xf86validateConfig (ptr))
235706f2543Smrg		return ptr;
236706f2543Smrg	else
237706f2543Smrg	{
238706f2543Smrg		CLEANUP (ptr);
239706f2543Smrg		return NULL;
240706f2543Smrg	}
241706f2543Smrg}
242706f2543Smrg
243706f2543Smrg#undef CLEANUP
244706f2543Smrg
245706f2543Smrg/*
246706f2543Smrg * adds an item to the end of the linked list. Any record whose first field
247706f2543Smrg * is a GenericListRec can be cast to this type and used with this function.
248706f2543Smrg * A pointer to the head of the list is returned to handle the addition of
249706f2543Smrg * the first item.
250706f2543Smrg */
251706f2543SmrgGenericListPtr
252706f2543Smrgxf86addListItem (GenericListPtr head, GenericListPtr new)
253706f2543Smrg{
254706f2543Smrg	GenericListPtr p = head;
255706f2543Smrg	GenericListPtr last = NULL;
256706f2543Smrg
257706f2543Smrg	while (p)
258706f2543Smrg	{
259706f2543Smrg		last = p;
260706f2543Smrg		p = p->next;
261706f2543Smrg	}
262706f2543Smrg
263706f2543Smrg	if (last)
264706f2543Smrg	{
265706f2543Smrg		last->next = new;
266706f2543Smrg		return head;
267706f2543Smrg	}
268706f2543Smrg	else
269706f2543Smrg		return new;
270706f2543Smrg}
271706f2543Smrg
272706f2543Smrg/*
273706f2543Smrg * Test if one chained list contains the other.
274706f2543Smrg * In this case both list have the same endpoint (provided they don't loop)
275706f2543Smrg */
276706f2543Smrgint
277706f2543Smrgxf86itemNotSublist(GenericListPtr list_1, GenericListPtr list_2)
278706f2543Smrg{
279706f2543Smrg	GenericListPtr p = list_1;
280706f2543Smrg	GenericListPtr last_1 = NULL, last_2 = NULL;
281706f2543Smrg
282706f2543Smrg	while (p) {
283706f2543Smrg		last_1 = p;
284706f2543Smrg		p = p->next;
285706f2543Smrg	}
286706f2543Smrg
287706f2543Smrg	p = list_2;
288706f2543Smrg	while (p) {
289706f2543Smrg		last_2 = p;
290706f2543Smrg		p = p->next;
291706f2543Smrg	}
292706f2543Smrg
293706f2543Smrg	return (!(last_1 == last_2));
294706f2543Smrg}
295706f2543Smrg
296706f2543Smrgvoid
297706f2543Smrgxf86freeConfig (XF86ConfigPtr p)
298706f2543Smrg{
299706f2543Smrg	if (p == NULL)
300706f2543Smrg		return;
301706f2543Smrg
302706f2543Smrg	xf86freeFiles (p->conf_files);
303706f2543Smrg	xf86freeModules (p->conf_modules);
304706f2543Smrg	xf86freeFlags (p->conf_flags);
305706f2543Smrg	xf86freeMonitorList (p->conf_monitor_lst);
306706f2543Smrg	xf86freeModesList (p->conf_modes_lst);
307706f2543Smrg	xf86freeVideoAdaptorList (p->conf_videoadaptor_lst);
308706f2543Smrg	xf86freeDeviceList (p->conf_device_lst);
309706f2543Smrg	xf86freeScreenList (p->conf_screen_lst);
310706f2543Smrg	xf86freeLayoutList (p->conf_layout_lst);
311706f2543Smrg	xf86freeInputList (p->conf_input_lst);
312706f2543Smrg	xf86freeVendorList (p->conf_vendor_lst);
313706f2543Smrg	xf86freeDRI (p->conf_dri);
314706f2543Smrg	xf86freeExtensions (p->conf_extensions);
315706f2543Smrg	TestFree(p->conf_comment);
316706f2543Smrg
317706f2543Smrg	free (p);
318706f2543Smrg}
319