First import
[xorg_rtime.git] / xorg-server-1.4 / hw / dmx / config / dmxparse.c
blob0bf9470517a1fa070211aff8249417a0c43bf327
1 /*
2 * Copyright 2002 Red Hat Inc., Durham, North Carolina.
4 * All Rights Reserved.
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
25 * SOFTWARE.
29 * Authors:
30 * Rickard E. (Rik) Faith <faith@redhat.com>
34 /** \file
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>
45 #endif
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <stdarg.h>
51 #include "dmxparse.h"
53 /** A general error logging routine that does not depend on the dmxLog
54 * functions. */
55 void dmxConfigLog(const char *format, ...)
57 va_list args;
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);
66 void *dmxConfigAlloc(unsigned long bytes)
68 void *area = malloc(bytes);
69 if (!area) {
70 dmxConfigLog("dmxConfigAlloc: out of memory\n");
71 return NULL;
73 memset(area, 0, bytes);
74 return area;
77 void *dmxConfigRealloc(void *orig, unsigned long orig_bytes,
78 unsigned long bytes)
80 unsigned char *area = realloc(orig, bytes);
81 if (!area) {
82 dmxConfigLog("dmxConfigRealloc: out of memory\n");
83 return NULL;
85 memset(area + orig_bytes, 0, bytes - orig_bytes);
86 return area;
89 const char *dmxConfigCopyString(const char *string, int length)
91 char *copy;
93 if (!length) length = strlen(string);
94 copy = dmxConfigAlloc(length + 1);
95 if (length) strncpy(copy, string, length);
96 copy[length] = '\0';
97 return copy;
100 void dmxConfigFree(void *area)
102 if (area) free(area);
105 DMXConfigTokenPtr dmxConfigCreateToken(int token, int line,
106 const char *comment)
108 DMXConfigTokenPtr pToken = dmxConfigAlloc(sizeof(*pToken));
109 pToken->token = token;
110 pToken->line = line;
111 pToken->comment = comment;
112 return pToken;
115 void dmxConfigFreeToken(DMXConfigTokenPtr p)
117 if (!p) return;
118 dmxConfigFree((void *)p->comment);
119 dmxConfigFree(p);
122 DMXConfigStringPtr dmxConfigCreateString(int token, int line,
123 const char *comment,
124 const char *string)
126 DMXConfigStringPtr pString = dmxConfigAlloc(sizeof(*pString));
128 pString->token = token;
129 pString->line = line;
130 pString->comment = comment;
131 pString->string = string;
132 return pString;
135 void dmxConfigFreeString(DMXConfigStringPtr p)
137 DMXConfigStringPtr next;
139 if (!p) return;
140 do {
141 next = p->next;
142 dmxConfigFree((void *)p->comment);
143 dmxConfigFree((void *)p->string);
144 dmxConfigFree(p);
145 } while ((p = next));
148 DMXConfigNumberPtr dmxConfigCreateNumber(int token, int line,
149 const char *comment,
150 int number)
152 DMXConfigNumberPtr pNumber = dmxConfigAlloc(sizeof(*pNumber));
154 pNumber->token = token;
155 pNumber->line = line;
156 pNumber->comment = comment;
157 pNumber->number = number;
158 return pNumber;
161 void dmxConfigFreeNumber(DMXConfigNumberPtr p)
163 if (!p) return;
164 dmxConfigFree((void *)p->comment);
165 dmxConfigFree(p);
168 DMXConfigPairPtr dmxConfigCreatePair(int token, int line,
169 const char *comment,
170 int x, int y,
171 int xsign, int ysign)
173 DMXConfigPairPtr pPair = dmxConfigAlloc(sizeof(*pPair));
175 pPair->token = token;
176 pPair->line = line;
177 pPair->comment = comment;
178 pPair->x = x;
179 pPair->y = y;
180 pPair->xsign = (xsign < 0) ? -1 : 1;
181 pPair->ysign = (ysign < 0) ? -1 : 1;
182 return pPair;
185 void dmxConfigFreePair(DMXConfigPairPtr p)
187 if (!p) return;
188 dmxConfigFree((void *)p->comment);
189 dmxConfigFree(p);
192 DMXConfigCommentPtr dmxConfigCreateComment(int token, int line,
193 const char *comment)
195 DMXConfigCommentPtr pComment = dmxConfigAlloc(sizeof(*pComment));
197 pComment->token = token;
198 pComment->line = line;
199 pComment->comment = comment;
200 return pComment;
203 void dmxConfigFreeComment(DMXConfigCommentPtr p)
205 if (!p) return;
206 dmxConfigFree((void *)p->comment);
207 dmxConfigFree(p);
210 DMXConfigPartDimPtr dmxConfigCreatePartDim(DMXConfigPairPtr pDim,
211 DMXConfigPairPtr pOffset)
213 DMXConfigPartDimPtr pPart = dmxConfigAlloc(sizeof(*pPart));
214 pPart->dim = pDim;
215 pPart->offset = pOffset;
216 return pPart;
219 void dmxConfigFreePartDim(DMXConfigPartDimPtr p)
221 if (!p) return;
222 dmxConfigFreePair(p->dim);
223 dmxConfigFreePair(p->offset);
224 dmxConfigFree(p);
227 DMXConfigFullDimPtr dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn,
228 DMXConfigPartDimPtr pRoot)
230 DMXConfigFullDimPtr pFull = dmxConfigAlloc(sizeof(*pFull));
231 pFull->scrn = pScrn;
232 pFull->root = pRoot;
233 return pFull;
236 void dmxConfigFreeFullDim(DMXConfigFullDimPtr p)
238 if (!p) return;
239 dmxConfigFreePartDim(p->scrn);
240 dmxConfigFreePartDim(p->root);
241 dmxConfigFree(p);
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
289 * scrn. */
290 pDisplay->rootWidth = pDisplay->scrnWidth;
291 pDisplay->rootHeight = pDisplay->scrnHeight;
295 return pDisplay;
298 void dmxConfigFreeDisplay(DMXConfigDisplayPtr p)
300 if (!p) return;
301 dmxConfigFreeToken(p->start);
302 dmxConfigFreeString(p->dname);
303 dmxConfigFreeFullDim(p->dim);
304 dmxConfigFreeToken(p->end);
305 dmxConfigFree(p);
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;
320 pWall->end = pEnd;
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;
327 return pWall;
330 void dmxConfigFreeWall(DMXConfigWallPtr p)
332 if (!p) return;
333 dmxConfigFreeToken(p->start);
334 dmxConfigFreePair(p->wallDim);
335 dmxConfigFreePair(p->displayDim);
336 dmxConfigFreeString(p->nameList);
337 dmxConfigFreeToken(p->end);
338 dmxConfigFree(p);
341 DMXConfigOptionPtr dmxConfigCreateOption(DMXConfigTokenPtr pStart,
342 DMXConfigStringPtr pOption,
343 DMXConfigTokenPtr pEnd)
345 int length = 0;
346 int offset = 0;
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) {
357 if (p->string) {
358 int len = strlen(p->string);
359 strncpy(option->string + offset, p->string, len);
360 offset += len;
361 if (p->next) option->string[offset++] = ' ';
364 option->string[offset] = '\0';
366 option->start = pStart;
367 option->option = pOption;
368 option->end = pEnd;
370 return option;
373 void dmxConfigFreeOption(DMXConfigOptionPtr p)
375 if (!p) return;
376 if (p->string) free(p->string);
377 dmxConfigFreeToken(p->start);
378 dmxConfigFreeString(p->option);
379 dmxConfigFreeToken(p->end);
380 dmxConfigFree(p);
383 const char **dmxConfigLookupParam(DMXConfigParamPtr p, const char *key,
384 int *argc)
386 DMXConfigParamPtr pt;
388 for (pt = p; pt; pt = pt->next) {
389 if (pt->argv && !strcasecmp(pt->argv[0], key)) {
390 *argc = pt->argc;
391 return pt->argv;
394 *argc = 0;
395 return NULL;
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;
407 param->argc = 0;
408 param->argv = NULL;
409 for (pt = pParam; pt; pt = pt->next) {
410 if (pt->string) {
411 param->argv = realloc(param->argv,
412 (param->argc+2) * sizeof(*param->argv));
413 param->argv[param->argc] = pt->string;
414 ++param->argc;
417 if (param->argv) param->argv[param->argc] = NULL;
419 param->start = pStart;
420 param->open = pOpen;
421 param->param = pParam;
422 param->close = pClose;
423 param->end = pEnd;
425 return param;
428 void dmxConfigFreeParam(DMXConfigParamPtr p)
430 DMXConfigParamPtr next;
432 if (!p) return;
433 do {
434 next = p->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);
441 dmxConfigFree(p);
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));
453 pSub->type = type;
454 switch (type) {
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;
462 return pSub;
465 void dmxConfigFreeSub(DMXConfigSubPtr sub)
467 DMXConfigSubPtr pt;
469 for (pt = sub; pt; pt = pt->next) {
470 switch (pt->type) {
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;
476 default:
477 dmxConfigLog("Type %d not supported in subentry\n", pt->type);
478 break;
481 dmxConfigFree(sub);
484 DMXConfigSubPtr dmxConfigSubComment(DMXConfigCommentPtr comment)
486 return dmxConfigCreateSub(dmxConfigComment, comment, NULL, NULL, NULL,
487 NULL);
490 DMXConfigSubPtr dmxConfigSubDisplay(DMXConfigDisplayPtr display)
492 return dmxConfigCreateSub(dmxConfigDisplay, NULL, display, NULL, NULL,
493 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,
512 DMXConfigSubPtr sub)
514 DMXConfigSubPtr pt;
516 if (!head) return sub;
517 for (pt = head; pt->next; pt = pt->next);
518 pt->next = sub;
519 return head;
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;
542 return pVirtual;
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));
561 pEntry->type = type;
562 switch (type) {
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;
567 return pEntry;
570 void dmxConfigFreeEntry(DMXConfigEntryPtr entry)
572 DMXConfigEntryPtr pt;
574 for (pt = entry; pt; pt = pt->next) {
575 switch (pt->type) {
576 case dmxConfigComment: dmxConfigFreeComment(pt->comment); break;
577 case dmxConfigVirtual: dmxConfigFreeVirtual(pt->virtual); break;
578 default:
579 dmxConfigLog("Type %d not supported in entry\n", pt->type);
580 break;
583 dmxConfigFree(entry);
586 DMXConfigEntryPtr dmxConfigAddEntry(DMXConfigEntryPtr head,
587 DMXConfigType type,
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);
597 pt->next = child;
599 return head;
602 DMXConfigEntryPtr dmxConfigEntryComment(DMXConfigCommentPtr comment)
604 return dmxConfigCreateEntry(dmxConfigComment, comment, NULL);
607 DMXConfigEntryPtr dmxConfigEntryVirtual(DMXConfigVirtualPtr virtual)
609 return dmxConfigCreateEntry(dmxConfigVirtual, NULL, virtual);