/* * 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 * */ /** \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. */ #ifdef HAVE_DMX_CONFIG_H #include #endif #include #include #include #include #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); }