From f05b935882198ccf7d81675736e3aeb089c5113a Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Thu, 5 May 2011 14:36:32 +0100 Subject: Merge WebKit at r74534: Initial merge by git. Change-Id: I6ccd1154fa1b19c2ec2a66878eb675738735f1eb --- WebKitTools/android/webkitmerge/webkitmerge.cpp | 1834 ----------------------- 1 file changed, 1834 deletions(-) delete mode 100644 WebKitTools/android/webkitmerge/webkitmerge.cpp (limited to 'WebKitTools/android/webkitmerge/webkitmerge.cpp') diff --git a/WebKitTools/android/webkitmerge/webkitmerge.cpp b/WebKitTools/android/webkitmerge/webkitmerge.cpp deleted file mode 100644 index 22eeb54..0000000 --- a/WebKitTools/android/webkitmerge/webkitmerge.cpp +++ /dev/null @@ -1,1834 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -using namespace std; - -string WEBKITLIB = "external/webkit"; - -string oldBaseStr; -string oldCmdStr; -string newBaseStr; -string newCmdStr; -string sandboxBaseStr; -string sandboxCmdStr; -string outputDir; -string scratchDir; - -const char* oldBase; -const char* oldCmd; -const char* newBase; -const char* newCmd; -const char* sandboxBase; -const char* sandboxCmd; - -bool assert_debug; - -#define myassert(a) do { \ - if (!(a)) { \ - fprintf(stderr, "%s %d %s\n", __FUNCTION__, __LINE__, #a); \ - fflush(stderr); \ - if (assert_debug) for(;;); else exit(0); \ - } \ -} while(false) - -class Options { -public: - Options() : emitGitCommands(false), emitPerforceCommands(false), - mergeMake(true), copyOther(true), mergeCore(true), - removeEmptyDirs(true), removeSVNDirs(true), debug(false), - execute(false), verbose(false), cleared(false) - { - } - - bool finish(); - void clearOnce() - { - if (cleared) - return; - mergeMake = copyOther = mergeCore = removeEmptyDirs = removeSVNDirs = false; - cleared = true; - } - string androidWebKit; - string baseWebKit; - string newWebKit; - bool emitGitCommands; - bool emitPerforceCommands; - bool mergeMake; - bool copyOther; - bool mergeCore; - bool removeEmptyDirs; - bool removeSVNDirs; - bool debug; - bool execute; - bool verbose; -private: - bool cleared; -}; - -Options options; - -char* GetFile(string fileNameStr, size_t* sizePtr = NULL, int* lines = NULL) -{ - const char* fileName = fileNameStr.c_str(); - FILE* file = fopen(fileName, "r"); - if (file == NULL) - { - fprintf(stderr, "can't read %s\n", fileName); - myassert(0); - return 0; - } - fseek(file, 0, SEEK_END); - size_t size = ftell(file); - if (sizePtr) - *sizePtr = size; - fseek(file, 0, SEEK_SET); - char* buffer = new char[size + 2]; - fread(buffer, size, 1, file); - buffer[size] = buffer[size + 1] = '\0'; - int lineCount = 0; - for (size_t index = 0; index < size; index++) { - if (buffer[index] == '\n') { - buffer[index] = '\0'; - lineCount++; - } - } - if (lines) - *lines = lineCount; - fclose(file); - return buffer; -} - -bool Options::finish() -{ - ::assert_debug = options.debug; - if (androidWebKit.size() == 0) { - fprintf(stderr, "missing --android parameter"); - return false; - } - if (baseWebKit.size() == 0) { - fprintf(stderr, "missing --basewebkit parameter"); - return false; - } - if (newWebKit.size() == 0) { - fprintf(stderr, "missing --newwebkit parameter"); - return false; - } - sandboxBaseStr = androidWebKit + "/" + WEBKITLIB; - sandboxCmdStr = sandboxBaseStr; - int err = system("pwd > pwd.txt"); - myassert(err != -1); - outputDir = string(GetFile("pwd.txt")); - system("rm pwd.txt"); - myassert(outputDir.size() > 0); - scratchDir = outputDir; - outputDir += "/scripts/"; - string outputMkdir = "test -d " + outputDir + " || mkdir " + outputDir; - system(outputMkdir.c_str()); - scratchDir += "/scratch/"; - string scratchMkdir = "test -d " + scratchDir + " || mkdir " + scratchDir; - system(scratchMkdir.c_str()); - oldBaseStr = baseWebKit; - oldCmdStr = oldBaseStr; - newBaseStr = newWebKit; - newCmdStr = newBaseStr; - oldBase = oldBaseStr.c_str(); - oldCmd = oldCmdStr.c_str(); - newBase = newBaseStr.c_str(); - newCmd = newCmdStr.c_str(); - sandboxBase = sandboxBaseStr.c_str(); - sandboxCmd = sandboxCmdStr.c_str(); - return true; -} - -// scratch files -string ScratchFile(const char* name) -{ - return scratchDir + name + ".txt"; -} - -FILE* commandFile; -FILE* copyDirFile; -FILE* oopsFile; - -string SedEscape(const char* str) -{ - string result; - char ch; - while ((ch = *str++) != '\0') { - if (ch == '/' || ch == '\\' || ch == '$') - result += '\\'; - result += ch; - } - return result; -} - -char* List(const char* base, char* name, const char* workingDir) -{ - string listStr = "ls -F \""; - listStr += string(base) + "/" + workingDir + "\" > " + ScratchFile(name); - int err = system(listStr.c_str()); - myassert(err == 0); - return GetFile(ScratchFile(name)); -} - -bool Merge(const char* oldDir, const char* oldFile, const char* newDir, const char* newFile, - const char* outFile) -{ - char scratch[2048]; - - sprintf(scratch, "merge -p -q \"%s/%s/%s\" \"%s/%s/%s\" \"%s/%s/%s\" > %s", - sandboxBase, oldDir, oldFile, oldBase, oldDir, oldFile, newBase, newDir, newFile, outFile); - int err = system(scratch); - myassert(err == 0 || err ==1 || err == 256); - return err == 0; -} - -bool Merge(const char* dir, const char* file) -{ - return Merge(dir, file, dir, file, "/dev/null"); -} - -/* -static const char* skipNonSpace(char** linePtr) { - char* line = *linePtr; - while (line[0] && isspace(line[0]) == false) - line++; - *linePtr = line; - return line; -} -*/ - -static bool endsWith(const char* str, const char* end) { - size_t endLen = strlen(end); - const char* endStr = str + strlen(str) - endLen; - return endStr >= str && strcmp(endStr, end) == 0; -} - -static void skipSpace(char** linePtr) { - char* line = *linePtr; - while (isspace(line[0])) - line++; - *linePtr = line; -} - -/* -static void setTrimmed(string& str, char* loc, int len) { - char* start = loc; - skipSpace(&loc); - len -= loc - start; - while (len > 0 && isspace(loc[len - 1])) - len--; - str = string(loc, len); -} -*/ - -static bool skipText(char** linePtr, const char* text) { - skipSpace(linePtr); - size_t length = strlen(text); - bool result = strncmp(*linePtr, text, length) == 0; - if (result) - *linePtr += length; - skipSpace(linePtr); - return result; -} - -static bool isTokenChar(char ch) { - return isalnum(ch) || ch == '_'; -} - -struct Pair { - char* name; - int brace; -}; - -class Parse { -public: - char* m_text; - bool m_inComment; - bool m_inFunction; - bool m_inFindFunctionType; - vector m_classes; - vector m_namespaces; - vector m_preprocessorConditions; - string m_functionName; - string m_functionDeclaration; - string m_classDeclaration; - int m_braceLevel; - int m_functionBrace; - - Parse(char* text) : m_text(text), m_inComment(false), m_inFunction(false), m_inFindFunctionType(false), - m_braceLevel(0), m_functionBrace(0) {} - - int CheckForBrace() - { - int indent = 0; - // don't count braces in strings, chars, comments - do { - char* openBrace = strchr(m_text, '{'); - char* closeBrace = strchr(m_text, '}'); - if (openBrace == NULL && closeBrace == NULL) - break; - char* brace = openBrace == NULL ? closeBrace : closeBrace == NULL ? openBrace : - openBrace < closeBrace ? openBrace : closeBrace; - char* doubleQ = strchr(m_text, '"'); - char* singleQ = strchr(m_text, '\''); - char* quote = doubleQ == NULL ? singleQ : singleQ == NULL ? doubleQ : - doubleQ < singleQ ? doubleQ : singleQ; - char quoteMark = quote == doubleQ ? '"' : '\''; - if (quote && quote < brace) { - myassert(quote[-1] != '\\'); - do { - quote = strchr(quote + 1, quoteMark); - myassert(doubleQ); - } while (quote[-1] == '\\'); - m_text = quote + 1; - continue; - } - indent += openBrace != NULL ? 1 : -1; - m_text = openBrace + 1; - } while (m_text[0] != '\0'); - return indent; - } - -int ParseLine() -{ - size_t textLen = strlen(m_text); - char* lineStart = m_text; - char* commentStart; - if (m_text[0] == '\0') - goto nextLine; - if (m_inComment == false && m_text[0] == '/') { - m_inComment = m_text[1] == '*'; - if (m_text[1] == '/' || m_text[1] == '*') - goto nextLine; - } - commentStart = m_text; // before anything else, turn embedded comments into their own lines - if (m_inComment == false && skipText(&commentStart, "//")) { - if (commentStart < lineStart + textLen) - commentStart[0] = '/'; - else - commentStart[-1] = ' '; - commentStart -= 2; - commentStart[0] = '\0'; - textLen = commentStart - lineStart; - goto nextLine; - } - if (m_inComment || skipText(&commentStart, "/*")) { - char* commentEnd = commentStart; - if (skipText(&commentEnd, "*/")) { - if (commentEnd < lineStart + textLen) { - commentEnd[-1] = '\0'; - textLen = commentEnd - lineStart - 2; - } - if (m_inComment) { - m_inComment = false; - goto nextLine; - } - } - if (m_inComment) - goto nextLine; - memcpy(commentStart - 2, "\0/*", 3); - textLen = commentStart - lineStart - 2; - } - if (skipText(&m_text, "#include")) - goto nextLine; - if (skipText(&m_text, "#if") || skipText(&m_text, "#else")) { - Pair condition = { lineStart, m_braceLevel }; - m_preprocessorConditions.push_back(condition); - goto nextLine; - } - { - bool is_endif = false; - if (skipText(&m_text, "#elif") || (is_endif = skipText(&m_text, "#endif")) != false) { // pop prior elif, if - char* lastText; - do { - int last = m_preprocessorConditions.size() - 1; - myassert(last >= 0); - lastText = m_preprocessorConditions[last].name; - m_preprocessorConditions.pop_back(); - } while (is_endif && skipText(&lastText, "#else") == true); - goto nextLine; - } - } - if (skipText(&m_text, "namespace")) { - Pair space = { lineStart, m_braceLevel }; - m_namespaces.push_back(space); - goto checkForBrace; - } - if (m_inFunction) - goto checkForBrace; - // detect functions by looking for token preceding open-paren. - if (m_inFindFunctionType == false) { - char* openParen = strchr(m_text, '('); - if (openParen) { - char* last = openParen; - while (last > m_text && isspace(last[-1])) - --last; - while (last > m_text && ((isTokenChar(last[-1]) || last[-1] == ':') && last[-2] == ':')) - --last; - myassert(isdigit(last[0]) == false); - if (isTokenChar(last[0])) { - m_inFindFunctionType = true; - m_functionName = string(last); - } - } - } - { - char* openBrace = strchr(m_text, '{'); - char* semiColon = strchr(m_text, ';'); - if (semiColon != NULL && semiColon < openBrace) - openBrace = NULL; - // functions are of the form: type (class::)*function(parameter-list) { - // all of which may be on separate lines - // so keep track of returntype, class, function, paramlist, openbrace separately - if (m_inFindFunctionType == true) { // look ahead to see which comes first, a semicolon or an open brace - if (openBrace) { - m_functionBrace = ++m_braceLevel; - m_inFunction = true; - m_inFindFunctionType = false; - m_text = openBrace + 1; - goto checkForBrace; - } - if (semiColon != NULL) { // a function declaration - m_inFindFunctionType = false; - m_functionDeclaration = m_functionName; - m_functionName.erase(0, m_functionName.length()); - } else - goto nextLine; - } - // FIXME what if class line has neither brace nor semi? - if (skipText(&m_text, "class")) { - if (openBrace > m_text) { - Pair _class = { lineStart, m_braceLevel }; - m_classes.push_back(_class); - } else if (semiColon != NULL) { - m_classDeclaration = lineStart; // !!! FIXME should have function form as above - } - } - } -checkForBrace: - m_braceLevel += CheckForBrace(); - if (m_functionBrace > 0 && m_braceLevel <= m_functionBrace) { - m_functionName.erase(0, m_functionName.length()); - m_functionBrace = 0; - } -nextLine: - return textLen; -} - -}; - -char* const GetAndroidDiffs(const char* dir, const char* filename) -{ - char scratch[2048]; - string diffsFile = ScratchFile(__FUNCTION__); - sprintf(scratch, "diff \"%s/%s/%s\" \"%s/%s/%s\" > %s", sandboxBase, dir, - filename, oldBase, dir, filename, diffsFile.c_str()); - int err = system(scratch); - myassert(err == 0 || err == 256); - char* const diffs = GetFile(diffsFile); - return diffs; -} - -void CheckForExec(const char* base1, const char* dir1, const char* file1, - const char* base2, const char* dir2, const char* file2, bool* ex1, bool* ex2) -{ - size_t file1Len = strlen(file1); - size_t file2Len = strlen(file2); - bool file1Ex = file1[file1Len - 1] == '*'; - bool file2Ex = file2[file2Len - 1] == '*'; - if (file1Ex != file2Ex) { - fprintf(stderr, "warning: %s/%s/%s has %sexec bit set while" - " %s/%s/%s has %sexec bit set\n", - base1, dir1, file1, file1Ex ? "" : "no ", - base2, dir2, file2, file2Ex ? "" : "no "); - } - if (ex1) *ex1 = file1Ex; - if (ex2) *ex2 = file2Ex; -} - -bool CompareFiles(const char* base1, const char* dir1, const char* file1, - const char* base2, const char* dir2, const char* file2) -{ - char scratch[2048]; - bool file1Ex, file2Ex; - string compareFileStr = ScratchFile(__FUNCTION__); - CheckForExec(base1, dir1, file1, base2, dir2, file2, &file1Ex, &file2Ex); - sprintf(scratch, "diff --brief \"%s/%s/%.*s\" \"%s/%s/%.*s\" > %s", - base1, dir1, (int) strlen(file1) - (int) file1Ex, file1, - base2, dir2, (int) strlen(file2) - (int) file2Ex, file2, - compareFileStr.c_str()); - int err = system(scratch); - myassert(err == 0 || err == 256); - char* scratchText = GetFile(compareFileStr); - size_t len = strlen(scratchText); - delete[] scratchText; - return len > 0; -} - -bool CompareFiles(const char* base1, const char* base2, const char* dir, const char* file) -{ - return CompareFiles(base1, dir, file, base2, dir, file); -} - -int Compare(char* one, size_t len1, char* two, size_t len2) -{ - char* o_end = one + len1; - char* t_end = two + len2; - do { - if (one == o_end) - return two == t_end ? 0 : 1; - if (two == t_end) - return -1; - char o = *one++; - char t = *two++; - if (o == t) - continue; - if (o == '/') - return -1; - if (t == '/') - return 1; - return o < t ? -1 : 1; - } while (true); - myassert(0); - return 0; -} - -string Find(const char* oldList) -{ - string result; - char scratch[2048]; - // look in WebCore and JavaScriptCore - string findWebCore = ScratchFile("FindWebCore"); - sprintf(scratch, "cd %s%s ; find . -name \"%s\" > %s", - newBase, "/WebCore", oldList, findWebCore.c_str()); - int err = system(scratch); - myassert(err == 0 || err == 256); - int webCount; - char* foundInWebCore = GetFile(findWebCore, NULL, &webCount); - char* originalFoundInWebCore = foundInWebCore; - string findJavaScriptCore = ScratchFile("FindJavaScriptCore"); - sprintf(scratch, "cd %s%s ; find . -name \"%s\" > %s", - newBase, "/JavaScriptCore", oldList, findJavaScriptCore.c_str()); - err = system(scratch); - myassert(err == 0 || err == 256); - int javaScriptCount; - char* foundInJavaScriptCore = GetFile(findJavaScriptCore, NULL, &javaScriptCount); - char* originalFoundInJavaScriptCore = foundInJavaScriptCore; - if (webCount == 1 && javaScriptCount == 0) { - result = "WebCore/" + string(&foundInWebCore[2]); - } else if (webCount == 0 && javaScriptCount == 1) { - result = "JavaScriptCore/" + string(&foundInJavaScriptCore[2]); - } else if (webCount == 1 && javaScriptCount == 1 && - strncmp(&foundInWebCore[2], "ForwardingHeaders/", 18) == 0) { - result = "JavaScriptCore/" + string(&foundInJavaScriptCore[2]); - } else if (webCount == 1 && javaScriptCount == 1 && - strncmp(&foundInJavaScriptCore[2], "API/tests/", 10) == 0) { - result = "JavaScriptCore/" + string(&foundInJavaScriptCore[2]); - } else if (webCount + javaScriptCount > 0) { - fprintf(stderr, "deleted file \"%s\" has more than one possible rename:\n", oldList); - int index; - for (index = 0; index < webCount; index++) { - fprintf(stderr, "WebCore/%s\n", &foundInWebCore[2]); - foundInWebCore += strlen(foundInWebCore) + 1; - } - for (index = 0; index < javaScriptCount; index++) { - fprintf(stderr, "JavaScriptCore/%s\n", &foundInJavaScriptCore[2]); - foundInJavaScriptCore += strlen(foundInJavaScriptCore) + 1; - } - } - delete[] originalFoundInWebCore; - delete[] originalFoundInJavaScriptCore; - return result; -} - -char* GetMakeAndExceptions(const char* dir, const char* filename, size_t* makeSize, - string* excludedFilesPtr, string* excludedGeneratedPtr, - string* excludedDirsPtr, string* androidFilesPtr, - char** startPtr, char** localStartPtr) -{ - char scratch[1024]; - sprintf(scratch, "%s/%s/%s", sandboxBase, dir, filename); - char* makeFile = GetFile(scratch, makeSize); - char* start = makeFile; - do { // find first filename in makefile - if (strncmp(start, "# LOCAL_SRC_FILES_EXCLUDED := \\", 30) == 0) - break; - start += strlen(start) + 1; - } while (start < makeFile + *makeSize); - myassert(start[0] != '\0'); - start += strlen(start) + 1; - // construct one very large regular expression that looks like: - // echo '%s' | grep -v -E 'DerivedSources.cpp|WebCorePrefix.cpp...' - // to filter out matches that aren't allowed - // wildcards '*' in the original need to be expanded to '.*' - string excludedFiles = "grep -v -E '"; - while (strncmp(start, "#\t", 2) == 0) { - start += 2; - char ch; - while ((ch = *start++) != ' ') { - if (ch == '*') - excludedFiles += '.'; - else if (ch == '.') - excludedFiles += '\\'; - excludedFiles += ch; - } - excludedFiles += "|"; - myassert(*start == '\\'); - start += 2; - } - excludedFiles[excludedFiles.size() - 1] = '\''; - *excludedFilesPtr = excludedFiles; - do { - if (strncmp(start, "# LOCAL_GENERATED_FILES_EXCLUDED := \\", 37) == 0 || - strncmp(start, "# LOCAL_DIR_WILDCARD_EXCLUDED := \\", 34) == 0) - break; - start += strlen(start) + 1; - } while (start < makeFile + *makeSize); - if (strncmp(start, "# LOCAL_GENERATED_FILES_EXCLUDED := \\", 37) == 0) { - string excludedGenerated = "grep -v -E '"; - start += strlen(start) + 1; - while (strncmp(start, "#\t", 2) == 0) { - start += 2; - char ch; - while ((ch = *start++) != ' ') { - if (ch == '*') - excludedGenerated += '.'; - else if (ch == '.') - excludedGenerated += '\\'; - excludedGenerated += ch; - } - excludedGenerated += "|"; - myassert(*start == '\\'); - start += 2; - } - myassert(excludedGeneratedPtr); - excludedGenerated[excludedGenerated.size() - 1] = '\''; - *excludedGeneratedPtr = excludedGenerated; - } - do { // find first filename in makefile - if (strncmp(start, "# LOCAL_DIR_WILDCARD_EXCLUDED := \\", 34) == 0) - break; - start += strlen(start) + 1; - } while (start < makeFile + *makeSize); - if (start[0] != '\0') { - string excludedDirs = "-e '/\\.vcproj\\// d' -e '/\\.svn\\// d' "; - do { - start += strlen(start) + 1; - char* exceptionDirStart = start; - if (strncmp(exceptionDirStart, "#\t", 2) != 0) { - myassert(exceptionDirStart[0] == '\0'); - break; - } - exceptionDirStart += 2; - char* exceptionDirEnd = exceptionDirStart; - do { - exceptionDirEnd = strchr(exceptionDirEnd, '\\'); - } while (exceptionDirEnd && *++exceptionDirEnd == '/'); - myassert(exceptionDirEnd); - --exceptionDirEnd; - myassert(exceptionDirEnd[-1] == ' '); - myassert(exceptionDirEnd[-2] == '*'); - myassert(exceptionDirEnd[-3] == '/'); - exceptionDirEnd[-3] = '\0'; - excludedDirs += "-e '/"; - if (exceptionDirStart[0] == '/') - excludedDirs += "\\"; - excludedDirs += exceptionDirStart; - excludedDirs += "\\// d' "; - start = exceptionDirEnd; - } while (true); - *excludedDirsPtr = excludedDirs; - } - *startPtr = start; - // optionally look for android-specific files - char* makeEnd = makeFile + *makeSize; - do { // find first filename in makefile - if (strcmp(start, "# LOCAL_ANDROID_SRC_FILES_INCLUDED := \\") == 0) - break; - } while ((start += strlen(start) + 1), start < makeEnd); - if (start >= makeEnd) - return makeFile; - start += strlen(start) + 1; - string androidFiles = "grep -v -E '"; - do { - myassert(strncmp(start, "#\t", 2) == 0); - start += 2; - char ch; - bool isIdl = strstr(start, "idl \\") != 0; - char* lastSlash = strrchr(start, '/') + 1; - while ((ch = *start++) != ' ') { - if (ch == '*') - androidFiles += '.'; - else if (ch == '.') - androidFiles += '\\'; - androidFiles += ch; - if (!isIdl) - continue; - if (ch == '/' && start == lastSlash) - androidFiles += "JS"; - if (ch == '.') { - myassert(strcmp(start, "idl \\") == 0); - start += 4; - androidFiles += 'h'; - break; - } - } - androidFiles += "|"; - myassert(*start == '\\'); - start += 2; - } while (start[0] == '#'); - androidFiles[androidFiles.size() - 1] = '\''; - *androidFilesPtr = androidFiles; - return makeFile; -} - -vector GetDerivedSourcesMake(const char* dir) -{ - vector result; - char scratch[1024]; - sprintf(scratch, "%s/%s/%s", newBase, dir, "DerivedSources.make"); - size_t fileSize; - char* file = GetFile(scratch, &fileSize); - char* fileEnd = file + fileSize; - myassert(file); - size_t len; - do { // find first filename in makefile - len = strlen(file); - if (strcmp(file, "all : \\") == 0) - break; - file += len + 1; - } while (file < fileEnd); - myassert(strcmp(file, "all : \\") == 0); - file += len + 1; - while (file[0] != '#') { - len = strlen(file); - char* st = file; - skipSpace(&st); - if (st[0] != '\\' && st[0] != '$') - result.push_back(st); - file += len + 1; - } - return result; -} - -bool MarkDerivedFound(vector& derived, char* check, size_t len) -{ - bool found = false; - for (unsigned index = 0; index < derived.size(); index++) { - char* der = derived[index]; - if (strncmp(der, check, len) == 0) { - der[0] = '\0'; - found = true; - } - } - return found; -} - -void UpdateDerivedMake() -{ - const char* dir = "WebCore"; - int err; - vector derived = GetDerivedSourcesMake(dir); - size_t makeSize; - char* start, * localStart; - string excludedDirs, excludedFiles, excludedGenerated, androidFiles; - char* makeFile = GetMakeAndExceptions(dir, "Android.derived.mk", &makeSize, - &excludedFiles, &excludedGenerated, &excludedDirs, &androidFiles, - &start, &localStart); - if (options.emitPerforceCommands) - fprintf(commandFile, "p4 edit %s/%s/%s\n", sandboxCmd, dir, "Android.derived.mk"); - fprintf(commandFile, "cat %s/%s/%s | sed \\\n", sandboxCmd, dir, "Android.derived.mk"); - string updateDerivedMake = ScratchFile(__FUNCTION__); - string filelist = string("cd ") + newBase + "/" + dir + - " ; find . -name '*.idl' | " + excludedFiles + - " | sed -e 's/.\\///' " + excludedDirs + - " | sed 's@\\(.*\\)/\\(.*\\)\\.idl@ $(intermediates)/\\1/JS\\2.h@' " - " | sort -o " + updateDerivedMake; - err = system(filelist.c_str()); - myassert(err == 0 || err == 256); - char* bindings = GetFile(updateDerivedMake); - bool inGen = false; - char* fileEnd = makeFile + makeSize; - char* nextStart; - do { - size_t startLen = strlen(start); - nextStart = start + startLen + 1; - bool onGen = false; - char* st = start; - if (inGen == false) { - if (strncmp(st, "GEN", 3) != 0) - continue; - st += 3; - skipSpace(&st); - if (strncmp(st, ":=", 2) != 0) - continue; - st += 2; - onGen = true; - } - skipSpace(&st); - inGen = start[startLen - 1] == '\\'; - if (inGen) { - if (st[0] == '\\' && st[1] == '\0') - continue; - if (strcmp(st, "$(addprefix $(intermediates)/, \\") == 0) - continue; - } else if (st[0] == ')' && st[1] == '\0') - continue; - static const char bindHead[] = "bindings/js/"; - const size_t bindLen = sizeof(bindHead) - 1; - string escaped; - if (strncmp(st, bindHead, bindLen) == 0) { - st += bindLen; - if (MarkDerivedFound(derived, st, strlen(st)) == false) { - fprintf(stderr, "*** webkit removed js binding: %s" - " (must be removed manually)\n", st); - escaped = SedEscape(st); - fprintf(commandFile, "-e '/%s/ d' ", escaped.c_str()); - } - continue; - } - myassert(strncmp(st, "$(intermediates)", 16) == 0); - if (onGen && inGen == false) { // no continuation - char* lastSlash; - myassert(strrchr(st, '/') != NULL); - while ((lastSlash = strrchr(st, '/')) != NULL) { - char* lastEnd = strchr(lastSlash, ' '); - if (lastEnd == NULL) - lastEnd = lastSlash + strlen(lastSlash); - myassert(lastSlash != 0); - lastSlash++; - size_t lastLen = lastEnd - lastSlash; - if (MarkDerivedFound(derived, lastSlash, lastLen) == false) { - fprintf(stderr, "*** webkit removed generated file:" - " %.*s (must be removed manually)\n", (int) lastLen, - lastSlash); - // escaped = SedEscape(st); - // fprintf(commandFile, "-e '/%s/ d' \\\n", escaped.c_str()); - } - char* priorDollar = strrchr(st, '$'); - myassert(priorDollar != NULL); - char* nextDollar = strchr(st, '$'); - if (nextDollar == priorDollar) - break; - priorDollar[0] = '\0'; - } - continue; - } - char* nextSt = nextStart; - skipSpace(&nextSt); - myassert(strncmp(nextSt, "$(intermediates)", 16) != 0 || strcmp(st, nextSt) < 0); - // do { - char* bind = bindings; - myassert(bind); - skipSpace(&bind); - int compare = strncmp(bind, st, strlen(bind) - 2); - if (compare < 0) { // add a file - escaped = SedEscape(st); - char* filename = strrchr(bindings, '/'); - myassert(filename); - filename += 3; - // FIX ME: exclude items in DerivedSources.make all : $(filter-out ... - char* bi = bindings; - skipSpace(&bi); - char* bindName = strrchr(bi, '/'); - myassert(bindName != NULL); - bindName++; - string biStr = SedEscape(bi); - fprintf(commandFile, "-e '/%s/ i\\\n_TAB_%s \\\\\n' ", - escaped.c_str(), biStr.c_str()); - MarkDerivedFound(derived, bindName, strlen(bindName)); - nextStart = start; - bindings += strlen(bindings) + 1; - inGen = true; - } else if (compare > 0) { - // if file to be deleted is locally added by android, leave it alone - myassert(strncmp(st, "$(intermediates)/", 17) == 0); - string subst = string(st).substr(17, strlen(st) - 17 - (inGen ? 2 : 0)); - string localDerivedStr = ScratchFile("LocalDerived"); - string filter = string("echo '") + subst + "' | " + androidFiles + - " > " + localDerivedStr; - if (options.debug) - fprintf(stderr, "LocalDerived.txt : %s\n", filter.c_str()); - err = system(filter.c_str()); - myassert(err == 0 || err == 256); - char* localDerived = GetFile(localDerivedStr); - if (localDerived[0] != '\0') { - escaped = SedEscape(st); - fprintf(commandFile, "-e '/%s/ d' ", escaped.c_str()); - } - } else { - char* stName = strrchr(st, '/'); - myassert(stName); - stName++; - MarkDerivedFound(derived, stName, strlen(stName)); - bindings += strlen(bindings) + 1; - } - // } while (strstr(start, "$(intermediates)") != NULL); - // if changing directories, add any new files to the end of this directory first - if (bindings[0] != '\0' && strstr(nextStart, "$(intermediates)") == NULL) { - st = start; - skipSpace(&st); - escaped = SedEscape(st); - st = strchr(st, '/'); - char* stDirEnd = strchr(st + 1, '/'); - do { - bind = strchr(bindings, '/'); - if (!bind) - break; - char* bindEnd = strchr(bind + 1, '/'); - if (!bindEnd) - break; - if (bindEnd - bind != stDirEnd - st) - break; - if (strncmp(st, bind, stDirEnd - st) != 0) - break; - if (inGen == false) - fprintf(commandFile, "-e '/%s/ s/$/ \\\\/' ", escaped.c_str()); - char* bi = bindings; - skipSpace(&bi); - string biStr = SedEscape(bi); - fprintf(commandFile, "-e '/%s/ a\\\n_TAB_%s\n' ", - escaped.c_str(), biStr.c_str()); - MarkDerivedFound(derived, bindEnd + 1, strlen(bindEnd + 1)); - escaped = biStr; - inGen = false; - bindings += strlen(bindings) + 1; - } while (true); - } - } while (start = nextStart, start < fileEnd); - for (unsigned index = 0; index < derived.size(); index++) { - char* der = derived[index]; - if (der[0] == '\0') - continue; - string excludedGeneratedStr = ScratchFile("ExcludedGenerated"); - string filter = string("echo '") + der + "' | " + excludedGenerated + - " > " + excludedGeneratedStr; - err = system(filter.c_str()); - myassert(err == 0 || err == 256); - char* excluded = GetFile(excludedGeneratedStr); - if (excluded[0] != '\0') - fprintf(stderr, "*** missing rule to generate %s\n", der); - } - fprintf(commandFile, " | sed 's/^_TAB_/\t/' > %s/%s/%s\n", sandboxCmd, dir, "xAndroid.derived.mk"); - fprintf(commandFile, "mv %s/%s/%s %s/%s/%s\n", - sandboxCmd, dir, "xAndroid.derived.mk", sandboxCmd, dir, "Android.derived.mk"); - if (options.emitGitCommands) - fprintf(commandFile, "git add %s/%s\n", dir, "Android.derived.mk"); -} - -int MatchLen(const char* one, const char* two, size_t len) -{ - bool svgIn1 = strstr(one, "svg") || strstr(one, "SVG"); - bool svgIn2 = strstr(two, "svg") || strstr(two, "SVG"); - if (svgIn1 != svgIn2) - return 0; - int signedLen = (int) len; - int original = signedLen; - while (*one++ == *two++ && --signedLen >= 0) - ; - return original - signedLen; -} - -// create the list of sed commands to update the WebCore Make file -void UpdateMake(const char* dir) -{ - // read in the makefile - size_t makeSize; - char* start, * localStart = NULL; - string excludedDirs, excludedFiles, androidFiles; - char* makeFile = GetMakeAndExceptions(dir, "Android.mk", &makeSize, - &excludedFiles, NULL, &excludedDirs, &androidFiles, &start, &localStart); - char* lastFileName = NULL; - size_t lastFileNameLen = 0; - int lastLineNumber = -1; - // get the actual list of files - string updateMakeStr = ScratchFile(__FUNCTION__); - string filelist = string("cd ") + newBase + "/" + dir + " ;" - " find . -name '*.cpp' -or -name '*.c' -or -name '*.y' | " + - excludedFiles + " | sed -e 's/.\\///' " + excludedDirs + - " | sort -o " + updateMakeStr; - if (options.debug) - fprintf(stderr, "make %s/%s filter: %s\n", dir, "Android.mk", filelist.c_str()); - int err = system(filelist.c_str()); - myassert(err == 0 || err == 256); - char* newList = GetFile(updateMakeStr); - do { // find first filename in makefile - if (strncmp(start, "LOCAL_SRC_FILES := \\", 20) == 0) - break; - start += strlen(start) + 1; - } while (start < makeFile + makeSize); - myassert(start[0] != '\0'); - if (options.emitPerforceCommands) - fprintf(commandFile, "p4 edit %s/%s/%s\n", sandboxCmd, dir, "Android.mk"); - fprintf(commandFile, "cat %s/%s/%s | sed ", sandboxCmd, dir, "Android.mk"); - int lineNumber = 0; - do { - start += strlen(start) + 1; - lineNumber++; - if (start - makeFile >= makeSize || start[0] == '$') - break; - if (start[0] == '\0' || !isspace(start[0])) - continue; - skipSpace(&start); - if (start[0] == '\0' || start[0] == '\\') - continue; - size_t startLen = strlen(start); - if (start[startLen - 1] == '\\') - --startLen; - while (isspace(start[startLen - 1])) - --startLen; - size_t newListLen = strlen(newList); - if (lastFileName != NULL) { - myassert(strncmp(start, lastFileName, startLen) > 0 || - startLen > lastFileNameLen); - } - if (strstr(start, "android") != NULL || strstr(start, "Android") != NULL) { - if (startLen == newListLen && strncmp(newList, start, startLen) == 0) - newList += newListLen + 1; - lastFileName = start; - lastFileNameLen = startLen; - lastLineNumber = lineNumber; - continue; - } - int compare; - bool backslash = lastFileName && - lastFileName[strlen(lastFileName) - 1] == '\\'; - do { - compare = strncmp(newList, start, startLen); - if (compare == 0 && startLen != newListLen) - compare = newListLen < startLen ? -1 : 1; - if (newList[0] == '\0' || compare >= 0) - break; - // add a file - if (lastFileName && lineNumber - lastLineNumber > 1 && - MatchLen(lastFileName, newList, lastFileNameLen) > - MatchLen(start, newList, startLen)) { - string escaped = SedEscape(lastFileName); - if (!backslash) - fprintf(commandFile, "-e '/%s/ s/$/ \\\\/' ", escaped.c_str()); - fprintf(commandFile, "-e '/%s/ a\\\n_TAB_%s%s\n' ", - SedEscape(lastFileName).c_str(), newList, - backslash ? " \\\\" : ""); - lastFileName = newList; - lastFileNameLen = newListLen; - } else { - fprintf(commandFile, "-e '/%s/ i\\\n_TAB_%s \\\\\n' ", - SedEscape(start).c_str(), newList); - } - newList += newListLen + 1; - newListLen = strlen(newList); - } while (true); - if (newList[0] == '\0' || compare > 0) { - // don't delete files added by Android - string localMakeStr = ScratchFile("LocalMake"); - string filter = "echo '" + string(start).substr(0, startLen) + - "' | " + androidFiles + " > " + localMakeStr; - int err = system(filter.c_str()); - myassert(err == 0 || err == 256); - char* localMake = GetFile(localMakeStr); - if (localMake[0] != '\0') { - string escaped = SedEscape(start); - fprintf(commandFile, "-e '/%s/ d' ", escaped.c_str()); - } - } else - newList += newListLen + 1; - lastFileName = start; - lastFileNameLen = startLen; - lastLineNumber = lineNumber; - } while (true); - fprintf(commandFile, " | sed 's/^_TAB_/\t/' > %s/%s/%s\n", sandboxCmd, dir, "xAndroid.mk"); - fprintf(commandFile, "mv %s/%s/%s %s/%s/%s\n", - sandboxCmd, dir, "xAndroid.mk", sandboxCmd, dir, "Android.mk"); - if (options.emitGitCommands) - fprintf(commandFile, "git add %s/%s\n", dir, "Android.mk"); -} - -static bool emptyDirectory(const char* base, const char* work, const char* dir) { - string findEmptyStr = "find \""; - string emptyDirStr = ScratchFile("emptyDirectory"); - if (base[0] != '\0') - findEmptyStr += string(base) + "/" + work + "/" + dir + "\""; - else - findEmptyStr += string(work) + "/" + dir + "\""; - findEmptyStr += " -type f -print > " + emptyDirStr; - int err = system(findEmptyStr.c_str()); - if (err != 0) - return true; - FILE* file = fopen(emptyDirStr.c_str(), "r"); - if (file == NULL) - { - fprintf(stderr, "can't read %s\n", emptyDirStr.c_str()); - myassert(0); - return true; - } - fseek(file, 0, SEEK_END); - size_t size = ftell(file); - fclose(file); - return size == 0; -} - -static bool emptyDirectory(const char* work, const char* dir) { - return emptyDirectory("", work, dir); -} - -void CompareDirs(const char* workingDir, bool renamePass) -{ - map renameMap; - char* oldList = List(oldBase, "old", workingDir); - char* newList = List(newBase, "new", workingDir); - char* sandList = List(sandboxBase, "sandbox", workingDir); - char* oldMem = oldList; - char* newMem = newList; - char* sandboxMem = sandList; - // identify files to be added, removed by comparing old, new lists - do { - size_t oldLen = strlen(oldList); - size_t newLen = strlen(newList); - size_t sandLen = strlen(sandList); - if (oldLen == 0 && newLen == 0 && sandLen == 0) - break; - bool oldDir = false; - bool oldExecutable = false; - if (oldLen > 0) { - char last = oldList[oldLen - 1]; - oldDir = last == '/'; - oldExecutable = last == '*'; - if (oldDir || oldExecutable) - --oldLen; - } - bool newDir = false; - bool newExecutable = false; - if (newLen > 0) { - char last = newList[newLen - 1]; - newDir = last == '/'; - newExecutable = last == '*'; - if (newDir || newExecutable) - --newLen; - } - bool sandDir = false; - bool sandExecutable = false; - if (sandLen > 0) { - char last = sandList[sandLen - 1]; - sandDir = last == '/'; - sandExecutable = last == '*'; - if (sandDir || sandExecutable) - --sandLen; - } - string oldFileStr = string(oldList).substr(0, oldLen); - const char* oldFile = oldFileStr.c_str(); - string newFileStr = string(newList).substr(0, newLen); - const char* newFile = newFileStr.c_str(); - string sandFileStr = string(sandList).substr(0, sandLen); - const char* sandFile = sandFileStr.c_str(); - int order = Compare(oldList, oldLen, newList, newLen); - int sandOrder = 0; - if ((oldLen > 0 || sandLen > 0) && order <= 0) { - sandOrder = Compare(sandList, sandLen, oldList, oldLen); - if (sandOrder > 0 && renamePass == false) - fprintf(stderr, "error: file in old webkit missing from sandbox: %s/%s\n", - workingDir, oldFile); - if (sandOrder < 0 && renamePass == false) { - // file added by android -- should always have name 'android?' - const char* android = strstr(sandFile, "ndroid"); - if (android == NULL) - fprintf(stderr, "warning: expect added %s to contain 'android': %s/%s\n", - sandDir ? "directory" : "file" , workingDir, sandFile); - } - if (sandOrder == 0) { - myassert(oldDir == sandDir); - if (oldExecutable != sandExecutable) - CheckForExec(oldBase, workingDir, oldList, - sandboxBase, workingDir, sandList, 0, 0); - } - if (sandOrder <= 0) - sandList += strlen(sandList) + 1; - if (sandOrder < 0) - continue; - } - if (order < 0) { // file in old list is not in new - // check to see if file is read only ; if so, call p4 delete -- otherwise, just call delete - if (oldDir == false) { - bool modifiedFile = false; - // check to see if android modified deleted file - if (sandOrder == 0) { - string rename(workingDir); - rename.append("/"); - rename.append(oldFile); - if (renamePass) { - string newName = Find(oldFile); - if (newName.length() > 0) { - map::iterator iter = renameMap.find(rename); - myassert(iter == renameMap.end()); // if I see the same file twice, must be a bug - renameMap[rename] = newName; - myassert(rename != newName); - if (options.debug) - fprintf(stderr, "map %s to %s\n", rename.c_str(), newName.c_str()); - } - } - if (renamePass == false) { - bool oldSandboxDiff = CompareFiles(oldBase, sandboxBase, workingDir, oldList); - const char* renamedDir = workingDir; - map::iterator iter = renameMap.find(rename); - if (iter != renameMap.end()) { - string newName = renameMap[rename]; - renamedDir = newName.c_str(); - char* renamed = (char*) strrchr(renamedDir, '/'); - *renamed++ = '\0'; // splits rename into two strings - if (options.emitPerforceCommands) { - fprintf(commandFile, "p4 integrate \"%s/%s/%s\" \"%s/%s/%s\"\n", sandboxCmd, workingDir, oldFile, - sandboxCmd, renamedDir, renamed); - fprintf(commandFile, "p4 resolve \"%s/%s/%s\"\n", sandboxCmd, renamedDir, renamed); - } else if (options.emitGitCommands) { - fprintf(commandFile, "git mv \"%s/%s\" \"%s/%s\"\n", workingDir, oldFile, - renamedDir, renamed); - } - if (oldSandboxDiff) { - if (options.emitPerforceCommands) - fprintf(commandFile, "p4 open \"%s/%s/%s\"\n", sandboxCmd, renamedDir, renamed); - fprintf(commandFile, "merge -q \"%s/%s/%s\" \"%s/%s/%s\" \"%s/%s/%s\"\n", - sandboxCmd, renamedDir, renamed, oldCmd, workingDir, oldFile, newCmd, renamedDir, renamed); - bool success = Merge(workingDir, oldFile, renamedDir, renamed, "/dev/null"); - if (success == false) { - fprintf(stderr, "*** Manual merge required: %s/%s\n", renamedDir, renamed); - fprintf(commandFile, "cat \"%s/%s/%s\" | sed -e 's/^<<<<<<<.*$/#ifdef MANUAL_MERGE_REQUIRED/' " - "-e 's/^=======$/#else \\/\\/ MANUAL_MERGE_REQUIRED/' " - "-e 's/^>>>>>>>.*$/#endif \\/\\/ MANUAL_MERGE_REQUIRED/' > \"%s/%s/x%s\"\n", - sandboxCmd, renamedDir, renamed, sandboxCmd, renamedDir, renamed); - fprintf(commandFile, "mv \"%s/%s/x%s\" \"%s/%s/%s\"\n", - sandboxCmd, renamedDir, renamed, sandboxCmd, renamedDir, renamed); - } - if (options.emitGitCommands) - fprintf(commandFile, "git add \"%s/%s\"\n", renamedDir, renamed); - } else { - bool oldNewDiff = CompareFiles(oldBase, workingDir, oldList, newBase, renamedDir, renamed); - if (oldNewDiff) { - if (options.emitPerforceCommands) - fprintf(oopsFile, "p4 open \"%s/%s/%s\"\n", sandboxCmd, renamedDir, renamed); - fprintf(oopsFile, "cp \"%s/%s/%s\" \"%s/%s/%s\"\n", - newCmd, renamedDir, renamed, sandboxCmd, renamedDir, renamed); - if (options.emitGitCommands) - fprintf(oopsFile, "git add \"%s/%s\"\n", renamedDir, renamed); - } - } - } else if (oldSandboxDiff) { - modifiedFile = true; - fprintf(stderr, "*** Modified file deleted: %s/%s\n", workingDir, oldFile); -// FindDeletedAndroidChanges(workingDir, oldFile); - } - } // if renamePass == false - } // if sandOrder == 0 - if (modifiedFile) { - fprintf(commandFile, "cat \"%s/%s/%s\" | sed -e '1 i\\\n#ifdef MANUAL_MERGE_REQUIRED\n' " - "-e '$ a\\\n#endif \\/\\/ MANUAL_MERGE_REQUIRED\n' > \"%s/%s/x%s\"\n", - sandboxCmd, workingDir, oldFile, sandboxCmd, workingDir, oldFile); - fprintf(commandFile, "mv \"%s/%s/x%s\" \"%s/%s/%s\"\n", - sandboxCmd, workingDir, oldFile, sandboxCmd, workingDir, oldFile); - } else if (options.emitPerforceCommands) - fprintf(commandFile, "p4 delete \"%s/%s/%s\"\n", sandboxCmd, workingDir, oldFile); - else if (options.emitGitCommands) - fprintf(commandFile, "git rm \"%s/%s\"\n", workingDir, oldFile); - else - fprintf(commandFile, "rm \"%s/%s/%s\"\n", sandboxCmd, workingDir, oldFile); - } else { // if oldDir != false - // !!! FIXME start here; - // check to see if old directory is empty ... (e.g., WebCore/doc) - // ... and/or isn't in sandbox anyway (e.g., WebCore/LayoutTests) - // if old directory is in sandbox (e.g. WebCore/kcanvas) that should work - if (options.emitPerforceCommands) - fprintf(commandFile, "p4 delete \"%s/%s/%s/...\"\n", sandboxCmd, workingDir, oldFile); - else if (options.emitGitCommands) - fprintf(commandFile, "git rm \"%s/%s/...\"\n", workingDir, oldFile); - else - fprintf(commandFile, "rm \"%s/%s/%s/...\"\n", sandboxCmd, workingDir, oldFile); - if (renamePass == false) - fprintf(stderr, "*** Directory deleted: %s/%s\n", workingDir, oldFile); - } - oldList += strlen(oldList) + 1; - continue; - } - if (order > 0) { - if (renamePass == false) { - string rename(workingDir); - rename.append("/"); - rename.append(newFile); - bool skip = false; - for (map::iterator iter = renameMap.begin(); iter != renameMap.end(); iter++) { - if (iter->second == rename) { - skip = true; - break; - } - } - if (skip == false) { - if (newDir) { - if (strcmp(sandFile, newFile) != 0 && - emptyDirectory(newBase, workingDir, newFile) == false) { - fprintf(copyDirFile, "find \"%s/%s/%s\" -type d -print | " - "sed 's@%s/\\(.*\\)@mkdir %s/\\1@' | bash -s\n", - newCmd, workingDir, newFile, newCmd, sandboxCmd); - fprintf(copyDirFile, "find \"%s/%s/%s\" -type f -print | " - "sed 's@%s/\\(.*\\)@cp %s/\\1 %s/\\1@' | bash -s\n", - newCmd, workingDir, newFile, newCmd, newCmd, sandboxCmd); - if (options.emitPerforceCommands) - fprintf(copyDirFile, "find \"%s/%s/%s\" -type f -print | " - "p4 -x - add\n", - sandboxCmd, workingDir, newFile); - else if (options.emitGitCommands) - fprintf(copyDirFile, "git add \"%s/%s\"\n", - workingDir, newFile); - } - } else { -// if (emptyDirectory(sandboxBase, workingDir)) { -// fprintf(commandFile, "mkdir \"%s/%s\"\n", sandboxCmd, workingDir); -// } - bool edit = false; - size_t newLen1 = strlen(newFile); - for (map::iterator iter = renameMap.begin(); iter != renameMap.end(); iter++) { - if (strcmp(iter->second.c_str(), workingDir) == 0) { - const char* first = iter->first.c_str(); - size_t firstLen = strlen(first); - if (firstLen > newLen1 && strcmp(newFile, - &first[firstLen - newLen1]) == 0) { - edit = true; - break; - } - } - } - if (edit == false) { - fprintf(commandFile, "cp \"%s/%s/%s\" \"%s/%s/%s\"\n", - newCmd, workingDir, newFile, sandboxCmd, workingDir, newFile); - if (options.emitPerforceCommands) - fprintf(commandFile, "p4 add \"%s/%s/%s\"\n", sandboxCmd, workingDir, newFile); - else if (options.emitGitCommands) - fprintf(commandFile, "git add \"%s/%s\"\n", workingDir, newFile); - } - } - } - } - newList += strlen(newList) + 1; - continue; - } - if (oldDir) { - myassert(newDir); - size_t newLen1 = strlen(workingDir) + strlen(oldList); - char* newFile = new char[newLen1 + 1]; - sprintf(newFile, "%s/%.*s", workingDir, (int) strlen(oldList) - 1, - oldList); - if (sandOrder > 0) { // file is on old and new but not sandbox - if (emptyDirectory(newBase, newFile) == false) { - fprintf(copyDirFile, "find \"%s/%s\" -type d -print | " - "sed 's@%s/\\(.*\\)@mkdir %s/\\1@' | bash -s\n", - newCmd, newFile, newCmd, sandboxCmd); - fprintf(copyDirFile, "find \"%s/%s\" -type f -print | " - "sed 's@%s/\\(.*\\)@cp %s/\\1 %s/\\1@' | bash -s\n", - newCmd, newFile, newCmd, newCmd, sandboxCmd); - if (options.emitPerforceCommands) - fprintf(copyDirFile, "find \"%s/%s\" -type f -print | " - "p4 -x - add\n", - sandboxCmd, newFile); - else if (options.emitGitCommands) - fprintf(copyDirFile, "git add \"%s\"", newFile); - } - } else - CompareDirs(newFile, renamePass); - delete[] newFile; - } else { - // at this point, the file is in both old and new webkits; see if it changed - // ignore executables, different or not (or always copy, or do text compare? or find binary compare? ) - if (oldExecutable != newExecutable) - fprintf(stderr, "*** %s/%s differs in the execute bit (may cause problems for perforce)\n", workingDir, oldFile); - // myassert(sandOrder != 0 || sandFile[sandLen - 1] == '*'); - // Diff(oldBase, sandboxBase, workingDir, oldFile); - bool oldNewDiff = CompareFiles(oldBase, newBase, workingDir, oldList); - if (oldNewDiff && sandOrder == 0 && renamePass == false) { // if it changed, see if android also changed it - if (options.emitPerforceCommands) - fprintf(commandFile, "p4 edit \"%s/%s/%s\"\n", sandboxCmd, workingDir, oldFile); - bool oldSandboxDiff = CompareFiles(oldBase, sandboxBase, workingDir, oldFile); - if (oldSandboxDiff) { - fprintf(commandFile, "merge -q \"%s/%s/%s\" \"%s/%s/%s\" \"%s/%s/%s\"\n", - sandboxCmd, workingDir, oldFile, oldCmd, workingDir, oldFile, newCmd, workingDir, oldFile); - bool success = Merge(workingDir, oldFile); - if (success == false) { - fprintf(stderr, "*** Manual merge required: %s/%s\n", workingDir, oldFile); - fprintf(commandFile, "cat \"%s/%s/%s\" | sed -e 's/^<<<<<<<.*$/#ifdef MANUAL_MERGE_REQUIRED/' " - "-e 's/^=======$/#else \\/\\/ MANUAL_MERGE_REQUIRED/' -e 's/^>>>>>>>.*$/#endif \\/\\/ MANUAL_MERGE_REQUIRED/' > \"%s/%s/x%s\"\n", - sandboxCmd, workingDir, oldFile, sandboxCmd, workingDir, oldFile); - fprintf(commandFile, "mv \"%s/%s/x%s\" \"%s/%s/%s\"\n", - sandboxCmd, workingDir, oldFile, sandboxCmd, workingDir, oldFile); - } - } else fprintf(commandFile, "cp \"%s/%s/%s\" \"%s/%s/%s\"\n", newCmd, workingDir, oldFile , - sandboxCmd, workingDir, oldFile); - if (options.emitGitCommands) - fprintf(commandFile, "git add \"%s/%s\"\n", workingDir, oldFile); - } - } - myassert(oldLen == newLen); - newList += strlen(newList) + 1; - oldList += strlen(oldList) + 1; - } while (true); - delete[] oldMem; - delete[] newMem; - delete[] sandboxMem; -} - -bool Ignore(char* fileName, size_t len) -{ - if (len == 0) - return true; - if (fileName[len - 1] =='/') - return true; - if (strcmp(fileName, ".DS_Store") == 0) - return true; - if (strcmp(fileName, ".ignoreSVN") == 0) - return true; - return false; -} - -void FixStar(char* fileName, size_t len) -{ - if (fileName[len - 1] =='*') - fileName[len - 1] = '\0'; -} - -void FixColon(char** fileNamePtr, size_t* lenPtr) -{ - char* fileName = *fileNamePtr; - size_t len = *lenPtr; - if (fileName[len - 1] !=':') - return; - fileName[len - 1] = '\0'; - if (strncmp(fileName ,"./", 2) != 0) - return; - fileName += 2; - *fileNamePtr = fileName; - len -= 2; - *lenPtr = len; -} - -bool IgnoreDirectory(const char* dir, const char** dirList) -{ - if (dirList == NULL) - return false; - const char* test; - while ((test = *dirList++) != NULL) { - if (strncmp(dir, test, strlen(test)) == 0) - return true; - } - return false; -} - -static void doSystem(char* scratch) -{ - if (false) printf("%s\n", scratch); - int err = system(scratch); - myassert(err == 0); -} - -static void copyToCommand(char* scratch, string file) -{ - doSystem(scratch); - char* diff = GetFile(file.c_str()); - while (*diff) { - fprintf(commandFile, "%s\n", diff); - diff += strlen(diff) + 1; - } -} - -#define WEBKIT_EXCLUDED_DIRECTORIES \ - "-not -path \"*Tests\" " /* includes LayoutTests, PageLoadTests */ \ - "-not -path \"*Tests/*\" " /* includes LayoutTests, PageLoadTests */ \ - "-not -path \"*Site\" " /* includes BugsSite, WebKitSite */ \ - "-not -path \"*Site/*\" " /* includes BugsSite, WebKitSite */ \ - "-not -path \"./PlanetWebKit/*\" " \ - "-not -path \"./PlanetWebKit\" " - -#define ANDROID_EXCLUDED_FILES \ - "-e '/^Files .* differ/ d' " \ - "-e '/^Only in .*/ d' " \ - "-e '/Android.mk/ d' " \ - "-e '/android$/ d' " - -#define ANDROID_EXCLUDED_DIRS \ - "-e '/\\/JavaScriptCore\\// d' " \ - "-e '/\\/WebCore\\// d' " - -#define ANDROID_EXCLUDED_DIRS_GIT \ - "-e '/ JavaScriptCore\\// d' " \ - "-e '/ WebCore\\// d' " - -void CopyOther() -{ - string excludedFiles = ANDROID_EXCLUDED_FILES; - if (options.emitGitCommands) - excludedFiles += ANDROID_EXCLUDED_DIRS_GIT; - else - excludedFiles += ANDROID_EXCLUDED_DIRS; - char scratch[1024]; - // directories to ignore in webkit - string copyOtherWebKit = ScratchFile("CopyOtherWebKit"); - sprintf(scratch, "cd %s ; find . -type d -not -empty " - WEBKIT_EXCLUDED_DIRECTORIES - " > %s", newBase, copyOtherWebKit.c_str()); - doSystem(scratch); - // directories to ignore in android - string copyOtherAndroid = ScratchFile("CopyOtherAndroid"); - sprintf(scratch, "cd %s ; find . -type d -not -empty " - "-not -path \"*.git*\" " - "-not -path \"*android*\" " - " > %s", sandboxBase, copyOtherAndroid.c_str()); - doSystem(scratch); - if (0) { - string copyOtherMkDir = ScratchFile("CopyOtherMkDir"); - sprintf(scratch, "diff %s %s | sed -e 's@< \\./\\(.*\\)$" - "@mkdir %s/\\1@' " - "-e '/^[0-9].*/ d' " - "-e '/>.*/ d' " - "-e '/---/ d' " - "-e '/\\/JavaScriptCore\\// d' " - "-e '/\\/WebCore\\// d' " - "> %s", copyOtherWebKit.c_str(), copyOtherAndroid.c_str(), sandboxCmd, - copyOtherMkDir.c_str()); - if (options.debug) - fprintf(stderr, "%s\n", scratch); - copyToCommand(scratch, copyOtherMkDir); - } - string copyOtherDiff = ScratchFile("CopyOtherDiff"); - int scratchLen = sprintf(scratch, "diff %s %s | sed -e 's@< \\./\\(.*\\)$" - "@mkdir -p -v %s/\\1 ; find %s/\\1 -type f -depth 1 -exec cp {} %s/\\1 \";\"", - copyOtherWebKit.c_str(), copyOtherAndroid.c_str(), sandboxCmd, newCmd, - sandboxCmd); - if (options.emitGitCommands) - scratchLen += sprintf(&scratch[scratchLen], " ; cd %s ; find ", sandboxCmd); - else - scratchLen += sprintf(&scratch[scratchLen], " ; find %s/", sandboxCmd); - scratchLen += sprintf(&scratch[scratchLen], "\\1 -type f -depth 1 | "); - if (options.emitPerforceCommands) - scratchLen += sprintf(&scratch[scratchLen], "p4 -x - add "); - else if (options.emitGitCommands) - scratchLen += sprintf(&scratch[scratchLen], "xargs git add "); - scratchLen += sprintf(&scratch[scratchLen], - "@' -e '/^[0-9].*/ d' " - "-e '/>.*/ d' " - "-e '/---/ d' " - "-e '/\\/JavaScriptCore\\// d' " - "-e '/\\/WebCore\\// d' " - "> %s", copyOtherDiff.c_str()); - if (options.debug) - fprintf(stderr, "%s\n", scratch); - copyToCommand(scratch, copyOtherDiff); - string deleteOtherDiff = ScratchFile("DeleteOtherDiff"); - scratchLen = sprintf(scratch, "diff -r -q %s %s | sed -e " - "'s@Only in %s/\\(.*\\)\\: \\(.*\\)@", - newBase, sandboxBase, sandboxBase); - if (options.emitPerforceCommands) - scratchLen += sprintf(&scratch[scratchLen], "p4 delete %s/", sandboxCmd); - else if (options.emitGitCommands) - scratchLen += sprintf(&scratch[scratchLen], "git rm "); - else - scratchLen += sprintf(&scratch[scratchLen], "rm %s/", sandboxCmd); - scratchLen += sprintf(&scratch[scratchLen], "\\1/\\2@' %s > %s", - excludedFiles.c_str(), deleteOtherDiff.c_str()); - if (options.debug) - fprintf(stderr, "%s\n", scratch); - copyToCommand(scratch, deleteOtherDiff); - string addOtherDiff = ScratchFile("AddOtherDiff"); - scratchLen = sprintf(scratch, "diff -r -q %s %s | sed -e " - "'s@Only in %s/\\(.*\\)\\: \\(.*\\)" - "@mkdir -p -v %s/\\1 ; cp %s/\\1/\\2 %s/\\1/\\2 ; ", - newBase, sandboxBase, newBase, sandboxCmd, newCmd, sandboxCmd); - if (options.emitPerforceCommands) - scratchLen += sprintf(&scratch[scratchLen], - "p4 add %s/\\1/\\2", sandboxCmd); - else if (options.emitGitCommands) - scratchLen += sprintf(&scratch[scratchLen], - "git add \\1/\\2"); - scratchLen += sprintf(&scratch[scratchLen], "@' %s > %s", - excludedFiles.c_str(), addOtherDiff.c_str()); - if (options.debug) - fprintf(stderr, "%s\n", scratch); - copyToCommand(scratch, addOtherDiff); - string editOtherDiff = ScratchFile("EditOtherDiff"); - scratchLen = sprintf(scratch, "diff -r -q %s %s | sed -e " - "'s@Files %s/\\(.*\\) and %s/\\(.*\\) differ@", - newBase, sandboxBase, newBase, sandboxBase); - if (options.emitPerforceCommands) - scratchLen += sprintf(&scratch[scratchLen], - "p4 edit %s/\\2 ; ", sandboxCmd); - scratchLen += sprintf(&scratch[scratchLen], "cp %s/\\1 %s/\\2 ", - newCmd, sandboxCmd); - if (options.emitGitCommands) - scratchLen += sprintf(&scratch[scratchLen], - " ; git add \\2"); - scratchLen += sprintf(&scratch[scratchLen], "@' %s > %s", - excludedFiles.c_str(), editOtherDiff.c_str()); - if (options.debug) - fprintf(stderr, "%s\n", scratch); - copyToCommand(scratch, editOtherDiff); -} - -void MakeExecutable(const string& filename) -{ - string makeExScript = "chmod +x "; - makeExScript += filename; - int err = system(makeExScript.c_str()); - myassert(err == 0); -} - -bool ReadArgs(char* const args[], int argCount) -{ - int index = 0; - const char* toolpath = args[index++]; - // first arg is path to this executable - // use this to build default paths - - for (; index < argCount; index++) { - const char* arg = args[index]; - if (strncmp(arg, "-a", 2) == 0 || strcmp(arg, "--android") == 0) { - index++; - options.androidWebKit = args[index]; - continue; - } - if (strncmp(arg, "-b", 2) == 0 || strcmp(arg, "--basewebkit") == 0) { - index++; - options.baseWebKit = args[index]; - continue; - } - if (strncmp(arg, "-c", 2) == 0 || strcmp(arg, "--mergecore") == 0) { - options.clearOnce(); - options.mergeCore = true; - continue; - } - if (strncmp(arg, "-d", 2) == 0 || strcmp(arg, "--debug") == 0) { - options.debug = true; - continue; - } - if (strncmp(arg, "-e", 2) == 0 || strcmp(arg, "--emptydirs") == 0) { - options.clearOnce(); - options.removeEmptyDirs = true; - continue; - } - if (strncmp(arg, "-g", 2) == 0 || strcmp(arg, "--git") == 0) { - options.emitGitCommands = true; - if (options.emitPerforceCommands == false) - continue; - } - if (strncmp(arg, "-m", 2) == 0 || strcmp(arg, "--mergemake") == 0) { - options.clearOnce(); - options.mergeMake = true; - continue; - } - if (strncmp(arg, "-n", 2) == 0 || strcmp(arg, "--newwebkit") == 0) { - index++; - options.newWebKit = args[index]; - continue; - } - if (strncmp(arg, "-o", 2) == 0 || strcmp(arg, "--copyother") == 0) { - options.clearOnce(); - options.copyOther = true; - continue; - } - if (strncmp(arg, "-p", 2) == 0 || strcmp(arg, "--perforce") == 0) { - options.emitPerforceCommands = true; - if (options.emitGitCommands == false) - continue; - } - if (strncmp(arg, "-s", 2) == 0 || strcmp(arg, "--removesvn") == 0) { - options.clearOnce(); - options.removeSVNDirs = true; - continue; - } - if (strncmp(arg, "-v", 2) == 0 || strcmp(arg, "--verbose") == 0) { - options.verbose = true; - fprintf(stderr, "path: %s\n", toolpath); - int err = system("pwd > pwd.txt"); - myassert(err != -1); - fprintf(stderr, "pwd: %s\n", GetFile("pwd.txt")); - system("rm pwd.txt"); - continue; - } - if (strncmp(arg, "-x", 2) == 0 || strcmp(arg, "--execute") == 0) { - options.execute = true; - continue; - } - if (options.emitGitCommands && options.emitPerforceCommands) - printf("choose one of --git and --perforce\n"); - else if (strncmp(arg, "-h", 2) != 0 && strcmp(arg, "--help") != 0 && strcmp(arg, "-?") != 0) - printf("%s not understood\n", args[index]); - printf( -"WebKit Merge for Android version 1.1\n" -"Usage: webkitmerge -a path -b path -n path [-g or -p] [-c -d -e -m -o -s -v -x]\n" -"Options -c -e -m -o -s are set unless one or more are passed.\n" -"Leave -g and -p unset to copy, merge, and delete files outside of source control.\n" -"-a --android path Set the Android webkit path to merge to.\n" -"-b --basewebkit path Set the common base for Android and the newer webkit.\n" -"-c --mergecore Create merge scripts for WebCore, JavaScriptCore .h .cpp.\n" -"-d --debug Show debugging printfs; loop forever on internal assert.\n" -"-e --emptydirs Remove empty directories from webkit trees.\n" -"-g --git Emit git commands.\n" -"-h --help Show this help.\n" -"-m --mergemake Create merge scripts for WebCore/Android.mk,\n" -" WebCore/Android.derived.mk, and JavaScriptCore/Android.mk.\n" -"-n --newwebkit path Set the webkit to merge from.\n" -"-o --copyother Create script to copy other webkit directories.\n" -"-p --perforce Emit perforce commands.\n" -"-s --removesvn Remove svn directories from webkit trees.\n" -"-v --verbose Show status printfs.\n" -"-x --execute Execute the merge scripts.\n" - ); - return false; - } - return options.finish(); -} - -int main (int argCount, char* const args[]) -{ - if (ReadArgs(args, argCount) == false) - return 0; - int err; - // First remove all .svn directories - if (options.removeSVNDirs) { - if (options.verbose) - fprintf(stderr, "removing svn directories from %s\n", newBase); - string removeSVNStr = string("find ") + newBase + - " -type d -name \".svn\" -print0 | xargs -0 rm -rf"; - err = system(removeSVNStr.c_str()); - myassert(err == 0); - } - // Remove all empty directories - if (options.removeEmptyDirs) { - if (options.verbose) - fprintf(stderr, "removing empty directories from %s, %s\n", - oldBase, newBase); - string removeEmpty = string("find ") + oldBase + " " + newBase + - " -type d -empty -delete"; - err = system(removeEmpty.c_str()); - myassert(err == 0); - } - if (options.mergeCore /* || options.mergeMake */) { - if (options.verbose) - fprintf(stderr, "building rename map\n"); - commandFile = fopen("/dev/null", "w"); - copyDirFile = fopen("/dev/null", "w"); - CompareDirs("WebCore", true); // build rename map - CompareDirs("JavaScriptCore", true); - fclose(copyDirFile); - fclose(commandFile); - } - if (options.mergeMake) { - if (options.verbose) - fprintf(stderr, "building make.sh\n"); - string makeShell = outputDir + "make.sh"; - commandFile = fopen(makeShell.c_str(), "w"); - if (options.emitGitCommands || options.emitPerforceCommands) - fprintf(commandFile, "cd %s\n", sandboxCmd); - UpdateMake("WebCore"); - UpdateMake("JavaScriptCore"); - UpdateDerivedMake(); - fclose(commandFile); - MakeExecutable(makeShell); - } - if (options.copyOther) { - if (options.verbose) - fprintf(stderr, "building copyOther.sh\n"); - string copyOtherShell = outputDir + "copyOther.sh"; - commandFile = fopen(copyOtherShell.c_str(), "w"); - if (options.emitGitCommands || options.emitPerforceCommands) - fprintf(commandFile, "cd %s\n", sandboxCmd); - CopyOther(); - fclose(commandFile); - MakeExecutable(copyOtherShell); - } - if (options.mergeCore) { - if (options.verbose) - fprintf(stderr, "building command.sh copyDir.sh oops.sh\n"); - string commandShell = outputDir + "command.sh"; - commandFile = fopen(commandShell.c_str(), "w"); - if (options.emitGitCommands || options.emitPerforceCommands) - fprintf(commandFile, "cd %s\n", sandboxCmd); - string copyDirShell = outputDir + "copyDir.sh"; - copyDirFile = fopen(copyDirShell.c_str(), "w"); - if (options.emitGitCommands || options.emitPerforceCommands) - fprintf(copyDirFile, "cd %s\n", sandboxCmd); - string oopsShell = outputDir + "oops.sh"; - oopsFile = fopen(oopsShell.c_str(), "w"); - if (options.emitGitCommands || options.emitPerforceCommands) - fprintf(oopsFile, "cd %s\n", sandboxCmd); - CompareDirs("WebCore", false); // generate command script - CompareDirs("JavaScriptCore", false); - fclose(oopsFile); - fclose(copyDirFile); - fclose(commandFile); - MakeExecutable(oopsShell); - MakeExecutable(copyDirShell); - MakeExecutable(commandShell); - } - if (options.execute) { - if (options.mergeCore) { - if (options.verbose) - fprintf(stderr, "executing command.sh\n"); - string execCommand = "cd " + options.androidWebKit + "; . " + outputDir + "command.sh"; - err = system(execCommand.c_str()); - myassert(err == 0); - if (options.verbose) - fprintf(stderr, "executing copyDir.sh\n"); - string execCopy = "cd " + options.androidWebKit + "; . " + outputDir + "copyDir.sh"; - err = system(execCopy.c_str()); - myassert(err == 0); - } - if (options.mergeMake) { - if (options.verbose) - fprintf(stderr, "executing make.sh\n"); - string execMake = "cd " + options.androidWebKit + "; . " + outputDir + "make.sh"; - err = system(execMake.c_str()); - myassert(err == 0); - } - if (options.copyOther) { - if (options.verbose) - fprintf(stderr, "executing copyOther.sh\n"); - string execCopyOther = "cd " + options.androidWebKit + "; . " + outputDir + "copyOther.sh"; - err = system(execCopyOther.c_str()); - myassert(err == 0); - } - } - if (options.verbose) - fprintf(stderr, "done!\n"); - else { - string rmAllCmd = "rm " + scratchDir + "* ; rmdir " + scratchDir; - err = system(rmAllCmd.c_str()); - myassert(err == 0); - } - return 0; -} - -/* things to do: - when inserting MANUAL_MERGE_REQUIRED, if contents is #preprocessor, balance first? -*/ -- cgit v1.1