Skip to content
Snippets Groups Projects
Commit f5714575 authored by goro's avatar goro
Browse files

Check in qtlibspatcher from change 321515 plus compile fixes

parent 866ab744
No related branches found
No related tags found
No related merge requests found
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include <cstdio>
#include <cstring>
#include <locale>
#include "binpatch.h"
// returns positive value if it finds a null termination inside the buffer
long BinPatch::getBufferStringLength(char *data, char *end)
{
long size = 0;
while (data < end) {
if (*data == '\0')
return size;
++data;
++size;
}
return -1;
}
// returns true if data ends with one of the tokens. (Sep. with ;)
bool BinPatch::endsWithTokens(const char *data)
{
if(strlen(endTokens) > 0) {
char endstmp[1024];
ulong tlen = ulong(strlen(data));
if(strlen(endTokens) >= sizeof(endstmp))
return false;
strcpy(endstmp, endTokens);
char *token = strtok(endstmp, ";");
while(token != NULL) {
// check if it ends with the token
if ((tlen >= strlen(token))
&& (strcasecmp((data+tlen)-strlen(token), token) == 0))
return true;
token = strtok(NULL, ";");
}
} else {
return true; //true if no tokens
}
return false; //no matching tokens
}
bool BinPatch::patchHelper(char *inbuffer, const char *oldstr, const char *newstr, size_t len, long *rw)
{
char nc1 = *oldstr;
char nc2 = 0;
char *inend = inbuffer + len;
size_t oldlen = strlen(oldstr);
size_t newlen = strlen(newstr);
char *instart = inbuffer;
*rw = 0;
bool write = true;
isupper(nc1) ? nc2 = tolower(nc1) : nc2 = toupper(nc1);
while(inbuffer < inend) {
if ((*inbuffer == nc1) || (*inbuffer == nc2)) {
if (inbuffer > (inend-oldlen) || inbuffer > (inend-newlen)) {
*rw = (long)(inend-inbuffer); //rewind, not enough to make a compare
break;
}
if (strncasecmp(inbuffer, oldstr, oldlen) == 0) {
if (useLength && (instart == inbuffer)) {
*rw = (long)(len+1); //we don't have access to the length byte, rewind all + 1!
write = false;
break;
}
long oldsize = -1;
if (useLength) { //VC60
oldsize = (unsigned char)(*(inbuffer-1));
// vc60 pdb files sometimes uses 0A, then it should be null terminated
if (oldsize < (long)oldlen) {
if (oldsize != 0x0A) { //strange case... skip
inbuffer+=oldlen;
continue;
}
oldsize = getBufferStringLength(inbuffer, inend);
if (oldsize < 0) {
*rw = (long)(inend-inbuffer); //rewind, entire string not in buffer
break;
}
}
if (inbuffer > (inend-oldsize)) {
*rw = (long)(inend-inbuffer); //rewind, entire string not in buffer
break;
}
} else { //VC7x
oldsize = getBufferStringLength(inbuffer, inend);
if (oldsize < 0) {
*rw = (long)(inend-inbuffer); //rewind, entire string not in buffer
break;
}
}
char oldPath[1024];
if (oldsize > (long)sizeof(oldPath)) {
//at least don't crash
inbuffer+=oldsize;
continue;
}
memset(oldPath, '\0', sizeof(oldPath));
strncpy(oldPath, newstr, newlen);
if (insertReplace)
strncat(oldPath, inbuffer+oldlen, oldsize-oldlen);
// just replace if it ends with a token in endTokens
if (endsWithTokens(oldPath)) {
if (oldsize < (long)strlen(oldPath))
oldsize = (long)strlen(oldPath);
memcpy(inbuffer, oldPath, oldsize);
}
inbuffer+=oldsize;
continue;
}
}
++inbuffer;
}
return write;
}
bool BinPatch::patch(const char *oldstr, const char *newstr)
{
size_t oldlen = strlen(oldstr);
size_t newlen = strlen(newstr);
if ((!fileName || strlen(fileName) < 1)
|| (!oldstr || oldlen < 1)
|| (!newstr || newlen < 1))
return false;
FILE *input;
if (!(input = fopen(fileName, "r+b")))
{
fprintf(stderr, "Cannot open file %s!\n", fileName);
return false;
}
char data[60000];
long rw = 0;
long offset = 0;
size_t len;
len = fread(data, sizeof(char), sizeof(data), input);
do {
if (patchHelper(data, oldstr, newstr, len, &rw)) {
fseek(input, offset, SEEK_SET); //overwrite
fwrite(data, sizeof(char), len, input);
}
offset += (long)((-rw) + len);
if (fseek(input, offset, SEEK_SET) != 0)
break;
len = fread(data, sizeof(char), sizeof(data), input);
} while(!(feof(input) && (len <= oldlen || len <= newlen)));
fclose(input);
return true;
}
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef BINPATCH_H
#define BINPATCH_H
#include <string.h>
typedef unsigned long ulong;
typedef unsigned int uint;
class BinPatch
{
public:
BinPatch(const char *file)
: useLength(false), insertReplace(false)
{
strcpy(endTokens, "");
strcpy(fileName, file);
}
void enableUseLength(bool enabled)
{ useLength = enabled; }
void enableInsertReplace(bool enabled)
{ insertReplace = enabled; }
void setEndTokens(const char *tokens)
{ strcpy(endTokens, tokens); }
bool patch(const char *oldstr, const char *newstr);
private:
long getBufferStringLength(char *data, char *end);
bool endsWithTokens(const char *data);
bool patchHelper(char *inbuffer, const char *oldstr,
const char *newstr, size_t len, long *rw);
bool useLength;
bool insertReplace;
char endTokens[1024];
char fileName[1024];
};
#endif
######################################################################
# Automatically generated by qmake (2.01a) Di 8. Jul 15:08:13 2008
######################################################################
CONFIG += console
QT -= gui
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
DESTDIR = ./
# Input
HEADERS += binpatch.h
SOURCES += binpatch.cpp qtlibspatchermain.cpp
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "binpatch.h"
#include <stdio.h>
#include <QFile>
#include <QRegExp>
#include <QTextStream>
#include <QString>
#include <QtCore/QDebug>
bool patchBinaryWithQtPathes(const char *fileName, const char *baseQtPath)
{
bool result = true;
static const struct
{
const char *variable;
const char *subDirectory;
} variables[] = {
{"qt_prfxpath=", ""},
{"qt_docspath=", "/doc"},
{"qt_hdrspath=", "/include"},
{"qt_libspath=", "/lib"},
{"qt_binspath=", "/bin"},
{"qt_plugpath=", "/plugins"},
{"qt_datapath=", ""},
{"qt_trnspath=", "/translations"},
{"qt_xmplpath=", "/examples"},
{"qt_demopath=", "/demos"}
};
for (int i = 0; i < sizeof(variables)/sizeof(variables[0]); i++) {
char newStr[256] = "";
strncpy(newStr, variables[i].variable, sizeof(newStr));
newStr[sizeof(newStr) - 1] = 0;
strncat(newStr, baseQtPath, sizeof(newStr) - strlen(newStr) - 1);
newStr[sizeof(newStr) - 1] = 0;
strncat(newStr, variables[i].subDirectory, sizeof(newStr) - strlen(newStr) - 1);
newStr[sizeof(newStr) - 1] = 0;
BinPatch binFile(fileName);
if (!binFile.patch(variables[i].variable, newStr)) {
result = false;
break;
}
}
return result;
}
bool patchBinariesWithQtPathes(const char *baseQtPath)
{
bool result = true;
static const char *filesToPatch[] = {
"/bin/qmake.exe",
"/bin/QtCore4.dll",
"/bin/QtCored4.dll"
};
for (int i = 0; i < sizeof(filesToPatch)/sizeof(filesToPatch[0]); i++) {
char fileName[FILENAME_MAX] = "";
strncpy(fileName, baseQtPath, sizeof(fileName));
fileName[sizeof(fileName)-1] = '\0';
strncat(fileName, filesToPatch[i], sizeof(fileName) - strlen(fileName) - 1);
fileName[sizeof(fileName)-1] = '\0';
if (!patchBinaryWithQtPathes(fileName, baseQtPath)) {
result = false;
break;
}
}
return result;
}
bool patchDebugLibrariesWithQtPath(const char *baseQtPath)
{
bool result = true;
static const struct
{
const char *fileName;
const char *sourceLocation;
} libraries[] = {
{"/bin/Qt3Supportd4.dll", "/src/qt3support/"},
{"/bin/QtCored4.dll", "/src/corelib/"},
{"/bin/QtGuid4.dll", "/src/gui/"},
{"/bin/QtHelpd4.dll", "/tools/assistant/lib/"},
{"/bin/QtNetworkd4.dll", "/src/network/"},
{"/bin/QtOpenGLd4.dll", "/src/opengl/"},
{"/bin/QtScriptd4.dll", "/src/script/"},
{"/bin/QtSqld4.dll", "/src/sql/"},
{"/bin/QtSvgd4.dll", "/src/svg/"},
{"/bin/QtTestd4.dll", "/src/testlib/"},
{"/bin/QtWebKitd4.dll", "/src/3rdparty/webkit/WebCore/"},
{"/bin/QtXmld4.dll", "/src/xml/"},
{"/bin/QtXmlPatternsd4.dll", "/src/xmlpatterns/"},
{"/plugins/accessible/qtaccessiblecompatwidgetsd4.dll", "/src/plugins/accessible/compat/"},
{"/plugins/accessible/qtaccessiblewidgetsd4.dll", "/src/plugins/accessible/widgets/"},
{"/plugins/codecs/qcncodecsd4.dll", "/src/plugins/codecs/cn/"},
{"/plugins/codecs/qjpcodecsd4.dll", "/src/plugins/codecs/jp/"},
{"/plugins/codecs/qkrcodecsd4.dll", "/src/plugins/codecs/kr/"},
{"/plugins/codecs/qtwcodecsd4.dll", "/src/plugins/codecs/tw/"},
{"/plugins/iconengines/qsvgicond4.dll", "/src/plugins/iconengines/svgiconengine/"},
{"/plugins/imageformats/qgifd4.dll", "/src/plugins/imageformats/gif/"},
{"/plugins/imageformats/qjpegd4.dll", "/src/plugins/imageformats/jpeg/"},
{"/plugins/imageformats/qmngd4.dll", "/src/plugins/imageformats/mng/"},
{"/plugins/imageformats/qsvgd4.dll", "/src/plugins/imageformats/svg/"},
{"/plugins/imageformats/qtiffd4.dll", "/src/plugins/imageformats/tiff/"},
{"/plugins/sqldrivers/qsqlited4.dll", "/src/plugins/sqldrivers/sqlite/"},
// {"/plugins/sqldrivers/qsqlodbcd4.dll", "/src/plugins/sqldrivers/odbc/"}
};
for (int i = 0; i < sizeof(libraries)/sizeof(libraries[0]); i++) {
char fileName[FILENAME_MAX] = "";
strncpy(fileName, baseQtPath, sizeof(fileName));
fileName[sizeof(fileName)-1] = '\0';
strncat(fileName, libraries[i].fileName, sizeof(fileName) - strlen(fileName) - 1);
fileName[sizeof(fileName)-1] = '\0';
char oldSourcePath[FILENAME_MAX] =
"C:/qt-greenhouse/Trolltech/Code_less_create_more/Trolltech/Code_less_create_more/Troll/4.4.3";
strncat(oldSourcePath, libraries[i].sourceLocation, sizeof(oldSourcePath) - strlen(oldSourcePath) - 1);
oldSourcePath[sizeof(oldSourcePath)-1] = '\0';
char newSourcePath[FILENAME_MAX] = "";
strncpy(newSourcePath, baseQtPath, sizeof(newSourcePath));
newSourcePath[sizeof(newSourcePath)-1] = '\0';
strncat(newSourcePath, libraries[i].sourceLocation, sizeof(newSourcePath) - strlen(newSourcePath) - 1);
newSourcePath[sizeof(newSourcePath)-1] = '\0';
BinPatch binFile(fileName);
if (!binFile.patch(oldSourcePath, newSourcePath)) {
result = false;
break;
}
}
return result;
}
void patchQMakeSpec(const char *path)
{
QString baseQtPath(path);
QFile f(baseQtPath + "/mkspecs/default/qmake.conf");
f.open(QIODevice::ReadOnly);
QTextStream in(&f);
QString all = in.readAll();
f.close();
// Old value is QMAKESPEC_ORIGINAL=C:/somepath/mkspecs/amakespce
// New value should be QMAKESPEC_ORIGINAL=baseQtPath/mkspec/amakespec
// We don't care to match the line end we simply match to the end of the file
QRegExp regExp("(QMAKESPEC_ORIGINAL=).*(/mkspecs/.*)");
all.replace(regExp, "\\1"+baseQtPath+"\\2");
f.open(QIODevice::WriteOnly);
QTextStream out(&f);
out << all;
}
int main(int argc, char *args[])
{
if (argc != 2) {
printf("Please provide a QTDIR value as parameter.\n"
"This is also the location where the binaries are expected\n"
"in the \"/bin\" and \"/plugins\" subdirectories.\n");
return 1;
}
char baseQtPath[FILENAME_MAX] = "";
strncpy(baseQtPath, args[1], sizeof(baseQtPath));
baseQtPath[sizeof(baseQtPath)-1] = '\0';
// Convert backslash to slash
for (char *p = baseQtPath; *p != '\0'; p++)
if (*p == '\\')
*p = '/';
// Remove trailing slash(es)
for (char *p = baseQtPath + strlen(baseQtPath) - 1; p != baseQtPath; p--)
if (*p == '/')
*p = '\0';
else
break;
patchQMakeSpec(baseQtPath);
return patchBinariesWithQtPathes(baseQtPath) && patchDebugLibrariesWithQtPath(baseQtPath)?0:1;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment