summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/dmx/config/dmxprint.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/dmx/config/dmxprint.c')
-rw-r--r--xc/programs/Xserver/hw/dmx/config/dmxprint.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/xc/programs/Xserver/hw/dmx/config/dmxprint.c b/xc/programs/Xserver/hw/dmx/config/dmxprint.c
new file mode 100644
index 000000000..f50162eb6
--- /dev/null
+++ b/xc/programs/Xserver/hw/dmx/config/dmxprint.c
@@ -0,0 +1,345 @@
+/* $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>
+ *
+ */
+
+#include "dmxconfig.h"
+#include "dmxparse.h"
+#include "dmxprint.h"
+#include "parser.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+static FILE *str = NULL;
+static int indent = 0;
+static int pos = 0;
+
+static struct stack {
+ int base;
+ int comment;
+ int step;
+ struct stack *next;
+} *stack, initialStack = { 0, 0, 4, NULL };
+
+static void dmxConfigIndent(void)
+{
+ int i;
+ if (indent < 0) indent = 0;
+ if (indent > 40) indent = 40;
+ for (i = 0; i < indent; i++) fprintf(str, " ");
+}
+
+static void dmxConfigNewline(void)
+{
+ if (pos) fprintf(str, "\n");
+ pos = 0;
+}
+
+static void dmxConfigPushState(int base, int comment, int step)
+{
+ struct stack *new = dmxConfigAlloc(sizeof(*new));
+ new->base = base;
+ new->comment = comment;
+ new->step = step;
+ new->next = stack;
+ stack = new;
+ indent = base;
+ dmxConfigNewline();
+}
+
+static void dmxConfigPushComment(void)
+{
+ if (stack) indent = stack->comment;
+}
+
+static void dmxConfigPushStep(void)
+{
+ if (stack) indent = stack->step;
+}
+
+static void dmxConfigPopState(void)
+{
+ struct stack *old = stack;
+
+ if (!stack) return;
+ indent = old->base;
+ stack = old->next;
+ if (!stack) {
+ dmxConfigLog("Stack underflow\n");
+ return;
+ }
+ dmxConfigFree(old);
+ dmxConfigNewline();
+}
+
+static void dmxConfigOutput(int addSpace, int doNewline, const char *comment,
+ const char *format, ...)
+{
+ va_list args;
+
+ if (!pos) dmxConfigIndent();
+ else if (addSpace) fprintf(str, " ");
+
+ if (format) {
+ va_start(args, format);
+ pos += vfprintf(str, format, args); /* assumes no newlines! */
+ va_end(args);
+ }
+
+ if (comment) {
+ if (pos) fprintf(str, " ");
+ pos += fprintf(str, "#%s", comment);
+ dmxConfigNewline();
+ dmxConfigPushComment();
+ } else if (doNewline) dmxConfigNewline();
+}
+
+static void dmxConfigPrintComment(DMXConfigCommentPtr p)
+{
+ dmxConfigOutput(1, 1, p->comment, NULL);
+}
+
+static void dmxConfigPrintToken(DMXConfigTokenPtr p)
+{
+ if (!p) return;
+ switch (p->token) {
+ case T_VIRTUAL:
+ dmxConfigPushState(0, 4, 4);
+ dmxConfigOutput(0, 0, p->comment, "virtual");
+ break;
+ case T_DISPLAY:
+ dmxConfigPushState(4, 12, 16);
+ dmxConfigOutput(0, 0, p->comment, "display");
+ break;
+ case T_WALL:
+ dmxConfigPushState(4, 12, 16);
+ dmxConfigOutput(0, 0, p->comment, "wall");
+ break;
+ case T_OPTION:
+ dmxConfigPushState(4, 12, 16);
+ dmxConfigOutput(0, 0, p->comment, "option");
+ break;
+ case ';':
+ dmxConfigOutput(0, 1, p->comment, ";");
+ dmxConfigPopState();
+ break;
+ case '{':
+ dmxConfigOutput(1, 1, p->comment, "{");
+ dmxConfigPushStep();
+ break;
+ case '}':
+ dmxConfigPopState();
+ dmxConfigOutput(0, 1, p->comment, "}");
+ break;
+ default:
+ dmxConfigLog("unknown token %d on line %d\n", p->token, p->line);
+ }
+}
+
+static int dmxConfigPrintQuotedString(const char *s)
+{
+ const char *pt;
+
+ if (!s || !s[0]) return 1; /* Quote empty string */
+ for (pt = s; *pt; ++pt) if (isspace(*pt)) return 1;
+ return 0;
+}
+
+static void dmxConfigPrintString(DMXConfigStringPtr p)
+{
+ DMXConfigStringPtr pt;
+
+ if (!p) return;
+ for (pt = p; pt; pt = pt->next) {
+ if (dmxConfigPrintQuotedString(pt->string))
+ dmxConfigOutput(1, 0, p->comment, "\"%s\"",
+ pt->string ? pt->string : "");
+ else
+ dmxConfigOutput(1, 0, p->comment, "%s",
+ pt->string ? pt->string : "");
+ }
+}
+
+static int dmxConfigPrintPair(DMXConfigPairPtr p, int addSpace)
+{
+ const char *format = NULL;
+
+ if (!p) return 0;
+ switch (p->token) {
+ case T_ORIGIN: format = "@%dx%d"; break;
+ case T_DIMENSION: format = "%dx%d"; break;
+ case T_OFFSET: format = "%c%d%c%d"; break;
+ }
+ if (p->token == T_OFFSET) {
+ if (!p->comment && !p->x && !p->y && p->xsign >= 0 && p->ysign >= 0)
+ return 0;
+ dmxConfigOutput(addSpace, 0, p->comment, format,
+ p->xsign < 0 ? '-' : '+', p->x,
+ p->ysign < 0 ? '-' : '+', p->y);
+ } else {
+ if (!p->comment && !p->x && !p->y) return 0;
+ dmxConfigOutput(addSpace, 0, p->comment, format, p->x, p->y);
+ }
+ return 1;
+}
+
+static void dmxConfigPrintDisplay(DMXConfigDisplayPtr p)
+{
+ DMXConfigToken dummyStart = { T_DISPLAY, 0, NULL };
+ DMXConfigToken dummyEnd = { ';', 0, NULL };
+ DMXConfigString dummyName = { T_STRING, 0, NULL, NULL, NULL };
+ DMXConfigPair dummyDim = { T_DIMENSION, 0, NULL, 0, 0, 0, 0 };
+ DMXConfigPair dummyOffset = { T_OFFSET, 0, NULL, 0, 0, 0, 0 };
+ DMXConfigPair dummyOrigin = { T_ORIGIN, 0, NULL, 0, 0, 0, 0 };
+ int output;
+
+ if (p->dname) p->dname->string = p->name;
+ else dummyName.string = p->name;
+
+ if (p->dim) p->dim->x = p->width, p->dim->y = p->height;
+ else dummyDim.x = p->width, dummyDim.y = p->height;
+
+ if (p->offset) p->offset->x = p->xoff, p->offset->y = p->yoff;
+ else dummyOffset.x = p->xoff, dummyOffset.y = p->yoff;
+
+ if (p->origin) {
+ p->origin->x = p->xorig, p->origin->y = p->yorig;
+ p->origin->xsign = p->xsign, p->origin->ysign = p->ysign;
+ } else {
+ dummyOrigin.x = p->xorig, dummyOrigin.y = p->yorig;
+ dummyOrigin.xsign = p->xsign, dummyOrigin.ysign = p->ysign;
+ }
+
+ dmxConfigPrintToken(p->start ? p->start : &dummyStart);
+ dmxConfigPrintString(p->dname ? p->dname : &dummyName);
+ output = dmxConfigPrintPair(p->dim ? p->dim : &dummyDim, 1);
+ dmxConfigPrintPair(p->offset ? p->offset : &dummyOffset, !output);
+ dmxConfigPrintPair(p->origin ? p->origin : &dummyOrigin, 1);
+ dmxConfigPrintToken(p->end ? p->end : &dummyEnd);
+}
+
+static void dmxConfigPrintWall(DMXConfigWallPtr p)
+{
+ dmxConfigPrintToken(p->start);
+ dmxConfigPrintPair(p->wallDim, 1);
+ dmxConfigPrintPair(p->displayDim, 1);
+ dmxConfigPrintString(p->nameList);
+ dmxConfigPrintToken(p->end);
+}
+
+static void dmxConfigPrintOption(DMXConfigOptionPtr p)
+{
+ DMXConfigToken dummyStart = { T_OPTION, 0, NULL };
+ DMXConfigString dummyOption = { T_STRING, 0, NULL, NULL, NULL };
+ DMXConfigToken dummyEnd = { ';', 0, NULL };
+
+ if (p->option) p->option->string = p->string;
+ else dummyOption.string = p->string;
+
+ dmxConfigPrintToken(p->start ? p->start : &dummyStart);
+ dmxConfigPrintString(p->option ? p->option : &dummyOption);
+ dmxConfigPrintToken(p->end ? p->end : &dummyEnd);
+}
+
+static void dmxConfigPrintSub(DMXConfigSubPtr p)
+{
+ DMXConfigSubPtr pt;
+
+ if (!p) return;
+ for (pt = p; pt; pt = pt->next) {
+ switch (pt->type) {
+ case dmxConfigComment: dmxConfigPrintComment(pt->comment); break;
+ case dmxConfigDisplay: dmxConfigPrintDisplay(pt->display); break;
+ case dmxConfigWall: dmxConfigPrintWall(pt->wall); break;
+ case dmxConfigOption: dmxConfigPrintOption(pt->option); break;
+ default:
+ dmxConfigLog("dmxConfigPrintSub:"
+ " cannot handle type %d in subentry\n", pt->type);
+ }
+ }
+}
+
+static void dmxConfigPrintVirtual(DMXConfigVirtualPtr p)
+{
+ DMXConfigToken dummyStart = { T_VIRTUAL, 0, NULL };
+ DMXConfigToken dummyOpen = { '{', 0, NULL };
+ DMXConfigToken dummyClose = { '}', 0, NULL };
+ DMXConfigString dummyName = { T_STRING, 0, NULL, NULL, NULL };
+ DMXConfigPair dummyDim = { T_DIMENSION, 0, NULL, 0, 0 };
+
+ if (p->vname) p->vname->string = p->name;
+ else dummyName.string = p->name;
+
+ if (p->dim) p->dim->x = p->width, p->dim->y = p->height;
+ else dummyDim.x = p->width, dummyDim.y = p->height;
+
+
+ dmxConfigPrintToken(p->start ? p->start : &dummyStart);
+ dmxConfigPrintString(p->vname ? p->vname : &dummyName);
+ dmxConfigPrintPair(p->dim ? p->dim : &dummyDim, 1);
+ dmxConfigPrintToken(p->open ? p->open : &dummyOpen);
+ dmxConfigPrintSub(p->subentry);
+ dmxConfigPrintToken(p->close ? p->close : &dummyClose);
+}
+
+void dmxConfigPrint(FILE *stream, DMXConfigEntryPtr entry)
+{
+ DMXConfigEntryPtr pt;
+
+ if (!stream) str = stdout;
+ else str = stream;
+
+ stack = &initialStack;
+
+ for (pt = entry; pt; pt = pt->next) {
+ switch (pt->type) {
+ case dmxConfigComment: dmxConfigPrintComment(pt->comment); break;
+ case dmxConfigVirtual: dmxConfigPrintVirtual(pt->virtual); break;
+ default:
+ dmxConfigLog("dmxConfigPrint: cannot handle type %d in entry\n",
+ pt->type);
+ }
+ }
+ if (pos) dmxConfigNewline();
+}
+
+void dmxConfigVirtualPrint(FILE *stream, DMXConfigVirtualPtr p)
+{
+ if (!stream) str = stdout;
+ else str = stream;
+
+ stack = &initialStack;
+
+ dmxConfigPrintVirtual(p);
+ if (pos) dmxConfigNewline();
+}