execute some loops even in cumulative mode
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>
Fri, 9 Aug 2013 10:17:11 +0000 (12:17 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 12 Aug 2013 16:16:43 +0000 (18:16 +0200)
we execute foreach loops now. this is (mostly) safe nowadays, because
a previous change added precautions against exponential value list
growth, so it's unlikely that two nested loops would keep the cpu busy
for a day as before.

we continue to exclude forever loops and loops with excessive integer
counts.

Task-number: QTBUG-8550
Change-Id: Iaa116086986cc7fd5023834753f791dd205102e5
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
src/linguist/shared/qmakeevaluator.cpp
tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro

index eb9e24c..9c7bf45 100644 (file)
@@ -583,13 +583,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
             okey = true, or_op = false; // force next evaluation
             break;
         case TokForLoop:
-            if (m_cumulative) { // This is a no-win situation, so just pretend it's no loop
-                skipHashStr(tokPtr);
-                uint exprLen = getBlockLen(tokPtr);
-                tokPtr += exprLen;
-                blockLen = getBlockLen(tokPtr);
-                ret = visitProBlock(tokPtr);
-            } else if (okey != or_op) {
+            if (m_cumulative || okey != or_op) {
                 const ProKey &variable = getHashStr(tokPtr);
                 uint exprLen = getBlockLen(tokPtr);
                 const ushort *exprPtr = tokPtr;
@@ -759,6 +753,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
     ProStringList list = values(it_list.toKey());
     if (list.isEmpty()) {
         if (it_list == statics.strforever) {
+            if (m_cumulative) {
+                // The termination conditions wouldn't be evaluated, so we must skip it.
+                traceMsg("skipping forever loop in cumulative mode");
+                return ReturnFalse;
+            }
             infinite = true;
         } else {
             const QString &itl = it_list.toQString(m_tmp1);
@@ -769,6 +768,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
                 if (ok) {
                     int end = itl.mid(dotdot+2).toInt(&ok);
                     if (ok) {
+                        if (m_cumulative && qAbs(end - start) > 100) {
+                            // Such a loop is unlikely to contribute something useful to the
+                            // file collection, and may cause considerable delay.
+                            traceMsg("skipping excessive loop in cumulative mode");
+                            return ReturnFalse;
+                        }
                         if (start < end) {
                             for (int i = start; i <= end; i++)
                                 list << ProString(QString::number(i));
index 5e23538..73c6d19 100644 (file)
@@ -1,6 +1,7 @@
 include(win/win.pri)
-include(mac/mac.pri)
-include(unix/unix.pri)
+more = mac unix
+for(dir, more): \
+    include($$dir/$${dir}.pri)
 include (common/common.pri)             # Important: keep the space before the '('
 include(relativity/relativity.pri)