Home | History | Annotate | Line # | Download | only in config
      1 /*
      2  * Copyright 2002 Red Hat Inc., Durham, North Carolina.
      3  *
      4  * All Rights Reserved.
      5  *
      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:
     13  *
     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.
     17  *
     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
     25  * SOFTWARE.
     26  */
     27 
     28 /*
     29  * Authors:
     30  *   Rickard E. (Rik) Faith <faith (at) redhat.com>
     31  *
     32  */
     33 
     34 /** \file
     35  *
     36  * This file provides support routines and helper functions to be used
     37  * by the DMX configuration file parser.
     38  *
     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. */
     42 
     43 #ifdef HAVE_DMX_CONFIG_H
     44 #include <dmx-config.h>
     45 #endif
     46 
     47 #include <stdio.h>
     48 #include <stdlib.h>
     49 #include <string.h>
     50 #include <stdarg.h>
     51 #include "dmxparse.h"
     52 
     53 /** A general error logging routine that does not depend on the dmxLog
     54  * functions. */
     55 void dmxConfigLog(const char *format, ...)
     56 {
     57     va_list args;
     58 
     59     va_start(args, format);
     60     vprintf(format, args);      /* RATS: All calls to dmxConfigLog from
     61                                  * dmxparse.c and dmxprint.c use a
     62                                  * trusted format. */
     63     va_end(args);
     64 }
     65 
     66 void *dmxConfigAlloc(unsigned long bytes)
     67 {
     68     void *area = calloc(1, bytes);
     69     if (!area) {
     70         dmxConfigLog("dmxConfigAlloc: out of memory\n");
     71         return NULL;
     72     }
     73     return area;
     74 }
     75 
     76 void *dmxConfigRealloc(void *orig, unsigned long orig_bytes,
     77                        unsigned long bytes)
     78 {
     79     unsigned char *area = realloc(orig, bytes);
     80     if (!area) {
     81         dmxConfigLog("dmxConfigRealloc: out of memory\n");
     82         return NULL;
     83     }
     84     memset(area + orig_bytes, 0, bytes - orig_bytes);
     85     return area;
     86 }
     87 
     88 const char *dmxConfigCopyString(const char *string, int length)
     89 {
     90     char *copy;
     91 
     92     if (!length) length = strlen(string);
     93     copy = dmxConfigAlloc(length + 1);
     94     if (length) strncpy(copy, string, length);
     95     copy[length] = '\0';
     96     return copy;
     97 }
     98 
     99 void dmxConfigFree(void *area)
    100 {
    101     free(area);
    102 }
    103 
    104 DMXConfigTokenPtr dmxConfigCreateToken(int token, int line,
    105                                        const char *comment)
    106 {
    107     DMXConfigTokenPtr pToken = dmxConfigAlloc(sizeof(*pToken));
    108     pToken->token   = token;
    109     pToken->line    = line;
    110     pToken->comment = comment;
    111     return pToken;
    112 }
    113 
    114 void dmxConfigFreeToken(DMXConfigTokenPtr p)
    115 {
    116     if (!p) return;
    117     dmxConfigFree((void *)p->comment);
    118     dmxConfigFree(p);
    119 }
    120 
    121 DMXConfigStringPtr dmxConfigCreateString(int token, int line,
    122                                          const char *comment,
    123                                          const char *string)
    124 {
    125     DMXConfigStringPtr pString = dmxConfigAlloc(sizeof(*pString));
    126 
    127     pString->token   = token;
    128     pString->line    = line;
    129     pString->comment = comment;
    130     pString->string  = string;
    131     return pString;
    132 }
    133 
    134 void dmxConfigFreeString(DMXConfigStringPtr p)
    135 {
    136     DMXConfigStringPtr next;
    137 
    138     if (!p) return;
    139     do {
    140         next = p->next;
    141         dmxConfigFree((void *)p->comment);
    142         dmxConfigFree((void *)p->string);
    143         dmxConfigFree(p);
    144     } while ((p = next));
    145 }
    146 
    147 DMXConfigNumberPtr dmxConfigCreateNumber(int token, int line,
    148                                          const char *comment,
    149                                          int number)
    150 {
    151     DMXConfigNumberPtr pNumber = dmxConfigAlloc(sizeof(*pNumber));
    152 
    153     pNumber->token   = token;
    154     pNumber->line    = line;
    155     pNumber->comment = comment;
    156     pNumber->number  = number;
    157     return pNumber;
    158 }
    159 
    160 void dmxConfigFreeNumber(DMXConfigNumberPtr p)
    161 {
    162     if (!p) return;
    163     dmxConfigFree((void *)p->comment);
    164     dmxConfigFree(p);
    165 }
    166 
    167 DMXConfigPairPtr dmxConfigCreatePair(int token, int line,
    168                                      const char *comment,
    169                                      int x, int y,
    170                                      int xsign, int ysign)
    171 {
    172     DMXConfigPairPtr pPair = dmxConfigAlloc(sizeof(*pPair));
    173 
    174     pPair->token   = token;
    175     pPair->line    = line;
    176     pPair->comment = comment;
    177     pPair->x       = x;
    178     pPair->y       = y;
    179     pPair->xsign   = (xsign < 0) ? -1 : 1;
    180     pPair->ysign   = (ysign < 0) ? -1 : 1;
    181     return pPair;
    182 }
    183 
    184 void dmxConfigFreePair(DMXConfigPairPtr p)
    185 {
    186     if (!p) return;
    187     dmxConfigFree((void *)p->comment);
    188     dmxConfigFree(p);
    189 }
    190 
    191 DMXConfigCommentPtr dmxConfigCreateComment(int token, int line,
    192                                            const char *comment)
    193 {
    194     DMXConfigCommentPtr pComment = dmxConfigAlloc(sizeof(*pComment));
    195 
    196     pComment->token   = token;
    197     pComment->line    = line;
    198     pComment->comment = comment;
    199     return pComment;
    200 }
    201 
    202 void dmxConfigFreeComment(DMXConfigCommentPtr p)
    203 {
    204     if (!p) return;
    205     dmxConfigFree((void *)p->comment);
    206     dmxConfigFree(p);
    207 }
    208 
    209 DMXConfigPartDimPtr dmxConfigCreatePartDim(DMXConfigPairPtr pDim,
    210                                            DMXConfigPairPtr pOffset)
    211 {
    212     DMXConfigPartDimPtr pPart = dmxConfigAlloc(sizeof(*pPart));
    213     pPart->dim    = pDim;
    214     pPart->offset = pOffset;
    215     return pPart;
    216 }
    217 
    218 void dmxConfigFreePartDim(DMXConfigPartDimPtr p)
    219 {
    220     if (!p) return;
    221     dmxConfigFreePair(p->dim);
    222     dmxConfigFreePair(p->offset);
    223     dmxConfigFree(p);
    224 }
    225 
    226 DMXConfigFullDimPtr dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn,
    227                                            DMXConfigPartDimPtr pRoot)
    228 {
    229     DMXConfigFullDimPtr pFull = dmxConfigAlloc(sizeof(*pFull));
    230     pFull->scrn = pScrn;
    231     pFull->root = pRoot;
    232     return pFull;
    233 }
    234 
    235 void dmxConfigFreeFullDim(DMXConfigFullDimPtr p)
    236 {
    237     if (!p) return;
    238     dmxConfigFreePartDim(p->scrn);
    239     dmxConfigFreePartDim(p->root);
    240     dmxConfigFree(p);
    241 }
    242 
    243 DMXConfigDisplayPtr dmxConfigCreateDisplay(DMXConfigTokenPtr pStart,
    244                                            DMXConfigStringPtr pName,
    245                                            DMXConfigFullDimPtr pDim,
    246                                            DMXConfigPairPtr pOrigin,
    247                                            DMXConfigTokenPtr pEnd)
    248 {
    249     DMXConfigDisplayPtr pDisplay = dmxConfigAlloc(sizeof(*pDisplay));
    250 
    251     pDisplay->start          = pStart;
    252     pDisplay->dname          = pName;
    253     pDisplay->dim            = pDim;
    254     pDisplay->origin         = pOrigin;
    255     pDisplay->end            = pEnd;
    256 
    257     pDisplay->name           = pName ? pName->string : NULL;
    258     pDisplay->rootXOrigin    = pOrigin ? pOrigin->x : 0;
    259     pDisplay->rootYOrigin    = pOrigin ? pOrigin->y : 0;
    260 
    261     if (pDim && pDim->scrn && pDim->scrn->dim) {
    262         pDisplay->scrnWidth  = pDim->scrn->dim->x;
    263         pDisplay->scrnHeight = pDim->scrn->dim->y;
    264     }
    265     if (pDim && pDim->scrn && pDim->scrn->offset) {
    266         pDisplay->scrnX      = pDim->scrn->offset->x;
    267         pDisplay->scrnY      = pDim->scrn->offset->y;
    268         pDisplay->scrnXSign  = pDim->scrn->offset->xsign;
    269         pDisplay->scrnYSign  = pDim->scrn->offset->ysign;
    270     }
    271 
    272     if (pDim && pDim->root) {
    273         if (pDim->root->dim) {
    274             pDisplay->rootWidth  = pDim->root->dim->x;
    275             pDisplay->rootHeight = pDim->root->dim->y;
    276         }
    277         if (pDim->root->offset) {
    278             pDisplay->rootX      = pDim->root->offset->x;
    279             pDisplay->rootY      = pDim->root->offset->y;
    280             pDisplay->rootXSign  = pDim->root->offset->xsign;
    281             pDisplay->rootYSign  = pDim->root->offset->ysign;
    282         }
    283     } else {                    /* If no root specification, copy width
    284                                  * and height from scrn -- leave offset
    285                                  * as zero, since it is relative to
    286                                  * scrn. */
    287         pDisplay->rootWidth  = pDisplay->scrnWidth;
    288         pDisplay->rootHeight = pDisplay->scrnHeight;
    289     }
    290 
    291 
    292     return pDisplay;
    293 }
    294 
    295 void dmxConfigFreeDisplay(DMXConfigDisplayPtr p)
    296 {
    297     if (!p) return;
    298     dmxConfigFreeToken(p->start);
    299     dmxConfigFreeString(p->dname);
    300     dmxConfigFreeFullDim(p->dim);
    301     dmxConfigFreeToken(p->end);
    302     dmxConfigFree(p);
    303 }
    304 
    305 DMXConfigWallPtr dmxConfigCreateWall(DMXConfigTokenPtr pStart,
    306                                      DMXConfigPairPtr pWallDim,
    307                                      DMXConfigPairPtr pDisplayDim,
    308                                      DMXConfigStringPtr pNameList,
    309                                      DMXConfigTokenPtr pEnd)
    310 {
    311     DMXConfigWallPtr pWall = dmxConfigAlloc(sizeof(*pWall));
    312 
    313     pWall->start      = pStart;
    314     pWall->wallDim    = pWallDim;
    315     pWall->displayDim = pDisplayDim;
    316     pWall->nameList   = pNameList;
    317     pWall->end        = pEnd;
    318 
    319     pWall->width      = pDisplayDim ? pDisplayDim->x : 0;
    320     pWall->height     = pDisplayDim ? pDisplayDim->y : 0;
    321     pWall->xwall      = pWallDim    ? pWallDim->x    : 0;
    322     pWall->ywall      = pWallDim    ? pWallDim->y    : 0;
    323 
    324     return pWall;
    325 }
    326 
    327 void dmxConfigFreeWall(DMXConfigWallPtr p)
    328 {
    329     if (!p) return;
    330     dmxConfigFreeToken(p->start);
    331     dmxConfigFreePair(p->wallDim);
    332     dmxConfigFreePair(p->displayDim);
    333     dmxConfigFreeString(p->nameList);
    334     dmxConfigFreeToken(p->end);
    335     dmxConfigFree(p);
    336 }
    337 
    338 DMXConfigOptionPtr dmxConfigCreateOption(DMXConfigTokenPtr pStart,
    339                                          DMXConfigStringPtr pOption,
    340                                          DMXConfigTokenPtr pEnd)
    341 {
    342     int                length = 0;
    343     int                offset = 0;
    344     DMXConfigStringPtr p;
    345     DMXConfigOptionPtr option = dmxConfigAlloc(sizeof(*option));
    346 
    347     for (p = pOption; p; p = p->next) {
    348         if (p->string) length += strlen(p->string) + 1;
    349     }
    350 
    351     option->string = dmxConfigAlloc(length + 1);
    352 
    353     for (p = pOption; p; p = p->next) {
    354         if (p->string) {
    355             int len = strlen(p->string);
    356             strncpy(option->string + offset, p->string, len);
    357             offset += len;
    358             if (p->next) option->string[offset++] = ' ';
    359         }
    360     }
    361     option->string[offset] = '\0';
    362 
    363     option->start  = pStart;
    364     option->option = pOption;
    365     option->end    = pEnd;
    366 
    367     return option;
    368 }
    369 
    370 void dmxConfigFreeOption(DMXConfigOptionPtr p)
    371 {
    372     if (!p) return;
    373     free(p->string);
    374     dmxConfigFreeToken(p->start);
    375     dmxConfigFreeString(p->option);
    376     dmxConfigFreeToken(p->end);
    377     dmxConfigFree(p);
    378 }
    379 
    380 const char **dmxConfigLookupParam(DMXConfigParamPtr p, const char *key,
    381                                   int *argc)
    382 {
    383     DMXConfigParamPtr pt;
    384 
    385     for (pt = p; pt; pt = pt->next) {
    386         if (pt->argv && !strcasecmp(pt->argv[0], key)) {
    387             *argc = pt->argc;
    388             return pt->argv;
    389         }
    390     }
    391     *argc  = 0;
    392     return NULL;
    393 }
    394 
    395 DMXConfigParamPtr dmxConfigCreateParam(DMXConfigTokenPtr pStart,
    396                                        DMXConfigTokenPtr pOpen,
    397                                        DMXConfigStringPtr pParam,
    398                                        DMXConfigTokenPtr pClose,
    399                                        DMXConfigTokenPtr pEnd)
    400 {
    401     DMXConfigParamPtr  param = dmxConfigAlloc(sizeof(*param));
    402     DMXConfigStringPtr pt;
    403 
    404     param->argc = 0;
    405     param->argv = NULL;
    406     for (pt = pParam; pt; pt = pt->next) {
    407         if (pt->string) {
    408             param->argv = realloc(param->argv,
    409                                   (param->argc+2) * sizeof(*param->argv));
    410             param->argv[param->argc] = pt->string;
    411             ++param->argc;
    412         }
    413     }
    414     if (param->argv) param->argv[param->argc] = NULL;
    415 
    416     param->start = pStart;
    417     param->open  = pOpen;
    418     param->param = pParam;
    419     param->close = pClose;
    420     param->end   = pEnd;
    421 
    422     return param;
    423 }
    424 
    425 void dmxConfigFreeParam(DMXConfigParamPtr p)
    426 {
    427     DMXConfigParamPtr next;
    428 
    429     if (!p) return;
    430     do {
    431         next = p->next;
    432         dmxConfigFreeToken(p->start);
    433         dmxConfigFreeToken(p->open);
    434         dmxConfigFreeString(p->param);
    435         dmxConfigFreeToken(p->close);
    436         dmxConfigFreeToken(p->end);
    437         dmxConfigFree(p->argv);
    438         dmxConfigFree(p);
    439     } while ((p = next));
    440 }
    441 
    442 DMXConfigSubPtr dmxConfigCreateSub(DMXConfigType type,
    443                                    DMXConfigCommentPtr comment,
    444                                    DMXConfigDisplayPtr display,
    445                                    DMXConfigWallPtr wall,
    446                                    DMXConfigOptionPtr option,
    447                                    DMXConfigParamPtr param)
    448 {
    449     DMXConfigSubPtr pSub = dmxConfigAlloc(sizeof(*pSub));
    450     pSub->type = type;
    451     switch (type) {
    452     case dmxConfigComment: pSub->comment = comment;                     break;
    453     case dmxConfigDisplay: pSub->display = display;                     break;
    454     case dmxConfigWall:    pSub->wall    = wall;                        break;
    455     case dmxConfigOption:  pSub->option  = option;                      break;
    456     case dmxConfigParam:   pSub->param   = param;                       break;
    457     default: dmxConfigLog("Type %d not supported in subentry\n", type); break;
    458     }
    459     return pSub;
    460 }
    461 
    462 void dmxConfigFreeSub(DMXConfigSubPtr sub)
    463 {
    464     DMXConfigSubPtr pt;
    465 
    466     for (pt = sub; pt; pt = pt->next) {
    467         switch (pt->type) {
    468         case dmxConfigComment: dmxConfigFreeComment(pt->comment); break;
    469         case dmxConfigDisplay: dmxConfigFreeDisplay(pt->display); break;
    470         case dmxConfigWall:    dmxConfigFreeWall(pt->wall);       break;
    471         case dmxConfigOption:  dmxConfigFreeOption(pt->option);   break;
    472         case dmxConfigParam:   dmxConfigFreeParam(pt->param);     break;
    473         default:
    474             dmxConfigLog("Type %d not supported in subentry\n", pt->type);
    475             break;
    476         }
    477     }
    478     dmxConfigFree(sub);
    479 }
    480 
    481 DMXConfigSubPtr dmxConfigSubComment(DMXConfigCommentPtr comment)
    482 {
    483     return dmxConfigCreateSub(dmxConfigComment, comment, NULL, NULL, NULL,
    484                               NULL);
    485 }
    486 
    487 DMXConfigSubPtr dmxConfigSubDisplay(DMXConfigDisplayPtr display)
    488 {
    489     return dmxConfigCreateSub(dmxConfigDisplay, NULL, display, NULL, NULL,
    490                               NULL);
    491 }
    492 
    493 DMXConfigSubPtr dmxConfigSubWall(DMXConfigWallPtr wall)
    494 {
    495     return dmxConfigCreateSub(dmxConfigWall, NULL, NULL, wall, NULL, NULL);
    496 }
    497 
    498 DMXConfigSubPtr dmxConfigSubOption(DMXConfigOptionPtr option)
    499 {
    500     return dmxConfigCreateSub(dmxConfigOption, NULL, NULL, NULL, option, NULL);
    501 }
    502 
    503 DMXConfigSubPtr dmxConfigSubParam(DMXConfigParamPtr param)
    504 {
    505     return dmxConfigCreateSub(dmxConfigParam, NULL, NULL, NULL, NULL, param);
    506 }
    507 
    508 extern DMXConfigSubPtr dmxConfigAddSub(DMXConfigSubPtr head,
    509                                        DMXConfigSubPtr sub)
    510 {
    511     DMXConfigSubPtr pt;
    512 
    513     if (!head) return sub;
    514     for (pt = head; pt->next; pt = pt->next);
    515     pt->next = sub;
    516     return head;
    517 }
    518 
    519 DMXConfigVirtualPtr dmxConfigCreateVirtual(DMXConfigTokenPtr pStart,
    520                                            DMXConfigStringPtr pName,
    521                                            DMXConfigPairPtr pDim,
    522                                            DMXConfigTokenPtr pOpen,
    523                                            DMXConfigSubPtr pSubentry,
    524                                            DMXConfigTokenPtr pClose)
    525 {
    526     DMXConfigVirtualPtr pVirtual = dmxConfigAlloc(sizeof(*pVirtual));
    527 
    528     pVirtual->start    = pStart;
    529     pVirtual->vname    = pName;
    530     pVirtual->dim      = pDim;
    531     pVirtual->open     = pOpen;
    532     pVirtual->subentry = pSubentry;
    533     pVirtual->close    = pClose;
    534 
    535     pVirtual->name     = pName ? pName->string : NULL;
    536     pVirtual->width    = pDim ? pDim->x : 0;
    537     pVirtual->height   = pDim ? pDim->y : 0;
    538 
    539     return pVirtual;
    540 }
    541 
    542 void dmxConfigFreeVirtual(DMXConfigVirtualPtr virtual)
    543 {
    544     dmxConfigFreeToken(virtual->start);
    545     dmxConfigFreeString(virtual->vname);
    546     dmxConfigFreePair(virtual->dim);
    547     dmxConfigFreeToken(virtual->open);
    548     dmxConfigFreeSub(virtual->subentry);
    549     dmxConfigFreeToken(virtual->close);
    550     dmxConfigFree(virtual);
    551 }
    552 
    553 DMXConfigEntryPtr dmxConfigCreateEntry(DMXConfigType type,
    554                                        DMXConfigCommentPtr comment,
    555                                        DMXConfigVirtualPtr virtual)
    556 {
    557     DMXConfigEntryPtr pEntry = dmxConfigAlloc(sizeof(*pEntry));
    558     pEntry->type = type;
    559     switch (type) {
    560     case dmxConfigComment: pEntry->comment = comment;                break;
    561     case dmxConfigVirtual: pEntry->virtual = virtual;                break;
    562     default: dmxConfigLog("Type %d not supported in entry\n", type); break;
    563     }
    564     return pEntry;
    565 }
    566 
    567 void dmxConfigFreeEntry(DMXConfigEntryPtr entry)
    568 {
    569     DMXConfigEntryPtr pt;
    570 
    571     for (pt = entry; pt; pt = pt->next) {
    572         switch (pt->type) {
    573         case dmxConfigComment: dmxConfigFreeComment(pt->comment); break;
    574         case dmxConfigVirtual: dmxConfigFreeVirtual(pt->virtual); break;
    575         default:
    576             dmxConfigLog("Type %d not supported in entry\n", pt->type);
    577             break;
    578         }
    579     }
    580     dmxConfigFree(entry);
    581 }
    582 
    583 DMXConfigEntryPtr dmxConfigAddEntry(DMXConfigEntryPtr head,
    584                                     DMXConfigType type,
    585                                     DMXConfigCommentPtr comment,
    586                                     DMXConfigVirtualPtr virtual)
    587 {
    588     DMXConfigEntryPtr child = dmxConfigCreateEntry(type, comment, virtual);
    589     DMXConfigEntryPtr pt;
    590 
    591     if (!head) return child;
    592 
    593     for (pt = head; pt->next; pt = pt->next);
    594     pt->next = child;
    595 
    596     return head;
    597 }
    598 
    599 DMXConfigEntryPtr dmxConfigEntryComment(DMXConfigCommentPtr comment)
    600 {
    601     return dmxConfigCreateEntry(dmxConfigComment, comment, NULL);
    602 }
    603 
    604 DMXConfigEntryPtr dmxConfigEntryVirtual(DMXConfigVirtualPtr virtual)
    605 {
    606     return dmxConfigCreateEntry(dmxConfigVirtual, NULL, virtual);
    607 }
    608