diff options
Diffstat (limited to 'src/shared/proparser/qmakebuiltins.cpp')
-rw-r--r-- | src/shared/proparser/qmakebuiltins.cpp | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/src/shared/proparser/qmakebuiltins.cpp b/src/shared/proparser/qmakebuiltins.cpp index bd19e00702..679e57d606 100644 --- a/src/shared/proparser/qmakebuiltins.cpp +++ b/src/shared/proparser/qmakebuiltins.cpp @@ -46,10 +46,14 @@ #include <QTextStream> #ifdef Q_OS_UNIX +#include <time.h> +#include <utime.h> +#include <errno.h> #include <unistd.h> +#include <sys/stat.h> #include <sys/utsname.h> #else -#include <Windows.h> +#include <windows.h> #endif #include <stdio.h> #include <stdlib.h> @@ -86,7 +90,7 @@ enum TestFunc { T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM, T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE, T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF, - T_MKPATH + T_MKPATH, T_TOUCH }; void QMakeEvaluator::initFunctionStatics() @@ -172,6 +176,7 @@ void QMakeEvaluator::initFunctionStatics() { "warning", T_WARNING }, { "error", T_ERROR }, { "mkpath", T_MKPATH }, + { "touch", T_TOUCH }, }; for (unsigned i = 0; i < sizeof(testInits)/sizeof(testInits[0]); ++i) statics.functions.insert(ProString(testInits[i].name), testInits[i].func); @@ -183,6 +188,23 @@ static bool isTrue(const ProString &_str, QString &tmp) return !str.compare(statics.strtrue, Qt::CaseInsensitive) || str.toInt(); } +#ifdef Q_OS_WIN +static QString windowsErrorCode() +{ + wchar_t *string = 0; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&string, + 0, + NULL); + QString ret = QString::fromWCharArray(string); + LocalFree((HLOCAL)string); + return ret; +} +#endif + static QString quoteValue(const ProString &val) { @@ -1359,6 +1381,49 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( } return ReturnTrue; } + case T_TOUCH: { + if (args.count() != 2) { + evalError(fL1S("touch(file, reffile) requires two arguments.")); + return ReturnFalse; + } + const QString &tfn = resolvePath(args.at(0).toQString(m_tmp1)); + const QString &rfn = resolvePath(args.at(1).toQString(m_tmp2)); +#ifdef Q_OS_UNIX + struct stat st; + if (stat(rfn.toLocal8Bit().constData(), &st)) { + evalError(fL1S("Cannot stat() reference file %1: %2.").arg(rfn, fL1S(strerror(errno)))); + return ReturnFalse; + } + struct utimbuf utb; + utb.actime = time(0); + utb.modtime = st.st_mtime; + if (utime(tfn.toLocal8Bit().constData(), &utb)) { + evalError(fL1S("Cannot touch %1: %2.").arg(tfn, fL1S(strerror(errno)))); + return ReturnFalse; + } +#else + HANDLE rHand = CreateFile((wchar_t*)rfn.utf16(), + GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (rHand == INVALID_HANDLE_VALUE) { + evalError(fL1S("Cannot open() reference file %1: %2.").arg(rfn, windowsErrorCode())); + return ReturnFalse; + } + FILETIME ft; + GetFileTime(rHand, 0, 0, &ft); + CloseHandle(rHand); + HANDLE wHand = CreateFile((wchar_t*)tfn.utf16(), + GENERIC_WRITE, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (wHand == INVALID_HANDLE_VALUE) { + evalError(fL1S("Cannot open() %1: %2.").arg(tfn, windowsErrorCode())); + return ReturnFalse; + } + SetFileTime(wHand, 0, 0, &ft); + CloseHandle(wHand); +#endif + return ReturnTrue; + } #endif case T_INVALID: evalError(fL1S("'%1' is not a recognized test function.") |