Index: trunk/qmake/project.cpp
===================================================================
--- trunk/qmake/project.cpp	(revision 405)
+++ trunk/qmake/project.cpp	(revision 561)
@@ -2,5 +2,6 @@
 **
 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
 **
 ** This file is part of the qmake application of the Qt Toolkit.
@@ -21,8 +22,7 @@
 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 **
 ** GNU General Public License Usage
@@ -34,6 +34,6 @@
 ** met: http://www.gnu.org/copyleft/gpl.html.
 **
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
 ** $QT_END_LICENSE$
 **
@@ -44,4 +44,6 @@
 #include "option.h"
 #include "cachekeys.h"
+
+#include "epocroot.h"
 
 #include <qdatetime.h>
@@ -58,5 +60,5 @@
 #include <sys/utsname.h>
 #elif defined(Q_OS_WIN32)
-#include <Windows.h>
+#include <windows.h>
 #elif defined(Q_OS_OS2)
 #include <qt_os2.h>
@@ -79,5 +81,6 @@
                   E_SPRINTF, 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_REPLACE };
+                  E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_REPLACE,
+                  E_SIZE };
 QMap<QString, ExpandFunc> qmake_expandFunctions()
 {
@@ -110,4 +113,5 @@
         qmake_expand_functions->insert("prompt", E_PROMPT);
         qmake_expand_functions->insert("replace", E_REPLACE);
+        qmake_expand_functions->insert("size", E_SIZE);
     }
     return *qmake_expand_functions;
@@ -155,89 +159,4 @@
     return *qmake_test_functions;
 }
-
-QT_END_NAMESPACE
-
-#ifdef QTSCRIPT_SUPPORT
-#include "qscriptvalue.h"
-#include "qscriptengine.h"
-#include "qscriptvalueiterator.h"
-
-QT_BEGIN_NAMESPACE
-
-static QScriptValue qscript_projectWrapper(QScriptEngine *eng, QMakeProject *project,
-                                    const QMap<QString, QStringList> &place);
-
-static bool qscript_createQMakeProjectMap(QMap<QString, QStringList> &vars, QScriptValue js)
-{
-    QScriptValueIterator it(js);
-    while(it.hasNext()) {
-        it.next();
-        vars[it.name()] = qscriptvalue_cast<QStringList>(it.value());
-    }
-    return true;
-}
-
-static QScriptValue qscript_call_testfunction(QScriptContext *context, QScriptEngine *engine)
-{
-    QMakeProject *self = qscriptvalue_cast<QMakeProject*>(context->callee().property("qmakeProject"));
-    QString func = context->callee().property("functionName").toString();
-    QStringList args;
-    for(int i = 0; i < context->argumentCount(); ++i)
-        args += context->argument(i).toString();
-    QMap<QString, QStringList> place = self->variables();
-    qscript_createQMakeProjectMap(place, engine->globalObject().property("qmake"));
-    QScriptValue ret(engine, self->doProjectTest(func, args, place));
-    engine->globalObject().setProperty("qmake", qscript_projectWrapper(engine, self, place));
-    return ret;
-}
-
-static QScriptValue qscript_call_expandfunction(QScriptContext *context, QScriptEngine *engine)
-{
-    QMakeProject *self = qscriptvalue_cast<QMakeProject*>(context->callee().property("qmakeProject"));
-    QString func = context->callee().property("functionName").toString();
-    QStringList args;
-    for(int i = 0; i < context->argumentCount(); ++i)
-        args += context->argument(i).toString();
-    QMap<QString, QStringList> place = self->variables();
-    qscript_createQMakeProjectMap(place, engine->globalObject().property("qmake"));
-    QScriptValue ret = qScriptValueFromValue(engine, self->doProjectExpand(func, args, place));
-    engine->globalObject().setProperty("qmake", qscript_projectWrapper(engine, self, place));
-    return ret;
-}
-
-static QScriptValue qscript_projectWrapper(QScriptEngine *eng, QMakeProject *project,
-                                           const QMap<QString, QStringList> &place)
-{
-    QScriptValue ret = eng->newObject();
-    {
-        QStringList testFuncs = qmake_testFunctions().keys() + project->userTestFunctions();
-        for(int i = 0; i < testFuncs.size(); ++i) {
-            QString funcName = testFuncs.at(i);
-            QScriptValue fun = eng->newFunction(qscript_call_testfunction);
-            fun.setProperty("qmakeProject", eng->newVariant(qVariantFromValue(project)));
-            fun.setProperty("functionName", QScriptValue(eng, funcName));
-            eng->globalObject().setProperty(funcName, fun);
-        }
-    }
-    {
-        QStringList testFuncs = qmake_expandFunctions().keys() + project->userExpandFunctions();
-        for(int i = 0; i < testFuncs.size(); ++i) {
-            QString funcName = testFuncs.at(i);
-            QScriptValue fun = eng->newFunction(qscript_call_expandfunction);
-            fun.setProperty("qmakeProject", eng->newVariant(qVariantFromValue(project)));
-            fun.setProperty("functionName", QScriptValue(eng, funcName));
-            eng->globalObject().setProperty(funcName, fun);
-        }
-    }
-    for(QMap<QString, QStringList>::ConstIterator it = place.begin(); it != place.end(); ++it)
-        ret.setProperty(it.key(), qScriptValueFromValue(eng, it.value()));
-    return ret;
-}
-
-QT_END_NAMESPACE
-
-#endif
-
-QT_BEGIN_NAMESPACE
 
 struct parser_info {
@@ -591,4 +510,67 @@
 }
 
