Current Version: 1.0.33
Project Name: csspp
expr_equality.cpp
Go to the documentation of this file.
1// Copyright (c) 2015-2025 Made to Order Software Corp. All Rights Reserved
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License along
14// with this program; if not, write to the Free Software Foundation, Inc.,
15// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16
26#include "csspp/expression.h"
27
28#include "csspp/exception.h"
29#include "csspp/parser.h"
30#include "csspp/unicode_range.h"
31
32#include <algorithm>
33#include <cmath>
34#include <iostream>
35
36namespace csspp
37{
38
39namespace
40{
41
43{
44 std::string s;
45 std::string l;
46
47 switch(mix_node_types(lhs->get_type(), rhs->get_type()))
48 {
50 s = lhs->get_string();
51 l = rhs->get_string();
52 break;
53
54 default:
55 error::instance() << lhs->get_position()
56 << "incompatible types between "
57 << lhs->get_type()
58 << " and "
59 << rhs->get_type()
60 << " for operator '~=', '^=', '$=', '*=', '|='."
62 return lhs->get_string() == rhs->get_string();
63
64 }
65
66 switch(op)
67 {
69 l = " " + l + " ";
70 s = " " + s + " ";
71 break;
72
74 if(l.length() < s.length())
75 {
76 return false;
77 }
78 return s == l.substr(0, s.length());
79
81 if(l.length() < s.length())
82 {
83 return false;
84 }
85 return s == l.substr(l.length() - s.length());
86
88 break;
89
91 l = "-" + l + "-";
92 s = "-" + s + "-";
93 break;
94
95 default: // LCOV_EXCL_LINE
96 throw csspp_exception_logic("expression.cpp:include_match(): called with an invalid operator."); // LCOV_EXCL_LINE
97
98 }
99
100 return l.find(s) != std::string::npos;
101}
102
104{
105 switch(n->get_type())
106 {
107 // return type as is
115 return n->get_type();
116
118 {
119 if(n->get_string() == "not-equal")
120 {
122 }
123 }
124#if __cplusplus >= 201700
125 [[fallthrough]];
126#endif
127 default:
129
130 }
131}
132
133} // no name namespace
134
136{
137 switch(mix_node_types(lhs->get_type(), rhs->get_type()))
138 {
143 return true;
144
149 if(lhs->get_string() == rhs->get_string())
150 {
151 return true;
152 }
153 break;
154
155 }
156
157 // dimensions must be exactly the same or the comparison fails
158 error::instance() << lhs->get_position()
159 << "incompatible types or dimensions between "
160 << lhs->get_type()
161 << " and "
162 << rhs->get_type()
163 << " for operator '=', '!=', '<', '<=', '>', '>=', '~=', '^=', '$=', '*=', or '|='."
165
166 return false;
167}
168
170{
171 switch(mix_node_types(lhs->get_type(), rhs->get_type()))
172 {
174 return lhs->get_boolean() == rhs->get_boolean();
175
177 return lhs->get_integer() == rhs->get_integer();
178
180#pragma GCC diagnostic push
181#pragma GCC diagnostic ignored "-Wfloat-equal"
182 return lhs->get_integer() == rhs->get_decimal_number();
183#pragma GCC diagnostic pop
184
186#pragma GCC diagnostic push
187#pragma GCC diagnostic ignored "-Wfloat-equal"
188 return lhs->get_decimal_number() == rhs->get_integer();
189#pragma GCC diagnostic pop
190
192#pragma GCC diagnostic push
193#pragma GCC diagnostic ignored "-Wfloat-equal"
194 return lhs->get_decimal_number() == rhs->get_decimal_number();
195#pragma GCC diagnostic pop
196
198#pragma GCC diagnostic push
199#pragma GCC diagnostic ignored "-Wfloat-equal"
200 return lhs->get_decimal_number() == rhs->get_decimal_number();
201#pragma GCC diagnostic pop
202
204 return lhs->get_string() == rhs->get_string();
205
207 {
208 color const lc(lhs->get_color());
209 color const rc(rhs->get_color());
210 return lc.get_color() == rc.get_color();
211 }
212
213 }
214
215 // the is_comparable() function prevents us from reaching this line
216 throw csspp_exception_logic("expression.cpp:include_match(): called with an invalid set of node types."); // LCOV_EXCL_LINE
217}
218
220{
221 // equality: relational
222 // | equality '=' relational
223 // | equality '!=' relational
224 // | equality '~=' relational
225 // | equality '^=' relational
226 // | equality '$=' relational
227 // | equality '*=' relational
228 // | equality '|=' relational
229
230 node::pointer_t result(relational());
231 if(!result)
232 {
233 return node::pointer_t();
234 }
235
236 node_type_t op(equality_operator(f_current));
237 while(op != node_type_t::UNKNOWN)
238 {
239 position pos(f_current->get_position());
240
241 // skip the equality operator
242 next();
243
245 if(rhs == nullptr)
246 {
247 return node::pointer_t();
248 }
249
250 // apply the equality operation
251 bool boolean_result(false);
252 if(is_comparable(result, rhs))
253 {
254 switch(op)
255 {
257 boolean_result = is_equal(result, rhs);
258 break;
259
261 boolean_result = !is_equal(result, rhs);
262 break;
263
269 boolean_result = match(op, result, rhs);
270 break;
271
272 default: // LCOV_EXCL_LINE
273 throw csspp_exception_logic("expression.cpp:equality(): unexpected operator in 'op'."); // LCOV_EXCL_LINE
274
275 }
276 result.reset(new node(node_type_t::BOOLEAN, pos));
277 result->set_boolean(boolean_result);
278 }
279
280 op = equality_operator(f_current);
281 }
282
283 return result;
284}
285
286} // namespace csspp
287
288// Local Variables:
289// mode: cpp
290// indent-tabs-mode: nil
291// c-basic-offset: 4
292// tab-width: 4
293// End:
294
295// vim: ts=4 sw=4 et
rgba_color_t get_color() const
Definition color.cpp:467
static error & instance()
Definition error.cpp:77
node::pointer_t equality()
node::pointer_t f_current
Definition expression.h:155
node::pointer_t relational()
bool is_comparable(node::pointer_t lhs, node::pointer_t rhs)
bool is_equal(node::pointer_t lhs, node::pointer_t rhs)
std::shared_ptr< node > pointer_t
Definition node.h:132
bool match(node_type_t op, node::pointer_t lhs, node::pointer_t rhs)
node_type_t equality_operator(node::pointer_t n)
The namespace of all the classes in the CSS Preprocessor.
Definition csspp.h:48
node_type_t
Definition node.h:41
int32_t constexpr mix_node_types(node_type_t a, node_type_t b)
Definition node.h:119

Documentation of CSS Preprocessor.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.