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>
This commit is contained in:
Oswald Buddenhagen 2016-05-13 13:31:14 +02:00
parent 3d21634fb6
commit d3cc25ef52
3 changed files with 89 additions and 2 deletions

View File

@ -2943,6 +2943,27 @@
\c position defaults to 0, causing the first value in the list to be \c position defaults to 0, causing the first value in the list to be
returned. 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) \section2 prompt(question)
Displays the specified \c question, and returns a value read from stdin. Displays the specified \c question, and returns a value read from stdin.

View File

@ -81,8 +81,8 @@ QT_BEGIN_NAMESPACE
enum ExpandFunc { enum ExpandFunc {
E_INVALID = 0, E_MEMBER, E_FIRST, E_TAKE_FIRST, E_LAST, E_TAKE_LAST, E_SIZE, 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_CAT, E_FROMFILE, E_EVAL, E_LIST, E_SPRINTF, E_FORMAT_NUMBER,
E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, 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_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_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, E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
@ -116,6 +116,7 @@ void QMakeEvaluator::initFunctionStatics()
{ "list", E_LIST }, { "list", E_LIST },
{ "sprintf", E_SPRINTF }, { "sprintf", E_SPRINTF },
{ "format_number", E_FORMAT_NUMBER }, { "format_number", E_FORMAT_NUMBER },
{ "num_add", E_NUM_ADD },
{ "join", E_JOIN }, { "join", E_JOIN },
{ "split", E_SPLIT }, { "split", E_SPLIT },
{ "basename", E_BASENAME }, { "basename", E_BASENAME },
@ -594,6 +595,29 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
} }
formfail: formfail:
break; 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: { case E_JOIN: {
if (args.count() < 1 || args.count() > 4) { if (args.count() < 1 || args.count() > 4) {
evalError(fL1S("join(var, glue, before, after) requires one to four arguments.")); evalError(fL1S("join(var, glue, before, after) requires one to four arguments."));

View File

@ -954,6 +954,48 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
<< "##:1: format_number(): invalid format option foo=bar." << "##:1: format_number(): invalid format option foo=bar."
<< true; << 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") QTest::newRow("$$join(): empty")
<< "IN = \nVAR = $$join(IN, //)" << "IN = \nVAR = $$join(IN, //)"
<< "VAR =" << "VAR ="