UFO: Alien Invasion
Loading...
Searching...
No Matches
binaryexpressionparser.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright (C) 2002-2025 UFO: Alien Invasion.
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23*/
24
26#include "common.h"
27
32
37private:
41 bool result;
42 const void* userdata;
43
44 inline void SkipWhiteSpaces (const char** s) const
45 {
46 while (**s == ' ' || **s == '\t')
47 (*s)++;
48 }
49
53 inline void NextChar (const char** s) const
54 {
55 (*s)++;
56 /* skip white-spaces too */
58 }
59
60 const char* GetSwitchName (const char** s)
61 {
62 int pos = 0;
63
64 /* skip non printable chars and special chars that are used to define the binary expression */
65 while (**s > ' ' && **s != '^' && **s != '|' && **s != '&' && **s != '!' && **s != '(' && **s != ')') {
66 varName[pos++] = **s;
67 (*s)++;
68 }
69 varName[pos] = '\0';
70
71 return varName;
72 }
73
79 bool CheckOR (const char** s)
80 {
81 bool result = false;
82 enum {
83 BEP_NONE, BEP_OR, BEP_EXCLUSIVE_OR
84 };
85 int goOn = BEP_NONE;
86
88 do {
89 if (goOn == BEP_EXCLUSIVE_OR)
90 result ^= CheckAND(s);
91 else
92 result |= CheckAND(s);
93
94 if (**s == '|') {
95 goOn = BEP_OR;
96 NextChar(s);
97 } else if (**s == '^') {
98 goOn = BEP_EXCLUSIVE_OR;
99 NextChar(s);
100 } else {
101 goOn = BEP_NONE;
102 }
103 } while (goOn != BEP_NONE && !binaryExpressionParserError);
104
105 return result;
106 }
107
108 bool CheckAND (const char** s)
109 {
110 bool result = true;
111 bool negate = false;
112 bool goOn = false;
113
114 do {
115 /* parse all negate chars and swap the flag accordingly */
116 while (**s == '!') {
117 negate ^= true;
118 NextChar(s);
119 }
120 /* handling braces */
121 if (**s == '(') {
122 NextChar(s);
123 /* and the result of the inner clause by calling the entry
124 * point again (and apply the negate flag) */
125 result &= CheckOR(s) ^ negate;
126 if (**s != ')')
128 NextChar(s);
129 } else {
130 /* get the variable state by calling the evaluate callback */
131 const int value = varFunc(GetSwitchName(s), userdata);
132 if (value == -1)
134 else
135 result &= value ^ negate;
137 }
138
139 /* check whether there is another and clause */
140 if (**s == '&') {
141 goOn = true;
142 NextChar(s);
143 } else {
144 goOn = false;
145 }
146 negate = false;
147 } while (goOn && !binaryExpressionParserError);
148
149 return result;
150 }
151
152public:
153 BinaryExpressionParser (const char* expr, BEPEvaluteCallback_t varFuncParam, const void* userdataPtr) :
154 binaryExpressionParserError(BEPERR_NONE), varFunc(varFuncParam), userdata(userdataPtr)
155 {
156 varName[0] = 0;
157 const char* str = expr;
158 result = CheckOR(&str);
159 /* check for no end error */
162 }
163
164 inline bool getResult() const
165 {
166 return result;
167 }
168
173};
174
175bool BEP_Evaluate (const char* expr, BEPEvaluteCallback_t varFuncParam, const void* userdata)
176{
177 if (!Q_strvalid(expr))
178 return true;
179
180 BinaryExpressionParser bep(expr, varFuncParam, userdata);
181 const bool result = bep.getResult();
182 const binaryExpressionParserError_t error = bep.getError();
183
184 switch (error) {
185 case BEPERR_NONE:
186 /* do nothing */
187 return result;
188 case BEPERR_BRACE:
189 Com_Printf("')' expected in binary expression (%s).\n", expr);
190 return true;
191 case BEPERR_NOEND:
192 Com_Printf("Unexpected end of condition in binary expression (%s).\n", expr);
193 return result;
194 case BEPERR_NOTFOUND:
195 Com_Printf("Variable not found in binary expression (%s).\n", expr);
196 return false;
197 }
198 Com_Error(ERR_FATAL, "Unknown CheckBEP error in binary expression (%s)", expr);
199}
binaryExpressionParserError_t
bool BEP_Evaluate(const char *expr, BEPEvaluteCallback_t varFuncParam, const void *userdata)
int(* BEPEvaluteCallback_t)(const char *var, const void *userdata)
Evaluates stuff like this expression.
const char * GetSwitchName(const char **s)
void NextChar(const char **s) const
Advance to the next char that is no whitespace.
binaryExpressionParserError_t getError() const
binaryExpressionParserError_t binaryExpressionParserError
BinaryExpressionParser(const char *expr, BEPEvaluteCallback_t varFuncParam, const void *userdataPtr)
bool CheckOR(const char **s)
Evaluates or and xor in the given string. This is the entry point, it delegates to the and checks tha...
void SkipWhiteSpaces(const char **s) const
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
definitions common between client and server, but not game lib
#define ERR_FATAL
Definition common.h:210
#define Q_strvalid(string)
Definition shared.h:141
#define MAX_VAR
Definition shared.h:36