include: Generate rmxftmpl.h from rmxftmpl.x using new build tool. (try 2)
Dylan Smith
dylan.ah.smith at gmail.com
Thu Apr 21 14:24:30 CDT 2011
---
.gitignore | 2 +
Make.rules.in | 4 +-
Make.vars.in | 1 +
include/Makefile.in | 8 +-
include/rmxftmpl.x | 268 ++++++++++++++++++++++++++
tools/Makefile.in | 5 +
tools/binencxftmpl.c | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 798 insertions(+), 2 deletions(-)
create mode 100644 include/rmxftmpl.x
create mode 100644 tools/binencxftmpl.c
diff --git a/.gitignore b/.gitignore
index 84bddc8..0a6d00d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -216,6 +216,7 @@ include/propsys.h
include/pstore.h
include/qedit.h
include/richole.h
+include/rmxftmpl.h
include/sensevts.h
include/servprov.h
include/shdeprecated.h
@@ -279,6 +280,7 @@ tools/make_ctests
tools/makedep
tools/relpath
tools/sfnt2fnt
+tools/binencxftmpl
tools/widl/parser.tab.c
tools/widl/parser.tab.h
tools/widl/parser.yy.c
diff --git a/Make.rules.in b/Make.rules.in
index cd9c22e..53c7298 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -27,7 +27,7 @@ IDL_GEN_HEADERS = $(IDL_H_SRCS:.idl=.h) $(IDL_C_SRCS:.idl=.h) $(IDL_I_SRCS:.idl=
CLEAN_FILES = *.o *.a *.so *.ln *.res *.fake *.$(LIBEXT) \\\#*\\\# *~ *% .\\\#* *.bak *.orig *.rej *.flc core
CLEAN_TARGETS = $(IDL_GEN_C_SRCS) $(IDL_GEN_HEADERS) $(IDL_TLB_SRCS:.idl=.tlb) $(IDL_P_SRCS:%=dlldata.c) \
$(BISON_SRCS:.y=.tab.c) $(BISON_SRCS:.y=.tab.h) $(LEX_SRCS:.l=.yy.c) \
- $(PO_SRCS:%=rsrc.pot) $(MC_SRCS:%=msg.pot)
+ $(PO_SRCS:%=rsrc.pot) $(MC_SRCS:%=msg.pot) $(XTEMPLATE_SRCS:.x=.h)
OBJS = $(C_SRCS:.c=.o) $(BISON_SRCS:.y=.tab.o) $(LEX_SRCS:.l=.yy.o) $(IDL_GEN_C_SRCS:.c=.o) \
$(IDL_R_SRCS:.idl=_r.res) $(RC_SRCS:.rc=.res) $(MC_SRCS:.mc=.res) $(EXTRA_OBJS)
@@ -193,6 +193,8 @@ $(PO_SRCS:.rc=.res): $(ALL_PO_FILES)
$(IDL_GEN_HEADERS) $(IDL_GEN_C_SRCS) $(IDL_TLB_SRCS:.idl=.tlb) $(IDL_R_SRCS:.idl=_r.res): $(WIDL)
+$(XTEMPLATE_SRCS:.x=.h): $(BINENCXFTMPL)
+
dummy:
.PHONY: dummy
diff --git a/Make.vars.in b/Make.vars.in
index 93eec22..b3be687 100644
--- a/Make.vars.in
+++ b/Make.vars.in
@@ -62,6 +62,7 @@ WINAPI_CHECK = $(top_srcdir)/tools/winapi/winapi_check
BUILDIMAGE = $(top_srcdir)/tools/buildimage
C2MAN = $(top_srcdir)/tools/c2man.pl
RUNTEST = $(top_srcdir)/tools/runtest
+BINENCXFTMPL = $(TOOLSDIR)/tools/binencxftmpl$(TOOLSEXT)
MAKECTESTS = $(TOOLSDIR)/tools/make_ctests$(TOOLSEXT)
MAKEDEP = $(TOOLSDIR)/tools/makedep$(TOOLSEXT)
RELPATH = $(TOOLSDIR)/tools/relpath$(TOOLSEXT)
diff --git a/include/Makefile.in b/include/Makefile.in
index 1155d30..dcc40a1 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -435,6 +435,7 @@ SRCDIR_INCLUDES = \
restartmanager.h \
richedit.h \
rmxfguid.h \
+ rmxftmpl.h \
row.idl \
rowchg.idl \
rpc.h \
@@ -573,11 +574,16 @@ INSTALLDIRS = \
IDL_H_SRCS = $(PUBLIC_IDL_H_SRCS) $(PRIVATE_IDL_H_SRCS)
+XTEMPLATE_SRCS = rmxftmpl.x
+
@MAKE_RULES@
OBJDIR_INCLUDES = $(PUBLIC_IDL_H_SRCS:.idl=.h)
-all: $(IDL_H_SRCS:.idl=.h) $(IDL_TLB_SRCS:.idl=.tlb)
+all: $(IDL_H_SRCS:.idl=.h) $(IDL_TLB_SRCS:.idl=.tlb) $(XTEMPLATE_SRCS:.x=.h)
+
+rmxftmpl.h: rmxftmpl.x
+ $(BINENCXFTMPL) -i D3DRM_XTEMPLATES -s D3DRM_XTEMPLATE_BYTES -o $@ $<
install install-dev:: $(OBJDIR_INCLUDES) $(INSTALLDIRS)
for f in $(SRCDIR_INCLUDES); do case $$f in \
diff --git a/include/rmxftmpl.x b/include/rmxftmpl.x
new file mode 100644
index 0000000..e7144b0
--- /dev/null
+++ b/include/rmxftmpl.x
@@ -0,0 +1,268 @@
+xof 0302txt 0064
+// Copyright (C) 2011 Dylan Smith
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+template Header
+{
+ <3D82AB43-62DA-11CF-AB39-0020AF71E433>
+ WORD major;
+ WORD minor;
+ DWORD flags;
+}
+
+template Vector
+{
+ <3D82AB5E-62DA-11CF-AB39-0020AF71E433>
+ FLOAT x;
+ FLOAT y;
+ FLOAT z;
+}
+
+template Coords2d
+{
+ <F6F23F44-7686-11CF-8F52-0040333594A3>
+ FLOAT u;
+ FLOAT v;
+}
+
+template Matrix4x4
+{
+ <F6F23F45-7686-11CF-8F52-0040333594A3>
+ array FLOAT matrix[16];
+}
+
+template ColorRGBA
+{
+ <35FF44E0-6C7C-11CF-8F52-0040333594A3>
+ FLOAT red;
+ FLOAT green;
+ FLOAT blue;
+ FLOAT alpha;
+}
+
+template ColorRGB
+{
+ <D3E16E81-7835-11CF-8F52-0040333594A3>
+ FLOAT red;
+ FLOAT green;
+ FLOAT blue;
+}
+
+template IndexedColor
+{
+ <1630B820-7842-11CF-8F52-0040333594A3>
+ DWORD index;
+ ColorRGBA indexColor;
+}
+
+template Boolean
+{
+ <537DA6A0-CA37-11D0-941C-0080C80CFA7B>
+ DWORD truefalse;
+}
+
+template Boolean2d
+{
+ <4885AE63-78E8-11CF-8F52-0040333594A3>
+ Boolean u;
+ Boolean v;
+}
+
+template MaterialWrap
+{
+ <4885AE60-78E8-11CF-8F52-0040333594A3>
+ Boolean u;
+ Boolean v;
+}
+
+template TextureFilename
+{
+ <A42790E1-7810-11CF-8F52-0040333594A3>
+ STRING filename;
+}
+
+template Material
+{
+ <3D82AB4D-62DA-11CF-AB39-0020AF71E433>
+ ColorRGBA faceColor;
+ FLOAT power;
+ ColorRGB specularColor;
+ ColorRGB emissiveColor;
+ [ ... ]
+}
+
+template MeshFace
+{
+ <3D82AB5F-62DA-11CF-AB39-0020AF71E433>
+ DWORD nFaceVertexIndices;
+ array DWORD faceVertexIndices[nFaceVertexIndices];
+}
+
+template MeshFaceWraps
+{
+ <ED1EC5C0-C0A8-11D0-941C-0080C80CFA7B>
+ DWORD nFaceWrapValues;
+ array Boolean2d faceWrapValues[nFaceWrapValues];
+}
+
+template MeshTextureCoords
+{
+ <F6F23F40-7686-11CF-8F52-0040333594A3>
+ DWORD nTextureCoords;
+ array Coords2d textureCoords[nTextureCoords];
+}
+
+template MeshMaterialList
+{
+ <F6F23F42-7686-11CF-8F52-0040333594A3>
+ DWORD nMaterials;
+ DWORD nFaceIndexes;
+ array DWORD faceIndexes[nFaceIndexes];
+ [ Material ]
+}
+
+template MeshNormals
+{
+ <F6F23F43-7686-11CF-8F52-0040333594A3>
+ DWORD nNormals;
+ array Vector normals[nNormals];
+ DWORD nFaceNormals;
+ array MeshFace faceNormals[nFaceNormals];
+}
+
+template MeshVertexColors
+{
+ <1630B821-7842-11CF-8F52-0040333594A3>
+ DWORD nVertexColors;
+ array IndexedColor vertexColors[nVertexColors];
+}
+
+template Mesh
+{
+ <3D82AB44-62DA-11CF-AB39-0020AF71E433>
+ DWORD nVertices;
+ array Vector vertices[nVertices];
+ DWORD nFaces;
+ array MeshFace faces[nFaces];
+ [ ... ]
+}
+
+template FrameTransformMatrix
+{
+ <F6F23F41-7686-11CF-8F52-0040333594A3>
+ Matrix4x4 frameMatrix;
+}
+
+template Frame
+{
+ <3D82AB46-62DA-11CF-AB39-0020AF71E433>
+ [ ... ]
+}
+
+template FloatKeys
+{
+ <10DD46A9-775B-11CF-8F52-0040333594A3>
+ DWORD nValues;
+ array FLOAT values[nValues];
+}
+
+template TimedFloatKeys
+{
+ <F406B180-7B3B-11CF-8F52-0040333594A3>
+ DWORD time;
+ FloatKeys tfkeys;
+}
+
+template AnimationKey
+{
+ <10DD46A8-775B-11CF-8F52-0040333594A3>
+ DWORD keyType;
+ DWORD nKeys;
+ array TimedFloatKeys keys[nKeys];
+}
+
+template AnimationOptions
+{
+ <E2BF56C0-840F-11CF-8F52-0040333594A3>
+ DWORD openclosed;
+ DWORD positionquality;
+}
+
+template Animation
+{
+ <3D82AB4F-62DA-11CF-AB39-0020AF71E433>
+ [ ... ]
+}
+
+template AnimationSet
+{
+ <3D82AB50-62DA-11CF-AB39-0020AF71E433>
+ [ Animation ]
+}
+
+template InlineData
+{
+ <3A23EEA0-94B1-11D0-AB39-0020AF71E433>
+ [ BINARY ]
+}
+
+template Url
+{
+ <3A23EEA1-94B1-11D0-AB39-0020AF71E433>
+ DWORD nUrls;
+ array STRING urls[nUrls];
+}
+
+template ProgressiveMesh
+{
+ <8A63C360-997D-11D0-941C-0080C80CFA7B>
+ [ Url, InlineData ]
+}
+
+template Guid
+{
+ <A42790E0-7810-11CF-8F52-0040333594A3>
+ DWORD data1;
+ WORD data2;
+ WORD data3;
+ array UCHAR data4[8];
+}
+
+template StringProperty
+{
+ <7F0F21E0-BFE1-11D1-82C0-00A0C9697271>
+ STRING key;
+ STRING value;
+}
+
+template PropertyBag
+{
+ <7F0F21E1-BFE1-11D1-82C0-00A0C9697271>
+ [ StringProperty ]
+}
+
+template ExternalVisual
+{
+ <98116AA0-BDBA-11D1-82C0-00A0C9697271>
+ Guid guidExternalVisual;
+ [ ... ]
+}
+
+template RightHanded
+{
+ <7F5D5EA0-D53A-11D1-82C0-00A0C9697271>
+ DWORD bRightHanded;
+}
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 4c8b238..e6d3f5f 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -3,6 +3,7 @@ EXTRAINCL = @FREETYPEINCL@
FREETYPELIBS = @FREETYPELIBS@
PROGRAMS = \
+ binencxftmpl$(EXEEXT) \
fnt2bdf$(EXEEXT) \
fnt2fon$(EXEEXT) \
make_ctests$(EXEEXT) \
@@ -18,6 +19,7 @@ EXTRA_MANPAGES = \
winemaker.fr.man
C_SRCS = \
+ binencxftmpl.c \
fnt2bdf.c \
fnt2fon.c \
make_ctests.c \
@@ -41,6 +43,9 @@ all: makedep$(EXEEXT) $(PROGRAMS)
@MAKE_RULES@
+binencxftmpl$(EXEEXT): binencxftmpl.o
+ $(CC) $(CFLAGS) -o $@ binencxftmpl.o $(LDFLAGS)
+
makedep$(EXEEXT) $(EXEEXT:%=makedep): makedep.o
$(CC) $(CFLAGS) -o $@ makedep.o $(LDFLAGS)
diff --git a/tools/binencxftmpl.c b/tools/binencxftmpl.c
new file mode 100644
index 0000000..8c00f8f
--- /dev/null
+++ b/tools/binencxftmpl.c
@@ -0,0 +1,512 @@
+/*
+ * Binary encode X templates from text format.
+ *
+ * Copyright 2011 Dylan Smith
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+#include "windef.h"
+#include "guiddef.h"
+
+#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
+
+#define TOKEN_NAME 1
+#define TOKEN_STRING 2
+#define TOKEN_INTEGER 3
+#define TOKEN_GUID 5
+#define TOKEN_INTEGER_LIST 6
+#define TOKEN_FLOAT_LIST 7
+#define TOKEN_OBRACE 10
+#define TOKEN_CBRACE 11
+#define TOKEN_OPAREN 12
+#define TOKEN_CPAREN 13
+#define TOKEN_OBRACKET 14
+#define TOKEN_CBRACKET 15
+#define TOKEN_OANGLE 16
+#define TOKEN_CANGLE 17
+#define TOKEN_DOT 18
+#define TOKEN_COMMA 19
+#define TOKEN_SEMICOLON 20
+#define TOKEN_TEMPLATE 31
+#define TOKEN_WORD 40
+#define TOKEN_DWORD 41
+#define TOKEN_FLOAT 42
+#define TOKEN_DOUBLE 43
+#define TOKEN_CHAR 44
+#define TOKEN_UCHAR 45
+#define TOKEN_SWORD 46
+#define TOKEN_SDWORD 47
+#define TOKEN_VOID 48
+#define TOKEN_LPSTR 49
+#define TOKEN_UNICODE 50
+#define TOKEN_CSTRING 51
+#define TOKEN_ARRAY 52
+
+struct parser
+{
+ FILE *infile;
+ FILE *outfile;
+ int line_no;
+ UINT bytes_output;
+ BOOL(*write_bytes)(struct parser *parser, const BYTE *data, DWORD size);
+};
+
+struct keyword
+{
+ const char *word;
+ WORD token;
+};
+
+static const struct keyword reserved_words[] = {
+ {"ARRAY", TOKEN_ARRAY},
+ {"CHAR", TOKEN_CHAR},
+ {"CSTRING", TOKEN_CSTRING},
+ {"DOUBLE", TOKEN_DOUBLE},
+ {"DWORD", TOKEN_DWORD},
+ {"FLOAT", TOKEN_FLOAT},
+ {"SDWORD", TOKEN_SDWORD},
+ {"STRING", TOKEN_LPSTR},
+ {"SWORD", TOKEN_SWORD},
+ {"TEMPLATE", TOKEN_TEMPLATE},
+ {"UCHAR", TOKEN_UCHAR},
+ {"UNICODE", TOKEN_UNICODE},
+ {"VOID", TOKEN_VOID},
+ {"WORD", TOKEN_WORD}
+};
+
+static char *program_name;
+
+static inline BOOL read_byte(struct parser *parser, char *byte)
+{
+ int c = fgetc(parser->infile);
+ *byte = c;
+ return c != EOF;
+}
+
+static inline BOOL unread_byte(struct parser *parser, char last_byte)
+{
+ return ungetc(last_byte, parser->infile) != EOF;
+}
+
+static inline BOOL read_bytes(struct parser *parser, void *data, DWORD size)
+{
+ return fread(data, size, 1, parser->infile) > 0;
+}
+
+static BOOL write_c_hex_bytes(struct parser *parser, const BYTE *data, DWORD size)
+{
+ while (size--)
+ {
+ if (parser->bytes_output % 12 == 0)
+ fprintf(parser->outfile, "\n ");
+ fprintf(parser->outfile, " 0x%02x,", *data++);
+ parser->bytes_output++;
+ }
+ return TRUE;
+}
+
+static BOOL write_raw_bytes(struct parser *parser, const BYTE *data, DWORD size)
+{
+ return fwrite(data, size, 1, parser->outfile) > 0;
+}
+
+static inline BOOL write_bytes(struct parser *parser, const void *data, DWORD size)
+{
+ return parser->write_bytes(parser, data, size);
+}
+
+static inline BOOL write_byte(struct parser *parser, BYTE value)
+{
+ return write_bytes(parser, &value, sizeof(value));
+}
+
+static inline BOOL write_word(struct parser *parser, WORD value)
+{
+ return write_bytes(parser, &value, sizeof(value));
+}
+
+static inline BOOL write_dword(struct parser *parser, DWORD value)
+{
+ return write_bytes(parser, &value, sizeof(value));
+}
+
+static int compare_names(const void *a, const void *b)
+{
+ return strcasecmp(*(const char **)a, *(const char **)b);
+}
+
+static BOOL parse_keyword(struct parser *parser, const char *name)
+{
+ const struct keyword *keyword;
+
+ keyword = bsearch(&name, reserved_words, ARRAY_SIZE(reserved_words),
+ sizeof(reserved_words[0]), compare_names);
+ if (!keyword)
+ return FALSE;
+
+ return write_word(parser, keyword->token);
+}
+
+static BOOL parse_guid(struct parser *parser)
+{
+ char buf[39];
+ GUID guid;
+ DWORD tab[10];
+ BOOL ret;
+ static const char *guidfmt = "<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>";
+
+ buf[0] = '<';
+ if (!read_bytes(parser, buf + 1, 37))
+ return FALSE;
+ buf[38] = 0;
+
+ ret = sscanf(buf, guidfmt, &guid.Data1, tab, tab+1, tab+2, tab+3, tab+4, tab+5, tab+6, tab+7, tab+8, tab+9);
+ if (ret != 11) {
+ fprintf(stderr, "%s: Invalid GUID '%s' (line %d)\n",
+ program_name, buf, parser->line_no);
+ return FALSE;
+ }
+
+ guid.Data2 = tab[0];
+ guid.Data3 = tab[1];
+ guid.Data4[0] = tab[2];
+ guid.Data4[1] = tab[3];
+ guid.Data4[2] = tab[4];
+ guid.Data4[3] = tab[5];
+ guid.Data4[4] = tab[6];
+ guid.Data4[5] = tab[7];
+ guid.Data4[6] = tab[8];
+ guid.Data4[7] = tab[9];
+
+ return write_word(parser, TOKEN_GUID) &&
+ write_bytes(parser, &guid, sizeof(guid));
+}
+
+static BOOL parse_name(struct parser *parser)
+{
+ char c;
+ int len = 0;
+ char name[512];
+
+ while (read_byte(parser, &c) && len < sizeof(name) &&
+ (isalnum(c) || c == '_' || c == '-'))
+ {
+ if (len + 1 < sizeof(name))
+ name[len++] = c;
+ }
+ unread_byte(parser, c);
+ name[len] = 0;
+
+ if (parse_keyword(parser, name)) {
+ return TRUE;
+ } else {
+ return write_word(parser, TOKEN_NAME) &&
+ write_dword(parser, len) &&
+ write_bytes(parser, name, len);
+ }
+}
+
+static BOOL parse_number(struct parser *parser)
+{
+ int len = 0;
+ char c;
+ char buffer[512];
+ BOOL dot = FALSE;
+ BOOL ret;
+
+ while (read_byte(parser, &c) &&
+ ((!len && c == '-') || (!dot && c == '.') || isdigit(c)))
+ {
+ if (len + 1 < sizeof(buffer))
+ buffer[len++] = c;
+ if (c == '.')
+ dot = TRUE;
+ }
+ unread_byte(parser, c);
+ buffer[len] = 0;
+
+ if (dot) {
+ float value;
+ ret = sscanf(buffer, "%f", &value);
+ if (!ret)
+ fprintf(stderr, "%s: Invalid float token (line %d).\n",
+ program_name, parser->line_no);
+ else
+ ret = write_word(parser, TOKEN_FLOAT) &&
+ write_bytes(parser, &value, sizeof(value));
+ } else {
+ int value;
+ ret = sscanf(buffer, "%d", &value);
+ if (!ret)
+ fprintf(stderr, "%s: Invalid integer token (line %d).\n",
+ program_name, parser->line_no);
+ else
+ ret = write_word(parser, TOKEN_INTEGER) &&
+ write_dword(parser, value);
+ }
+
+ return ret;
+}
+
+BOOL parse_token(struct parser *parser)
+{
+ char c;
+
+ if (!read_byte(parser, &c))
+ return FALSE;
+
+ switch (c)
+ {
+ case '\n':
+ parser->line_no++;
+ /* fall through */
+ case '\r':
+ case ' ':
+ case '\t':
+ return TRUE;
+
+ case '{': return write_word(parser, TOKEN_OBRACE);
+ case '}': return write_word(parser, TOKEN_CBRACE);
+ case '[': return write_word(parser, TOKEN_OBRACKET);
+ case ']': return write_word(parser, TOKEN_CBRACKET);
+ case '(': return write_word(parser, TOKEN_OPAREN);
+ case ')': return write_word(parser, TOKEN_CPAREN);
+ case ',': return write_word(parser, TOKEN_COMMA);
+ case ';': return write_word(parser, TOKEN_SEMICOLON);
+ case '.': return write_word(parser, TOKEN_DOT);
+
+ case '/':
+ if (!read_byte(parser, &c) || c != '/') {
+ fprintf(stderr, "%s: Invalid single '/' comment token (line %d).\n",
+ program_name, parser->line_no);
+ return FALSE;
+ }
+ /* fall through */
+ case '#':
+ while (read_byte(parser, &c) && c != '\n');
+ return c == '\n';
+
+ case '<':
+ return parse_guid(parser);
+
+ case '"':
+ {
+ int len = 0;
+ char buffer[512];
+
+ /* FIXME: Handle '\' (e.g. "valid\"string") */
+ while (read_byte(parser, &c) && c != '"') {
+ if (len + 1 < sizeof(buffer))
+ buffer[len++] = c;
+ }
+ if (c == EOF) {
+ fprintf(stderr, "%s: Unterminated string (line %d).\n",
+ program_name, parser->line_no);
+ return FALSE;
+ }
+ return write_word(parser, TOKEN_STRING) &&
+ write_dword(parser, len) &&
+ write_bytes(parser, buffer, len);
+ }
+
+ default:
+ unread_byte(parser, c);
+ if (isdigit(c) || c == '-')
+ return parse_number(parser);
+ if (isalpha(c) || c == '_')
+ return parse_name(parser);
+ fprintf(stderr, "%s: Invalid character (%d) to start token (line %d).\n",
+ program_name, c, parser->line_no);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: %s [OPTIONS] INFILE\n"
+ "Options:\n"
+ " -i NAME Output to a c header file, data in variable NAME\n"
+ " -s NAME In a c header file, define NAME to be the data size\n"
+ " -o FILE Write output to FILE\n",
+ program_name);
+}
+
+static char *option_inc_var_name = NULL;
+static char *option_inc_size_name = NULL;
+static const char *option_outfile_name = "-";
+
+static char **parse_options(int argc, char **argv)
+{
+ int optc;
+
+ while ((optc = getopt(argc, argv, "hi:o:s:")) != -1)
+ {
+ switch (optc)
+ {
+ case 'h':
+ usage();
+ exit(0);
+ case 'i':
+ option_inc_var_name = strdup(optarg);
+ break;
+ case 'o':
+ option_outfile_name = strdup(optarg);
+ break;
+ case 's':
+ option_inc_size_name = strdup(optarg);
+ break;
+ }
+ }
+ return &argv[optind];
+}
+
+int main(int argc, char **argv)
+{
+ const char *infile_name;
+ int ret = 1;
+ char header[16];
+ struct parser parser;
+ char **args;
+ char *header_name = NULL;
+
+ program_name = argv[0];
+
+ args = parse_options(argc, argv);
+ infile_name = *args++;
+ if (!infile_name || *args)
+ {
+ usage();
+ return 1;
+ }
+
+ parser.infile = stdin;
+ parser.outfile = stdout;
+
+ if (!strcmp(infile_name, "-")) {
+ infile_name = "stdin";
+ } else if (!(parser.infile = fopen(infile_name, "rb"))) {
+ perror(infile_name);
+ goto done;
+ }
+
+ if (!strcmp(option_outfile_name, "-")) {
+ option_outfile_name = "stdout";
+ } else if (!(parser.outfile = fopen(option_outfile_name, "wb"))) {
+ perror(option_outfile_name);
+ goto done;
+ }
+
+ if (!read_bytes(&parser, header, sizeof(header)))
+ goto done;
+ if (strncmp(header, "xof ", 4))
+ {
+ fprintf(stderr, "%s: Invalid magic value '%.4s'\n", program_name, header);
+ goto done;
+ }
+ if (strncmp(header + 4, "0302", 4) && strncmp(header + 4, "0303", 4))
+ {
+ fprintf(stderr, "%s: Unsupported version '%.4s'\n", program_name, header + 4);
+ goto done;
+ }
+ if (strncmp(header + 8, "txt ", 4))
+ {
+ fprintf(stderr, "%s: Only support conversion from text encoded X files.",
+ program_name);
+ goto done;
+ }
+ if (strncmp(header + 12, "0032", 4) && strncmp(header + 12, "0064", 4))
+ {
+ fprintf(stderr, "%s: Only 32-bit or 64-bit float format supported, not '%.4s'.\n",
+ program_name, header + 12);
+ goto done;
+ }
+
+ if (option_inc_var_name)
+ {
+ char *str_ptr;
+
+ header_name = strrchr(option_outfile_name, '/');
+ if (header_name)
+ header_name = strdup(header_name + 1);
+ else
+ header_name = strdup(option_outfile_name);
+ if (!header_name) {
+ fprintf(stderr, "Out of memory\n");
+ goto done;
+ }
+
+ str_ptr = header_name;
+ while (*str_ptr) {
+ if (*str_ptr == '.')
+ *str_ptr++ = '_';
+ else
+ *str_ptr++ = toupper(*str_ptr);
+ }
+
+ fprintf(parser.outfile,
+ "/* File generated automatically from %s; do not edit */\n"
+ "\n"
+ "#ifndef __WINE_%s\n"
+ "#define __WINE_%s\n"
+ "\n"
+ "unsigned char %s[] = {",
+ infile_name, header_name, header_name, option_inc_var_name);
+
+ parser.write_bytes = &write_c_hex_bytes;
+ } else {
+ parser.write_bytes = &write_raw_bytes;
+ }
+
+ parser.bytes_output = 0;
+ if (!write_bytes(&parser, "xof 0302bin 0064", 16))
+ goto done;
+
+ parser.line_no = 1;
+ while (parse_token(&parser));
+
+ if (option_inc_var_name)
+ {
+ fprintf(parser.outfile, "\n};\n\n");
+ if (option_inc_size_name)
+ fprintf(parser.outfile, "#define %s %u\n\n", option_inc_size_name, parser.bytes_output);
+ fprintf(parser.outfile, "#endif /* __WINE_%s */\n", header_name);
+ }
+
+ ret = ferror(parser.outfile) ? 1 : 0;
+done:
+ if (parser.infile) {
+ if (ferror(parser.infile))
+ perror(infile_name);
+ fclose(parser.infile);
+ }
+ if (parser.outfile) {
+ if (ferror(parser.outfile))
+ perror(option_outfile_name);
+ fclose(parser.outfile);
+ }
+ return ret;
+}
--
1.7.2.5
More information about the wine-patches
mailing list