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