Created
December 12, 2012 20:49
-
-
Save clarete/4271479 to your computer and use it in GitHub Desktop.
Updated version of this tool http://lists.trolltech.com/qt-interest/2005-11/thread00257-0.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#if defined(_WIN32) | |
#include <windows.h> | |
#elif defined(__linux__) | |
#include <sys/stat.h> | |
#include <sys/mman.h> | |
#endif | |
#define InFile argv[1] | |
#define TargetPath argv[2] | |
#define ARRAYCOUNT(array) sizeof(array)/sizeof(array[0]) | |
typedef struct | |
{ | |
char *find; | |
char *add; | |
} sdata; | |
#if defined(_WIN32) | |
#define PATHSEP "\\" | |
#elif defined(__linux__) | |
#define PATHSEP "/" | |
#endif | |
sdata Searches[] = {{"qt_prfxpath=", ""}, | |
{"qt_docspath=", PATHSEP "doc"}, | |
{"qt_hdrspath=", PATHSEP "include"}, | |
{"qt_libspath=", PATHSEP "lib"}, | |
{"qt_binspath=", PATHSEP "bin"}, | |
{"qt_plugpath=", PATHSEP "plugins"}, | |
{"qt_datapath=", ""}, | |
{"qt_trnspath=", PATHSEP "translations"}, | |
{"qt_xmplpath=", PATHSEP "examples"}, | |
// {"qt_demopath=", PATHSEP "demos"}, | |
{"qt_lbexpath=", PATHSEP "libexec"}, | |
{"qt_impspath=", PATHSEP "imports"}, | |
{"qt_qml2path=", PATHSEP "qml"}, | |
{"qt_adatpath=", ""}, | |
{"qt_tstspath=", PATHSEP "tests"}, | |
{"qt_hpfxpath=", ""}, | |
{"qt_hbinpath=", PATHSEP "bin"}, | |
{"qt_hdatpath=", ""} | |
}; | |
// This is Win32 code currently, but could easily be adapted to use mmap | |
char *MapFile(char *file, size_t *FileLen) | |
{ | |
static void* lpMapAddress = NULL; | |
#if defined(_WIN32) | |
static HANDLE hQMake = NULL; | |
static HANDLE hMapFile = NULL; | |
// If this is an open | |
if (file != NULL) | |
{ | |
hQMake = CreateFile(file, // File name | |
GENERIC_READ | GENERIC_WRITE, // Desired access | |
FILE_SHARE_READ, // Sharing allowed | |
NULL, // Default security | |
OPEN_EXISTING, // Do not create a new file | |
FILE_ATTRIBUTE_NORMAL, // File attributes | |
NULL); | |
if (hQMake == INVALID_HANDLE_VALUE) | |
{ | |
printf("Could not open file.\n"); | |
return NULL; | |
} | |
*FileLen = GetFileSize(hQMake, NULL); | |
if (*FileLen == INVALID_FILE_SIZE) | |
{ | |
printf("Could not get file size.\n"); | |
CloseHandle(hQMake); | |
return NULL; | |
} | |
hMapFile = CreateFileMapping(hQMake, // Current file handle. | |
NULL, // Default security. | |
PAGE_READWRITE, // Read/write permission. | |
0, // Max. object size. | |
0, // Size of hFile. | |
"QMake"); // Name of mapping object. | |
if (hMapFile == INVALID_HANDLE_VALUE) | |
{ | |
printf("Could not create file-mapping object.\n"); | |
CloseHandle(hQMake); | |
return NULL; | |
} | |
lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object. | |
FILE_MAP_ALL_ACCESS, // Read/write permission | |
0, // Max. object size. | |
0, // Size of hFile. | |
0); // Map entire file. | |
if (lpMapAddress == INVALID_HANDLE_VALUE) | |
{ | |
printf("Could not map view of file.\n"); | |
CloseHandle(hMapFile); | |
CloseHandle(hQMake); | |
return NULL; | |
} | |
return (char*) lpMapAddress; | |
} | |
// This is a close | |
else | |
{ | |
if (!UnmapViewOfFile(lpMapAddress)) | |
{ | |
printf("Could not unmap view of file.\n"); | |
} | |
CloseHandle(hMapFile); | |
CloseHandle(hQMake); | |
return NULL; | |
} | |
#elif defined(__linux__) | |
static FILE *hQMake = NULL; | |
static void *map = NULL; | |
struct stat filesize; | |
// If this is an open | |
if (file != NULL) | |
{ | |
hQMake = fopen(file, "rb+"); | |
if (hQMake == NULL) | |
{ | |
printf("Could not open file.\n"); | |
return NULL; | |
} | |
if (fstat(fileno(hQMake), &filesize)) | |
{ | |
printf("Could not get file size.\n"); | |
fclose(hQMake); | |
return NULL; | |
} | |
*FileLen = filesize.st_size; | |
lpMapAddress = mmap(0, // Don't care what address we get | |
*FileLen, // Map the whole file | |
PROT_READ | PROT_WRITE, // Read/write permission | |
MAP_SHARED, // Shared mapping, stores affect original file | |
fileno(hQMake), // File number | |
0); | |
if (lpMapAddress == MAP_FAILED) | |
{ | |
printf("Could not map view of file.\n"); | |
fclose(hQMake); | |
return NULL; | |
} | |
map = lpMapAddress; | |
return (char*) lpMapAddress; | |
} | |
// This is a close | |
else | |
{ | |
munmap(map, *FileLen); | |
fclose(hQMake); | |
return NULL; | |
} | |
#endif | |
} | |
int main(int argc, char* argv[]) | |
{ | |
char *filedata; | |
size_t filesize; | |
char *match; | |
char *end; | |
char *nextbeg; | |
int i; | |
#if defined(__linux__) | |
FILE *backup = NULL; | |
#endif | |
if (argc < 2) | |
{ | |
printf ("Usage: patchqmake <path to qmake> <install path>\n\n"); | |
return 255; | |
} | |
// Map the file | |
filedata = MapFile(InFile, &filesize); | |
if (filedata == NULL) | |
return 1; | |
// Back up the file | |
match = (char*) malloc(strlen(InFile) + 5); | |
if (match == NULL) | |
return 2; | |
strcpy(match, InFile); | |
strcat(match, ".bak"); | |
#if defined(_WIN32) | |
if (!CopyFile(InFile, match, FALSE)) | |
{ | |
printf("Couldn't make backup of file!\n"); | |
MapFile(NULL, &filesize); | |
return 3; | |
} | |
#elif defined(__linux__) | |
backup = fopen(match, "wb"); | |
if (backup == NULL) | |
{ | |
printf("Couldn't make backup of file!\n"); | |
MapFile(NULL, &filesize); | |
return 3; | |
} | |
fwrite(filedata, 1, filesize, backup); | |
fclose(backup); | |
#endif | |
free(match); | |
for (i = 0; i < ARRAYCOUNT(Searches); i++) | |
{ | |
printf("Searching for '%s'...", Searches[i].find); | |
for (match = filedata; match < filedata + filesize; match++) | |
{ | |
// See if we've found the string to change | |
if (memcmp(match, Searches[i].find, strlen(Searches[i].find)) == 0) | |
{ | |
// Move past the string key | |
match += strlen(Searches[i].find); | |
// Find the end of space used, clearing it as we go | |
for (end = match; *end; end++) | |
*end = '\0'; | |
// Find the end of the allotted space | |
for (nextbeg = end; !*nextbeg; nextbeg++); | |
if ((size_t) (nextbeg - match) < strlen(TargetPath)) | |
{ | |
printf("not enough room for %s!\n", TargetPath); | |
MapFile(NULL, &filesize); | |
return 4; | |
} | |
printf("patching.\n"); | |
// Copy in the path they asked for | |
strcpy(match, TargetPath); | |
strcat(match, Searches[i].add); | |
break; | |
} | |
} | |
// Did we find it? | |
if (match >= filedata + filesize) | |
{ | |
printf("couldn't find it!\n"); | |
MapFile(NULL, &filesize); | |
return 5; | |
} | |
} | |
// Unmap the file | |
MapFile(NULL, &filesize); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment