summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2016-05-13 13:31:14 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2016-05-25 06:18:55 +0000
commitd3cc25ef52d0b2b7ba1cb06609f7c205ee19c2d6 (patch)
treeff902c67105d8cb005511103a63d44ec761629b7
parent3d21634fb693634b7d41a152287d29afb80ac5e2 (diff)
add $$num_add() (numeric addition) function
amazing how we managed to do without it for so long. ^^ the name is intentionally somewhat obscure to avoid clashes, and some namespacing is good anyway. [ChangeLog][qmake] Added $$num_add() function. Change-Id: Ib7648b1f425ef096a87b51f158d0f1409e5c4daa Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r--qmake/doc/src/qmake-manual.qdoc21
-rw-r--r--qmake/library/qmakebuiltins.cpp28
-rw-r--r--tests/auto/tools/qmakelib/evaltest.cpp42
3 files changed, 89 insertions, 2 deletions
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index c196cb841a..4e69fd9897 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -2943,6 +2943,27 @@
\c position defaults to 0, causing the first value in the list to be
returned.
+ \section2 num_add(arg1 [, arg2 ..., argn])
+
+ Takes an arbitrary number of numeric arguments and adds them up,
+ returning the sum.
+
+ Subtraction is implicitly supported due to the possibility to simply
+ prepend a minus sign to a numeric value to negate it:
+
+ \code
+ sum = $$num_add($$first, -$$second)
+ \endcode
+
+ If the operand may be already negative, another step is necessary to
+ normalize the number:
+
+ \code
+ second_neg = -$$second
+ second_neg ~= s/^--//
+ sum = $$num_add($$first, $$second_neg)
+ \endcode
+
\section2 prompt(question)
Displays the specified \c question, and returns a value read from stdin.
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index e919f1a77e..9e9ebf8cc4 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -81,8 +81,8 @@ QT_BEGIN_NAMESPACE
enum ExpandFunc {
E_INVALID = 0, E_MEMBER, E_FIRST, E_TAKE_FIRST, E_LAST, E_TAKE_LAST, E_SIZE,
- E_CAT, E_FROMFILE, E_EVAL, E_LIST,
- E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
+ E_CAT, E_FROMFILE, E_EVAL, E_LIST, E_SPRINTF, E_FORMAT_NUMBER,
+ E_NUM_ADD, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
E_FIND, E_SYSTEM, E_UNIQUE, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND,
E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
@@ -116,6 +116,7 @@ void QMakeEvaluator::initFunctionStatics()
{ "list", E_LIST },
{ "sprintf", E_SPRINTF },
{ "format_number", E_FORMAT_NUMBER },
+ { "num_add", E_NUM_ADD },
{ "join", E_JOIN },
{ "split", E_SPLIT },
{ "basename", E_BASENAME },
@@ -594,6 +595,29 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
}
formfail:
break;
+ case E_NUM_ADD:
+ if (args.count() < 1 || args.at(0).isEmpty()) {
+ evalError(fL1S("num_add(num, ...) requires at least one argument."));
+ } else {
+ qlonglong sum = 0;
+ for (const ProString &arg : qAsConst(args)) {
+ if (arg.contains(QLatin1Char('.'))) {
+ evalError(fL1S("num_add(): floats are currently not supported."));
+ goto nafail;
+ }
+ bool ok;
+ qlonglong num = arg.toLongLong(&ok);
+ if (!ok) {
+ evalError(fL1S("num_add(): malformed number %1.")
+ .arg(arg.toQString(m_tmp3)));
+ goto nafail;
+ }
+ sum += num;
+ }
+ ret += ProString(QString::number(sum));
+ }
+ nafail:
+ break;
case E_JOIN: {
if (args.count() < 1 || args.count() > 4) {
evalError(fL1S("join(var, glue, before, after) requires one to four arguments."));
diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp
index 69ccf4858f..a516f91070 100644
--- a/tests/auto/tools/qmakelib/evaltest.cpp
+++ b/tests/auto/tools/qmakelib/evaltest.cpp
@@ -954,6 +954,48 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
<< "##:1: format_number(): invalid format option foo=bar."
<< true;
+ QTest::newRow("$$num_add(): one")
+ << "VAR = $$num_add(10)"
+ << "VAR = 10"
+ << ""
+ << true;
+
+ QTest::newRow("$$num_add(): two")
+ << "VAR = $$num_add(1, 2)"
+ << "VAR = 3"
+ << ""
+ << true;
+
+ QTest::newRow("$$num_add(): three")
+ << "VAR = $$num_add(1, 3, 5)"
+ << "VAR = 9"
+ << ""
+ << true;
+
+ QTest::newRow("$$num_add(): negative")
+ << "VAR = $$num_add(7, -13)"
+ << "VAR = -6"
+ << ""
+ << true;
+
+ QTest::newRow("$$num_add(): bad number of arguments")
+ << "VAR = $$num_add()"
+ << "VAR = "
+ << "##:1: num_add(num, ...) requires at least one argument."
+ << true;
+
+ QTest::newRow("$$num_add(): bad number: float")
+ << "VAR = $$num_add(1.1)"
+ << "VAR ="
+ << "##:1: num_add(): floats are currently not supported."
+ << true;
+
+ QTest::newRow("$$num_add(): bad number: malformed")
+ << "VAR = $$num_add(fail)"
+ << "VAR ="
+ << "##:1: num_add(): malformed number fail."
+ << true;
+
QTest::newRow("$$join(): empty")
<< "IN = \nVAR = $$join(IN, //)"
<< "VAR ="