Fixing some GCC warnings
[qt-netbsd.git] / src / xmlpatterns / data / qatomicmathematicians.cpp
blobbb167af6c376bdf075fc5683afa331b841a0725f
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
42 #include <math.h>
44 #include <qnumeric.h>
46 #include "qabstractdatetime_p.h"
47 #include "qabstractduration_p.h"
48 #include "qabstractfloat_p.h"
49 #include "qdaytimeduration_p.h"
50 #include "qdecimal_p.h"
51 #include "qinteger_p.h"
52 #include "qpatternistlocale_p.h"
54 #include "qatomicmathematicians_p.h"
56 QT_BEGIN_NAMESPACE
58 using namespace QPatternist;
60 /* The translation strings is place here once, in order to reduce work for translators,
61 * and provide consistency. */
63 static inline QString idivZeroInvalid()
65 return QtXmlPatterns::tr("Integer division (%1) by zero (%2) is undefined.")
66 .arg(formatKeyword("idiv"))
67 .arg(formatData("0"));
70 static inline QString divZeroInvalid()
72 return QtXmlPatterns::tr("Division (%1) by zero (%2) is undefined.")
73 .arg(formatKeyword("div"))
74 .arg(formatData("0"));
77 static inline QString modZeroInvalid()
79 return QtXmlPatterns::tr("Modulus division (%1) by zero (%2) is undefined.")
80 .arg(formatKeyword("mod"))
81 .arg(formatData("0"));
84 Item DecimalMathematician::calculate(const Item &o1,
85 const Operator op,
86 const Item &o2,
87 const QExplicitlySharedDataPointer<DynamicContext> &context) const
89 switch(op)
91 case Div:
93 if(o2.as<Numeric>()->toInteger() == 0)
95 context->error(divZeroInvalid(), ReportContext::FOAR0001, this);
96 return Item(); /* Silences source code analyzer warning. */
98 else
99 return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() / o2.as<Numeric>()->toDecimal()));
101 case IDiv:
103 if(o2.as<Numeric>()->toInteger() == 0)
105 context->error(idivZeroInvalid(), ReportContext::FOAR0001, this);
106 return Item(); /* Silences source code analyzer warning. */
108 else
109 return Integer::fromValue(static_cast<xsInteger>(o1.as<Numeric>()->toDecimal() /
110 o2.as<Numeric>()->toDecimal()));
112 case Substract:
113 return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() - o2.as<Numeric>()->toDecimal()));
114 case Mod:
116 if(o2.as<Numeric>()->toInteger() == 0)
118 context->error(modZeroInvalid(), ReportContext::FOAR0001, this);
119 return Item(); /* Silences source code analyzer warning. */
121 else
122 return toItem(Decimal::fromValue(::fmod(o1.as<Numeric>()->toDecimal(), o2.as<Numeric>()->toDecimal())));
124 case Multiply:
125 return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() * o2.as<Numeric>()->toDecimal()));
126 case Add:
127 return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() + o2.as<Numeric>()->toDecimal()));
130 Q_ASSERT(false);
131 return Item(); /* GCC unbarfer. */
134 Item IntegerMathematician::calculate(const Item &o1,
135 const Operator op,
136 const Item &o2,
137 const QExplicitlySharedDataPointer<DynamicContext> &context) const
139 switch(op)
141 case Div:
142 if(o2.as<Numeric>()->toInteger() == 0)
144 context->error(divZeroInvalid(), ReportContext::FOAR0001, this);
145 return Item(); /* Silences source code analyzer warning. */
147 else /* C++ automatically performs truncation of long integer(xsInteger). */
148 return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() / o2.as<Numeric>()->toDecimal()));
149 case IDiv:
151 if(o2.as<Numeric>()->toInteger() == 0)
153 context->error(idivZeroInvalid(), ReportContext::FOAR0001, this);
154 return Item(); /* Silences source code analyzer warning. */
156 else /* C++ automatically performs truncation of long integer(xsInteger). */
157 return Integer::fromValue(o1.as<Numeric>()->toInteger() / o2.as<Numeric>()->toInteger());
159 case Substract:
160 return Integer::fromValue(o1.as<Numeric>()->toInteger() - o2.as<Numeric>()->toInteger());
161 case Mod:
163 const xsInteger divisor = o2.as<Numeric>()->toInteger();
165 if(divisor == 0)
167 context->error(modZeroInvalid(), ReportContext::FOAR0001, this);
168 return Item(); /* Silences source code analyzer warning. */
170 else
171 return Integer::fromValue(o1.as<Numeric>()->toInteger() % divisor);
173 case Multiply:
174 return Integer::fromValue(o1.as<Numeric>()->toInteger() * o2.as<Numeric>()->toInteger());
175 case Add:
176 return Integer::fromValue(o1.as<Numeric>()->toInteger() + o2.as<Numeric>()->toInteger());
179 Q_ASSERT(false);
180 return Item(); /* GCC unbarfer. */
183 Item DurationNumericMathematician::calculate(const Item &o1,
184 const Operator op,
185 const Item &o2,
186 const QExplicitlySharedDataPointer<DynamicContext> &context) const
188 Q_ASSERT(op == Div || op == Multiply);
190 const AbstractDuration::Ptr duration(o1.as<AbstractDuration>());
191 const xsDouble dbl = o2.as<Numeric>()->toDouble();
193 switch(op)
195 case Div:
197 if(qIsInf(dbl))
198 return duration->fromValue(0);
199 else if(qIsNaN(dbl))
201 context->error(QtXmlPatterns::tr(
202 "Dividing a value of type %1 by %2 (not-a-number) "
203 "is not allowed.")
204 .arg(formatType(context->namePool(),
205 duration->type()))
206 .arg(formatData("NaN")),
207 ReportContext::FOCA0005,
208 this);
209 return Item();
211 else if(Double::isEqual(dbl, 0))
213 context->error(QtXmlPatterns::tr(
214 "Dividing a value of type %1 by %2 or %3 (plus or "
215 "minus zero) is not allowed.")
216 .arg(formatType(context->namePool(),
217 duration->type()))
218 .arg(formatData("-0"))
219 .arg(formatData("0")),
220 ReportContext::FODT0002,
221 this);
222 return Item();
225 return duration->fromValue(static_cast<AbstractDuration::Value>(duration->value() / dbl));
227 case Multiply:
229 if(Double::isEqual(dbl, 0))
230 return duration->fromValue(0);
231 else if(qIsNaN(dbl))
233 context->error(QtXmlPatterns::tr(
234 "Dividing a value of type %1 by %2 (not-a-number) "
235 "is not allowed.")
236 .arg(formatType(context->namePool(),
237 duration->type()))
238 .arg(formatData("NaN")),
239 ReportContext::FOCA0005,
240 this);
241 return Item();
243 else if(qIsInf(dbl))
245 context->error(QtXmlPatterns::tr(
246 "Multiplication of a value of type %1 by %2 or %3 "
247 "(plus or minus infinity) is not allowed.")
248 .arg(formatType(context->namePool(),
249 duration->type()))
250 .arg(formatData("-INF"))
251 .arg(formatData("INF")),
252 ReportContext::FODT0002,
253 this);
254 return Item();
257 return duration->fromValue(static_cast<AbstractDuration::Value>(duration->value() * dbl));
259 default:
261 Q_ASSERT(false);
262 return Item(); /* Silence warning. */
267 Item DurationDurationMathematician::calculate(const Item &o1,
268 const Operator op,
269 const Item &o2,
270 const QExplicitlySharedDataPointer<DynamicContext> &) const
272 const AbstractDuration::Ptr duration(o1.as<AbstractDuration>());
273 const AbstractDuration::Value op2 = o2.as<AbstractDuration>()->value();
275 switch(op)
277 case Div:
278 return toItem(Decimal::fromValue(static_cast<xsDecimal>(duration->value()) / op2));
279 case Substract:
280 return duration->fromValue(duration->value() - op2);
281 case Add:
282 return duration->fromValue(duration->value() + op2);
283 default:
285 Q_ASSERT(false);
286 return Item(); /* Silence warning. */
291 OperandSwitcherMathematician::
292 OperandSwitcherMathematician(const AtomicMathematician::Ptr &mathematician) : m_mather(mathematician)
294 Q_ASSERT(mathematician);
297 Item OperandSwitcherMathematician::calculate(const Item &o1,
298 const Operator op,
299 const Item &o2,
300 const QExplicitlySharedDataPointer<DynamicContext> &context) const
302 return m_mather->calculate(o2, op, o1, context);
306 Item DateTimeDurationMathematician::calculate(const Item &o1,
307 const Operator op,
308 const Item &o2,
309 const QExplicitlySharedDataPointer<DynamicContext> &context) const
311 Q_ASSERT(op == Substract || op == Add);
313 const AbstractDateTime::Ptr adt(o1.as<AbstractDateTime>());
314 const AbstractDuration::Ptr dur(o2.as<AbstractDuration>());
315 QDateTime dt(adt->toDateTime());
316 //pDebug() << "DateTimeDurationMathematician::calculate():" << dt.toString();
317 //dt.setDateOnly(false);
318 const qint8 sign = (op == Add ? 1 : -1) * (dur->isPositive() ? 1 : -1);
320 // TODO milli seconds
321 dt = dt.addSecs(sign * (dur->seconds() + dur->minutes() * 60 + dur->hours() * 60 * 60));
322 dt = dt.addDays(sign * dur->days());
323 dt = dt.addMonths(sign * dur->months());
324 dt = dt.addYears(sign * dur->years());
326 QString msg;
328 if(AbstractDateTime::isRangeValid(dt.date(), msg))
329 return adt->fromValue(dt);
330 else
332 context->error(msg, ReportContext::FODT0001,
333 this);
334 return Item();
338 Item AbstractDateTimeMathematician::calculate(const Item &o1,
339 const Operator op,
340 const Item &o2,
341 const QExplicitlySharedDataPointer<DynamicContext> &) const
343 Q_ASSERT(op == Substract || op == Add);
344 QDateTime dt1(o1.as<AbstractDateTime>()->toDateTime());
345 QDateTime dt2(o2.as<AbstractDateTime>()->toDateTime());
347 const int diff = op == Add ? dt1.secsTo(dt2) : dt2.secsTo(dt1);
349 return toItem(DayTimeDuration::fromSeconds(diff));
352 QT_END_NAMESPACE