2 * Copyright 2002 Red Hat Inc., Durham, North Carolina.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * Rickard E. (Rik) Faith <faith@redhat.com>
36 * This file provides support routines and helper functions to be used
37 * by the DMX configuration file parser.
39 * Because the DMX configuration file parsing should be capable of being
40 * used in a stand-alone fashion (i.e., independent from the DMX server
41 * source tree), no dependencies on other DMX routines are made. */
43 #ifdef HAVE_DMX_CONFIG_H
44 #include <dmx-config.h>
53 /** A general error logging routine that does not depend on the dmxLog
55 void dmxConfigLog(const char *format
, ...)
59 va_start(args
, format
);
60 vprintf(format
, args
); /* RATS: All calls to dmxConfigLog from
61 * dmxparse.c and dmxprint.c use a
66 void *dmxConfigAlloc(unsigned long bytes
)
68 void *area
= malloc(bytes
);
70 dmxConfigLog("dmxConfigAlloc: out of memory\n");
73 memset(area
, 0, bytes
);
77 void *dmxConfigRealloc(void *orig
, unsigned long orig_bytes
,
80 unsigned char *area
= realloc(orig
, bytes
);
82 dmxConfigLog("dmxConfigRealloc: out of memory\n");
85 memset(area
+ orig_bytes
, 0, bytes
- orig_bytes
);
89 const char *dmxConfigCopyString(const char *string
, int length
)
93 if (!length
) length
= strlen(string
);
94 copy
= dmxConfigAlloc(length
+ 1);
95 if (length
) strncpy(copy
, string
, length
);
100 void dmxConfigFree(void *area
)
102 if (area
) free(area
);
105 DMXConfigTokenPtr
dmxConfigCreateToken(int token
, int line
,
108 DMXConfigTokenPtr pToken
= dmxConfigAlloc(sizeof(*pToken
));
109 pToken
->token
= token
;
111 pToken
->comment
= comment
;
115 void dmxConfigFreeToken(DMXConfigTokenPtr p
)
118 dmxConfigFree((void *)p
->comment
);
122 DMXConfigStringPtr
dmxConfigCreateString(int token
, int line
,
126 DMXConfigStringPtr pString
= dmxConfigAlloc(sizeof(*pString
));
128 pString
->token
= token
;
129 pString
->line
= line
;
130 pString
->comment
= comment
;
131 pString
->string
= string
;
135 void dmxConfigFreeString(DMXConfigStringPtr p
)
137 DMXConfigStringPtr next
;
142 dmxConfigFree((void *)p
->comment
);
143 dmxConfigFree((void *)p
->string
);
145 } while ((p
= next
));
148 DMXConfigNumberPtr
dmxConfigCreateNumber(int token
, int line
,
152 DMXConfigNumberPtr pNumber
= dmxConfigAlloc(sizeof(*pNumber
));
154 pNumber
->token
= token
;
155 pNumber
->line
= line
;
156 pNumber
->comment
= comment
;
157 pNumber
->number
= number
;
161 void dmxConfigFreeNumber(DMXConfigNumberPtr p
)
164 dmxConfigFree((void *)p
->comment
);
168 DMXConfigPairPtr
dmxConfigCreatePair(int token
, int line
,
171 int xsign
, int ysign
)
173 DMXConfigPairPtr pPair
= dmxConfigAlloc(sizeof(*pPair
));
175 pPair
->token
= token
;
177 pPair
->comment
= comment
;
180 pPair
->xsign
= (xsign
< 0) ? -1 : 1;
181 pPair
->ysign
= (ysign
< 0) ? -1 : 1;
185 void dmxConfigFreePair(DMXConfigPairPtr p
)
188 dmxConfigFree((void *)p
->comment
);
192 DMXConfigCommentPtr
dmxConfigCreateComment(int token
, int line
,
195 DMXConfigCommentPtr pComment
= dmxConfigAlloc(sizeof(*pComment
));
197 pComment
->token
= token
;
198 pComment
->line
= line
;
199 pComment
->comment
= comment
;
203 void dmxConfigFreeComment(DMXConfigCommentPtr p
)
206 dmxConfigFree((void *)p
->comment
);
210 DMXConfigPartDimPtr
dmxConfigCreatePartDim(DMXConfigPairPtr pDim
,
211 DMXConfigPairPtr pOffset
)
213 DMXConfigPartDimPtr pPart
= dmxConfigAlloc(sizeof(*pPart
));
215 pPart
->offset
= pOffset
;
219 void dmxConfigFreePartDim(DMXConfigPartDimPtr p
)
222 dmxConfigFreePair(p
->dim
);
223 dmxConfigFreePair(p
->offset
);
227 DMXConfigFullDimPtr
dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn
,
228 DMXConfigPartDimPtr pRoot
)
230 DMXConfigFullDimPtr pFull
= dmxConfigAlloc(sizeof(*pFull
));
236 void dmxConfigFreeFullDim(DMXConfigFullDimPtr p
)
239 dmxConfigFreePartDim(p
->scrn
);
240 dmxConfigFreePartDim(p
->root
);
244 DMXConfigDisplayPtr
dmxConfigCreateDisplay(DMXConfigTokenPtr pStart
,
245 DMXConfigStringPtr pName
,
246 DMXConfigFullDimPtr pDim
,
247 DMXConfigPairPtr pOrigin
,
248 DMXConfigTokenPtr pEnd
)
250 DMXConfigDisplayPtr pDisplay
= dmxConfigAlloc(sizeof(*pDisplay
));
252 memset(pDisplay
, 0, sizeof(*pDisplay
));
254 pDisplay
->start
= pStart
;
255 pDisplay
->dname
= pName
;
256 pDisplay
->dim
= pDim
;
257 pDisplay
->origin
= pOrigin
;
258 pDisplay
->end
= pEnd
;
260 pDisplay
->name
= pName
? pName
->string
: NULL
;
261 pDisplay
->rootXOrigin
= pOrigin
? pOrigin
->x
: 0;
262 pDisplay
->rootYOrigin
= pOrigin
? pOrigin
->y
: 0;
264 if (pDim
&& pDim
->scrn
&& pDim
->scrn
->dim
) {
265 pDisplay
->scrnWidth
= pDim
->scrn
->dim
->x
;
266 pDisplay
->scrnHeight
= pDim
->scrn
->dim
->y
;
268 if (pDim
&& pDim
->scrn
&& pDim
->scrn
->offset
) {
269 pDisplay
->scrnX
= pDim
->scrn
->offset
->x
;
270 pDisplay
->scrnY
= pDim
->scrn
->offset
->y
;
271 pDisplay
->scrnXSign
= pDim
->scrn
->offset
->xsign
;
272 pDisplay
->scrnYSign
= pDim
->scrn
->offset
->ysign
;
275 if (pDim
&& pDim
->root
) {
276 if (pDim
->root
->dim
) {
277 pDisplay
->rootWidth
= pDim
->root
->dim
->x
;
278 pDisplay
->rootHeight
= pDim
->root
->dim
->y
;
280 if (pDim
->root
->offset
) {
281 pDisplay
->rootX
= pDim
->root
->offset
->x
;
282 pDisplay
->rootY
= pDim
->root
->offset
->y
;
283 pDisplay
->rootXSign
= pDim
->root
->offset
->xsign
;
284 pDisplay
->rootYSign
= pDim
->root
->offset
->ysign
;
286 } else { /* If no root specification, copy width
287 * and height from scrn -- leave offset
288 * as zero, since it is relative to
290 pDisplay
->rootWidth
= pDisplay
->scrnWidth
;
291 pDisplay
->rootHeight
= pDisplay
->scrnHeight
;
298 void dmxConfigFreeDisplay(DMXConfigDisplayPtr p
)
301 dmxConfigFreeToken(p
->start
);
302 dmxConfigFreeString(p
->dname
);
303 dmxConfigFreeFullDim(p
->dim
);
304 dmxConfigFreeToken(p
->end
);
308 DMXConfigWallPtr
dmxConfigCreateWall(DMXConfigTokenPtr pStart
,
309 DMXConfigPairPtr pWallDim
,
310 DMXConfigPairPtr pDisplayDim
,
311 DMXConfigStringPtr pNameList
,
312 DMXConfigTokenPtr pEnd
)
314 DMXConfigWallPtr pWall
= dmxConfigAlloc(sizeof(*pWall
));
316 pWall
->start
= pStart
;
317 pWall
->wallDim
= pWallDim
;
318 pWall
->displayDim
= pDisplayDim
;
319 pWall
->nameList
= pNameList
;
322 pWall
->width
= pDisplayDim
? pDisplayDim
->x
: 0;
323 pWall
->height
= pDisplayDim
? pDisplayDim
->y
: 0;
324 pWall
->xwall
= pWallDim
? pWallDim
->x
: 0;
325 pWall
->ywall
= pWallDim
? pWallDim
->y
: 0;
330 void dmxConfigFreeWall(DMXConfigWallPtr p
)
333 dmxConfigFreeToken(p
->start
);
334 dmxConfigFreePair(p
->wallDim
);
335 dmxConfigFreePair(p
->displayDim
);
336 dmxConfigFreeString(p
->nameList
);
337 dmxConfigFreeToken(p
->end
);
341 DMXConfigOptionPtr
dmxConfigCreateOption(DMXConfigTokenPtr pStart
,
342 DMXConfigStringPtr pOption
,
343 DMXConfigTokenPtr pEnd
)
347 DMXConfigStringPtr p
;
348 DMXConfigOptionPtr option
= dmxConfigAlloc(sizeof(*option
));
350 for (p
= pOption
; p
; p
= p
->next
) {
351 if (p
->string
) length
+= strlen(p
->string
) + 1;
354 option
->string
= dmxConfigAlloc(length
+ 1);
356 for (p
= pOption
; p
; p
= p
->next
) {
358 int len
= strlen(p
->string
);
359 strncpy(option
->string
+ offset
, p
->string
, len
);
361 if (p
->next
) option
->string
[offset
++] = ' ';
364 option
->string
[offset
] = '\0';
366 option
->start
= pStart
;
367 option
->option
= pOption
;
373 void dmxConfigFreeOption(DMXConfigOptionPtr p
)
376 if (p
->string
) free(p
->string
);
377 dmxConfigFreeToken(p
->start
);
378 dmxConfigFreeString(p
->option
);
379 dmxConfigFreeToken(p
->end
);
383 const char **dmxConfigLookupParam(DMXConfigParamPtr p
, const char *key
,
386 DMXConfigParamPtr pt
;
388 for (pt
= p
; pt
; pt
= pt
->next
) {
389 if (pt
->argv
&& !strcasecmp(pt
->argv
[0], key
)) {
398 DMXConfigParamPtr
dmxConfigCreateParam(DMXConfigTokenPtr pStart
,
399 DMXConfigTokenPtr pOpen
,
400 DMXConfigStringPtr pParam
,
401 DMXConfigTokenPtr pClose
,
402 DMXConfigTokenPtr pEnd
)
404 DMXConfigParamPtr param
= dmxConfigAlloc(sizeof(*param
));
405 DMXConfigStringPtr pt
;
409 for (pt
= pParam
; pt
; pt
= pt
->next
) {
411 param
->argv
= realloc(param
->argv
,
412 (param
->argc
+2) * sizeof(*param
->argv
));
413 param
->argv
[param
->argc
] = pt
->string
;
417 if (param
->argv
) param
->argv
[param
->argc
] = NULL
;
419 param
->start
= pStart
;
421 param
->param
= pParam
;
422 param
->close
= pClose
;
428 void dmxConfigFreeParam(DMXConfigParamPtr p
)
430 DMXConfigParamPtr next
;
435 dmxConfigFreeToken(p
->start
);
436 dmxConfigFreeToken(p
->open
);
437 dmxConfigFreeString(p
->param
);
438 dmxConfigFreeToken(p
->close
);
439 dmxConfigFreeToken(p
->end
);
440 dmxConfigFree(p
->argv
);
442 } while ((p
= next
));
445 DMXConfigSubPtr
dmxConfigCreateSub(DMXConfigType type
,
446 DMXConfigCommentPtr comment
,
447 DMXConfigDisplayPtr display
,
448 DMXConfigWallPtr wall
,
449 DMXConfigOptionPtr option
,
450 DMXConfigParamPtr param
)
452 DMXConfigSubPtr pSub
= dmxConfigAlloc(sizeof(*pSub
));
455 case dmxConfigComment
: pSub
->comment
= comment
; break;
456 case dmxConfigDisplay
: pSub
->display
= display
; break;
457 case dmxConfigWall
: pSub
->wall
= wall
; break;
458 case dmxConfigOption
: pSub
->option
= option
; break;
459 case dmxConfigParam
: pSub
->param
= param
; break;
460 default: dmxConfigLog("Type %d not supported in subentry\n", type
); break;
465 void dmxConfigFreeSub(DMXConfigSubPtr sub
)
469 for (pt
= sub
; pt
; pt
= pt
->next
) {
471 case dmxConfigComment
: dmxConfigFreeComment(pt
->comment
); break;
472 case dmxConfigDisplay
: dmxConfigFreeDisplay(pt
->display
); break;
473 case dmxConfigWall
: dmxConfigFreeWall(pt
->wall
); break;
474 case dmxConfigOption
: dmxConfigFreeOption(pt
->option
); break;
475 case dmxConfigParam
: dmxConfigFreeParam(pt
->param
); break;
477 dmxConfigLog("Type %d not supported in subentry\n", pt
->type
);
484 DMXConfigSubPtr
dmxConfigSubComment(DMXConfigCommentPtr comment
)
486 return dmxConfigCreateSub(dmxConfigComment
, comment
, NULL
, NULL
, NULL
,
490 DMXConfigSubPtr
dmxConfigSubDisplay(DMXConfigDisplayPtr display
)
492 return dmxConfigCreateSub(dmxConfigDisplay
, NULL
, display
, NULL
, NULL
,
496 DMXConfigSubPtr
dmxConfigSubWall(DMXConfigWallPtr wall
)
498 return dmxConfigCreateSub(dmxConfigWall
, NULL
, NULL
, wall
, NULL
, NULL
);
501 DMXConfigSubPtr
dmxConfigSubOption(DMXConfigOptionPtr option
)
503 return dmxConfigCreateSub(dmxConfigOption
, NULL
, NULL
, NULL
, option
, NULL
);
506 DMXConfigSubPtr
dmxConfigSubParam(DMXConfigParamPtr param
)
508 return dmxConfigCreateSub(dmxConfigParam
, NULL
, NULL
, NULL
, NULL
, param
);
511 extern DMXConfigSubPtr
dmxConfigAddSub(DMXConfigSubPtr head
,
516 if (!head
) return sub
;
517 for (pt
= head
; pt
->next
; pt
= pt
->next
);
522 DMXConfigVirtualPtr
dmxConfigCreateVirtual(DMXConfigTokenPtr pStart
,
523 DMXConfigStringPtr pName
,
524 DMXConfigPairPtr pDim
,
525 DMXConfigTokenPtr pOpen
,
526 DMXConfigSubPtr pSubentry
,
527 DMXConfigTokenPtr pClose
)
529 DMXConfigVirtualPtr pVirtual
= dmxConfigAlloc(sizeof(*pVirtual
));
531 pVirtual
->start
= pStart
;
532 pVirtual
->vname
= pName
;
533 pVirtual
->dim
= pDim
;
534 pVirtual
->open
= pOpen
;
535 pVirtual
->subentry
= pSubentry
;
536 pVirtual
->close
= pClose
;
538 pVirtual
->name
= pName
? pName
->string
: NULL
;
539 pVirtual
->width
= pDim
? pDim
->x
: 0;
540 pVirtual
->height
= pDim
? pDim
->y
: 0;
545 void dmxConfigFreeVirtual(DMXConfigVirtualPtr
virtual)
547 dmxConfigFreeToken(virtual->start
);
548 dmxConfigFreeString(virtual->vname
);
549 dmxConfigFreePair(virtual->dim
);
550 dmxConfigFreeToken(virtual->open
);
551 dmxConfigFreeSub(virtual->subentry
);
552 dmxConfigFreeToken(virtual->close
);
553 dmxConfigFree(virtual);
556 DMXConfigEntryPtr
dmxConfigCreateEntry(DMXConfigType type
,
557 DMXConfigCommentPtr comment
,
558 DMXConfigVirtualPtr
virtual)
560 DMXConfigEntryPtr pEntry
= dmxConfigAlloc(sizeof(*pEntry
));
563 case dmxConfigComment
: pEntry
->comment
= comment
; break;
564 case dmxConfigVirtual
: pEntry
->virtual = virtual; break;
565 default: dmxConfigLog("Type %d not supported in entry\n", type
); break;
570 void dmxConfigFreeEntry(DMXConfigEntryPtr entry
)
572 DMXConfigEntryPtr pt
;
574 for (pt
= entry
; pt
; pt
= pt
->next
) {
576 case dmxConfigComment
: dmxConfigFreeComment(pt
->comment
); break;
577 case dmxConfigVirtual
: dmxConfigFreeVirtual(pt
->virtual); break;
579 dmxConfigLog("Type %d not supported in entry\n", pt
->type
);
583 dmxConfigFree(entry
);
586 DMXConfigEntryPtr
dmxConfigAddEntry(DMXConfigEntryPtr head
,
588 DMXConfigCommentPtr comment
,
589 DMXConfigVirtualPtr
virtual)
591 DMXConfigEntryPtr child
= dmxConfigCreateEntry(type
, comment
, virtual);
592 DMXConfigEntryPtr pt
;
594 if (!head
) return child
;
596 for (pt
= head
; pt
->next
; pt
= pt
->next
);
602 DMXConfigEntryPtr
dmxConfigEntryComment(DMXConfigCommentPtr comment
)
604 return dmxConfigCreateEntry(dmxConfigComment
, comment
, NULL
);
607 DMXConfigEntryPtr
dmxConfigEntryVirtual(DMXConfigVirtualPtr
virtual)
609 return dmxConfigCreateEntry(dmxConfigVirtual
, NULL
, virtual);