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@redhat.com>
31  */
32 
33 /** \file
34  * This file provides some compatibility support for reading VDL files
35  * that are used by xmovie
36  * (http://www.llnl.gov/icc/sdd/img/xmovie/xmovie.shtml).
37  *
38  * This file is not used by the DMX server.
39  */
40 
41 #ifdef HAVE_DMX_CONFIG_H
42 #include <dmx-config.h>
43 #endif
44 
45 #include "os.h"
46 #include "dmxconfig.h"
47 #include "dmxparse.h"
48 #include "dmxcompat.h"
49 #include "parser.h"
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <ctype.h>
54 
55 static int
dmxVDLReadLine(FILE * str,char * buf,int len)56 dmxVDLReadLine(FILE * str, char *buf, int len)
57 {
58     if (fgets(buf, len, str))
59         return strlen(buf);
60     return 0;
61 }
62 
63 static int
dmxVDLCount(const char * buf)64 dmxVDLCount(const char *buf)
65 {
66     return strtol(buf, NULL, 10);
67 }
68 
69 static void
dmxVDLVirtualEntry(const char * buf,char * name,int * len,int * x,int * y)70 dmxVDLVirtualEntry(const char *buf, char *name, int *len, int *x, int *y)
71 {
72     char *end;
73     const char *s;
74     char *d;
75     int start;
76 
77     *x = strtol(buf, &end, 10);
78     *y = strtol(end, &end, 10);
79 
80     for (s = end, d = name, start = 1; *s && *s != '['; ++s) {
81         if (start && isspace(*s))
82             continue;
83         *d++ = *s;
84         start = 0;
85     }
86     *d = '\0';
87     while (d > name && isspace(d[-1]))
88         *--d = '\0';            /* remove trailing space */
89     *len = strlen(name);
90 }
91 
92 static void
dmxVDLDisplayEntry(const char * buf,char * name,int * len,int * x,int * y,int * xoff,int * yoff,int * xorig,int * yorig)93 dmxVDLDisplayEntry(const char *buf,
94                    char *name, int *len,
95                    int *x, int *y, int *xoff, int *yoff, int *xorig, int *yorig)
96 {
97     const char *pt;
98     char *end;
99 
100     pt = strchr(buf, ' ');
101     strlcpy(name, buf, 1 + pt - buf);
102     *len = strlen(name);
103 
104     *x = strtol(pt, &end, 10);
105     *y = strtol(end, &end, 10);
106     *xorig = strtol(end, &end, 10);
107     *yorig = strtol(end, &end, 10);
108     *xoff = strtol(end, &end, 10);
109     *yoff = strtol(end, NULL, 10);
110 }
111 
112 /** Read from the VDL format \a filename and return a newly allocated \a
113  * DMXConfigEntryPtr */
114 DMXConfigEntryPtr
dmxVDLRead(const char * filename)115 dmxVDLRead(const char *filename)
116 {
117     FILE *str;
118     char buf[2048];             /* RATS: Use ok */
119     char *pt;
120     int lineno = 0;
121     DMXConfigEntryPtr entry = NULL;
122     DMXConfigVirtualPtr virtual = NULL;
123     DMXConfigSubPtr sub = NULL;
124     DMXConfigDisplayPtr display = NULL;
125     DMXConfigFullDimPtr fdim = NULL;
126     int dcount = 0;
127     int icount = 0;
128     int x, y, xoff, yoff, xorig, yorig;
129     char name[2048];            /* RATS: Use ok */
130     const char *tmp;
131     int len;
132     enum {
133         simulateFlag,
134         virtualCount,
135         virtualEntry,
136         displayCount,
137         displayEntry,
138         ignoreCount,
139         ignoreEntry
140     } state = simulateFlag;
141 
142     if (!filename)
143         str = stdin;
144     else
145         str = fopen(filename, "r");
146     if (!str)
147         return NULL;
148 
149     while (dmxVDLReadLine(str, buf, sizeof(buf))) {
150         DMXConfigCommentPtr comment = NULL;
151 
152         ++lineno;
153         for (pt = buf; *pt; pt++)
154             if (*pt == '\r' || *pt == '\n') {
155                 *pt = '\0';
156                 break;
157             }
158         if (buf[0] == '#') {
159             tmp = dmxConfigCopyString(buf + 1, strlen(buf + 1));
160             comment = dmxConfigCreateComment(T_COMMENT, lineno, tmp);
161             entry = dmxConfigAddEntry(entry, dmxConfigComment, comment, NULL);
162             continue;
163         }
164         switch (state) {
165         case simulateFlag:
166             state = virtualCount;
167             break;
168         case virtualCount:
169             state = virtualEntry;
170             break;
171         case virtualEntry:
172             len = sizeof(name);
173             dmxVDLVirtualEntry(buf, name, &len, &x, &y);
174             tmp = dmxConfigCopyString(name, len);
175             virtual = dmxConfigCreateVirtual(NULL,
176                                              dmxConfigCreateString(T_STRING,
177                                                                    lineno,
178                                                                    NULL,
179                                                                    tmp),
180                                              dmxConfigCreatePair(T_DIMENSION,
181                                                                  lineno,
182                                                                  NULL,
183                                                                  x, y, 0, 0),
184                                              NULL, NULL, NULL);
185             state = displayCount;
186             break;
187         case displayCount:
188             dcount = dmxVDLCount(buf);
189             state = displayEntry;
190             break;
191         case displayEntry:
192             dmxVDLDisplayEntry(buf, name, &len, &x, &y, &xoff, &yoff,
193                                &xorig, &yorig);
194             tmp = dmxConfigCopyString(name, len);
195             fdim =
196                 dmxConfigCreateFullDim(dmxConfigCreatePartDim
197                                        (dmxConfigCreatePair
198                                         (T_DIMENSION, lineno, NULL, x, y, 0, 0),
199                                         dmxConfigCreatePair(T_OFFSET, lineno,
200                                                             NULL, xoff, yoff,
201                                                             xoff, yoff)), NULL);
202             display =
203                 dmxConfigCreateDisplay(NULL,
204                                        dmxConfigCreateString(T_STRING, lineno,
205                                                              NULL, tmp), fdim,
206                                        dmxConfigCreatePair(T_ORIGIN, lineno,
207                                                            NULL, xorig, yorig,
208                                                            0, 0), NULL);
209             sub = dmxConfigAddSub(sub, dmxConfigSubDisplay(display));
210             if (!--dcount) {
211                 state = ignoreCount;
212                 virtual->subentry = sub;
213                 entry = dmxConfigAddEntry(entry,
214                                           dmxConfigVirtual, NULL, virtual);
215                 virtual = NULL;
216                 sub = NULL;
217             }
218             break;
219         case ignoreCount:
220             icount = dmxVDLCount(buf);
221             state = ignoreEntry;
222             break;
223         case ignoreEntry:
224             if (!--icount)
225                 state = virtualEntry;
226             break;
227         }
228     }
229 
230     if (str != stdin)
231         fclose(str);
232 
233     return entry;
234 }
235