608 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			608 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
/* $XFree86$ */
 | 
						|
/*
 | 
						|
 * Copyright 2002 Red Hat Inc., Durham, North Carolina.
 | 
						|
 *
 | 
						|
 * All Rights Reserved.
 | 
						|
 *
 | 
						|
 * Permission is hereby granted, free of charge, to any person obtaining
 | 
						|
 * a copy of this software and associated documentation files (the
 | 
						|
 * "Software"), to deal in the Software without restriction, including
 | 
						|
 * without limitation on the rights to use, copy, modify, merge,
 | 
						|
 * publish, distribute, sublicense, and/or sell copies of the Software,
 | 
						|
 * and to permit persons to whom the Software is furnished to do so,
 | 
						|
 * subject to the following conditions:
 | 
						|
 *
 | 
						|
 * The above copyright notice and this permission notice (including the
 | 
						|
 * next paragraph) shall be included in all copies or substantial
 | 
						|
 * portions of the Software.
 | 
						|
 *
 | 
						|
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
						|
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
						|
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
						|
 * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
 | 
						|
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
						|
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
						|
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
						|
 * SOFTWARE.
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 * Authors:
 | 
						|
 *   Rickard E. (Rik) Faith <faith@redhat.com>
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
/** \file
 | 
						|
 *
 | 
						|
 * This file provides support routines and helper functions to be used
 | 
						|
 * by the DMX configuration file parser.
 | 
						|
 *
 | 
						|
 * Because the DMX configuration file parsing should be capable of being
 | 
						|
 * used in a stand-alone fashion (i.e., independent from the DMX server
 | 
						|
 * source tree), no dependencies on other DMX routines are made. */
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <stdarg.h>
 | 
						|
#include "dmxparse.h"
 | 
						|
 | 
						|
/** A general error logging routine that does not depend on the dmxLog
 | 
						|
 * functions. */
 | 
						|
void dmxConfigLog(const char *format, ...)
 | 
						|
{
 | 
						|
    va_list args;
 | 
						|
    
 | 
						|
    va_start(args, format);
 | 
						|
    vprintf(format, args);      /* RATS: All calls to dmxConfigLog from
 | 
						|
                                 * dmxparse.c and dmxprint.c use a
 | 
						|
                                 * trusted format. */
 | 
						|
    va_end(args);
 | 
						|
}
 | 
						|
 | 
						|
