read.c revision 35c4bbdf
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#ifdef HAVE_XORG_CONFIG_H
56#include <xorg-config.h>
57#endif
58
59#include "xf86Parser.h"
60#include "xf86tokens.h"
61#include "Configint.h"
62
63
64static xf86ConfigSymTabRec TopLevelTab[] = {
65    {SECTION, "section"},
66    {-1, ""},
67};
68
69#define CLEANUP xf86freeConfig
70
71/*
72 * This function resolves name references and reports errors if the named
73 * objects cannot be found.
74 */
75static int
76xf86validateConfig(XF86ConfigPtr p)
77{
78    if (!xf86validateScreen(p))
79        return FALSE;
80    if (!xf86validateInput(p))
81        return FALSE;
82    if (!xf86validateLayout(p))
83        return FALSE;
84
85    return TRUE;
86}
87
88XF86ConfigPtr
89xf86readConfigFile(void)
90{
91    int token;
92    XF86ConfigPtr ptr = NULL;
93
94    if ((ptr = calloc(1, sizeof(XF86ConfigRec))) == NULL) {
95        return NULL;
96    }
97
98    while ((token = xf86getToken(TopLevelTab)) != EOF_TOKEN) {
99        switch (token) {
100        case COMMENT:
101            ptr->conf_comment = xf86addComment(ptr->conf_comment, xf86_lex_val.str);
102            break;
103        case SECTION:
104            if (xf86getSubToken(&(ptr->conf_comment)) != STRING) {
105                xf86parseError(QUOTE_MSG, "Section");
106                CLEANUP(ptr);
107                return NULL;
108            }
109            xf86setSection(xf86_lex_val.str);
110            if (xf86nameCompare(xf86_lex_val.str, "files") == 0) {
111                free(xf86_lex_val.str);
112                xf86_lex_val.str = NULL;
113                HANDLE_RETURN(conf_files, xf86parseFilesSection());
114            }
115            else if (xf86nameCompare(xf86_lex_val.str, "serverflags") == 0) {
116                free(xf86_lex_val.str);
117                xf86_lex_val.str = NULL;
118                HANDLE_RETURN(conf_flags, xf86parseFlagsSection());
119            }
120            else if (xf86nameCompare(xf86_lex_val.str, "pointer") == 0) {
121                free(xf86_lex_val.str);
122                xf86_lex_val.str = NULL;
123                HANDLE_LIST(conf_input_lst, xf86parsePointerSection,
124                            XF86ConfInputPtr);
125            }
126            else if (xf86nameCompare(xf86_lex_val.str, "videoadaptor") == 0) {
127                free(xf86_lex_val.str);
128                xf86_lex_val.str = NULL;
129                HANDLE_LIST(conf_videoadaptor_lst, xf86parseVideoAdaptorSection,
130                            XF86ConfVideoAdaptorPtr);
131            }
132            else if (xf86nameCompare(xf86_lex_val.str, "device") == 0) {
133                free(xf86_lex_val.str);
134                xf86_lex_val.str = NULL;
135                HANDLE_LIST(conf_device_lst, xf86parseDeviceSection,
136                            XF86ConfDevicePtr);
137            }
138            else if (xf86nameCompare(xf86_lex_val.str, "monitor") == 0) {
139                free(xf86_lex_val.str);
140                xf86_lex_val.str = NULL;
141                HANDLE_LIST(conf_monitor_lst, xf86parseMonitorSection,
142                            XF86ConfMonitorPtr);
143            }
144            else if (xf86nameCompare(xf86_lex_val.str, "modes") == 0) {
145                free(xf86_lex_val.str);
146                xf86_lex_val.str = NULL;
147                HANDLE_LIST(conf_modes_lst, xf86parseModesSection,
148                            XF86ConfModesPtr);
149            }
150            else if (xf86nameCompare(xf86_lex_val.str, "screen") == 0) {
151                free(xf86_lex_val.str);
152                xf86_lex_val.str = NULL;
153                HANDLE_LIST(conf_screen_lst, xf86parseScreenSection,
154                            XF86ConfScreenPtr);
155            }
156            else if (xf86nameCompare(xf86_lex_val.str, "inputdevice") == 0) {
157                free(xf86_lex_val.str);
158                xf86_lex_val.str = NULL;
159                HANDLE_LIST(conf_input_lst, xf86parseInputSection,
160                            XF86ConfInputPtr);
161            }
162            else if (xf86nameCompare(xf86_lex_val.str, "inputclass") == 0) {
163                free(xf86_lex_val.str);
164                xf86_lex_val.str = NULL;
165                HANDLE_LIST(conf_inputclass_lst,
166                            xf86parseInputClassSection, XF86ConfInputClassPtr);
167            }
168            else if (xf86nameCompare(xf86_lex_val.str, "outputclass") == 0) {
169                free(xf86_lex_val.str);
170                xf86_lex_val.str = NULL;
171                HANDLE_LIST(conf_outputclass_lst, xf86parseOutputClassSection,
172                            XF86ConfOutputClassPtr);
173            }
174            else if (xf86nameCompare(xf86_lex_val.str, "module") == 0) {
175                free(xf86_lex_val.str);
176                xf86_lex_val.str = NULL;
177                HANDLE_RETURN(conf_modules, xf86parseModuleSection());
178            }
179            else if (xf86nameCompare(xf86_lex_val.str, "serverlayout") == 0) {
180                free(xf86_lex_val.str);
181                xf86_lex_val.str = NULL;
182                HANDLE_LIST(conf_layout_lst, xf86parseLayoutSection,
183                            XF86ConfLayoutPtr);
184            }
185            else if (xf86nameCompare(xf86_lex_val.str, "vendor") == 0) {
186                free(xf86_lex_val.str);
187                xf86_lex_val.str = NULL;
188                HANDLE_LIST(conf_vendor_lst, xf86parseVendorSection,
189                            XF86ConfVendorPtr);
190            }
191            else if (xf86nameCompare(xf86_lex_val.str, "dri") == 0) {
192                free(xf86_lex_val.str);
193                xf86_lex_val.str = NULL;
194                HANDLE_RETURN(conf_dri, xf86parseDRISection());
195            }
196            else if (xf86nameCompare(xf86_lex_val.str, "extensions") == 0) {
197                free(xf86_lex_val.str);
198                xf86_lex_val.str = NULL;
199                HANDLE_RETURN(conf_extensions, xf86parseExtensionsSection());
200            }
201            else {
202                free(xf86_lex_val.str);
203                xf86_lex_val.str = NULL;
204                Error(INVALID_SECTION_MSG, xf86tokenString());
205            }
206            break;
207        default:
208            free(xf86_lex_val.str);
209            xf86_lex_val.str = NULL;
210            Error(INVALID_KEYWORD_MSG, xf86tokenString());
211        }
212    }
213
214    if (xf86validateConfig(ptr))
215        return ptr;
216    else {
217        CLEANUP(ptr);
218        return NULL;
219    }
220}
221
222#undef CLEANUP
223
224/*
225 * adds an item to the end of the linked list. Any record whose first field
226 * is a GenericListRec can be cast to this type and used with this function.
227 * A pointer to the head of the list is returned to handle the addition of
228 * the first item.
229 */
230GenericListPtr
231xf86addListItem(GenericListPtr head, GenericListPtr new)
232{
233    GenericListPtr p = head;
234    GenericListPtr last = NULL;
235
236    while (p) {
237        last = p;
238        p = p->next;
239    }
240
241    if (last) {
242        last->next = new;
243        return head;
244    }
245    else
246        return new;
247}
248
249/*
250 * Test if one chained list contains the other.
251 * In this case both list have the same endpoint (provided they don't loop)
252 */
253int
254xf86itemNotSublist(GenericListPtr list_1, GenericListPtr list_2)
255{
256    GenericListPtr p = list_1;
257    GenericListPtr last_1 = NULL, last_2 = NULL;
258
259    while (p) {
260        last_1 = p;
261        p = p->next;
262    }
263
264    p = list_2;
265    while (p) {
266        last_2 = p;
267        p = p->next;
268    }
269
270    return (!(last_1 == last_2));
271}
272
273void
274xf86freeConfig(XF86ConfigPtr p)
275{
276    if (p == NULL)
277        return;
278
279    xf86freeFiles(p->conf_files);
280    xf86freeModules(p->conf_modules);
281    xf86freeFlags(p->conf_flags);
282    xf86freeMonitorList(p->conf_monitor_lst);
283    xf86freeModesList(p->conf_modes_lst);
284    xf86freeVideoAdaptorList(p->conf_videoadaptor_lst);
285    xf86freeDeviceList(p->conf_device_lst);
286    xf86freeScreenList(p->conf_screen_lst);
287    xf86freeLayoutList(p->conf_layout_lst);
288    xf86freeInputList(p->conf_input_lst);
289    xf86freeVendorList(p->conf_vendor_lst);
290    xf86freeDRI(p->conf_dri);
291    xf86freeExtensions(p->conf_extensions);
292    TestFree(p->conf_comment);
293
294    free(p);
295}
296