diff options
author | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-05-13 13:31:14 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-05-25 06:18:55 +0000 |
commit | d3cc25ef52d0b2b7ba1cb06609f7c205ee19c2d6 (patch) | |
tree | ff902c67105d8cb005511103a63d44ec761629b7 | |
parent | 3d21634fb693634b7d41a152287d29afb80ac5e2 (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.qdoc | 21 | ||||
-rw-r--r-- | qmake/library/qmakebuiltins.cpp | 28 | ||||
-rw-r--r-- | tests/auto/tools/qmakelib/evaltest.cpp | 42 |
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 =" |