void *dmxConfigAlloc(unsigned long bytes)
 | 
						|
{
 | 
						|
    void *area = malloc(bytes);
 | 
						|
    if (!area) {
 | 
						|
        dmxConfigLog("dmxConfigAlloc: out of memory\n");
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    memset(area, 0, bytes);
 | 
						|
    return area;
 | 
						|
}
 | 
						|
 | 
						|
void *dmxConfigRealloc(void *orig, unsigned long orig_bytes,
 | 
						|
                       unsigned long bytes)
 | 
						|
{
 | 
						|
    unsigned char *area = realloc(orig, bytes);
 | 
						|
    if (!area) {
 | 
						|
        dmxConfigLog("dmxConfigRealloc: out of memory\n");
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    memset(area + orig_bytes, 0, bytes - orig_bytes);
 | 
						|
    return area;
 | 
						|
}
 | 
						|
 | 
						|
const char *dmxConfigCopyString(const char *string, int length)
 | 
						|
{
 | 
						|
    char *copy;
 | 
						|
    
 | 
						|
    if (!length) length = strlen(string);
 | 
						|
    copy = dmxConfigAlloc(length + 1);
 | 
						|
    if (length) strncpy(copy, string, length);
 | 
						|
    copy[length] = '\0';
 | 
						|
    return copy;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFree(void *area)
 | 
						|
{
 | 
						|
    if (area) free(area);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigTokenPtr dmxConfigCreateToken(int token, int line,
 | 
						|
                                       const char *comment)
 | 
						|
{
 | 
						|
    DMXConfigTokenPtr pToken = dmxConfigAlloc(sizeof(*pToken));
 | 
						|
    pToken->token   = token;
 | 
						|
    pToken->line    = line;
 | 
						|
    pToken->comment = comment;
 | 
						|
    return pToken;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeToken(DMXConfigTokenPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFree((void *)p->comment);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigStringPtr dmxConfigCreateString(int token, int line,
 | 
						|
                                         const char *comment,
 | 
						|
                                         const char *string)
 | 
						|
{
 | 
						|
    DMXConfigStringPtr pString = dmxConfigAlloc(sizeof(*pString));
 | 
						|
 | 
						|
    pString->token   = token;
 | 
						|
    pString->line    = line;
 | 
						|
    pString->comment = comment;
 | 
						|
    pString->string  = string;
 | 
						|
    return pString;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeString(DMXConfigStringPtr p)
 | 
						|
{
 | 
						|
    DMXConfigStringPtr next;
 | 
						|
 | 
						|
    if (!p) return;
 | 
						|
    do {
 | 
						|
        next = p->next;
 | 
						|
        dmxConfigFree((void *)p->comment);
 | 
						|
        dmxConfigFree((void *)p->string);
 | 
						|
        dmxConfigFree(p);
 | 
						|
    } while ((p = next));
 | 
						|
}
 | 
						|
 
 | 
						|
DMXConfigNumberPtr dmxConfigCreateNumber(int token, int line,
 | 
						|
                                         const char *comment,
 | 
						|
                                         int number)
 | 
						|
{
 | 
						|
    DMXConfigNumberPtr pNumber = dmxConfigAlloc(sizeof(*pNumber));
 | 
						|
 | 
						|
    pNumber->token   = token;
 | 
						|
    pNumber->line    = line;
 | 
						|
    pNumber->comment = comment;
 | 
						|
    pNumber->number  = number;
 | 
						|
    return pNumber;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeNumber(DMXConfigNumberPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFree((void *)p->comment);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigPairPtr dmxConfigCreatePair(int token, int line,
 | 
						|
                                     const char *comment,
 | 
						|
                                     int x, int y,
 | 
						|
                                     int xsign, int ysign)
 | 
						|
{
 | 
						|
    DMXConfigPairPtr pPair = dmxConfigAlloc(sizeof(*pPair));
 | 
						|
 | 
						|
    pPair->token   = token;
 | 
						|
    pPair->line    = line;
 | 
						|
    pPair->comment = comment;
 | 
						|
    pPair->x       = x;
 | 
						|
    pPair->y       = y;
 | 
						|
    pPair->xsign   = (xsign < 0) ? -1 : 1;
 | 
						|
    pPair->ysign   = (ysign < 0) ? -1 : 1;
 | 
						|
    return pPair;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreePair(DMXConfigPairPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFree((void *)p->comment);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigCommentPtr dmxConfigCreateComment(int token, int line,
 | 
						|
                                           const char *comment)
 | 
						|
{
 | 
						|
    DMXConfigCommentPtr pComment = dmxConfigAlloc(sizeof(*pComment));
 | 
						|
 | 
						|
    pComment->token   = token;
 | 
						|
    pComment->line    = line;
 | 
						|
    pComment->comment = comment;
 | 
						|
    return pComment;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeComment(DMXConfigCommentPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFree((void *)p->comment);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigPartDimPtr dmxConfigCreatePartDim(DMXConfigPairPtr pDim,
 | 
						|
                                           DMXConfigPairPtr pOffset)
 | 
						|
{
 | 
						|
    DMXConfigPartDimPtr pPart = dmxConfigAlloc(sizeof(*pPart));
 | 
						|
    pPart->dim    = pDim;
 | 
						|
    pPart->offset = pOffset;
 | 
						|
    return pPart;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreePartDim(DMXConfigPartDimPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFreePair(p->dim);
 | 
						|
    dmxConfigFreePair(p->offset);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigFullDimPtr dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn,
 | 
						|
                                           DMXConfigPartDimPtr pRoot)
 | 
						|
{
 | 
						|
    DMXConfigFullDimPtr pFull = dmxConfigAlloc(sizeof(*pFull));
 | 
						|
    pFull->scrn = pScrn;
 | 
						|
    pFull->root = pRoot;
 | 
						|
    return pFull;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeFullDim(DMXConfigFullDimPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFreePartDim(p->scrn);
 | 
						|
    dmxConfigFreePartDim(p->root);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigDisplayPtr dmxConfigCreateDisplay(DMXConfigTokenPtr pStart,
 | 
						|
                                           DMXConfigStringPtr pName,
 | 
						|
                                           DMXConfigFullDimPtr pDim,
 | 
						|
                                           DMXConfigPairPtr pOrigin,
 | 
						|
                                           DMXConfigTokenPtr pEnd)
 | 
						|
{
 | 
						|
    DMXConfigDisplayPtr pDisplay = dmxConfigAlloc(sizeof(*pDisplay));
 | 
						|
 | 
						|
    memset(pDisplay, 0, sizeof(*pDisplay));
 | 
						|
 | 
						|
    pDisplay->start          = pStart;
 | 
						|
    pDisplay->dname          = pName;
 | 
						|
    pDisplay->dim            = pDim;
 | 
						|
    pDisplay->origin         = pOrigin;
 | 
						|
    pDisplay->end            = pEnd;
 | 
						|
 | 
						|
    pDisplay->name           = pName ? pName->string : NULL;
 | 
						|
    pDisplay->rootXOrigin    = pOrigin ? pOrigin->x : 0;
 | 
						|
    pDisplay->rootYOrigin    = pOrigin ? pOrigin->y : 0;
 | 
						|
 | 
						|
    if (pDim && pDim->scrn && pDim->scrn->dim) {
 | 
						|
        pDisplay->scrnWidth  = pDim->scrn->dim->x;
 | 
						|
        pDisplay->scrnHeight = pDim->scrn->dim->y;
 | 
						|
    }
 | 
						|
    if (pDim && pDim->scrn && pDim->scrn->offset) {
 | 
						|
        pDisplay->scrnX      = pDim->scrn->offset->x;
 | 
						|
        pDisplay->scrnY      = pDim->scrn->offset->y;
 | 
						|
        pDisplay->scrnXSign  = pDim->scrn->offset->xsign;
 | 
						|
        pDisplay->scrnYSign  = pDim->scrn->offset->ysign;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (pDim && pDim->root) {
 | 
						|
        if (pDim->root->dim) {
 | 
						|
            pDisplay->rootWidth  = pDim->root->dim->x;
 | 
						|
            pDisplay->rootHeight = pDim->root->dim->y;
 | 
						|
        }
 | 
						|
        if (pDim->root->offset) {
 | 
						|
            pDisplay->rootX      = pDim->root->offset->x;
 | 
						|
            pDisplay->rootY      = pDim->root->offset->y;
 | 
						|
            pDisplay->rootXSign  = pDim->root->offset->xsign;
 | 
						|
            pDisplay->rootYSign  = pDim->root->offset->ysign;
 | 
						|
        }
 | 
						|
    } else {                    /* If no root specification, copy width
 | 
						|
                                 * and height from scrn -- leave offset
 | 
						|
                                 * as zero, since it is relative to
 | 
						|
                                 * scrn. */
 | 
						|
        pDisplay->rootWidth  = pDisplay->scrnWidth;
 | 
						|
        pDisplay->rootHeight = pDisplay->scrnHeight;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    return pDisplay;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeDisplay(DMXConfigDisplayPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFreeToken(p->start);
 | 
						|
    dmxConfigFreeString(p->dname);
 | 
						|
    dmxConfigFreeFullDim(p->dim);
 | 
						|
    dmxConfigFreeToken(p->end);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigWallPtr dmxConfigCreateWall(DMXConfigTokenPtr pStart,
 | 
						|
                                     DMXConfigPairPtr pWallDim,
 | 
						|
                                     DMXConfigPairPtr pDisplayDim,
 | 
						|
                                     DMXConfigStringPtr pNameList,
 | 
						|
                                     DMXConfigTokenPtr pEnd)
 | 
						|
{
 | 
						|
    DMXConfigWallPtr pWall = dmxConfigAlloc(sizeof(*pWall));
 | 
						|
 | 
						|
    pWall->start      = pStart;
 | 
						|
    pWall->wallDim    = pWallDim;
 | 
						|
    pWall->displayDim = pDisplayDim;
 | 
						|
    pWall->nameList   = pNameList;
 | 
						|
    pWall->end        = pEnd;
 | 
						|
 | 
						|
    pWall->width      = pDisplayDim ? pDisplayDim->x : 0;
 | 
						|
    pWall->height     = pDisplayDim ? pDisplayDim->y : 0;
 | 
						|
    pWall->xwall      = pWallDim    ? pWallDim->x    : 0;
 | 
						|
    pWall->ywall      = pWallDim    ? pWallDim->y    : 0;
 | 
						|
 | 
						|
    return pWall;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeWall(DMXConfigWallPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    dmxConfigFreeToken(p->start);
 | 
						|
    dmxConfigFreePair(p->wallDim);
 | 
						|
    dmxConfigFreePair(p->displayDim);
 | 
						|
    dmxConfigFreeString(p->nameList);
 | 
						|
    dmxConfigFreeToken(p->end);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigOptionPtr dmxConfigCreateOption(DMXConfigTokenPtr pStart,
 | 
						|
                                         DMXConfigStringPtr pOption,
 | 
						|
                                         DMXConfigTokenPtr pEnd)
 | 
						|
{
 | 
						|
    int                length = 0;
 | 
						|
    int                offset = 0;
 | 
						|
    DMXConfigStringPtr p;
 | 
						|
    DMXConfigOptionPtr option = dmxConfigAlloc(sizeof(*option));
 | 
						|
 | 
						|
    for (p = pOption; p; p = p->next) {
 | 
						|
        if (p->string) length += strlen(p->string) + 1;
 | 
						|
    }
 | 
						|
 | 
						|
    option->string = dmxConfigAlloc(length + 1);
 | 
						|
    
 | 
						|
    for (p = pOption; p; p = p->next) {
 | 
						|
        if (p->string) {
 | 
						|
            int len = strlen(p->string);
 | 
						|
            strncpy(option->string + offset, p->string, len);
 | 
						|
            offset += len;
 | 
						|
            if (p->next) option->string[offset++] = ' ';
 | 
						|
        }
 | 
						|
    }
 | 
						|
    option->string[offset] = '\0';
 | 
						|
 | 
						|
    option->start  = pStart;
 | 
						|
    option->option = pOption;
 | 
						|
    option->end    = pEnd;
 | 
						|
 | 
						|
    return option;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeOption(DMXConfigOptionPtr p)
 | 
						|
{
 | 
						|
    if (!p) return;
 | 
						|
    if (p->string) free(p->string);
 | 
						|
    dmxConfigFreeToken(p->start);
 | 
						|
    dmxConfigFreeString(p->option);
 | 
						|
    dmxConfigFreeToken(p->end);
 | 
						|
    dmxConfigFree(p);
 | 
						|
}
 | 
						|
 | 
						|
const char **dmxConfigLookupParam(DMXConfigParamPtr p, const char *key,
 | 
						|
                                  int *argc)
 | 
						|
{
 | 
						|
    DMXConfigParamPtr pt;
 | 
						|
 | 
						|
    for (pt = p; pt; pt = pt->next) {
 | 
						|
        if (pt->argv && !strcasecmp(pt->argv[0], key)) {
 | 
						|
            *argc = pt->argc;
 | 
						|
            return pt->argv;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    *argc  = 0;
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigParamPtr dmxConfigCreateParam(DMXConfigTokenPtr pStart,
 | 
						|
                                       DMXConfigTokenPtr pOpen,
 | 
						|
                                       DMXConfigStringPtr pParam,
 | 
						|
                                       DMXConfigTokenPtr pClose,
 | 
						|
                                       DMXConfigTokenPtr pEnd)
 | 
						|
{
 | 
						|
    DMXConfigParamPtr  param = dmxConfigAlloc(sizeof(*param));
 | 
						|
    DMXConfigStringPtr pt;
 | 
						|
 | 
						|
    param->argc = 0;
 | 
						|
    param->argv = NULL;
 | 
						|
    for (pt = pParam; pt; pt = pt->next) {
 | 
						|
        if (pt->string) {
 | 
						|
            param->argv = realloc(param->argv,
 | 
						|
                                  (param->argc+2) * sizeof(*param->argv));
 | 
						|
            param->argv[param->argc] = pt->string;
 | 
						|
            ++param->argc;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (param->argv) param->argv[param->argc] = NULL;
 | 
						|
 | 
						|
    param->start = pStart;
 | 
						|
    param->open  = pOpen;
 | 
						|
    param->param = pParam;
 | 
						|
    param->close = pClose;
 | 
						|
    param->end   = pEnd;
 | 
						|
 | 
						|
    return param;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeParam(DMXConfigParamPtr p)
 | 
						|
{
 | 
						|
    DMXConfigParamPtr next;
 | 
						|
 | 
						|
    if (!p) return;
 | 
						|
    do {
 | 
						|
        next = p->next;
 | 
						|
        dmxConfigFreeToken(p->start);
 | 
						|
        dmxConfigFreeToken(p->open);
 | 
						|
        dmxConfigFreeString(p->param);
 | 
						|
        dmxConfigFreeToken(p->close);
 | 
						|
        dmxConfigFreeToken(p->end);
 | 
						|
        dmxConfigFree(p->argv);
 | 
						|
        dmxConfigFree(p);
 | 
						|
    } while ((p = next));
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigSubPtr dmxConfigCreateSub(DMXConfigType type,
 | 
						|
                                   DMXConfigCommentPtr comment,
 | 
						|
                                   DMXConfigDisplayPtr display,
 | 
						|
                                   DMXConfigWallPtr wall,
 | 
						|
                                   DMXConfigOptionPtr option,
 | 
						|
                                   DMXConfigParamPtr param)
 | 
						|
{
 | 
						|
    DMXConfigSubPtr pSub = dmxConfigAlloc(sizeof(*pSub));
 | 
						|
    pSub->type = type;
 | 
						|
    switch (type) {
 | 
						|
    case dmxConfigComment: pSub->comment = comment;                     break;
 | 
						|
    case dmxConfigDisplay: pSub->display = display;                     break;
 | 
						|
    case dmxConfigWall:    pSub->wall    = wall;                        break;
 | 
						|
    case dmxConfigOption:  pSub->option  = option;                      break;
 | 
						|
    case dmxConfigParam:   pSub->param   = param;                       break;
 | 
						|
    default: dmxConfigLog("Type %d not supported in subentry\n", type); break;
 | 
						|
    }
 | 
						|
    return pSub;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeSub(DMXConfigSubPtr sub)
 | 
						|
{
 | 
						|
    DMXConfigSubPtr pt;
 | 
						|
 | 
						|
    for (pt = sub; pt; pt = pt->next) {
 | 
						|
        switch (pt->type) {
 | 
						|
        case dmxConfigComment: dmxConfigFreeComment(pt->comment); break;
 | 
						|
        case dmxConfigDisplay: dmxConfigFreeDisplay(pt->display); break;
 | 
						|
        case dmxConfigWall:    dmxConfigFreeWall(pt->wall);       break;
 | 
						|
        case dmxConfigOption:  dmxConfigFreeOption(pt->option);   break;
 | 
						|
        case dmxConfigParam:   dmxConfigFreeParam(pt->param);     break;
 | 
						|
        default:
 | 
						|
            dmxConfigLog("Type %d not supported in subentry\n", pt->type);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    dmxConfigFree(sub);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigSubPtr dmxConfigSubComment(DMXConfigCommentPtr comment)
 | 
						|
{
 | 
						|
    return dmxConfigCreateSub(dmxConfigComment, comment, NULL, NULL, NULL,
 | 
						|
                              NULL);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigSubPtr dmxConfigSubDisplay(DMXConfigDisplayPtr display)
 | 
						|
{
 | 
						|
    return dmxConfigCreateSub(dmxConfigDisplay, NULL, display, NULL, NULL,
 | 
						|
                              NULL);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigSubPtr dmxConfigSubWall(DMXConfigWallPtr wall)
 | 
						|
{
 | 
						|
    return dmxConfigCreateSub(dmxConfigWall, NULL, NULL, wall, NULL, NULL);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigSubPtr dmxConfigSubOption(DMXConfigOptionPtr option)
 | 
						|
{
 | 
						|
    return dmxConfigCreateSub(dmxConfigOption, NULL, NULL, NULL, option, NULL);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigSubPtr dmxConfigSubParam(DMXConfigParamPtr param)
 | 
						|
{
 | 
						|
    return dmxConfigCreateSub(dmxConfigParam, NULL, NULL, NULL, NULL, param);
 | 
						|
}
 | 
						|
 | 
						|
extern DMXConfigSubPtr dmxConfigAddSub(DMXConfigSubPtr head,
 | 
						|
                                       DMXConfigSubPtr sub)
 | 
						|
{
 | 
						|
    DMXConfigSubPtr pt;
 | 
						|
    
 | 
						|
    if (!head) return sub;
 | 
						|
    for (pt = head; pt->next; pt = pt->next);
 | 
						|
    pt->next = sub;
 | 
						|
    return head;
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigVirtualPtr dmxConfigCreateVirtual(DMXConfigTokenPtr pStart,
 | 
						|
                                           DMXConfigStringPtr pName,
 | 
						|
                                           DMXConfigPairPtr pDim,
 | 
						|
                                           DMXConfigTokenPtr pOpen,
 | 
						|
                                           DMXConfigSubPtr pSubentry,
 | 
						|
                                           DMXConfigTokenPtr pClose)
 | 
						|
{
 | 
						|
    DMXConfigVirtualPtr pVirtual = dmxConfigAlloc(sizeof(*pVirtual));
 | 
						|
 | 
						|
    pVirtual->start    = pStart;
 | 
						|
    pVirtual->vname    = pName;
 | 
						|
    pVirtual->dim      = pDim;
 | 
						|
    pVirtual->open     = pOpen;
 | 
						|
    pVirtual->subentry = pSubentry;
 | 
						|
    pVirtual->close    = pClose;
 | 
						|
 | 
						|
    pVirtual->name     = pName ? pName->string : NULL;
 | 
						|
    pVirtual->width    = pDim ? pDim->x : 0;
 | 
						|
    pVirtual->height   = pDim ? pDim->y : 0;
 | 
						|
    
 | 
						|
    return pVirtual;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeVirtual(DMXConfigVirtualPtr virtual)
 | 
						|
{
 | 
						|
    dmxConfigFreeToken(virtual->start);
 | 
						|
    dmxConfigFreeString(virtual->vname);
 | 
						|
    dmxConfigFreePair(virtual->dim);
 | 
						|
    dmxConfigFreeToken(virtual->open);
 | 
						|
    dmxConfigFreeSub(virtual->subentry);
 | 
						|
    dmxConfigFreeToken(virtual->close);
 | 
						|
    dmxConfigFree(virtual);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigEntryPtr dmxConfigCreateEntry(DMXConfigType type,
 | 
						|
                                       DMXConfigCommentPtr comment,
 | 
						|
                                       DMXConfigVirtualPtr virtual)
 | 
						|
{
 | 
						|
    DMXConfigEntryPtr pEntry = dmxConfigAlloc(sizeof(*pEntry));
 | 
						|
    pEntry->type = type;
 | 
						|
    switch (type) {
 | 
						|
    case dmxConfigComment: pEntry->comment = comment;                break;
 | 
						|
    case dmxConfigVirtual: pEntry->virtual = virtual;                break;
 | 
						|
    default: dmxConfigLog("Type %d not supported in entry\n", type); break;
 | 
						|
    }
 | 
						|
    return pEntry;
 | 
						|
}
 | 
						|
 | 
						|
void dmxConfigFreeEntry(DMXConfigEntryPtr entry)
 | 
						|
{
 | 
						|
    DMXConfigEntryPtr pt;
 | 
						|
 | 
						|
    for (pt = entry; pt; pt = pt->next) {
 | 
						|
        switch (pt->type) {
 | 
						|
        case dmxConfigComment: dmxConfigFreeComment(pt->comment); break;
 | 
						|
        case dmxConfigVirtual: dmxConfigFreeVirtual(pt->virtual); break;
 | 
						|
        default:
 | 
						|
            dmxConfigLog("Type %d not supported in entry\n", pt->type);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    dmxConfigFree(entry);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigEntryPtr dmxConfigAddEntry(DMXConfigEntryPtr head,
 | 
						|
                                    DMXConfigType type,
 | 
						|
                                    DMXConfigCommentPtr comment,
 | 
						|
                                    DMXConfigVirtualPtr virtual)
 | 
						|
{
 | 
						|
    DMXConfigEntryPtr child = dmxConfigCreateEntry(type, comment, virtual);
 | 
						|
    DMXConfigEntryPtr pt;
 | 
						|
 | 
						|
    if (!head) return child;
 | 
						|
 | 
						|
    for (pt = head; pt->next; pt = pt->next);
 | 
						|
    pt->next = child;
 | 
						|
 | 
						|
    return head;
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigEntryPtr dmxConfigEntryComment(DMXConfigCommentPtr comment)
 | 
						|
{
 | 
						|
    return dmxConfigCreateEntry(dmxConfigComment, comment, NULL);
 | 
						|
}
 | 
						|
 | 
						|
DMXConfigEntryPtr dmxConfigEntryVirtual(DMXConfigVirtualPtr virtual)
 | 
						|
{
 | 
						|
    return dmxConfigCreateEntry(dmxConfigVirtual, NULL, virtual);
 | 
						|
}
 |