xref: /OK3568_Linux_fs/external/xserver/hw/dmx/config/dmxparse.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2002 Red Hat Inc., Durham, North Carolina.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * All Rights Reserved.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining
7*4882a593Smuzhiyun  * a copy of this software and associated documentation files (the
8*4882a593Smuzhiyun  * "Software"), to deal in the Software without restriction, including
9*4882a593Smuzhiyun  * without limitation on the rights to use, copy, modify, merge,
10*4882a593Smuzhiyun  * publish, distribute, sublicense, and/or sell copies of the Software,
11*4882a593Smuzhiyun  * and to permit persons to whom the Software is furnished to do so,
12*4882a593Smuzhiyun  * subject to the following conditions:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * The above copyright notice and this permission notice (including the
15*4882a593Smuzhiyun  * next paragraph) shall be included in all copies or substantial
16*4882a593Smuzhiyun  * portions of the Software.
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19*4882a593Smuzhiyun  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*4882a593Smuzhiyun  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21*4882a593Smuzhiyun  * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22*4882a593Smuzhiyun  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23*4882a593Smuzhiyun  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24*4882a593Smuzhiyun  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25*4882a593Smuzhiyun  * SOFTWARE.
26*4882a593Smuzhiyun  */
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun  * Authors:
30*4882a593Smuzhiyun  *   Rickard E. (Rik) Faith <faith@redhat.com>
31*4882a593Smuzhiyun  *
32*4882a593Smuzhiyun  */
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /** \file
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * This file provides support routines and helper functions to be used
37*4882a593Smuzhiyun  * by the DMX configuration file parser.
38*4882a593Smuzhiyun  *
39*4882a593Smuzhiyun  * Because the DMX configuration file parsing should be capable of being
40*4882a593Smuzhiyun  * used in a stand-alone fashion (i.e., independent from the DMX server
41*4882a593Smuzhiyun  * source tree), no dependencies on other DMX routines are made. */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #ifdef HAVE_DMX_CONFIG_H
44*4882a593Smuzhiyun #include <dmx-config.h>
45*4882a593Smuzhiyun #endif
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #include <stdio.h>
48*4882a593Smuzhiyun #include <stdlib.h>
49*4882a593Smuzhiyun #include <string.h>
50*4882a593Smuzhiyun #include <stdarg.h>
51*4882a593Smuzhiyun #include "dmxparse.h"
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /** A general error logging routine that does not depend on the dmxLog
54*4882a593Smuzhiyun  * functions. */
55*4882a593Smuzhiyun void
dmxConfigLog(const char * format,...)56*4882a593Smuzhiyun dmxConfigLog(const char *format, ...)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun     va_list args;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun     va_start(args, format);
61*4882a593Smuzhiyun     vprintf(format, args);      /* RATS: All calls to dmxConfigLog from
62*4882a593Smuzhiyun                                  * dmxparse.c and dmxprint.c use a
63*4882a593Smuzhiyun                                  * trusted format. */
64*4882a593Smuzhiyun     va_end(args);
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun void *
dmxConfigAlloc(unsigned long bytes)68*4882a593Smuzhiyun dmxConfigAlloc(unsigned long bytes)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun     void *area = calloc(1, bytes);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun     if (!area) {
73*4882a593Smuzhiyun         dmxConfigLog("dmxConfigAlloc: out of memory\n");
74*4882a593Smuzhiyun         return NULL;
75*4882a593Smuzhiyun     }
76*4882a593Smuzhiyun     return area;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun void *
dmxConfigRealloc(void * orig,unsigned long orig_bytes,unsigned long bytes)80*4882a593Smuzhiyun dmxConfigRealloc(void *orig, unsigned long orig_bytes, unsigned long bytes)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun     unsigned char *area = realloc(orig, bytes);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun     if (!area) {
85*4882a593Smuzhiyun         dmxConfigLog("dmxConfigRealloc: out of memory\n");
86*4882a593Smuzhiyun         return NULL;
87*4882a593Smuzhiyun     }
88*4882a593Smuzhiyun     memset(area + orig_bytes, 0, bytes - orig_bytes);
89*4882a593Smuzhiyun     return area;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun const char *
dmxConfigCopyString(const char * string,int length)93*4882a593Smuzhiyun dmxConfigCopyString(const char *string, int length)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun     char *copy;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun     if (!length)
98*4882a593Smuzhiyun         length = strlen(string);
99*4882a593Smuzhiyun     copy = dmxConfigAlloc(length + 1);
100*4882a593Smuzhiyun     if (length)
101*4882a593Smuzhiyun         strncpy(copy, string, length);
102*4882a593Smuzhiyun     copy[length] = '\0';
103*4882a593Smuzhiyun     return copy;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun void
dmxConfigFree(void * area)107*4882a593Smuzhiyun dmxConfigFree(void *area)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun     free(area);
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun DMXConfigTokenPtr
dmxConfigCreateToken(int token,int line,const char * comment)113*4882a593Smuzhiyun dmxConfigCreateToken(int token, int line, const char *comment)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun     DMXConfigTokenPtr pToken = dmxConfigAlloc(sizeof(*pToken));
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun     pToken->token = token;
118*4882a593Smuzhiyun     pToken->line = line;
119*4882a593Smuzhiyun     pToken->comment = comment;
120*4882a593Smuzhiyun     return pToken;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun void
dmxConfigFreeToken(DMXConfigTokenPtr p)124*4882a593Smuzhiyun dmxConfigFreeToken(DMXConfigTokenPtr p)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun     if (!p)
127*4882a593Smuzhiyun         return;
128*4882a593Smuzhiyun     dmxConfigFree((void *) p->comment);
129*4882a593Smuzhiyun     dmxConfigFree(p);
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun DMXConfigStringPtr
dmxConfigCreateString(int token,int line,const char * comment,const char * string)133*4882a593Smuzhiyun dmxConfigCreateString(int token, int line,
134*4882a593Smuzhiyun                       const char *comment, const char *string)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun     DMXConfigStringPtr pString = dmxConfigAlloc(sizeof(*pString));
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun     pString->token = token;
139*4882a593Smuzhiyun     pString->line = line;
140*4882a593Smuzhiyun     pString->comment = comment;
141*4882a593Smuzhiyun     pString->string = string;
142*4882a593Smuzhiyun     return pString;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun void
dmxConfigFreeString(DMXConfigStringPtr p)146*4882a593Smuzhiyun dmxConfigFreeString(DMXConfigStringPtr p)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun     DMXConfigStringPtr next;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun     if (!p)
151*4882a593Smuzhiyun         return;
152*4882a593Smuzhiyun     do {
153*4882a593Smuzhiyun         next = p->next;
154*4882a593Smuzhiyun         dmxConfigFree((void *) p->comment);
155*4882a593Smuzhiyun         dmxConfigFree((void *) p->string);
156*4882a593Smuzhiyun         dmxConfigFree(p);
157*4882a593Smuzhiyun     } while ((p = next));
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun DMXConfigNumberPtr
dmxConfigCreateNumber(int token,int line,const char * comment,int number)161*4882a593Smuzhiyun dmxConfigCreateNumber(int token, int line, const char *comment, int number)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun     DMXConfigNumberPtr pNumber = dmxConfigAlloc(sizeof(*pNumber));
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun     pNumber->token = token;
166*4882a593Smuzhiyun     pNumber->line = line;
167*4882a593Smuzhiyun     pNumber->comment = comment;
168*4882a593Smuzhiyun     pNumber->number = number;
169*4882a593Smuzhiyun     return pNumber;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun void
dmxConfigFreeNumber(DMXConfigNumberPtr p)173*4882a593Smuzhiyun dmxConfigFreeNumber(DMXConfigNumberPtr p)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun     if (!p)
176*4882a593Smuzhiyun         return;
177*4882a593Smuzhiyun     dmxConfigFree((void *) p->comment);
178*4882a593Smuzhiyun     dmxConfigFree(p);
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun DMXConfigPairPtr
dmxConfigCreatePair(int token,int line,const char * comment,int x,int y,int xsign,int ysign)182*4882a593Smuzhiyun dmxConfigCreatePair(int token, int line,
183*4882a593Smuzhiyun                     const char *comment, int x, int y, int xsign, int ysign)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun     DMXConfigPairPtr pPair = dmxConfigAlloc(sizeof(*pPair));
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun     pPair->token = token;
188*4882a593Smuzhiyun     pPair->line = line;
189*4882a593Smuzhiyun     pPair->comment = comment;
190*4882a593Smuzhiyun     pPair->x = x;
191*4882a593Smuzhiyun     pPair->y = y;
192*4882a593Smuzhiyun     pPair->xsign = (xsign < 0) ? -1 : 1;
193*4882a593Smuzhiyun     pPair->ysign = (ysign < 0) ? -1 : 1;
194*4882a593Smuzhiyun     return pPair;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun void
dmxConfigFreePair(DMXConfigPairPtr p)198*4882a593Smuzhiyun dmxConfigFreePair(DMXConfigPairPtr p)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun     if (!p)
201*4882a593Smuzhiyun         return;
202*4882a593Smuzhiyun     dmxConfigFree((void *) p->comment);
203*4882a593Smuzhiyun     dmxConfigFree(p);
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun DMXConfigCommentPtr
dmxConfigCreateComment(int token,int line,const char * comment)207*4882a593Smuzhiyun dmxConfigCreateComment(int token, int line, const char *comment)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun     DMXConfigCommentPtr pComment = dmxConfigAlloc(sizeof(*pComment));
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun     pComment->token = token;
212*4882a593Smuzhiyun     pComment->line = line;
213*4882a593Smuzhiyun     pComment->comment = comment;
214*4882a593Smuzhiyun     return pComment;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun void
dmxConfigFreeComment(DMXConfigCommentPtr p)218*4882a593Smuzhiyun dmxConfigFreeComment(DMXConfigCommentPtr p)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun     if (!p)
221*4882a593Smuzhiyun         return;
222*4882a593Smuzhiyun     dmxConfigFree((void *) p->comment);
223*4882a593Smuzhiyun     dmxConfigFree(p);
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun DMXConfigPartDimPtr
dmxConfigCreatePartDim(DMXConfigPairPtr pDim,DMXConfigPairPtr pOffset)227*4882a593Smuzhiyun dmxConfigCreatePartDim(DMXConfigPairPtr pDim, DMXConfigPairPtr pOffset)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun     DMXConfigPartDimPtr pPart = dmxConfigAlloc(sizeof(*pPart));
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun     pPart->dim = pDim;
232*4882a593Smuzhiyun     pPart->offset = pOffset;
233*4882a593Smuzhiyun     return pPart;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun void
dmxConfigFreePartDim(DMXConfigPartDimPtr p)237*4882a593Smuzhiyun dmxConfigFreePartDim(DMXConfigPartDimPtr p)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun     if (!p)
240*4882a593Smuzhiyun         return;
241*4882a593Smuzhiyun     dmxConfigFreePair(p->dim);
242*4882a593Smuzhiyun     dmxConfigFreePair(p->offset);
243*4882a593Smuzhiyun     dmxConfigFree(p);
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun DMXConfigFullDimPtr
dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn,DMXConfigPartDimPtr pRoot)247*4882a593Smuzhiyun dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn, DMXConfigPartDimPtr pRoot)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun     DMXConfigFullDimPtr pFull = dmxConfigAlloc(sizeof(*pFull));
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun     pFull->scrn = pScrn;
252*4882a593Smuzhiyun     pFull->root = pRoot;
253*4882a593Smuzhiyun     return pFull;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun void
dmxConfigFreeFullDim(DMXConfigFullDimPtr p)257*4882a593Smuzhiyun dmxConfigFreeFullDim(DMXConfigFullDimPtr p)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun     if (!p)
260*4882a593Smuzhiyun         return;
261*4882a593Smuzhiyun     dmxConfigFreePartDim(p->scrn);
262*4882a593Smuzhiyun     dmxConfigFreePartDim(p->root);
263*4882a593Smuzhiyun     dmxConfigFree(p);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun DMXConfigDisplayPtr
dmxConfigCreateDisplay(DMXConfigTokenPtr pStart,DMXConfigStringPtr pName,DMXConfigFullDimPtr pDim,DMXConfigPairPtr pOrigin,DMXConfigTokenPtr pEnd)267*4882a593Smuzhiyun dmxConfigCreateDisplay(DMXConfigTokenPtr pStart,
268*4882a593Smuzhiyun                        DMXConfigStringPtr pName,
269*4882a593Smuzhiyun                        DMXConfigFullDimPtr pDim,
270*4882a593Smuzhiyun                        DMXConfigPairPtr pOrigin, DMXConfigTokenPtr pEnd)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun     DMXConfigDisplayPtr pDisplay = dmxConfigAlloc(sizeof(*pDisplay));
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun     pDisplay->start = pStart;
275*4882a593Smuzhiyun     pDisplay->dname = pName;
276*4882a593Smuzhiyun     pDisplay->dim = pDim;
277*4882a593Smuzhiyun     pDisplay->origin = pOrigin;
278*4882a593Smuzhiyun     pDisplay->end = pEnd;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun     pDisplay->name = pName ? pName->string : NULL;
281*4882a593Smuzhiyun     pDisplay->rootXOrigin = pOrigin ? pOrigin->x : 0;
282*4882a593Smuzhiyun     pDisplay->rootYOrigin = pOrigin ? pOrigin->y : 0;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun     if (pDim && pDim->scrn && pDim->scrn->dim) {
285*4882a593Smuzhiyun         pDisplay->scrnWidth = pDim->scrn->dim->x;
286*4882a593Smuzhiyun         pDisplay->scrnHeight = pDim->scrn->dim->y;
287*4882a593Smuzhiyun     }
288*4882a593Smuzhiyun     if (pDim && pDim->scrn && pDim->scrn->offset) {
289*4882a593Smuzhiyun         pDisplay->scrnX = pDim->scrn->offset->x;
290*4882a593Smuzhiyun         pDisplay->scrnY = pDim->scrn->offset->y;
291*4882a593Smuzhiyun         pDisplay->scrnXSign = pDim->scrn->offset->xsign;
292*4882a593Smuzhiyun         pDisplay->scrnYSign = pDim->scrn->offset->ysign;
293*4882a593Smuzhiyun     }
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun     if (pDim && pDim->root) {
296*4882a593Smuzhiyun         if (pDim->root->dim) {
297*4882a593Smuzhiyun             pDisplay->rootWidth = pDim->root->dim->x;
298*4882a593Smuzhiyun             pDisplay->rootHeight = pDim->root->dim->y;
299*4882a593Smuzhiyun         }
300*4882a593Smuzhiyun         if (pDim->root->offset) {
301*4882a593Smuzhiyun             pDisplay->rootX = pDim->root->offset->x;
302*4882a593Smuzhiyun             pDisplay->rootY = pDim->root->offset->y;
303*4882a593Smuzhiyun             pDisplay->rootXSign = pDim->root->offset->xsign;
304*4882a593Smuzhiyun             pDisplay->rootYSign = pDim->root->offset->ysign;
305*4882a593Smuzhiyun         }
306*4882a593Smuzhiyun     }
307*4882a593Smuzhiyun     else {                      /* If no root specification, copy width
308*4882a593Smuzhiyun                                  * and height from scrn -- leave offset
309*4882a593Smuzhiyun                                  * as zero, since it is relative to
310*4882a593Smuzhiyun                                  * scrn. */
311*4882a593Smuzhiyun         pDisplay->rootWidth = pDisplay->scrnWidth;
312*4882a593Smuzhiyun         pDisplay->rootHeight = pDisplay->scrnHeight;
313*4882a593Smuzhiyun     }
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun     return pDisplay;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun void
dmxConfigFreeDisplay(DMXConfigDisplayPtr p)319*4882a593Smuzhiyun dmxConfigFreeDisplay(DMXConfigDisplayPtr p)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun     if (!p)
322*4882a593Smuzhiyun         return;
323*4882a593Smuzhiyun     dmxConfigFreeToken(p->start);
324*4882a593Smuzhiyun     dmxConfigFreeString(p->dname);
325*4882a593Smuzhiyun     dmxConfigFreeFullDim(p->dim);
326*4882a593Smuzhiyun     dmxConfigFreeToken(p->end);
327*4882a593Smuzhiyun     dmxConfigFree(p);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun DMXConfigWallPtr
dmxConfigCreateWall(DMXConfigTokenPtr pStart,DMXConfigPairPtr pWallDim,DMXConfigPairPtr pDisplayDim,DMXConfigStringPtr pNameList,DMXConfigTokenPtr pEnd)331*4882a593Smuzhiyun dmxConfigCreateWall(DMXConfigTokenPtr pStart,
332*4882a593Smuzhiyun                     DMXConfigPairPtr pWallDim,
333*4882a593Smuzhiyun                     DMXConfigPairPtr pDisplayDim,
334*4882a593Smuzhiyun                     DMXConfigStringPtr pNameList, DMXConfigTokenPtr pEnd)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun     DMXConfigWallPtr pWall = dmxConfigAlloc(sizeof(*pWall));
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun     pWall->start = pStart;
339*4882a593Smuzhiyun     pWall->wallDim = pWallDim;
340*4882a593Smuzhiyun     pWall->displayDim = pDisplayDim;
341*4882a593Smuzhiyun     pWall->nameList = pNameList;
342*4882a593Smuzhiyun     pWall->end = pEnd;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun     pWall->width = pDisplayDim ? pDisplayDim->x : 0;
345*4882a593Smuzhiyun     pWall->height = pDisplayDim ? pDisplayDim->y : 0;
346*4882a593Smuzhiyun     pWall->xwall = pWallDim ? pWallDim->x : 0;
347*4882a593Smuzhiyun     pWall->ywall = pWallDim ? pWallDim->y : 0;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun     return pWall;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun void
dmxConfigFreeWall(DMXConfigWallPtr p)353*4882a593Smuzhiyun dmxConfigFreeWall(DMXConfigWallPtr p)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun     if (!p)
356*4882a593Smuzhiyun         return;
357*4882a593Smuzhiyun     dmxConfigFreeToken(p->start);
358*4882a593Smuzhiyun     dmxConfigFreePair(p->wallDim);
359*4882a593Smuzhiyun     dmxConfigFreePair(p->displayDim);
360*4882a593Smuzhiyun     dmxConfigFreeString(p->nameList);
361*4882a593Smuzhiyun     dmxConfigFreeToken(p->end);
362*4882a593Smuzhiyun     dmxConfigFree(p);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun DMXConfigOptionPtr
dmxConfigCreateOption(DMXConfigTokenPtr pStart,DMXConfigStringPtr pOption,DMXConfigTokenPtr pEnd)366*4882a593Smuzhiyun dmxConfigCreateOption(DMXConfigTokenPtr pStart,
367*4882a593Smuzhiyun                       DMXConfigStringPtr pOption, DMXConfigTokenPtr pEnd)
368*4882a593Smuzhiyun {
369*4882a593Smuzhiyun     int length = 0;
370*4882a593Smuzhiyun     int offset = 0;
371*4882a593Smuzhiyun     DMXConfigStringPtr p;
372*4882a593Smuzhiyun     DMXConfigOptionPtr option = dmxConfigAlloc(sizeof(*option));
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun     for (p = pOption; p; p = p->next) {
375*4882a593Smuzhiyun         if (p->string)
376*4882a593Smuzhiyun             length += strlen(p->string) + 1;
377*4882a593Smuzhiyun     }
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun     option->string = dmxConfigAlloc(length + 1);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun     for (p = pOption; p; p = p->next) {
382*4882a593Smuzhiyun         if (p->string) {
383*4882a593Smuzhiyun             int len = strlen(p->string);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun             memcpy(option->string + offset, p->string, len);
386*4882a593Smuzhiyun             offset += len;
387*4882a593Smuzhiyun             if (p->next)
388*4882a593Smuzhiyun                 option->string[offset++] = ' ';
389*4882a593Smuzhiyun         }
390*4882a593Smuzhiyun     }
391*4882a593Smuzhiyun     option->string[offset] = '\0';
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun     option->start = pStart;
394*4882a593Smuzhiyun     option->option = pOption;
395*4882a593Smuzhiyun     option->end = pEnd;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun     return option;
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun void
dmxConfigFreeOption(DMXConfigOptionPtr p)401*4882a593Smuzhiyun dmxConfigFreeOption(DMXConfigOptionPtr p)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun     if (!p)
404*4882a593Smuzhiyun         return;
405*4882a593Smuzhiyun     free(p->string);
406*4882a593Smuzhiyun     dmxConfigFreeToken(p->start);
407*4882a593Smuzhiyun     dmxConfigFreeString(p->option);
408*4882a593Smuzhiyun     dmxConfigFreeToken(p->end);
409*4882a593Smuzhiyun     dmxConfigFree(p);
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun const char **
dmxConfigLookupParam(DMXConfigParamPtr p,const char * key,int * argc)413*4882a593Smuzhiyun dmxConfigLookupParam(DMXConfigParamPtr p, const char *key, int *argc)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun     DMXConfigParamPtr pt;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun     for (pt = p; pt; pt = pt->next) {
418*4882a593Smuzhiyun         if (pt->argv && !strcasecmp(pt->argv[0], key)) {
419*4882a593Smuzhiyun             *argc = pt->argc;
420*4882a593Smuzhiyun             return pt->argv;
421*4882a593Smuzhiyun         }
422*4882a593Smuzhiyun     }
423*4882a593Smuzhiyun     *argc = 0;
424*4882a593Smuzhiyun     return NULL;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun DMXConfigParamPtr
dmxConfigCreateParam(DMXConfigTokenPtr pStart,DMXConfigTokenPtr pOpen,DMXConfigStringPtr pParam,DMXConfigTokenPtr pClose,DMXConfigTokenPtr pEnd)428*4882a593Smuzhiyun dmxConfigCreateParam(DMXConfigTokenPtr pStart,
429*4882a593Smuzhiyun                      DMXConfigTokenPtr pOpen,
430*4882a593Smuzhiyun                      DMXConfigStringPtr pParam,
431*4882a593Smuzhiyun                      DMXConfigTokenPtr pClose, DMXConfigTokenPtr pEnd)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun     DMXConfigParamPtr param = dmxConfigAlloc(sizeof(*param));
434*4882a593Smuzhiyun     DMXConfigStringPtr pt;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun     param->argc = 0;
437*4882a593Smuzhiyun     param->argv = NULL;
438*4882a593Smuzhiyun     for (pt = pParam; pt; pt = pt->next) {
439*4882a593Smuzhiyun         if (pt->string) {
440*4882a593Smuzhiyun             param->argv = realloc(param->argv,
441*4882a593Smuzhiyun                                   (param->argc + 2) * sizeof(*param->argv));
442*4882a593Smuzhiyun             param->argv[param->argc] = pt->string;
443*4882a593Smuzhiyun             ++param->argc;
444*4882a593Smuzhiyun         }
445*4882a593Smuzhiyun     }
446*4882a593Smuzhiyun     if (param->argv)
447*4882a593Smuzhiyun         param->argv[param->argc] = NULL;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun     param->start = pStart;
450*4882a593Smuzhiyun     param->open = pOpen;
451*4882a593Smuzhiyun     param->param = pParam;
452*4882a593Smuzhiyun     param->close = pClose;
453*4882a593Smuzhiyun     param->end = pEnd;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun     return param;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun void
dmxConfigFreeParam(DMXConfigParamPtr p)459*4882a593Smuzhiyun dmxConfigFreeParam(DMXConfigParamPtr p)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun     DMXConfigParamPtr next;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun     if (!p)
464*4882a593Smuzhiyun         return;
465*4882a593Smuzhiyun     do {
466*4882a593Smuzhiyun         next = p->next;
467*4882a593Smuzhiyun         dmxConfigFreeToken(p->start);
468*4882a593Smuzhiyun         dmxConfigFreeToken(p->open);
469*4882a593Smuzhiyun         dmxConfigFreeString(p->param);
470*4882a593Smuzhiyun         dmxConfigFreeToken(p->close);
471*4882a593Smuzhiyun         dmxConfigFreeToken(p->end);
472*4882a593Smuzhiyun         dmxConfigFree(p->argv);
473*4882a593Smuzhiyun         dmxConfigFree(p);
474*4882a593Smuzhiyun     } while ((p = next));
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun DMXConfigSubPtr
dmxConfigCreateSub(DMXConfigType type,DMXConfigCommentPtr comment,DMXConfigDisplayPtr display,DMXConfigWallPtr wall,DMXConfigOptionPtr option,DMXConfigParamPtr param)478*4882a593Smuzhiyun dmxConfigCreateSub(DMXConfigType type,
479*4882a593Smuzhiyun                    DMXConfigCommentPtr comment,
480*4882a593Smuzhiyun                    DMXConfigDisplayPtr display,
481*4882a593Smuzhiyun                    DMXConfigWallPtr wall,
482*4882a593Smuzhiyun                    DMXConfigOptionPtr option, DMXConfigParamPtr param)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun     DMXConfigSubPtr pSub = dmxConfigAlloc(sizeof(*pSub));
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun     pSub->type = type;
487*4882a593Smuzhiyun     switch (type) {
488*4882a593Smuzhiyun     case dmxConfigComment:
489*4882a593Smuzhiyun         pSub->comment = comment;
490*4882a593Smuzhiyun         break;
491*4882a593Smuzhiyun     case dmxConfigDisplay:
492*4882a593Smuzhiyun         pSub->display = display;
493*4882a593Smuzhiyun         break;
494*4882a593Smuzhiyun     case dmxConfigWall:
495*4882a593Smuzhiyun         pSub->wall = wall;
496*4882a593Smuzhiyun         break;
497*4882a593Smuzhiyun     case dmxConfigOption:
498*4882a593Smuzhiyun         pSub->option = option;
499*4882a593Smuzhiyun         break;
500*4882a593Smuzhiyun     case dmxConfigParam:
501*4882a593Smuzhiyun         pSub->param = param;
502*4882a593Smuzhiyun         break;
503*4882a593Smuzhiyun     default:
504*4882a593Smuzhiyun         dmxConfigLog("Type %d not supported in subentry\n", type);
505*4882a593Smuzhiyun         break;
506*4882a593Smuzhiyun     }
507*4882a593Smuzhiyun     return pSub;
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun void
dmxConfigFreeSub(DMXConfigSubPtr sub)511*4882a593Smuzhiyun dmxConfigFreeSub(DMXConfigSubPtr sub)
512*4882a593Smuzhiyun {
513*4882a593Smuzhiyun     DMXConfigSubPtr pt;
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun     for (pt = sub; pt; pt = pt->next) {
516*4882a593Smuzhiyun         switch (pt->type) {
517*4882a593Smuzhiyun         case dmxConfigComment:
518*4882a593Smuzhiyun             dmxConfigFreeComment(pt->comment);
519*4882a593Smuzhiyun             break;
520*4882a593Smuzhiyun         case dmxConfigDisplay:
521*4882a593Smuzhiyun             dmxConfigFreeDisplay(pt->display);
522*4882a593Smuzhiyun             break;
523*4882a593Smuzhiyun         case dmxConfigWall:
524*4882a593Smuzhiyun             dmxConfigFreeWall(pt->wall);
525*4882a593Smuzhiyun             break;
526*4882a593Smuzhiyun         case dmxConfigOption:
527*4882a593Smuzhiyun             dmxConfigFreeOption(pt->option);
528*4882a593Smuzhiyun             break;
529*4882a593Smuzhiyun         case dmxConfigParam:
530*4882a593Smuzhiyun             dmxConfigFreeParam(pt->param);
531*4882a593Smuzhiyun             break;
532*4882a593Smuzhiyun         default:
533*4882a593Smuzhiyun             dmxConfigLog("Type %d not supported in subentry\n", pt->type);
534*4882a593Smuzhiyun             break;
535*4882a593Smuzhiyun         }
536*4882a593Smuzhiyun     }
537*4882a593Smuzhiyun     dmxConfigFree(sub);
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun DMXConfigSubPtr
dmxConfigSubComment(DMXConfigCommentPtr comment)541*4882a593Smuzhiyun dmxConfigSubComment(DMXConfigCommentPtr comment)
542*4882a593Smuzhiyun {
543*4882a593Smuzhiyun     return dmxConfigCreateSub(dmxConfigComment, comment, NULL, NULL, NULL,
544*4882a593Smuzhiyun                               NULL);
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun DMXConfigSubPtr
dmxConfigSubDisplay(DMXConfigDisplayPtr display)548*4882a593Smuzhiyun dmxConfigSubDisplay(DMXConfigDisplayPtr display)
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun     return dmxConfigCreateSub(dmxConfigDisplay, NULL, display, NULL, NULL,
551*4882a593Smuzhiyun                               NULL);
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun DMXConfigSubPtr
dmxConfigSubWall(DMXConfigWallPtr wall)555*4882a593Smuzhiyun dmxConfigSubWall(DMXConfigWallPtr wall)
556*4882a593Smuzhiyun {
557*4882a593Smuzhiyun     return dmxConfigCreateSub(dmxConfigWall, NULL, NULL, wall, NULL, NULL);
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun DMXConfigSubPtr
dmxConfigSubOption(DMXConfigOptionPtr option)561*4882a593Smuzhiyun dmxConfigSubOption(DMXConfigOptionPtr option)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun     return dmxConfigCreateSub(dmxConfigOption, NULL, NULL, NULL, option, NULL);
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun DMXConfigSubPtr
dmxConfigSubParam(DMXConfigParamPtr param)567*4882a593Smuzhiyun dmxConfigSubParam(DMXConfigParamPtr param)
568*4882a593Smuzhiyun {
569*4882a593Smuzhiyun     return dmxConfigCreateSub(dmxConfigParam, NULL, NULL, NULL, NULL, param);
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun extern DMXConfigSubPtr
dmxConfigAddSub(DMXConfigSubPtr head,DMXConfigSubPtr sub)573*4882a593Smuzhiyun dmxConfigAddSub(DMXConfigSubPtr head, DMXConfigSubPtr sub)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun     DMXConfigSubPtr pt;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun     if (!head)
578*4882a593Smuzhiyun         return sub;
579*4882a593Smuzhiyun     for (pt = head; pt->next; pt = pt->next);
580*4882a593Smuzhiyun     pt->next = sub;
581*4882a593Smuzhiyun     return head;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun DMXConfigVirtualPtr
dmxConfigCreateVirtual(DMXConfigTokenPtr pStart,DMXConfigStringPtr pName,DMXConfigPairPtr pDim,DMXConfigTokenPtr pOpen,DMXConfigSubPtr pSubentry,DMXConfigTokenPtr pClose)585*4882a593Smuzhiyun dmxConfigCreateVirtual(DMXConfigTokenPtr pStart,
586*4882a593Smuzhiyun                        DMXConfigStringPtr pName,
587*4882a593Smuzhiyun                        DMXConfigPairPtr pDim,
588*4882a593Smuzhiyun                        DMXConfigTokenPtr pOpen,
589*4882a593Smuzhiyun                        DMXConfigSubPtr pSubentry, DMXConfigTokenPtr pClose)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun     DMXConfigVirtualPtr pVirtual = dmxConfigAlloc(sizeof(*pVirtual));
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun     pVirtual->start = pStart;
594*4882a593Smuzhiyun     pVirtual->vname = pName;
595*4882a593Smuzhiyun     pVirtual->dim = pDim;
596*4882a593Smuzhiyun     pVirtual->open = pOpen;
597*4882a593Smuzhiyun     pVirtual->subentry = pSubentry;
598*4882a593Smuzhiyun     pVirtual->close = pClose;
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun     pVirtual->name = pName ? pName->string : NULL;
601*4882a593Smuzhiyun     pVirtual->width = pDim ? pDim->x : 0;
602*4882a593Smuzhiyun     pVirtual->height = pDim ? pDim->y : 0;
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun     return pVirtual;
605*4882a593Smuzhiyun }
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun void
dmxConfigFreeVirtual(DMXConfigVirtualPtr virtual)608*4882a593Smuzhiyun dmxConfigFreeVirtual(DMXConfigVirtualPtr virtual)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun     dmxConfigFreeToken(virtual->start);
611*4882a593Smuzhiyun     dmxConfigFreeString(virtual->vname);
612*4882a593Smuzhiyun     dmxConfigFreePair(virtual->dim);
613*4882a593Smuzhiyun     dmxConfigFreeToken(virtual->open);
614*4882a593Smuzhiyun     dmxConfigFreeSub(virtual->subentry);
615*4882a593Smuzhiyun     dmxConfigFreeToken(virtual->close);
616*4882a593Smuzhiyun     dmxConfigFree(virtual);
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun DMXConfigEntryPtr
dmxConfigCreateEntry(DMXConfigType type,DMXConfigCommentPtr comment,DMXConfigVirtualPtr virtual)620*4882a593Smuzhiyun dmxConfigCreateEntry(DMXConfigType type,
621*4882a593Smuzhiyun                      DMXConfigCommentPtr comment, DMXConfigVirtualPtr virtual)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun     DMXConfigEntryPtr pEntry = dmxConfigAlloc(sizeof(*pEntry));
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun     pEntry->type = type;
626*4882a593Smuzhiyun     switch (type) {
627*4882a593Smuzhiyun     case dmxConfigComment:
628*4882a593Smuzhiyun         pEntry->comment = comment;
629*4882a593Smuzhiyun         break;
630*4882a593Smuzhiyun     case dmxConfigVirtual:
631*4882a593Smuzhiyun         pEntry->virtual = virtual;
632*4882a593Smuzhiyun         break;
633*4882a593Smuzhiyun     default:
634*4882a593Smuzhiyun         dmxConfigLog("Type %d not supported in entry\n", type);
635*4882a593Smuzhiyun         break;
636*4882a593Smuzhiyun     }
637*4882a593Smuzhiyun     return pEntry;
638*4882a593Smuzhiyun }
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun void
dmxConfigFreeEntry(DMXConfigEntryPtr entry)641*4882a593Smuzhiyun dmxConfigFreeEntry(DMXConfigEntryPtr entry)
642*4882a593Smuzhiyun {
643*4882a593Smuzhiyun     DMXConfigEntryPtr pt;
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun     for (pt = entry; pt; pt = pt->next) {
646*4882a593Smuzhiyun         switch (pt->type) {
647*4882a593Smuzhiyun         case dmxConfigComment:
648*4882a593Smuzhiyun             dmxConfigFreeComment(pt->comment);
649*4882a593Smuzhiyun             break;
650*4882a593Smuzhiyun         case dmxConfigVirtual:
651*4882a593Smuzhiyun             dmxConfigFreeVirtual(pt->virtual);
652*4882a593Smuzhiyun             break;
653*4882a593Smuzhiyun         default:
654*4882a593Smuzhiyun             dmxConfigLog("Type %d not supported in entry\n", pt->type);
655*4882a593Smuzhiyun             break;
656*4882a593Smuzhiyun         }
657*4882a593Smuzhiyun     }
658*4882a593Smuzhiyun     dmxConfigFree(entry);
659*4882a593Smuzhiyun }
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun DMXConfigEntryPtr
dmxConfigAddEntry(DMXConfigEntryPtr head,DMXConfigType type,DMXConfigCommentPtr comment,DMXConfigVirtualPtr virtual)662*4882a593Smuzhiyun dmxConfigAddEntry(DMXConfigEntryPtr head,
663*4882a593Smuzhiyun                   DMXConfigType type,
664*4882a593Smuzhiyun                   DMXConfigCommentPtr comment, DMXConfigVirtualPtr virtual)
665*4882a593Smuzhiyun {
666*4882a593Smuzhiyun     DMXConfigEntryPtr child = dmxConfigCreateEntry(type, comment, virtual);
667*4882a593Smuzhiyun     DMXConfigEntryPtr pt;
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun     if (!head)
670*4882a593Smuzhiyun         return child;
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun     for (pt = head; pt->next; pt = pt->next);
673*4882a593Smuzhiyun     pt->next = child;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun     return head;
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun DMXConfigEntryPtr
dmxConfigEntryComment(DMXConfigCommentPtr comment)679*4882a593Smuzhiyun dmxConfigEntryComment(DMXConfigCommentPtr comment)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun     return dmxConfigCreateEntry(dmxConfigComment, comment, NULL);
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun DMXConfigEntryPtr
dmxConfigEntryVirtual(DMXConfigVirtualPtr virtual)685*4882a593Smuzhiyun dmxConfigEntryVirtual(DMXConfigVirtualPtr virtual)
686*4882a593Smuzhiyun {
687*4882a593Smuzhiyun     return dmxConfigCreateEntry(dmxConfigVirtual, NULL, virtual);
688*4882a593Smuzhiyun }
689