add $$format_number() function
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>
Tue, 3 Apr 2012 11:35:53 +0000 (13:35 +0200)
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>
Tue, 19 Jun 2012 14:39:56 +0000 (16:39 +0200)
Change-Id: I04266c1f5fb72af94073f3f508cee59085e365b6
Reviewed-by: Marius Storm-Olsen <marius.storm-olsen@nokia.com>
qmake/project.cpp
tests/auto/tools/qmake/testdata/functions/functions.pro

index de010fa..24ea3a0 100644 (file)
@@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE
 
 //expand functions
 enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_CAT, E_FROMFILE, E_EVAL, E_LIST,
-                  E_SPRINTF, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
+                  E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
                   E_FIND, E_SYSTEM, E_UNIQUE, E_QUOTE, E_ESCAPE_EXPAND,
                   E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, E_REPLACE,
                   E_SIZE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
@@ -97,6 +97,7 @@ QHash<QString, ExpandFunc> qmake_expandFunctions()
         qmake_expand_functions->insert("eval", E_EVAL);
         qmake_expand_functions->insert("list", E_LIST);
         qmake_expand_functions->insert("sprintf", E_SPRINTF);
+        qmake_expand_functions->insert("format_number", E_FORMAT_NUMBER);
         qmake_expand_functions->insert("join", E_JOIN);
         qmake_expand_functions->insert("split", E_SPLIT);
         qmake_expand_functions->insert("basename", E_BASENAME);
@@ -2190,6 +2191,79 @@ QMakeProject::doProjectExpand(QString func, QList<QStringList> args_list,
             ret = split_value_list(tmp);
         }
         break; }
+    case E_FORMAT_NUMBER:
+        if (args.count() > 2) {
+            fprintf(stderr, "%s:%d: format_number(number[, options...]) requires one or two arguments.\n",
+                    parser.file.toLatin1().constData(), parser.line_no);
+        } else {
+            int ibase = 10;
+            int obase = 10;
+            int width = 0;
+            bool zeropad = false;
+            bool leftalign = false;
+            enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign;
+            if (args.count() >= 2) {
+                foreach (const QString &opt, split_value_list(args.at(1))) {
+                    if (opt.startsWith(QLatin1String("ibase="))) {
+                        ibase = opt.mid(6).toInt();
+                    } else if (opt.startsWith(QLatin1String("obase="))) {
+                        obase = opt.mid(6).toInt();
+                    } else if (opt.startsWith(QLatin1String("width="))) {
+                        width = opt.mid(6).toInt();
+                    } else if (opt == QLatin1String("zeropad")) {
+                        zeropad = true;
+                    } else if (opt == QLatin1String("padsign")) {
+                        sign = PadSign;
+                    } else if (opt == QLatin1String("alwayssign")) {
+                        sign = AlwaysSign;
+                    } else if (opt == QLatin1String("leftalign")) {
+                        leftalign = true;
+                    } else {
+                        fprintf(stderr, "%s:%d: format_number(): invalid format option %s.\n",
+                                parser.file.toLatin1().constData(), parser.line_no,
+                                opt.toLatin1().constData());
+                        goto formfail;
+                    }
+                }
+            }
+            if (args.at(0).contains(QLatin1Char('.'))) {
+                fprintf(stderr, "%s:%d: format_number(): floats are currently not supported.\n",
+                        parser.file.toLatin1().constData(), parser.line_no);
+                break;
+            }
+            bool ok;
+            qlonglong num = args.at(0).toLongLong(&ok, ibase);
+            if (!ok) {
+                fprintf(stderr, "%s:%d: format_number(): malformed number %s for base %d.\n",
+                        parser.file.toLatin1().constData(), parser.line_no,
+                        args.at(0).toLatin1().constData(), ibase);
+                break;
+            }
+            QString outstr;
+            if (num < 0) {
+                num = -num;
+                outstr = QLatin1Char('-');
+            } else if (sign == AlwaysSign) {
+                outstr = QLatin1Char('+');
+            } else if (sign == PadSign) {
+                outstr = QLatin1Char(' ');
+            }
+            QString numstr = QString::number(num, obase);
+            int space = width - outstr.length() - numstr.length();
+            if (space <= 0) {
+                outstr += numstr;
+            } else if (leftalign) {
+                outstr += numstr + QString(space, QLatin1Char(' '));
+            } else if (zeropad) {
+                outstr += QString(space, QLatin1Char('0')) + numstr;
+            } else {
+                outstr.prepend(QString(space, QLatin1Char(' ')));
+                outstr += numstr;
+            }
+            ret += outstr;
+        }
+      formfail:
+        break;
     case E_JOIN: {
         if(args.count() < 1 || args.count() > 4) {
             fprintf(stderr, "%s:%d: join(var, glue, before, after) requires four"
index 0b70b24..2972128 100644 (file)
@@ -113,3 +113,17 @@ out = "easy \"less easy\" sca\$\${LITERAL_HASH}ry crazy\$\$escape_expand(\\\\t\\
 testReplace($$val_escape(in), $$out, "val_escape")
 
 testReplace($$shadowed($$PWD/something), $$OUT_PWD/something, "shadowed")
+
+#format_number
+spc = " "
+testReplace($$format_number(13), 13, "simple number format")
+testReplace($$format_number(-13), -13, "negative number format")
+testReplace($$format_number(13, ibase=16), 19, "hex input number format")
+testReplace($$format_number(13, obase=16), d, "hex output number format")
+testReplace($$format_number(13, width=5), " $$spc 13", "right aligned number format")
+testReplace($$format_number(13, width=5 leftalign), "13 $$spc ", "left aligned number format")
+testReplace($$format_number(13, width=5 zeropad), "00013", "zero-padded number format")
+testReplace($$format_number(13, width=5 alwayssign), "$$spc +13", "always signed number format")
+testReplace($$format_number(13, width=5 alwayssign zeropad), "+0013", "zero-padded always signed number format")
+testReplace($$format_number(13, width=5 padsign), " $$spc 13", "sign-padded number format")
+testReplace($$format_number(13, width=5 padsign zeropad), " 0013", "zero-padded sign-padded number format")