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

Documentation of CSS Preprocessor.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.