+enum isForSymbian_enum {
+    isForSymbian_NOT_SET = -1,
+    isForSymbian_FALSE = 0,
+    isForSymbian_ABLD = 1,
+    isForSymbian_SBSV2 = 2,
+};
+
+static isForSymbian_enum isForSymbian_value = isForSymbian_NOT_SET;
+
+// Checking for symbian build is primarily determined from the qmake spec,
+// but if that is not specified, detect if symbian is the default spec
+// by checking the MAKEFILE_GENERATOR variable value.
+static void init_symbian(const QMap<QString, QStringList>& vars)
+{
+    if (isForSymbian_value != isForSymbian_NOT_SET)
+        return;
+
+    QString spec = QFileInfo(Option::mkfile::qmakespec).fileName();
+    if (spec.startsWith("symbian-abld", Qt::CaseInsensitive)) {
+        isForSymbian_value = isForSymbian_ABLD;
+    } else if (spec.startsWith("symbian-sbsv2", Qt::CaseInsensitive)) {
+        isForSymbian_value = isForSymbian_SBSV2;
+    } else {
+        QStringList generatorList = vars["MAKEFILE_GENERATOR"];
+
+        if (!generatorList.isEmpty()) {
+            QString generator = generatorList.first();
+            if (generator.startsWith("SYMBIAN_ABLD"))
+                isForSymbian_value = isForSymbian_ABLD;
+            else if (generator.startsWith("SYMBIAN_SBSV2"))
+                isForSymbian_value = isForSymbian_SBSV2;
+            else
+                isForSymbian_value = isForSymbian_FALSE;
+        } else {
+            isForSymbian_value = isForSymbian_FALSE;
+        }
+    }
+
+    // Force recursive on Symbian, as non-recursive is not really a viable option there
+    if (isForSymbian_value != isForSymbian_FALSE)
+        Option::recursive = true;
+}
+
+bool isForSymbian()
+{
+    // If isForSymbian_value has not been initialized explicitly yet,
+    // call initializer with dummy map to check qmake spec.
+    if (isForSymbian_value == isForSymbian_NOT_SET)
+        init_symbian(QMap<QString, QStringList>());
+
+    return (isForSymbian_value != isForSymbian_FALSE);
+}
+
+bool isForSymbianSbsv2()
+{
+    // If isForSymbian_value has not been initialized explicitly yet,
+    // call initializer with dummy map to check qmake spec.
+    if (isForSymbian_value == isForSymbian_NOT_SET)
+        init_symbian(QMap<QString, QStringList>());
+
+    return (isForSymbian_value == isForSymbian_SBSV2);
+}
+
 /*
    1) environment variable QMAKEFEATURES (as separated by colons)
@@ -617,9 +599,19 @@
             break;
         case Option::TARG_UNIX_MODE:
-            concat << base_concat + QDir::separator() + "unix";
-            break;
+            {
+                if (isForSymbian())
+                    concat << base_concat + QDir::separator() + "symbian";
+                else
+                    concat << base_concat + QDir::separator() + "unix";
+                break;
+            }
         case Option::TARG_WIN_MODE:
-            concat << base_concat + QDir::separator() + "win32";
-            break;
+            {
+                if (isForSymbian())
+                    concat << base_concat + QDir::separator() + "symbian";
+                else
+                    concat << base_concat + QDir::separator() + "win32";
+                break;
+            }
         case Option::TARG_OS2_MODE:
             concat << base_concat + QDir::separator() + "os2";
@@ -628,8 +620,4 @@
             concat << base_concat + QDir::separator() + "mac";
             concat << base_concat + QDir::separator() + "mac9";
-            break;
-        case Option::TARG_QNX6_MODE: //also a unix
-            concat << base_concat + QDir::separator() + "qnx6";
-            concat << base_concat + QDir::separator() + "unix";
             break;
         }
@@ -1481,4 +1469,7 @@
                 return false;
             }
+
+            init_symbian(base_vars);
+
             if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) {
                 debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.toLatin1().constData());
@@ -1527,6 +1518,6 @@
     if(cmd & ReadProFile) { // parse project file
         debug_msg(1, "Project file: reading %s", pfile.toLatin1().constData());
-        if(pfile != "-" && !QFile::exists(pfile) && !pfile.endsWith(".pro"))
-            pfile += ".pro";
+        if(pfile != "-" && !QFile::exists(pfile) && !pfile.endsWith(Option::pro_ext))
+            pfile += Option::pro_ext;
         if(!read(pfile, vars))
             return false;
@@ -1615,25 +1606,32 @@
         return false;
 
+    static QString spec;
+    if(spec.isEmpty())
+        spec = QFileInfo(Option::mkfile::qmakespec).fileName();
+
+    // Symbian is an exception to how scopes are resolved. Since we do not
+    // have a separate target mode for Symbian, but we expect the scope to resolve
+    // on other platforms we base it entirely on the mkspec. This means that
+    // using a mkspec starting with 'symbian*' will resolve both the 'symbian'
+    // and the 'unix' (because of Open C) scopes to true.
+    if(isForSymbian() && (x == "symbian" || x == "unix"))
+        return true;
+
     //mkspecs
-    if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE ||
+    if((Option::target_mode == Option::TARG_MACX_MODE ||
         Option::target_mode == Option::TARG_UNIX_MODE) && x == "unix")
-        return true;
+        return !isForSymbian();
     else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx")
-        return true;
-    else if(Option::target_mode == Option::TARG_QNX6_MODE && x == "qnx6")
-        return true;
+        return !isForSymbian();
     else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9")
-        return true;
+        return !isForSymbian();
     else if((Option::target_mode == Option::TARG_MAC9_MODE || Option::target_mode == Option::TARG_MACX_MODE) &&
             x == "mac")
-        return true;
+        return !isForSymbian();
     else if(Option::target_mode == Option::TARG_WIN_MODE && x == "win32")
-        return true;
+        return !isForSymbian();
     else if(Option::target_mode == Option::TARG_OS2_MODE && x == "os2")
         return true;
     QRegExp re(x, Qt::CaseSensitive, QRegExp::Wildcard);
-    static QString spec;
-    if(spec.isEmpty())
-        spec = QFileInfo(Option::mkfile::qmakespec).fileName();
     if((regex && re.exactMatch(spec)) || (!regex && spec == x))
         return true;
@@ -1723,4 +1721,5 @@
             static QStringList *feature_roots = 0;
             if(!feature_roots) {
+                init_symbian(base_vars);
                 feature_roots = new QStringList(qmake_feature_paths(prop));
                 qmakeAddCacheClear(qmakeDeleteCacheClear_QStringList, (void**)&feature_roots);
@@ -1808,25 +1807,6 @@
     parser_info pi = parser;
     if(format == JSFormat) {
-#ifdef QTSCRIPT_SUPPORT
-        eng.globalObject().setProperty("qmake", qscript_projectWrapper(&eng, this, place));
-        QFile f(file);
-        if (f.open(QFile::ReadOnly)) {
-            QString code = f.readAll();
-            QScriptValue r = eng.evaluate(code);
-            if(eng.hasUncaughtException()) {
-                const int lineNo = eng.uncaughtExceptionLineNumber();
-                fprintf(stderr, "%s:%d: %s\n", file.toLatin1().constData(), lineNo,
-                        r.toString().toLatin1().constData());
-            } else {
-                parsed = true;
-                QScriptValue variables = eng.globalObject().property("qmake");
-                if (variables.isValid() && variables.isObject())
-                    qscript_createQMakeProjectMap(place, variables);
-            }
-        }
-#else
         warn_msg(WarnParser, "%s:%d: QtScript support disabled for %s.",
                  pi.file.toLatin1().constData(), pi.line_no, orig_file.toLatin1().constData());
-#endif
     } else {
         QStack<ScopeBlock> sc = scope_blocks;
@@ -2165,9 +2145,9 @@
             QMakeProjectEnv env(place);
             char buff[256];
-            FILE *proc = QT_POPEN(args[0].toLatin1(), "r");
             bool singleLine = true;
             if(args.count() > 1)
                 singleLine = (args[1].toLower() == "true");
             QString output;
+            FILE *proc = QT_POPEN(args[0].toLatin1(), "r");
             while(proc && !feof(proc)) {
                 int read_in = int(fread(buff, 1, 255, proc));
@@ -2318,18 +2298,15 @@
         }
         break; }
+    case E_SIZE: {
+        if(args.count() != 1) {
+            fprintf(stderr, "%s:%d: size(var) requires one argument.\n",
+                    parser.file.toLatin1().constData(), parser.line_no);
+        } else {
+            //QString target = args[0];
+            int size = values(args[0]).size();
+            ret += QString::number(size);
+        }
+        break; }
     default: {
-#ifdef QTSCRIPT_SUPPORT
-        {
-            QScriptValue jsFunc = eng.globalObject().property(func);
-            if(jsFunc.isFunction()) {
-                QScriptValueList jsArgs;
-                for(int i = 0; i < args.size(); ++i)
-                    jsArgs += QScriptValue(&eng, args.at(i));
-                QScriptValue jsRet = jsFunc.call(eng.globalObject(), jsArgs);
-                ret = qscriptvalue_cast<QStringList>(jsRet);
-                break;
-            }
-        }
-#endif
         fprintf(stderr, "%s:%d: Unknown replace function: %s\n",
                 parser.file.toLatin1().constData(), parser.line_no,
@@ -2413,5 +2390,5 @@
             int lhs_int = lhs.toInt(&ok);
             if(ok) {
-                if(func == "greaterThan")
+                if(func_t == T_GREATERTHAN)
                     return lhs_int > rhs_int;
                 return lhs_int < rhs_int;
@@ -2708,8 +2685,13 @@
         QString parseInto;
         const bool include_statement = (func_t == T_INCLUDE);
-        bool ignore_error = include_statement;
-        if(args.count() == 2) {
+        bool ignore_error = false;
+        if(args.count() >= 2) {
             if(func_t == T_INCLUDE) {
                 parseInto = args[1];
+                if (args.count() == 3){
+                    QString sarg = args[2];
+                    if (sarg.toLower() == "true" || sarg.toInt())
+                        ignore_error = true;
+                }
             } else {
                 QString sarg = args[1];
@@ -2753,6 +2735,6 @@
             warn_msg(WarnParser, "%s:%d: Duplicate of loaded feature %s",
                      parser.file.toLatin1().constData(), parser.line_no, file.toLatin1().constData());
-        } else if(stat == IncludeNoExist && include_statement) {
-            warn_msg(WarnParser, "%s:%d: Unable to find file for inclusion %s",
+        } else if(stat == IncludeNoExist && !ignore_error) {
+            warn_msg(WarnAll, "%s:%d: Unable to find file for inclusion %s",
                      parser.file.toLatin1().constData(), parser.line_no, file.toLatin1().constData());
             return false;
@@ -2797,18 +2779,4 @@
         return true; }
     default:
-#ifdef QTSCRIPT_SUPPORT
-        {
-            QScriptValue jsFunc = eng.globalObject().property(func);
-            if(jsFunc.isFunction()) {
-                QScriptValueList jsArgs;
-                for(int i = 0; i < args.size(); ++i)
-                    jsArgs += QScriptValue(&eng, args.at(i));
-                QScriptValue jsRet = jsFunc.call(eng.globalObject(), jsArgs);
-                if(eng.hasUncaughtException())
-                    return false;
-                return qscriptvalue_cast<bool>(jsRet);
-            }
-        }
-#endif
         fprintf(stderr, "%s:%d: Unknown test function: %s\n", parser.file.toLatin1().constData(), parser.line_no,
                 func.toLatin1().constData());
@@ -3126,7 +3094,7 @@
         } else if(type == "name") {
             DWORD name_length = 1024;
-            TCHAR name[1024];
-            if(GetComputerName(name, &name_length))
-                ret = QString::fromUtf16((ushort*)name, name_length);
+            wchar_t name[1024];
+            if (GetComputerName(name, &name_length))
+                ret = QString::fromWCharArray(name);
         } else if(type == "version" || type == "version_string") {
             QSysInfo::WinVersion ver = QSysInfo::WindowsVersion;
@@ -3225,4 +3193,7 @@
         if (place[var].isEmpty())
             return values("DIR_SEPARATOR", place);
+    } else if (var == QLatin1String("EPOCROOT")) {
+        if (place[var].isEmpty())
+            place[var] = QStringList(epocRoot());
     }
     //qDebug("REPLACE [%s]->[%s]", qPrintable(var), qPrintable(place[var].join("::")));
