1 /*
2 ** parse_xlat.cpp
3 ** Translation definition compiler
4 **
5 **---------------------------------------------------------------------------
6 ** Copyright 1998-2008 Randy Heit
7 ** Copyright 2008 Christoph Oelckers
8 ** All rights reserved.
9 **
10 ** Redistribution and use in source and binary forms, with or without
11 ** modification, are permitted provided that the following conditions
12 ** are met:
13 **
14 ** 1. Redistributions of source code must retain the above copyright
15 **    notice, this list of conditions and the following disclaimer.
16 ** 2. Redistributions in binary form must reproduce the above copyright
17 **    notice, this list of conditions and the following disclaimer in the
18 **    documentation and/or other materials provided with the distribution.
19 ** 3. The name of the author may not be used to endorse or promote products
20 **    derived from this software without specific prior written permission.
21 **
22 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 **---------------------------------------------------------------------------
33 **
34 */
35 
36 
37 #include "doomtype.h"
38 #include "w_wad.h"
39 #include "c_console.h"
40 #include "info.h"
41 #include "gi.h"
42 #include "parsecontext.h"
43 #include "xlat_parser.h"
44 #include "xlat.h"
45 
46 
47 // Token types not used in the grammar
48 enum
49 {
50 	XLAT_INCLUDE=128,
51 	XLAT_STRING,
52 	XLAT_FLOATVAL,	// floats are not used by the grammar
53 };
54 
55 DEFINE_TOKEN_TRANS(XLAT_)
56 
57 
58 static FString LastTranslator;
59 TAutoGrowArray<FLineTrans> SimpleLineTranslations;
60 TArray<int> XlatExpressions;
61 FBoomTranslator Boomish[MAX_BOOMISH];
62 int NumBoomish;
63 TAutoGrowArray<FSectorTrans> SectorTranslations;
64 TArray<FSectorMask> SectorMasks;
65 FLineFlagTrans LineFlagTranslations[16];
66 
67 
68 struct SpecialArgs
69 {
70 	int addflags;
71 	int argcount;
72 	int args[5];
73 };
74 
75 struct SpecialArg
76 {
77 	int arg;
78 	ELineTransArgOp argop;
79 };
80 
81 struct ListFilter
82 {
83 	WORD filter;
84 	BYTE value;
85 };
86 
87 struct MoreFilters
88 {
89 	MoreFilters *next;
90 	ListFilter filter;
91 };
92 
93 struct MoreLines
94 {
95 	MoreLines *next;
96 	FBoomArg arg;
97 };
98 
99 struct ParseBoomArg
100 {
101 	BYTE constant;
102 	WORD mask;
103 	MoreFilters *filters;
104 };
105 
106 
107 struct XlatParseContext : public FParseContext
108 {
XlatParseContextXlatParseContext109 	XlatParseContext(void *parser, ParseFunc parse, int *tt)
110 		: FParseContext(parser, parse, tt)
111 	{
112 		DefiningLineType = -1;
113 	}
114 
115 	//==========================================================================
116 	//
117 	//
118 	//
119 	//==========================================================================
FindTokenXlatParseContext120 	bool FindToken (char *tok, int *type)
121 	{
122 		static const char *tokens[] =
123 		{
124 			"arg2", "arg3", "arg4", "arg5", "bitmask", "clear",
125 			"define", "enum", "flags", "include", "lineflag", "lineid",
126 			"maxlinespecial", "nobitmask", "sector", "tag"
127 		};
128 		static const short types[] =
129 		{
130 			XLAT_ARG2, XLAT_ARG3, XLAT_ARG4, XLAT_ARG5, XLAT_BITMASK, XLAT_CLEAR,
131 			XLAT_DEFINE, XLAT_ENUM, XLAT_FLAGS, XLAT_INCLUDE, XLAT_LINEFLAG, XLAT_TAG,
132 			XLAT_MAXLINESPECIAL, XLAT_NOBITMASK, XLAT_SECTOR, XLAT_TAG
133 		};
134 
135 		int min = 0, max = countof(tokens) - 1;
136 
137 		while (min <= max)
138 		{
139 			int mid = (min + max) / 2;
140 			int lexval = stricmp (tok, tokens[mid]);
141 			if (lexval == 0)
142 			{
143 				*type = types[mid];
144 				return true;
145 			}
146 			else if (lexval > 0)
147 			{
148 				min = mid + 1;
149 			}
150 			else
151 			{
152 				max = mid - 1;
153 			}
154 		}
155 		return false;
156 	}
157 
158 	int DefiningLineType;
159 };
160 
161 #include "xlat_parser.c"
162 
163 
164 //==========================================================================
165 //
166 //
167 //
168 //==========================================================================
169 
P_ClearTranslator()170 void P_ClearTranslator()
171 {
172 	SimpleLineTranslations.Clear();
173 	XlatExpressions.Clear();
174 	NumBoomish = 0;
175 	SectorTranslations.Clear();
176 	SectorMasks.Clear();
177 	memset(LineFlagTranslations, 0, sizeof(LineFlagTranslations));
178 	LastTranslator = "";
179 }
180 
P_LoadTranslator(const char * lumpname)181 void P_LoadTranslator(const char *lumpname)
182 {
183 	// Only read the lump if it differs from the previous one.
184 	if (LastTranslator.CompareNoCase(lumpname))
185 	{
186 		// Clear the old data before parsing the lump.
187 		P_ClearTranslator();
188 
189 		void *pParser = XlatParseAlloc(malloc);
190 
191 		XlatParseContext context(pParser, XlatParse, TokenTrans);
192 
193 		context.ParseLump(lumpname);
194 		FParseToken tok;
195 		tok.val=0;
196 		XlatParse(pParser, 0, tok, &context);
197 		XlatParseFree(pParser, free);
198 		LastTranslator = lumpname;
199 	}
200 }
201 
202 
203