1 /*
2 ===========================================================================
3 Copyright (C) 1999 - 2005, Id Software, Inc.
4 Copyright (C) 2000 - 2013, Raven Software, Inc.
5 Copyright (C) 2001 - 2013, Activision, Inc.
6 Copyright (C) 2013 - 2015, OpenJK contributors
7 
8 This file is part of the OpenJK source code.
9 
10 OpenJK is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 ===========================================================================
22 */
23 
24 /*****************************************************************************
25  * name:		l_script.h
26  *
27  * desc:		lexicographical parser
28  *
29  * $Archive: /source/code/botlib/l_script.h $
30  * $Author: Mrelusive $
31  * $Revision: 2 $
32  * $Modtime: 10/05/99 3:32p $
33  * $Date: 10/05/99 3:42p $
34  *
35  *****************************************************************************/
36 
37 #pragma once
38 
39 //undef if binary numbers of the form 0b... or 0B... are not allowed
40 #define BINARYNUMBERS
41 //undef if not using the token.intvalue and token.floatvalue
42 #define NUMBERVALUE
43 //use dollar sign also as punctuation
44 #define DOLLAR
45 
46 //maximum token length
47 #define MAX_TOKEN					1024
48 
49 #if defined(BSPC) && !defined(QDECL)
50 #define QDECL
51 #endif
52 
53 
54 //script flags
55 #define SCFL_NOERRORS				0x0001
56 #define SCFL_NOWARNINGS				0x0002
57 #define SCFL_NOSTRINGWHITESPACES	0x0004
58 #define SCFL_NOSTRINGESCAPECHARS	0x0008
59 #define SCFL_PRIMITIVE				0x0010
60 #define SCFL_NOBINARYNUMBERS		0x0020
61 #define SCFL_NONUMBERVALUES		0x0040
62 
63 //token types
64 #define TT_STRING						1			// string
65 #define TT_LITERAL					2			// literal
66 #define TT_NUMBER						3			// number
67 #define TT_NAME						4			// name
68 #define TT_PUNCTUATION				5			// punctuation
69 
70 //string sub type
71 //---------------
72 //		the length of the string
73 //literal sub type
74 //----------------
75 //		the ASCII code of the literal
76 //number sub type
77 //---------------
78 #define TT_DECIMAL					0x0008	// decimal number
79 #define TT_HEX							0x0100	// hexadecimal number
80 #define TT_OCTAL						0x0200	// octal number
81 #ifdef BINARYNUMBERS
82 #define TT_BINARY						0x0400	// binary number
83 #endif //BINARYNUMBERS
84 #define TT_FLOAT						0x0800	// floating point number
85 #define TT_INTEGER					0x1000	// integer number
86 #define TT_LONG						0x2000	// long number
87 #define TT_UNSIGNED					0x4000	// unsigned number
88 //punctuation sub type
89 //--------------------
90 #define P_RSHIFT_ASSIGN				1
91 #define P_LSHIFT_ASSIGN				2
92 #define P_PARMS						3
93 #define P_PRECOMPMERGE				4
94 
95 #define P_LOGIC_AND					5
96 #define P_LOGIC_OR					6
97 #define P_LOGIC_GEQ					7
98 #define P_LOGIC_LEQ					8
99 #define P_LOGIC_EQ					9
100 #define P_LOGIC_UNEQ					10
101 
102 #define P_MUL_ASSIGN					11
103 #define P_DIV_ASSIGN					12
104 #define P_MOD_ASSIGN					13
105 #define P_ADD_ASSIGN					14
106 #define P_SUB_ASSIGN					15
107 #define P_INC							16
108 #define P_DEC							17
109 
110 #define P_BIN_AND_ASSIGN			18
111 #define P_BIN_OR_ASSIGN				19
112 #define P_BIN_XOR_ASSIGN			20
113 #define P_RSHIFT						21
114 #define P_LSHIFT						22
115 
116 #define P_POINTERREF					23
117 #define P_CPP1							24
118 #define P_CPP2							25
119 #define P_MUL							26
120 #define P_DIV							27
121 #define P_MOD							28
122 #define P_ADD							29
123 #define P_SUB							30
124 #define P_ASSIGN						31
125 
126 #define P_BIN_AND						32
127 #define P_BIN_OR						33
128 #define P_BIN_XOR						34
129 #define P_BIN_NOT						35
130 
131 #define P_LOGIC_NOT					36
132 #define P_LOGIC_GREATER				37
133 #define P_LOGIC_LESS					38
134 
135 #define P_REF							39
136 #define P_COMMA						40
137 #define P_SEMICOLON					41
138 #define P_COLON						42
139 #define P_QUESTIONMARK				43
140 
141 #define P_PARENTHESESOPEN			44
142 #define P_PARENTHESESCLOSE			45
143 #define P_BRACEOPEN					46
144 #define P_BRACECLOSE					47
145 #define P_SQBRACKETOPEN				48
146 #define P_SQBRACKETCLOSE			49
147 #define P_BACKSLASH					50
148 
149 #define P_PRECOMP						51
150 #define P_DOLLAR						52
151 #define	P_ATSIGN						53
152 //name sub type
153 //-------------
154 //		the length of the name
155 
156 //punctuation
157 typedef struct punctuation_s
158 {
159 	const char *p;					//punctuation character(s)
160 	int n;							//punctuation indication
161 	struct punctuation_s *next;		//next punctuation
162 } punctuation_t;
163 
164 //token
165 typedef struct token_s
166 {
167 	char string[MAX_TOKEN];			//available token
168 	int type;						//last read token type
169 	int subtype;					//last read token sub type
170 #ifdef NUMBERVALUE
171 	unsigned long int intvalue;	//integer value
172 	long double floatvalue;			//floating point value
173 #endif //NUMBERVALUE
174 	char *whitespace_p;				//start of white space before token
175 	char *endwhitespace_p;			//start of white space before token
176 	int line;						//line the token was on
177 	int linescrossed;				//lines crossed in white space
178 	struct token_s *next;			//next token in chain
179 } token_t;
180 
181 //script file
182 typedef struct script_s
183 {
184 	char filename[1024];			//file name of the script
185 	char *buffer;					//buffer containing the script
186 	char *script_p;					//current pointer in the script
187 	char *end_p;					//pointer to the end of the script
188 	char *lastscript_p;				//script pointer before reading token
189 	char *whitespace_p;				//begin of the white space
190 	char *endwhitespace_p;			//end of the white space
191 	int length;						//length of the script in bytes
192 	int line;						//current line in script
193 	int lastline;					//line before reading token
194 	int tokenavailable;				//set by UnreadLastToken
195 	int flags;						//several script flags
196 	punctuation_t *punctuations;	//the punctuations used in the script
197 	punctuation_t **punctuationtable;
198 	token_t token;					//available token
199 	struct script_s *next;			//next script in a chain
200 } script_t;
201 
202 //read a token from the script
203 int PS_ReadToken(script_t *script, token_t *token);
204 //expect a certain token
205 int PS_ExpectTokenString(script_t *script, char *string);
206 //expect a certain token type
207 int PS_ExpectTokenType(script_t *script, int type, int subtype, token_t *token);
208 //expect a token
209 int PS_ExpectAnyToken(script_t *script, token_t *token);
210 //returns true when the token is available
211 int PS_CheckTokenString(script_t *script, char *string);
212 //returns true and reads the token when a token with the given type is available
213 int PS_CheckTokenType(script_t *script, int type, int subtype, token_t *token);
214 //skip tokens until the given token string is read
215 int PS_SkipUntilString(script_t *script, char *string);
216 //unread the last token read from the script
217 void PS_UnreadLastToken(script_t *script);
218 //unread the given token
219 void PS_UnreadToken(script_t *script, token_t *token);
220 //returns the next character of the read white space, returns NULL if none
221 char PS_NextWhiteSpaceChar(script_t *script);
222 //remove any leading and trailing double quotes from the token
223 void StripDoubleQuotes(char *string);
224 //remove any leading and trailing single quotes from the token
225 void StripSingleQuotes(char *string);
226 //read a possible signed integer
227 signed long int ReadSignedInt(script_t *script);
228 //read a possible signed floating point number
229 long double ReadSignedFloat(script_t *script);
230 //set an array with punctuations, NULL restores default C/C++ set
231 void SetScriptPunctuations(script_t *script, punctuation_t *p);
232 //set script flags
233 void SetScriptFlags(script_t *script, int flags);
234 //get script flags
235 int GetScriptFlags(script_t *script);
236 //reset a script
237 void ResetScript(script_t *script);
238 //returns true if at the end of the script
239 int EndOfScript(script_t *script);
240 //returns a pointer to the punctuation with the given number
241 const char *PunctuationFromNum(script_t *script, int num);
242 //load a script from the given file at the given offset with the given length
243 script_t *LoadScriptFile(const char *filename);
244 //load a script from the given memory with the given length
245 script_t *LoadScriptMemory(char *ptr, int length, char *name);
246 //free a script
247 void FreeScript(script_t *script);
248 //set the base folder to load files from
249 void PS_SetBaseFolder(char *path);
250 //print a script error with filename and line number
251 void QDECL ScriptError(script_t *script, char *str, ...) __attribute__ ((format (printf, 2, 3)));
252 //print a script warning with filename and line number
253 void QDECL ScriptWarning(script_t *script, char *str, ...) __attribute__ ((format (printf, 2, 3)));
254