From 9736437cb8e6bff3e0044d91422ef38edce269f2 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Mon, 12 Apr 2021 21:51:51 +0700 Subject: [PATCH] Remove gradle build system & Cleanup --- .gitattributes | 4 - .gitignore | 6 +- .gitmodules | 3 - build.gradle | 60 --- buildSrc/build.gradle | 33 -- .../builder/FileSystemTreeBuilder.groovy | 58 --- .../dirsync/builder/FileTreeMerger.groovy | 60 --- .../dirsync/builder/PostBuildPass.groovy | 22 - .../dirsync/builder/ZipTreeBuilder.groovy | 53 --- .../dirsync/merger/FileTreeComparator.groovy | 97 ---- .../dirsync/merger/FileTreeDiffApplier.groovy | 103 ---- .../model/synccmd/AbstractSyncCmd.groovy | 4 - .../dirsync/model/synccmd/CopyDirCmd.groovy | 8 - .../dirsync/model/synccmd/CopyFileCmd.groovy | 9 - .../dirsync/model/synccmd/DeleteDirCmd.groovy | 7 - .../model/synccmd/DeleteFileCmd.groovy | 7 - .../model/synccmd/ReplaceFileCmd.groovy | 8 - .../model/tree/AbstractFileTreeNode.groovy | 27 -- .../dirsync/model/tree/DirectoryNode.groovy | 42 -- .../groovy/dirsync/model/tree/FSMapper.groovy | 50 -- .../groovy/dirsync/model/tree/FileNode.groovy | 8 - .../dirsync/model/tree/TreePhysMapper.groovy | 11 - .../groovy/dirsync/model/tree/ZipData.groovy | 9 - .../dirsync/model/tree/ZipTreeMapper.groovy | 72 --- .../gradlecpp/CppUnitTestExtension.groovy | 19 - .../groovy/gradlecpp/CppUnitTestPlugin.groovy | 242 ---------- .../gradlecpp/RegameDLLPlayTestPlugin.groovy | 17 - .../gradlecpp/RegameDLLPlayTestTask.groovy | 86 ---- .../groovy/gradlecpp/VelocityUtils.groovy | 38 -- .../teamcity/TeamCityIntegration.groovy | 84 ---- .../testdemo/RegameDLLDemoRunner.groovy | 106 ----- .../testdemo/RegameDLLTestInfo.groovy | 9 - .../testdemo/RegameDLLTestParser.groovy | 63 --- .../src/main/groovy/versioning/GitInfo.groovy | 16 - .../groovy/versioning/GitVersioner.groovy | 140 ------ .../versioning/RegamedllVersionInfo.groovy | 58 --- .../dirsync/builder/ZipTreeBuilderTest.groovy | 44 -- dep/cppunitlite/build.gradle | 62 --- .../include/cppunitlite/Assertions.h | 4 +- dep/cppunitlite/include/cppunitlite/Failure.h | 6 +- .../{GradleAdapter.h => MainAdapter.h} | 2 +- dep/cppunitlite/include/cppunitlite/Test.h | 9 +- .../include/cppunitlite/TestResult.h | 4 + dep/cppunitlite/msvc/cppunitlite.vcxproj | 19 +- .../msvc/cppunitlite.vcxproj.filters | 4 +- dep/cppunitlite/src/Assertions.cpp | 16 +- .../{GradleAdapter.cpp => MainAdapter.cpp} | 35 +- dep/cppunitlite/src/Test.cpp | 13 +- dep/cppunitlite/src/TestRegistry.cpp | 38 +- dep/cppunitlite/src/TestResult.cpp | 36 +- getucrtinfo.bat | 19 - gradle.properties | 3 - gradle/wrapper/gradle-wrapper.jar | Bin 52279 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 - gradlew | 164 ------- gradlew.bat | 90 ---- msvc/ReGameDLL.sln | 15 +- publish.gradle | 142 ------ regamedll/build.gradle | 444 ------------------ regamedll/dlls/API/CAPI_Impl.h | 26 +- regamedll/dlls/player.cpp | 4 +- regamedll/dlls/weapons.cpp | 5 +- regamedll/dlls/weapons.h | 2 +- regamedll/msvc/PreBuild.bat | 14 - regamedll/msvc/ReGameDLL.vcxproj | 65 ++- regamedll/msvc/ReGameDLL.vcxproj.filters | 15 - regamedll/unittests/TestRunner.cpp | 12 +- regamedll/version/appversion.sh | 53 ++- regamedll/version/appversion.vm | 18 - regamedll/version/version.cpp | 10 - regamedll/version/version.h | 10 + settings.gradle | 3 - shared.gradle | 54 --- shared_clang.gradle | 55 --- shared_gcc.gradle | 55 --- shared_icc.gradle | 66 --- shared_msvc.gradle | 135 ------ 77 files changed, 218 insertions(+), 3198 deletions(-) delete mode 100644 .gitmodules delete mode 100644 build.gradle delete mode 100644 buildSrc/build.gradle delete mode 100644 buildSrc/src/main/groovy/dirsync/builder/FileSystemTreeBuilder.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/builder/FileTreeMerger.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/builder/PostBuildPass.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/builder/ZipTreeBuilder.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/merger/FileTreeComparator.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/merger/FileTreeDiffApplier.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/synccmd/AbstractSyncCmd.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/synccmd/CopyDirCmd.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/synccmd/CopyFileCmd.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteDirCmd.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteFileCmd.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/synccmd/ReplaceFileCmd.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/tree/AbstractFileTreeNode.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/tree/DirectoryNode.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/tree/FSMapper.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/tree/FileNode.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/tree/TreePhysMapper.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/tree/ZipData.groovy delete mode 100644 buildSrc/src/main/groovy/dirsync/model/tree/ZipTreeMapper.groovy delete mode 100644 buildSrc/src/main/groovy/gradlecpp/CppUnitTestExtension.groovy delete mode 100644 buildSrc/src/main/groovy/gradlecpp/CppUnitTestPlugin.groovy delete mode 100644 buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestPlugin.groovy delete mode 100644 buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestTask.groovy delete mode 100644 buildSrc/src/main/groovy/gradlecpp/VelocityUtils.groovy delete mode 100644 buildSrc/src/main/groovy/gradlecpp/teamcity/TeamCityIntegration.groovy delete mode 100644 buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLDemoRunner.groovy delete mode 100644 buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestInfo.groovy delete mode 100644 buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestParser.groovy delete mode 100644 buildSrc/src/main/groovy/versioning/GitInfo.groovy delete mode 100644 buildSrc/src/main/groovy/versioning/GitVersioner.groovy delete mode 100644 buildSrc/src/main/groovy/versioning/RegamedllVersionInfo.groovy delete mode 100644 buildSrc/src/test/groovy/dirsync/builder/ZipTreeBuilderTest.groovy delete mode 100644 dep/cppunitlite/build.gradle rename dep/cppunitlite/include/cppunitlite/{GradleAdapter.h => MainAdapter.h} (91%) rename dep/cppunitlite/src/{GradleAdapter.cpp => MainAdapter.cpp} (76%) delete mode 100644 getucrtinfo.bat delete mode 100644 gradle.properties delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradlew delete mode 100644 gradlew.bat delete mode 100644 publish.gradle delete mode 100644 regamedll/build.gradle delete mode 100644 regamedll/version/appversion.vm delete mode 100644 regamedll/version/version.cpp create mode 100644 regamedll/version/version.h delete mode 100644 settings.gradle delete mode 100644 shared.gradle delete mode 100644 shared_clang.gradle delete mode 100644 shared_gcc.gradle delete mode 100644 shared_icc.gradle delete mode 100644 shared_msvc.gradle diff --git a/.gitattributes b/.gitattributes index b5c177f24..dbc771118 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,14 +16,10 @@ # Scripts *.sh text eol=lf -gradlew text eol=lf *.bat text eol=crlf -*.gradle text eol=crlf -*.groovy text eol=crlf *.def text eol=crlf *.fgd text eol=crlf *.cfg text eol=crlf -*.properties text eol=crlf *.vm text eol=crlf # Compiled Object files diff --git a/.gitignore b/.gitignore index b836d5b5e..dc6d161e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ **/build -**/.gradle -.idea -*.iml *.bat *.log *.lnk @@ -15,12 +12,11 @@ **/msvc/*.db **/msvc/*.opendb **/msvc/*.txt +**/msvc/*.aps **/msvc/*.amplxeproj **/msvc/.vs **/msvc/ipch regamedll/version/appversion.h regamedll/msvc/PublishPath*.txt -regamedll/_regamedllTestImg -regamedll/_dev publish diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index cdf4960a1..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "regamedll/extra/cssdk"] - path = regamedll/extra/cssdk - url = https://github.com/s1lentq/CSSDK.git diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 0fe367244..000000000 --- a/build.gradle +++ /dev/null @@ -1,60 +0,0 @@ -import versioning.GitVersioner -import versioning.RegamedllVersionInfo -import org.joda.time.DateTime - -apply plugin: 'maven-publish' -apply from: 'shared.gradle' -group = 'regamedll' - -apply plugin: 'idea' - -idea { - project { - languageLevel = 'JDK_1_7' - } -} - -def gitInfo = GitVersioner.versionForDir(project.rootDir) -RegamedllVersionInfo versionInfo -if (gitInfo && gitInfo.tag && gitInfo.tag[0] == 'v') { - def m = gitInfo.tag =~ /^v(\d+)\.(\d+)(\.(\d+))?$/ - if (!m.find()) { - throw new RuntimeException("Invalid git version tag name ${gitInfo.tag}") - } - - versionInfo = new RegamedllVersionInfo( - majorVersion: m.group(1) as int, - minorVersion: m.group(2) as int, - maintenanceVersion: m.group(4) ? (m.group(4) as int) : null, - localChanges: gitInfo.localChanges, - commitDate: gitInfo.commitDate, - commitSHA: gitInfo.commitSHA, - commitURL: gitInfo.commitURL - ) -} else { - - if (!gitInfo) { - System.err.println "WARNING! couldn't get gitInfo"; - } - - versionInfo = new RegamedllVersionInfo( - majorVersion: project.majorVersion as int, - minorVersion: project.minorVersion as int, - maintenanceVersion: project.maintenanceVersion as int, - suffix: 'dev', - localChanges: gitInfo ? gitInfo.localChanges : true, - commitDate: gitInfo ? gitInfo.commitDate : new DateTime(), - commitSHA: gitInfo ? gitInfo.commitSHA : "", - commitURL: gitInfo ? gitInfo.commitURL : "", - commitCount: gitInfo ? (gitInfo.commitCount as int) : null - ) -} - -project.ext.regamedllVersionInfo = versionInfo -project.version = versionInfo.asMavenVersion() - -apply from: 'publish.gradle' - -task wrapper(type: Wrapper) { - gradleVersion = '2.4' -} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index f842a1d21..000000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -apply plugin: 'groovy' - -repositories { - //mavenLocal() - mavenCentral() - maven { - url 'http://nexus.rehlds.org/nexus/content/repositories/regamedll-releases/' - } - maven { - url 'http://nexus.rehlds.org/nexus/content/repositories/regamedll-snapshots/' - } - maven { - url 'http://nexus.rehlds.org/nexus/content/repositories/regamedll-dev/' - } - -} - -dependencies { - compile gradleApi() - compile localGroovy() - compile 'commons-io:commons-io:2.4' - compile 'commons-lang:commons-lang:2.6' - compile 'joda-time:joda-time:2.7' - - compile 'org.doomedsociety.gradlecpp:gradle-cpp-plugin:1.2' - compile 'org.eclipse.jgit:org.eclipse.jgit:3.7.0.201502260915-r' - - compile 'org.apache.commons:commons-compress:1.9' - compile 'org.apache.ant:ant-compress:1.2' - compile 'org.apache.ant:ant:1.9.6' - - compile 'org.apache.velocity:velocity:1.7' -} diff --git a/buildSrc/src/main/groovy/dirsync/builder/FileSystemTreeBuilder.groovy b/buildSrc/src/main/groovy/dirsync/builder/FileSystemTreeBuilder.groovy deleted file mode 100644 index af2180c24..000000000 --- a/buildSrc/src/main/groovy/dirsync/builder/FileSystemTreeBuilder.groovy +++ /dev/null @@ -1,58 +0,0 @@ -package dirsync.builder - -import dirsync.model.tree.DirectoryNode -import dirsync.model.tree.FileNode -import groovy.transform.CompileStatic - -class FileSystemTreeBuilder { - - @CompileStatic - private static FileNode buildNodeForFile(File file, DirectoryNode parent) { - if (parent.getChildren(file.name)) { - throw new RuntimeException("Parent dir ${parent.name} already contains child node ${file.name}"); - } - - return new FileNode( - name: file.name, - lastModifiedDate: file.lastModified(), - data: file, - parent: parent, - size: file.size() - ); - } - - @CompileStatic - private static DirectoryNode buildNodeForDirectoryRecursive(File dir, DirectoryNode parent) { - if (!dir.isDirectory()) { - throw new RuntimeException("File ${dir.absolutePath} is not a directory") - } - - if (parent != null && parent.getChildren(dir.name)) { - throw new RuntimeException("Parent dir ${parent.name} already contains child node ${dir.name}"); - } - - DirectoryNode thisNode = new DirectoryNode( - name: dir.name, - lastModifiedDate: dir.lastModified(), - data: dir, - parent: parent - ); - - dir.eachFile { File f -> - if (f.isDirectory()) { - thisNode.childNodes[f.name] = buildNodeForDirectoryRecursive(f, thisNode) - } else { - thisNode.childNodes[f.name] = buildNodeForFile(f, thisNode) - } - } - - return thisNode; - } - - static DirectoryNode buildFileSystemTree(File rootDir) { - def root = buildNodeForDirectoryRecursive(rootDir, null); - PostBuildPass.doPostBuild(root) - - return root - } -} diff --git a/buildSrc/src/main/groovy/dirsync/builder/FileTreeMerger.groovy b/buildSrc/src/main/groovy/dirsync/builder/FileTreeMerger.groovy deleted file mode 100644 index df92119a3..000000000 --- a/buildSrc/src/main/groovy/dirsync/builder/FileTreeMerger.groovy +++ /dev/null @@ -1,60 +0,0 @@ -package dirsync.builder - -import dirsync.model.tree.DirectoryNode -import dirsync.model.tree.FileNode - -class FileTreeMerger { - - private static void mergeContentsRecursive(DirectoryNode newParent, DirectoryNode toMerge) { - toMerge.childNodes.each { cn -> - def node = cn.value - def existingNode = newParent.childNodes[node.name] - if (existingNode) { - if (!(existingNode instanceof DirectoryNode) || !(node instanceof DirectoryNode)) - throw new RuntimeException("Failed to merge non-directory nodes ${node.fullPath}") - - def existingDirNode = existingNode as DirectoryNode - def dirNode = node as DirectoryNode - - existingDirNode.lastModifiedDate = Math.max(existingDirNode.lastModifiedDate, dirNode.lastModifiedDate) - mergeContentsRecursive(existingDirNode, dirNode) - } else { - if (node instanceof DirectoryNode) { - def dirNode = node as DirectoryNode - def newNode = new DirectoryNode( - name: dirNode.name, - data: dirNode.data, - parent: newParent, - lastModifiedDate: dirNode.lastModifiedDate - ) - newParent.childNodes[node.name] = newNode - - mergeContentsRecursive(newNode, dirNode) - } else { - FileNode fileNode = node as FileNode - FileNode newNode = new FileNode( - name: fileNode.name, - data: fileNode.data, - parent: newParent, - lastModifiedDate: fileNode.lastModifiedDate, - size: fileNode.size - ) - - newParent.childNodes[node.name] = newNode - } - } - } - } - - public static DirectoryNode mergeTrees(DirectoryNode tree1, DirectoryNode tree2) { - DirectoryNode newRoot = new DirectoryNode( - name: tree1.name ?: tree2.name - ) - - mergeContentsRecursive(newRoot, tree1) - mergeContentsRecursive(newRoot, tree2) - PostBuildPass.doPostBuild(newRoot) - - return newRoot - } -} diff --git a/buildSrc/src/main/groovy/dirsync/builder/PostBuildPass.groovy b/buildSrc/src/main/groovy/dirsync/builder/PostBuildPass.groovy deleted file mode 100644 index 87782dd7d..000000000 --- a/buildSrc/src/main/groovy/dirsync/builder/PostBuildPass.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package dirsync.builder - -import dirsync.model.tree.DirectoryNode - -class PostBuildPass { - - private static void postProcessRecursive(DirectoryNode dir) { - dir.childNodes.each { cne -> - def childNode = cne.value - childNode.fullPath = dir.fullPath ? dir.fullPath + '/' + childNode.name : childNode.name - if (childNode instanceof DirectoryNode) { - def childDirNode = childNode as DirectoryNode - postProcessRecursive(childDirNode) - } - } - } - - static void doPostBuild(DirectoryNode root) { - root.fullPath = '' - postProcessRecursive(root) - } -} diff --git a/buildSrc/src/main/groovy/dirsync/builder/ZipTreeBuilder.groovy b/buildSrc/src/main/groovy/dirsync/builder/ZipTreeBuilder.groovy deleted file mode 100644 index c14092d58..000000000 --- a/buildSrc/src/main/groovy/dirsync/builder/ZipTreeBuilder.groovy +++ /dev/null @@ -1,53 +0,0 @@ -package dirsync.builder - -import dirsync.model.tree.DirectoryNode -import dirsync.model.tree.FileNode -import dirsync.model.tree.ZipData - -import java.util.zip.ZipFile - -class ZipTreeBuilder { - static DirectoryNode buildForZipArchive(String zipArchive, ZipFile zf) { - DirectoryNode root = new DirectoryNode<>() - - zf.entries().each { ze -> - def path = ze.name.replace('\\', '/') - if (path.endsWith('/')) - path = path.substring(0, path.length() - 1) - - def parentPath = path.contains('/') ? path.substring(0, path.lastIndexOf('/')) : '' - def childPath = path.contains('/') ? path.substring(path.lastIndexOf('/') + 1) : path - - def parentNode = (DirectoryNode) root.getByPath(parentPath) - if (parentNode == null) - throw new RuntimeException("Error reading ${zipArchive}: could not find parent path ${parentPath} for path ${path}") - - def childNode = parentNode.getChildren(childPath) - if (childNode) - throw new RuntimeException("Error reading ${zipArchive}: duplicate path ${path}") - - if (ze.directory) { - childNode = new DirectoryNode( - name: childPath, - lastModifiedDate: ze.time, - data: new ZipData(zipEntryName: ze.name, zipArchiveName: zipArchive), - parent: parentNode - ); - } else { - childNode = new FileNode( - name: childPath, - lastModifiedDate: ze.time, - data: new ZipData(zipEntryName: ze.name, zipArchiveName: zipArchive), - parent: parentNode, - size: ze.size - ); - } - parentNode.childNodes[childPath] = childNode - - //println '' + ze.directory + ' ' + ze.name + ' ' + parentPath + ' ' + childPath - } - - PostBuildPass.doPostBuild(root) - return root - } -} diff --git a/buildSrc/src/main/groovy/dirsync/merger/FileTreeComparator.groovy b/buildSrc/src/main/groovy/dirsync/merger/FileTreeComparator.groovy deleted file mode 100644 index e018a2c7b..000000000 --- a/buildSrc/src/main/groovy/dirsync/merger/FileTreeComparator.groovy +++ /dev/null @@ -1,97 +0,0 @@ -package dirsync.merger - -import dirsync.model.synccmd.AbstractSyncCmd -import dirsync.model.synccmd.CopyDirCmd -import dirsync.model.synccmd.CopyFileCmd -import dirsync.model.synccmd.DeleteDirCmd -import dirsync.model.synccmd.DeleteFileCmd -import dirsync.model.synccmd.ReplaceFileCmd -import dirsync.model.tree.DirectoryNode -import dirsync.model.tree.FileNode -import groovy.transform.TypeChecked - -@TypeChecked -class FileTreeComparator { - - private static void mergeDirsRecursive(DirectoryNode left, DirectoryNode right, List> diffs) { - - // left => right - left.childNodes.each { le -> - def leftNode = le.value - def rightNode = right.childNodes[leftNode.name] - - if (rightNode == null) { - switch (leftNode) { - case DirectoryNode: - def leftDirNode = leftNode as DirectoryNode - diffs << new CopyDirCmd<>(src: leftDirNode, dstParentDir: right) - break - - case FileNode: - def leftFileNode = leftNode as FileNode - diffs << new CopyFileCmd<>(src: leftFileNode, dstDir: right) - break - - default: - throw new RuntimeException("Invalid node class ${leftNode.class.name}") - } - - return - } - - if (rightNode.class != leftNode.class) { - throw new RuntimeException("node classes mismatch: ${leftNode.class.name} != ${rightNode.class.name}") - } - - switch (rightNode) { - case DirectoryNode: - def leftDirNode = leftNode as DirectoryNode - def rightDirNode = rightNode as DirectoryNode - mergeDirsRecursive(leftDirNode, rightDirNode, diffs) - break - - case FileNode: - def leftFileNode = leftNode as FileNode - def rightFileNode = rightNode as FileNode - if (leftFileNode.size != rightFileNode.size || leftFileNode.lastModifiedDate != rightFileNode.lastModifiedDate) { - diffs << new ReplaceFileCmd<>(src: leftFileNode, dst: rightFileNode) - } - break - - default: - throw new RuntimeException("Invalid node class ${rightNode.class.name}") - } - } // ~left => right - - //right => left - right.childNodes.each { re -> - def rightNode = re.value - def leftNode = left.childNodes[rightNode.name] - - if (leftNode != null) { - return //already processed in left => right - } - - switch (rightNode) { - case DirectoryNode: - def rightDirNode = rightNode as DirectoryNode - diffs << new DeleteDirCmd<>(dirNode: rightDirNode) - break - - case FileNode: - def rightFileNode = rightNode as FileNode - diffs << new DeleteFileCmd<>(node: rightFileNode) - break - - default: - throw new RuntimeException("Invalid node class ${rightNode.class.name}") - } - } // ~right => left - } - - static List> mergeTrees(DirectoryNode leftRoot, DirectoryNode rightRoot) { - List> res = [] - mergeDirsRecursive(leftRoot, rightRoot, res) - return res - } -} diff --git a/buildSrc/src/main/groovy/dirsync/merger/FileTreeDiffApplier.groovy b/buildSrc/src/main/groovy/dirsync/merger/FileTreeDiffApplier.groovy deleted file mode 100644 index 1c1404e48..000000000 --- a/buildSrc/src/main/groovy/dirsync/merger/FileTreeDiffApplier.groovy +++ /dev/null @@ -1,103 +0,0 @@ -package dirsync.merger - -import dirsync.model.synccmd.AbstractSyncCmd -import dirsync.model.synccmd.CopyDirCmd -import dirsync.model.synccmd.CopyFileCmd -import dirsync.model.synccmd.DeleteDirCmd -import dirsync.model.synccmd.DeleteFileCmd -import dirsync.model.synccmd.ReplaceFileCmd -import dirsync.model.tree.DirectoryNode -import dirsync.model.tree.FileNode -import dirsync.model.tree.TreePhysMapper -import groovy.transform.TypeChecked -import org.apache.commons.io.IOUtils - -@TypeChecked -public class FileTreeDiffApplier { - - static void copyDirRecursive(DirectoryNode src, TreePhysMapper srcMapper, TreePhysMapper dstMapper) { - dstMapper.createDirectory(src.fullPath) - src.childNodes.each { ce -> - def childNode = ce.value - def childPath = childNode.fullPath - switch (childNode) { - case FileNode: - srcMapper.fileContent(childNode.data).withStream { InputStream inStream -> - dstMapper.createFile(childPath).withStream { OutputStream outStream -> - IOUtils.copy(inStream, outStream) - } - - dstMapper.setFileLastUpdatedDate(childPath, childNode.lastModifiedDate) - } - break; - - case DirectoryNode: - copyDirRecursive(childNode as DirectoryNode, srcMapper, dstMapper) - break; - - default: - throw new RuntimeException("Invalid node class: ${childNode.class.name}") - } - } - } - - static void handleCopyFile(CopyFileCmd fileCopy, TreePhysMapper srcMapper, TreePhysMapper dstMapper) { - def dstPath = fileCopy.dstDir.fullPath ? fileCopy.dstDir.fullPath + '/' + fileCopy.src.name : fileCopy.src.name - srcMapper.fileContent(fileCopy.src.data).withStream { InputStream inStream -> - dstMapper.createFile(dstPath).withStream { OutputStream outStream -> - IOUtils.copy(inStream, outStream) - } - - dstMapper.setFileLastUpdatedDate(dstPath, fileCopy.src.lastModifiedDate) - } - } - - static void handleDeleteDir(DeleteDirCmd delDir, TreePhysMapper srcMapper, TreePhysMapper dstMapper) { - dstMapper.removeDirectory(delDir.dirNode.fullPath) - } - - static void handleDeleteFile(DeleteFileCmd delFile, TreePhysMapper srcMapper, TreePhysMapper dstMapper) { - dstMapper.removeFile(delFile.node.fullPath) - } - - static void handleReplaceFile(ReplaceFileCmd replaceFile, TreePhysMapper srcMapper, TreePhysMapper dstMapper) { - dstMapper.removeFile(replaceFile.dst.fullPath) - srcMapper.fileContent(replaceFile.src.data).withStream { InputStream inStream -> - dstMapper.createFile(replaceFile.dst.fullPath).withStream { OutputStream outStream -> - IOUtils.copy(inStream, outStream) - } - - dstMapper.setFileLastUpdatedDate(replaceFile.dst.fullPath, replaceFile.src.lastModifiedDate) - } - } - - static void applyDiffs(List> diffs, TreePhysMapper srcMapper, TreePhysMapper dstMapper) { - diffs.each { diff -> - switch (diff) { - case CopyDirCmd: - def copyDir = diff as CopyDirCmd - copyDirRecursive(copyDir.src, srcMapper, dstMapper) - break - - case CopyFileCmd: - handleCopyFile(diff as CopyFileCmd, srcMapper, dstMapper) - break - - case DeleteDirCmd: - handleDeleteDir(diff as DeleteDirCmd, srcMapper, dstMapper) - break - - case DeleteFileCmd: - handleDeleteFile(diff as DeleteFileCmd, srcMapper, dstMapper) - break - - case ReplaceFileCmd: - handleReplaceFile(diff as ReplaceFileCmd, srcMapper, dstMapper) - break - - default: - throw new RuntimeException("Invalid diff command ${diff.class.name}") - } - } - } -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/dirsync/model/synccmd/AbstractSyncCmd.groovy b/buildSrc/src/main/groovy/dirsync/model/synccmd/AbstractSyncCmd.groovy deleted file mode 100644 index 20e0a1b61..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/synccmd/AbstractSyncCmd.groovy +++ /dev/null @@ -1,4 +0,0 @@ -package dirsync.model.synccmd - -class AbstractSyncCmd { -} diff --git a/buildSrc/src/main/groovy/dirsync/model/synccmd/CopyDirCmd.groovy b/buildSrc/src/main/groovy/dirsync/model/synccmd/CopyDirCmd.groovy deleted file mode 100644 index 8a03abed2..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/synccmd/CopyDirCmd.groovy +++ /dev/null @@ -1,8 +0,0 @@ -package dirsync.model.synccmd - -import dirsync.model.tree.DirectoryNode - -class CopyDirCmd extends AbstractSyncCmd { - DirectoryNode src - DirectoryNode dstParentDir -} diff --git a/buildSrc/src/main/groovy/dirsync/model/synccmd/CopyFileCmd.groovy b/buildSrc/src/main/groovy/dirsync/model/synccmd/CopyFileCmd.groovy deleted file mode 100644 index 8511dc376..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/synccmd/CopyFileCmd.groovy +++ /dev/null @@ -1,9 +0,0 @@ -package dirsync.model.synccmd - -import dirsync.model.tree.DirectoryNode -import dirsync.model.tree.FileNode - -class CopyFileCmd extends AbstractSyncCmd { - FileNode src - DirectoryNode dstDir -} diff --git a/buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteDirCmd.groovy b/buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteDirCmd.groovy deleted file mode 100644 index f5a8d2abd..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteDirCmd.groovy +++ /dev/null @@ -1,7 +0,0 @@ -package dirsync.model.synccmd - -import dirsync.model.tree.DirectoryNode - -class DeleteDirCmd extends AbstractSyncCmd { - DirectoryNode dirNode -} diff --git a/buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteFileCmd.groovy b/buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteFileCmd.groovy deleted file mode 100644 index 0cd429d3a..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/synccmd/DeleteFileCmd.groovy +++ /dev/null @@ -1,7 +0,0 @@ -package dirsync.model.synccmd - -import dirsync.model.tree.FileNode - -class DeleteFileCmd extends AbstractSyncCmd { - FileNode node -} diff --git a/buildSrc/src/main/groovy/dirsync/model/synccmd/ReplaceFileCmd.groovy b/buildSrc/src/main/groovy/dirsync/model/synccmd/ReplaceFileCmd.groovy deleted file mode 100644 index 3153b1e4b..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/synccmd/ReplaceFileCmd.groovy +++ /dev/null @@ -1,8 +0,0 @@ -package dirsync.model.synccmd - -import dirsync.model.tree.FileNode - -class ReplaceFileCmd extends AbstractSyncCmd { - FileNode src - FileNode dst -} diff --git a/buildSrc/src/main/groovy/dirsync/model/tree/AbstractFileTreeNode.groovy b/buildSrc/src/main/groovy/dirsync/model/tree/AbstractFileTreeNode.groovy deleted file mode 100644 index 12d0a141d..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/tree/AbstractFileTreeNode.groovy +++ /dev/null @@ -1,27 +0,0 @@ -package dirsync.model.tree - -import groovy.transform.CompileStatic - -@CompileStatic -abstract class AbstractFileTreeNode { - DirectoryNode parent - String name - String fullPath - long lastModifiedDate - T data - - boolean equals(o) { - if (this.is(o)) return true - if (getClass() != o.class) return false - - AbstractFileTreeNode that = (AbstractFileTreeNode) o - - if (name != that.name) return false - - return true - } - - int hashCode() { - return (name != null ? name.hashCode() : 0) - } -} diff --git a/buildSrc/src/main/groovy/dirsync/model/tree/DirectoryNode.groovy b/buildSrc/src/main/groovy/dirsync/model/tree/DirectoryNode.groovy deleted file mode 100644 index 3e4687752..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/tree/DirectoryNode.groovy +++ /dev/null @@ -1,42 +0,0 @@ -package dirsync.model.tree - -import groovy.transform.CompileStatic - -@CompileStatic -class DirectoryNode extends AbstractFileTreeNode { - Map> childNodes = new HashMap<>() - - AbstractFileTreeNode getChildren(String name) { - return childNodes[name]; - } - - AbstractFileTreeNode getChildren(String[] names, int idx) { - if (idx == names.length) - return this - - AbstractFileTreeNode c = childNodes[names[idx]] - if (c == null) - return null - - if (c instanceof DirectoryNode) { - def d = (DirectoryNode) c; - return d.getChildren(names, idx + 1) - } - - return null; - } - - AbstractFileTreeNode getByPath(String path) { - path = path.replace('\\', '/') - if (path.endsWith('/')) - path = path.substring(0, path.length() - 1) - - if (path.empty) { - return this - } - - String[] components = path.split('/') - return getChildren(components, 0) - } - -} diff --git a/buildSrc/src/main/groovy/dirsync/model/tree/FSMapper.groovy b/buildSrc/src/main/groovy/dirsync/model/tree/FSMapper.groovy deleted file mode 100644 index 9c187c4f7..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/tree/FSMapper.groovy +++ /dev/null @@ -1,50 +0,0 @@ -package dirsync.model.tree - -class FSMapper extends TreePhysMapper { - final File root - - FSMapper(File root) { - this.root = root - } - - @Override - InputStream fileContent(File file) { - return file.newDataInputStream() - } - - @Override - void createDirectory(String dir) { - def target = new File(root, dir) - if (!target.mkdirs()) { - throw new RuntimeException("Failed to create directory ${target.absolutePath}") - } - } - - @Override - void removeDirectory(String dir) { - def target = new File(root, dir) - if (!target.deleteDir()) { - throw new RuntimeException("Failed to delete directory ${target.absolutePath}") - } - } - - @Override - void removeFile(String path) { - def target = new File(root, path) - if (!target.delete()) { - throw new RuntimeException("Failed to delete file ${target.absolutePath}") - } - } - - @Override - OutputStream createFile(String path) { - def target = new File(root, path) - return target.newOutputStream() - } - - @Override - void setFileLastUpdatedDate(String path, long date) { - def target = new File(root, path) - target.setLastModified(date) - } -} diff --git a/buildSrc/src/main/groovy/dirsync/model/tree/FileNode.groovy b/buildSrc/src/main/groovy/dirsync/model/tree/FileNode.groovy deleted file mode 100644 index e17c28491..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/tree/FileNode.groovy +++ /dev/null @@ -1,8 +0,0 @@ -package dirsync.model.tree - -import groovy.transform.CompileStatic - -@CompileStatic -class FileNode extends AbstractFileTreeNode { - long size -} diff --git a/buildSrc/src/main/groovy/dirsync/model/tree/TreePhysMapper.groovy b/buildSrc/src/main/groovy/dirsync/model/tree/TreePhysMapper.groovy deleted file mode 100644 index 34ebce048..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/tree/TreePhysMapper.groovy +++ /dev/null @@ -1,11 +0,0 @@ -package dirsync.model.tree - -abstract class TreePhysMapper { - abstract InputStream fileContent(T file) - abstract void createDirectory(String dir) - abstract void removeDirectory(String dir) - abstract void removeFile(String path) - abstract OutputStream createFile(String path) - - abstract void setFileLastUpdatedDate(String path, long date) -} diff --git a/buildSrc/src/main/groovy/dirsync/model/tree/ZipData.groovy b/buildSrc/src/main/groovy/dirsync/model/tree/ZipData.groovy deleted file mode 100644 index 12114e570..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/tree/ZipData.groovy +++ /dev/null @@ -1,9 +0,0 @@ -package dirsync.model.tree - -import groovy.transform.CompileStatic - -@CompileStatic -class ZipData { - String zipEntryName - String zipArchiveName -} diff --git a/buildSrc/src/main/groovy/dirsync/model/tree/ZipTreeMapper.groovy b/buildSrc/src/main/groovy/dirsync/model/tree/ZipTreeMapper.groovy deleted file mode 100644 index 3adb50f28..000000000 --- a/buildSrc/src/main/groovy/dirsync/model/tree/ZipTreeMapper.groovy +++ /dev/null @@ -1,72 +0,0 @@ -package dirsync.model.tree - -import dirsync.builder.FileTreeMerger -import dirsync.builder.ZipTreeBuilder -import sun.reflect.generics.reflectiveObjects.NotImplementedException - -import java.util.zip.ZipFile - -public class ZipTreeMapper extends TreePhysMapper implements Closeable { - Map zipArchives = [:] - - void addZipArchive(String zipArchive) { - zipArchives[zipArchive] = new ZipFile(zipArchive) - } - - DirectoryNode buildFileTree() { - def root = new DirectoryNode() - zipArchives.each { ze -> - def zipTree = ZipTreeBuilder.buildForZipArchive(ze.key, ze.value) - root = FileTreeMerger.mergeTrees(root, zipTree) - } - - return root - } - - @Override - void close() throws IOException { - zipArchives.each { ze -> - try { ze.value.close() } catch (Exception ignored) { } - } - } - - @Override - InputStream fileContent(ZipData file) { - def archive = zipArchives[file.zipArchiveName] - if (!archive) { - throw new RuntimeException("Archive ${file.zipArchiveName} is not loaded"); - } - - def zipEntry = archive.getEntry(file.zipEntryName) - if (!zipEntry) { - throw new RuntimeException("File ${file.zipEntryName} not found in archive ${file.zipArchiveName}"); - } - - return archive.getInputStream(zipEntry) - } - - @Override - void createDirectory(String dir) { - throw new NotImplementedException() - } - - @Override - void removeDirectory(String dir) { - throw new NotImplementedException() - } - - @Override - void removeFile(String path) { - throw new NotImplementedException() - } - - @Override - OutputStream createFile(String path) { - throw new NotImplementedException() - } - - @Override - void setFileLastUpdatedDate(String path, long date) { - throw new NotImplementedException() - } -} diff --git a/buildSrc/src/main/groovy/gradlecpp/CppUnitTestExtension.groovy b/buildSrc/src/main/groovy/gradlecpp/CppUnitTestExtension.groovy deleted file mode 100644 index 26ea726e5..000000000 --- a/buildSrc/src/main/groovy/gradlecpp/CppUnitTestExtension.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package gradlecpp - -import org.gradle.api.Project -import org.gradle.nativeplatform.NativeBinarySpec - -class CppUnitTestExtension { - Project _project - - CppUnitTestExtension(Project p) { - _project = p - } - - void eachTestExecutable(Closure action) { - _project.binaries.each { NativeBinarySpec bin -> - if (!bin.hasProperty('cppUnitTestsExecutable')) return - action(bin) - } - } -} diff --git a/buildSrc/src/main/groovy/gradlecpp/CppUnitTestPlugin.groovy b/buildSrc/src/main/groovy/gradlecpp/CppUnitTestPlugin.groovy deleted file mode 100644 index 986eb472d..000000000 --- a/buildSrc/src/main/groovy/gradlecpp/CppUnitTestPlugin.groovy +++ /dev/null @@ -1,242 +0,0 @@ -package gradlecpp - -import gradlecpp.teamcity.TeamCityIntegration -import org.gradle.api.Action -import org.gradle.api.GradleException -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.api.internal.project.AbstractProject -import org.gradle.model.internal.core.DirectNodeModelAction -import org.gradle.model.internal.core.ModelActionRole -import org.gradle.model.internal.core.ModelPath -import org.gradle.model.internal.core.ModelReference -import org.gradle.model.internal.core.MutableModelNode -import org.gradle.model.internal.core.rule.describe.ModelRuleDescriptor -import org.gradle.model.internal.core.rule.describe.SimpleModelRuleDescriptor -import org.gradle.model.internal.registry.ModelRegistry -import org.gradle.nativeplatform.NativeBinarySpec -import org.gradle.nativeplatform.NativeLibrarySpec -import org.gradle.nativeplatform.internal.AbstractNativeBinarySpec - -import org.doomedsociety.gradlecpp.GradleCppUtils - -class CppUnitTestPlugin implements Plugin { - - private static class TestExecStatus { - boolean successful - int exitCode - String output - long durationMsec - String cmdLine - String execDir - } - - static void onBinariesCreated(Project p, String desc, Closure action) { - ModelRegistry mr = (p as AbstractProject).getModelRegistry() - def modelPath = ModelPath.path("binaries") - ModelRuleDescriptor ruleDescriptor = new SimpleModelRuleDescriptor(desc); - - mr.configure(ModelActionRole.Finalize, DirectNodeModelAction.of(ModelReference.of(modelPath), ruleDescriptor, new Action() { - @Override - void execute(MutableModelNode node) { - action() - } - })) - } - - @Override - void apply(Project project) { - project.extensions.create('cppUnitTest', CppUnitTestExtension, project) - onBinariesCreated(project, 'CppUnitTestPlugin::AttachUnitTest', { - processCppUnitTests(project) - }) - } - - - - /** - * Attaches test tasks to C/C++ libraries build tasks - */ - static void processCppUnitTests(Project p) { - //println "processCppUnitTests::afterEvaluate on ${p.name}: project type is ${p.projectType}" - - p.binaries.all { NativeBinarySpec bin -> - if (!(bin.component instanceof NativeLibrarySpec)) { - return - } - - def testComponentName = bin.component.name + '_tests' - Collection testCandidates = p.binaries.matching { it.component.name == testComponentName && bin.buildType == it.buildType && bin.flavor == it.flavor } - if (testCandidates.size() > 1) { - throw new GradleException("Found >1 test candidates for library ${bin.component.name} in project ${p}: ${testCandidates}") - } else if (!testCandidates.empty) { - def testBinary = testCandidates.first() - GradleCppUtils.onTasksCreated(p, 'CppUnitTestPlugin::AttachUnitTestTask', { - attachTestTaskToCppLibrary(bin, testBinary) - }) - String testTaskName = bin.namingScheme.getTaskName('unitTest') - bin.ext.cppUnitTestTask = testTaskName - } else { - throw new GradleException("No tests found for library ${bin.component.name} in project ${p}") - } - } - - } - - static TestExecStatus runTestExecutable(NativeBinarySpec testSubject, String executable, List params, String phase, int timeout) { - def execFile = new File(executable) - def outDir = new File(testSubject.buildTask.project.buildDir, "tests/${testSubject.name}/run") - outDir.mkdirs() - - def outPath = new File(outDir, "${phase}.log") - - def cmdParams = []; - cmdParams << execFile.absolutePath - cmdParams.addAll(params) - - def execDir = execFile.parentFile - def pb = new ProcessBuilder(cmdParams).redirectErrorStream(true).directory(execDir) - if (!GradleCppUtils.windows) { - pb.environment().put('LD_LIBRARY_PATH', '.') - } - - - def sout = new StringBuffer() - - long startTime = System.currentTimeMillis() - def p = pb.start() - p.consumeProcessOutput(sout, sout) - - p.waitForOrKill(timeout * 1000) - long endTime = System.currentTimeMillis() - - int exitVal = p.exitValue() - - outPath.withWriter('UTF-8') { writer -> - writer.write(sout.toString()) - } - - return new TestExecStatus( - exitCode: exitVal, - successful: (exitVal == 0), - output: sout.toString(), - durationMsec: endTime - startTime, - cmdLine: cmdParams.join(' '), - execDir: execDir.absolutePath - ) - } - - static void dumpTestExecStatus(TestExecStatus stat) { - if (!stat) { - println "Execution of test executable failed" - } - - println "Test executable command: ${stat.cmdLine}" - println "Test executable run directury: ${stat.execDir}" - println "Test executable exit code: ${stat.exitCode}" - println "Test executable output BEGIN" - println stat.output - println "Test executable output END" - } - - static void attachTestTaskToCppLibrary(NativeBinarySpec libBin, NativeBinarySpec testExecBin) { - Project p = libBin.buildTask.project - - def libBinImpl = libBin as AbstractNativeBinarySpec - def libLinkTask = GradleCppUtils.getLinkTask(libBin) - def testExecLinkTask = GradleCppUtils.getLinkTask(testExecBin) - - // collect all output files from library and test executable - def depFiles = [] - depFiles.addAll(libLinkTask.outputs.files.files) - depFiles.addAll(testExecLinkTask.outputs.files.files) - - //create 'tests' task - def testTaskName = libBinImpl.namingScheme.getTaskName('unitTest') - def testTask = p.task(testTaskName, { Task testTask -> - - //output dir - def testResDir = new File(p.buildDir, "tests/${libBin.name}") - - //inputs/outputs for up-to-date check - testTask.outputs.dir testResDir - testTask.inputs.files depFiles - - //dependencies on library and test executable - testTask.dependsOn libLinkTask - testTask.dependsOn testExecLinkTask - - // binary build depends on unit test - libBin.buildTask.dependsOn testTask - - // extra project-specific dependencies - def testDepsTask = p.tasks.findByName('testDeps') - if (testDepsTask != null) { - testTask.dependsOn testDepsTask - } - - // task actions - testTask.doLast { - - //temporary file that store info about all tests (XML) - File allTests = File.createTempFile('j4s-testinfo', 'data') - allTests.deleteOnExit() - - //fill file with test info - print "Fetching test info..." - def getTestsStatus = runTestExecutable(libBin, testExecBin.executableFile.absolutePath, ['-writeTestInfo', allTests.absolutePath], '__getTests', 5000) - if (!getTestsStatus.successful) { - println " Failed" - dumpTestExecStatus(getTestsStatus) - throw new GradleException("Unable to fetch test names") - } - println " OK" - getTestsStatus = null // allow GC to collect it - - // parse the test info file - def root = new XmlSlurper().parse(allTests) - - // run all tests - println "Running ${root.test.size()} tests..." - TeamCityIntegration.suiteStarted("unitTests.${libBin.name}") - int failCount = 0; - root.test.list().each { testInfo -> - def testName = '' + testInfo.@name.text() - def testGroup = '' + testInfo.@group.text() - def testTimeout = ('' + testInfo.@timeout.text()) as int - - if (!TeamCityIntegration.writeOutput) { - print " ${testGroup}-${testName}..." - System.out.flush() - } - - TeamCityIntegration.testStarted("${testGroup}-${testName}") - def testExecStatus = runTestExecutable(libBin, testExecBin.executableFile.absolutePath, ['-runTest', testGroup, testName], "${testGroup}-${testName}", testTimeout) - if (!testExecStatus.successful) { - if (!TeamCityIntegration.writeOutput) { - println " Failed" - } - - TeamCityIntegration.testFailed("${testGroup}-${testName}", "test executable return code is ${testExecStatus.exitCode}", "test executable return code is ${testExecStatus.exitCode}") - dumpTestExecStatus(testExecStatus) - failCount++ - } else { - if (!TeamCityIntegration.writeOutput) { - println " OK" - } - } - - TeamCityIntegration.testStdOut("${testGroup}-${testName}", testExecStatus.output) - TeamCityIntegration.testFinished("${testGroup}-${testName}", testExecStatus.durationMsec) - - } - TeamCityIntegration.suiteFinished("unitTests.${libBin.name}") - - if (failCount) { - throw new GradleException("CPP unit tests: ${failCount} tests failed"); - } - } - }) - } -} diff --git a/buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestPlugin.groovy b/buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestPlugin.groovy deleted file mode 100644 index 639cb22e8..000000000 --- a/buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestPlugin.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package gradlecpp - -import org.gradle.api.Plugin -import org.gradle.api.Project - -class RegamedllPlayTestPlugin implements Plugin { - @Override - void apply(Project project) { - project.configurations { - regamedll_playtest_image - } - - project.dependencies { - regamedll_playtest_image 'regamedll.testimg:testimg:2.0' - } - } -} diff --git a/buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestTask.groovy b/buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestTask.groovy deleted file mode 100644 index 0fe4947d6..000000000 --- a/buildSrc/src/main/groovy/gradlecpp/RegameDLLPlayTestTask.groovy +++ /dev/null @@ -1,86 +0,0 @@ -package gradlecpp - -import gradlecpp.teamcity.TeamCityIntegration -import org.apache.commons.lang.SystemUtils -import org.gradle.api.DefaultTask -import org.gradle.api.file.FileCollection -import org.gradle.api.tasks.TaskAction -import org.gradle.nativeplatform.NativeBinarySpec -import regamedll.testdemo.RegamedllDemoRunner -import regamedll.testdemo.RegamedllTestParser - -class RegamedllPlayTestTask extends DefaultTask { - - def FileCollection testDemos - def Closure postExtractAction - def File regamedllImageRoot - def File regamedllTestLogs - def NativeBinarySpec testFor - - @TaskAction - def doPlay() { - if (!SystemUtils.IS_OS_WINDOWS) { - return - } - - if (!testDemos) { - println 'RegamedllPlayTestTask: no demos attached to the testDemos property' - } - - regamedllImageRoot.mkdirs() - regamedllTestLogs.mkdirs() - - def demoRunner = new RegamedllDemoRunner(this.project.configurations.regamedll_playtest_image.getFiles(), regamedllImageRoot, postExtractAction) - - println "Preparing engine..." - demoRunner.prepareEngine() - - println "Running ${testDemos.getFiles().size()} ReGameDLL_CS test demos..." - - TeamCityIntegration.suiteStarted("regamedllDemo.${testFor.name}") - int failCount = 0; - testDemos.getFiles().each { f -> - - demoRunner.prepareEngine(); - def testInfo = RegamedllTestParser.parseTestInfo(f) - - TeamCityIntegration.testStarted(testInfo.testName) - - if (!TeamCityIntegration.writeOutput) { - println "Running ReGameDLL_CS test demo ${testInfo.testName} " - System.out.flush() - } - - println "Preparing files for test demo ${testInfo.testName} " - - demoRunner.prepareDemo(f) - - def testRes = demoRunner.runTest(testInfo, regamedllTestLogs) - - if (testRes.success) { - if (!TeamCityIntegration.writeOutput) { - println ' OK' - } - } else { - - TeamCityIntegration.testFailed(testInfo.testName, "Exit code: ${testRes.returnCode}", "Exit code: ${testRes.returnCode}") - if (!TeamCityIntegration.writeOutput) { - println ' Failed' - println "ReGameDLL_CS testdemo ${testInfo.testName} playback failed. Exit status is ${testRes.returnCode}." - println "Dumping console output:" - println testRes.hldsConsoleOutput - } - - failCount++ - } - - TeamCityIntegration.testStdOut(testInfo.testName, testRes.hldsConsoleOutput) - TeamCityIntegration.testFinished(testInfo.testName, testRes.duration) - } - TeamCityIntegration.suiteFinished("regamedllDemo.${testFor.name}") - - if (failCount) { - throw new RuntimeException("ReGameDLL_CS testdemos: failed ${failCount} tests") - } - } -} diff --git a/buildSrc/src/main/groovy/gradlecpp/VelocityUtils.groovy b/buildSrc/src/main/groovy/gradlecpp/VelocityUtils.groovy deleted file mode 100644 index b318714df..000000000 --- a/buildSrc/src/main/groovy/gradlecpp/VelocityUtils.groovy +++ /dev/null @@ -1,38 +0,0 @@ -package gradlecpp - -import org.apache.velocity.Template -import org.apache.velocity.VelocityContext -import org.apache.velocity.app.Velocity -import org.joda.time.format.DateTimeFormat - -class VelocityUtils { - - static { - Properties p = new Properties(); - - p.setProperty("resource.loader", "class"); - p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader"); - p.setProperty("class.resource.loader.path", ""); - - p.setProperty("input.encoding", "UTF-8"); - p.setProperty("output.encoding", "UTF-8"); - - Velocity.init(p); - } - - static String renderTemplate(File tplFile, Map ctx) { - Template tpl = Velocity.getTemplate(tplFile.absolutePath) - if (!tpl) { - throw new RuntimeException("Failed to load velocity template ${tplFile.absolutePath}: not found") - } - - - def velocityContext = new VelocityContext(ctx) - velocityContext.put("_DateTimeFormat", DateTimeFormat) - - def sw = new StringWriter() - tpl.merge(velocityContext, sw) - - return sw.toString() - } -} diff --git a/buildSrc/src/main/groovy/gradlecpp/teamcity/TeamCityIntegration.groovy b/buildSrc/src/main/groovy/gradlecpp/teamcity/TeamCityIntegration.groovy deleted file mode 100644 index 9832a8518..000000000 --- a/buildSrc/src/main/groovy/gradlecpp/teamcity/TeamCityIntegration.groovy +++ /dev/null @@ -1,84 +0,0 @@ -package gradlecpp.teamcity - -import groovy.transform.CompileStatic - - -class TeamCityIntegration { - - static final String flowId = System.getenv('TEAMCITY_PROCESS_FLOW_ID') - static final boolean underTeamcity = System.getenv('TEAMCITY_PROJECT_NAME') - static boolean writeOutput = underTeamcity - - @CompileStatic - private static String escape(String s) { - StringBuilder sb = new StringBuilder((int)(s.length() * 1.2)); - for (char c in s.chars) { - switch (c) { - case '\n': sb.append('|n'); break; - case '\r': sb.append('|r'); break; - case '\'': sb.append('|\''); break; - case '|': sb.append('||'); break; - case ']': sb.append('|]'); break; - default: sb.append(c); - } - } - - return sb.toString() - } - - @CompileStatic - static void writeMessage(String name, Map params) { - if (!writeOutput) return - StringBuilder sb = new StringBuilder() - sb.append('##teamcity[').append(name) - params.each { e -> - if (e.value != null) { - sb.append(' ').append('' + e.key).append('=\'').append(escape('' + e.value)).append('\'') - } - } - sb.append(']') - - println sb.toString() - } - - static void suiteStarted(String suiteName) { - writeMessage('testSuiteStarted', [name: suiteName, flowId: flowId ?: null]) - } - - static void suiteFinished(String suiteName) { - writeMessage('testSuiteFinished', [name: suiteName, flowId: flowId ?: null]) - } - - static void testStarted(String testName) { - writeMessage('testStarted', [name: testName, flowId: flowId ?: null]) - } - - static void testStdOut(String testName, String output) { - writeMessage('testStdOut', [name: testName, out: output, flowId: flowId ?: null]) - } - - static void testFinished(String testName, long durationMs) { - writeMessage('testFinished', [ - name: testName, - flowId: flowId ?: null, - duration: (durationMs >= 0) ? durationMs : null - ]) - } - - static void testFailed(String testName, String message, String details) { - writeMessage('testFailed', [ - name: testName, - flowId: flowId ?: null, - message: message, - details: details - ]) - } - - static void testIgnored(String testName, String message) { - writeMessage('testIgnored', [ - name: testName, - flowId: flowId ?: null, - message: message, - ]) - } -} diff --git a/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLDemoRunner.groovy b/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLDemoRunner.groovy deleted file mode 100644 index 6f78a4c86..000000000 --- a/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLDemoRunner.groovy +++ /dev/null @@ -1,106 +0,0 @@ -package regamedll.testdemo - -import dirsync.builder.FileSystemTreeBuilder -import dirsync.merger.FileTreeComparator -import dirsync.merger.FileTreeDiffApplier -import dirsync.model.tree.DirectoryNode -import dirsync.model.tree.FSMapper -import dirsync.model.tree.ZipData -import dirsync.model.tree.ZipTreeMapper -import org.apache.ant.compress.taskdefs.Unzip -import org.apache.tools.ant.types.PatternSet; - -class RegamedllDemoRunner { - ZipTreeMapper regamedllImage = new ZipTreeMapper() - File rootDir - DirectoryNode engineImageTree - Closure postExtract - - static class TestResult { - boolean success - int returnCode - String hldsConsoleOutput - long duration - } - - RegamedllDemoRunner(Collection engineImageZips, File rootDir, Closure postExtract) { - this.rootDir = rootDir - engineImageZips.each { f -> - regamedllImage.addZipArchive(f.absolutePath) - } - engineImageTree = regamedllImage.buildFileTree() - this.postExtract = postExtract - } - - void prepareDemo(File demoArchive) { - - if (demoArchive == null) { - throw new RuntimeException("ReGameDLL_CS testdemos: file is null") - } - - PatternSet patt = new PatternSet(); - - patt.setExcludes("**/*.bin"); - patt.setExcludes("**/*.xml"); - - //patt.setIncludes("**/cstrike/*"); - //patt.setIncludes("**/czero/*"); - //patt.setIncludes("**/valve/*"); - - Unzip unzipper = new Unzip(); - - unzipper.setDest( rootDir ); // directory unzipped - unzipper.setSrc( demoArchive ); // zip file - unzipper.addPatternset( patt ); - unzipper.execute(); - } - - void prepareEngine() { - def existingTree = FileSystemTreeBuilder.buildFileSystemTree(rootDir) - def cmds = FileTreeComparator.mergeTrees(engineImageTree, existingTree) - - FSMapper fsMapper = new FSMapper(rootDir) - FileTreeDiffApplier.applyDiffs(cmds, regamedllImage, fsMapper) - if (postExtract != null) { - postExtract.run() - } - } - - TestResult runTest(RegamedllTestInfo info, File testLogDir) { - long startTime = System.currentTimeMillis() - - //prepareEngine() - - def outPath = new File(testLogDir, "${info.testName}_run.log") - - def cmdParams = [] - cmdParams << new File(rootDir, 'hlds.exe').absolutePath - cmdParams.addAll(info.hldsArgs) - if (info.regamedllExtraArgs) { - cmdParams.addAll(info.regamedllExtraArgs) - } - cmdParams << '--rehlds-test-play' << info.testBinFile.absolutePath - - def pb = new ProcessBuilder(cmdParams).redirectErrorStream(true).directory(rootDir) - def sout = new StringBuffer() - - def p = pb.start() - p.consumeProcessOutput(sout, sout) - - p.waitForOrKill(info.timeoutSeconds * 1000) - int exitVal = p.exitValue() - - outPath.withWriter('UTF-8') { writer -> - writer.write(sout.toString()) - } - - long endTime = System.currentTimeMillis() - - return new TestResult( - success: (exitVal == 777), - returnCode: exitVal, - hldsConsoleOutput: sout.toString(), - duration: endTime - startTime - ) - } -} diff --git a/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestInfo.groovy b/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestInfo.groovy deleted file mode 100644 index 560e00389..000000000 --- a/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestInfo.groovy +++ /dev/null @@ -1,9 +0,0 @@ -package regamedll.testdemo - -class RegamedllTestInfo { - String testName - List hldsArgs - String regamedllExtraArgs - int timeoutSeconds - File testBinFile -} diff --git a/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestParser.groovy b/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestParser.groovy deleted file mode 100644 index bf54f159f..000000000 --- a/buildSrc/src/main/groovy/regamedll/testdemo/RegameDLLTestParser.groovy +++ /dev/null @@ -1,63 +0,0 @@ -package regamedll.testdemo - -import groovy.util.slurpersupport.GPathResult -import org.apache.commons.io.IOUtils - -import java.util.zip.ZipFile - -class RegamedllTestParser { - static final String REGAMEDLL_TEST_METAINFO_FILE = 'regamedll_test_metainfo.xml' - - static RegamedllTestInfo parseTestInfo(File testArchive) { - def zf = new ZipFile(testArchive); - try { - def metaInfoEntry = zf.getEntry(REGAMEDLL_TEST_METAINFO_FILE) - if (metaInfoEntry == null) { - throw new RuntimeException("Unable to open ${REGAMEDLL_TEST_METAINFO_FILE} in ${testArchive.absolutePath}") - } - - GPathResult metaInfo = null - zf.getInputStream(metaInfoEntry).withStream { InputStream ins -> - metaInfo = new XmlSlurper().parse(ins) - } - - RegamedllTestInfo testInfo = new RegamedllTestInfo( - testName: metaInfo.name.text(), - hldsArgs: metaInfo.runArgs.arg.list().collect { it.text().trim() }, - timeoutSeconds: metaInfo.timeout.text() as int - ) - - //validate testInfo - if (!testInfo.testName) { - throw new RuntimeException("Error parsing ${testArchive.absolutePath}: test name is not specified") - } - - if (!testInfo.hldsArgs) { - throw new RuntimeException("Error parsing ${testArchive.absolutePath}: run arguments are not specified") - } - - if (testInfo.timeoutSeconds <= 0) { - throw new RuntimeException("Error parsing ${testArchive.absolutePath}: bad timeout") - } - - def testBinName = testInfo.testName + '.bin' - def testBinEntry = zf.getEntry(testBinName) - if (testBinEntry == null) { - throw new RuntimeException("Error parsing ${testArchive.absolutePath}: test binary ${testBinName} not found inside archive") - } - - testInfo.testBinFile = File.createTempFile(testBinName, 'regamedll') - testInfo.testBinFile.deleteOnExit() - zf.getInputStream(testBinEntry).withStream { InputStream ins -> - testInfo.testBinFile.withOutputStream { OutputStream os -> - IOUtils.copy(ins, os) - } - } - - return testInfo - } finally { - try { zf.close() } catch (Exception ignored) { } - } - - } -} diff --git a/buildSrc/src/main/groovy/versioning/GitInfo.groovy b/buildSrc/src/main/groovy/versioning/GitInfo.groovy deleted file mode 100644 index e0ad38f87..000000000 --- a/buildSrc/src/main/groovy/versioning/GitInfo.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package versioning - -import groovy.transform.CompileStatic -import groovy.transform.TypeChecked -import org.joda.time.DateTime - -@CompileStatic @TypeChecked -class GitInfo { - boolean localChanges - DateTime commitDate - String branch - String tag - String commitSHA - String commitURL - Integer commitCount -} diff --git a/buildSrc/src/main/groovy/versioning/GitVersioner.groovy b/buildSrc/src/main/groovy/versioning/GitVersioner.groovy deleted file mode 100644 index e60f91460..000000000 --- a/buildSrc/src/main/groovy/versioning/GitVersioner.groovy +++ /dev/null @@ -1,140 +0,0 @@ -package versioning - -import java.util.Set; - -import groovy.transform.CompileStatic -import groovy.transform.TypeChecked -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.api.Status; -import org.eclipse.jgit.lib.ObjectId -import org.eclipse.jgit.lib.Repository -import org.eclipse.jgit.lib.StoredConfig -import org.eclipse.jgit.submodule.SubmoduleWalk; -import org.eclipse.jgit.revwalk.RevCommit -import org.eclipse.jgit.revwalk.RevWalk -import org.eclipse.jgit.storage.file.FileRepositoryBuilder -import org.joda.time.DateTime -import org.joda.time.DateTimeZone - -@CompileStatic @TypeChecked -class GitVersioner { - - static GitInfo versionForDir(String dir) { - versionForDir(new File(dir)) - } - static int getCountCommit(Repository repo) { - Iterable commits = Git.wrap(repo).log().call() - int count = 0; - commits.each { - count++; - } - - return count; - } - static String prepareUrlToCommits(String url) { - if (url == null) { - // default remote url - return "https://github.com/s1lentq/ReGameDLL_CS/commit/"; - } - - StringBuilder sb = new StringBuilder(); - String childPath; - int pos = url.indexOf('@'); - if (pos != -1) { - childPath = url.substring(pos + 1, url.lastIndexOf('.git')).replace(':', '/'); - sb.append('https://'); - } else { - pos = url.lastIndexOf('.git'); - childPath = (pos == -1) ? url : url.substring(0, pos); - } - - // support for different links to history of commits - if (url.indexOf('bitbucket.org') != -1) { - sb.append(childPath).append('/commits/'); - } else { - sb.append(childPath).append('/commit/'); - } - return sb.toString(); - } - // check uncommited changes - static boolean getUncommittedChanges(Repository repo) { - Git git = new Git(repo); - Status status = git.status().setIgnoreSubmodules(SubmoduleWalk.IgnoreSubmoduleMode.ALL).call(); - Set uncommittedChanges = status.getUncommittedChanges(); - System.err.println ' UncommittedChanges: ' + uncommittedChanges - - if (!uncommittedChanges.isEmpty()) { - System.err.println 'getUncommittedChanges details' - System.err.println ' Added: ' + status.getAdded() - System.err.println ' Changed: ' + status.getChanged() - System.err.println ' Removed: ' + status.getRemoved() - System.err.println ' Missing: ' + status.getMissing() - System.err.println ' Modified: ' + status.getModified() - System.err.println ' Conflicting: ' + status.getConflicting() - - System.err.println ' ConflictingStageState: ' + status.getConflictingStageState() - System.err.println ' IgnoredNotInIndex: ' + status.getIgnoredNotInIndex() - System.err.println ' Untracked: ' + status.getUntracked() - System.err.println ' UntrackedFolders: ' + status.getUntrackedFolders() - - return true; - } - - return false; - } - static GitInfo versionForDir(File dir) { - FileRepositoryBuilder builder = new FileRepositoryBuilder(); - Repository repo = builder.setWorkTree(dir) - .findGitDir() - .build() - - ObjectId head = repo.resolve('HEAD'); - if (!head) { - return null - } - - final StoredConfig cfg = repo.getConfig(); - def commit = new RevWalk(repo).parseCommit(head); - if (!commit) { - throw new RuntimeException("Can't find last commit."); - } - - def localChanges = getUncommittedChanges(repo); - def commitDate = new DateTime(1000L * commit.commitTime, DateTimeZone.UTC); - if (localChanges) { - commitDate = new DateTime(); - } - - def branch = repo.getBranch(); - - String url = null; - String remote_name = cfg.getString("branch", branch, "remote"); - - if (remote_name == null) { - for (String remotes : cfg.getSubsections("remote")) { - if (url != null) { - println 'Found a second remote: (' + remotes + '), url: (' + cfg.getString("remote", remotes, "url") + ')' - continue; - } - - url = cfg.getString("remote", remotes, "url"); - } - } else { - url = cfg.getString("remote", remote_name, "url"); - } - - String commitURL = prepareUrlToCommits(url); - String tag = repo.tags.find { kv -> kv.value.objectId == commit.id }?.key - String commitSHA = commit.getId().abbreviate(7).name(); - - return new GitInfo( - localChanges: localChanges, - commitDate: commitDate, - branch: branch, - tag: tag, - commitSHA: commitSHA, - commitURL: commitURL, - commitCount: getCountCommit(repo) - ) - } -} diff --git a/buildSrc/src/main/groovy/versioning/RegamedllVersionInfo.groovy b/buildSrc/src/main/groovy/versioning/RegamedllVersionInfo.groovy deleted file mode 100644 index 8151e6364..000000000 --- a/buildSrc/src/main/groovy/versioning/RegamedllVersionInfo.groovy +++ /dev/null @@ -1,58 +0,0 @@ -package versioning - -import groovy.transform.CompileStatic -import groovy.transform.ToString -import groovy.transform.TypeChecked -import org.joda.time.format.DateTimeFormat -import org.joda.time.DateTime - -@CompileStatic @TypeChecked -@ToString(includeNames = true) -class RegamedllVersionInfo { - Integer majorVersion - Integer minorVersion - Integer maintenanceVersion - String suffix - - boolean localChanges - DateTime commitDate - String commitSHA - String commitURL - Integer commitCount - - String asMavenVersion(boolean extra = true) { - StringBuilder sb = new StringBuilder() - sb.append(majorVersion).append('.' + minorVersion); - if (maintenanceVersion != null) { - sb.append('.' + maintenanceVersion); - } - - if (commitCount != null) { - sb.append('.' + commitCount) - } - - if (extra && suffix) { - sb.append('-' + suffix) - } - - // do mark for this build like a modified version - if (extra && localChanges) { - sb.append('+m'); - } - - return sb.toString() - } - String asCommitDate(String pattern = null) { - if (pattern == null) { - pattern = "MMM d yyyy"; - if (commitDate.getDayOfMonth() >= 10) { - pattern = "MMM d yyyy"; - } - } - - return DateTimeFormat.forPattern(pattern).withLocale(Locale.ENGLISH).print(commitDate); - } - String asCommitTime() { - return DateTimeFormat.forPattern('HH:mm:ss').withLocale(Locale.ENGLISH).print(commitDate); - } -} diff --git a/buildSrc/src/test/groovy/dirsync/builder/ZipTreeBuilderTest.groovy b/buildSrc/src/test/groovy/dirsync/builder/ZipTreeBuilderTest.groovy deleted file mode 100644 index 38a2eabb2..000000000 --- a/buildSrc/src/test/groovy/dirsync/builder/ZipTreeBuilderTest.groovy +++ /dev/null @@ -1,44 +0,0 @@ -package dirsync.builder - -import org.junit.Test - -import java.io.File - -import dirsync.builder.ZipTreeBuilder - -import java.util.zip.ZipEntry -import java.util.zip.ZipFile -import java.util.zip.ZipOutputStream; - -import static org.junit.Assert.*; - -class ZipTreeBuilderTest { - - @Test - void test1() { - File zipFile = File.createTempFile('ZipTreeBuilderTest', 'zip') - zipFile.deleteOnExit() - - new ZipOutputStream(zipFile.newDataOutputStream()).withStream { ZipOutputStream zos -> - zos.putNextEntry(new ZipEntry('aRootFile1.txt')) - zos.write(65) //'A' - - zos.putNextEntry(new ZipEntry('dir1/')) - zos.putNextEntry(new ZipEntry('dir1/dir2/')) - - zos.putNextEntry(new ZipEntry('dir1/dir2/d1d2f1.txt')) - zos.write(65); zos.write(66) //'AB' - - zos.putNextEntry(new ZipEntry('dir1/d1f1.txt')) - zos.write(65); zos.write(66); zos.write(67) //'ABC' - - zos.putNextEntry(new ZipEntry('zRootFile2.txt')) - zos.write(65); zos.write(66); zos.write(67); zos.write(68) //'ABCD' - } - - ZipFile zf = new ZipFile(zipFile.absolutePath) - def tree = ZipTreeBuilder.buildForZipArchive(zipFile.absolutePath, zf) - - assert tree.childNodes.size() == 3 - } -} \ No newline at end of file diff --git a/dep/cppunitlite/build.gradle b/dep/cppunitlite/build.gradle deleted file mode 100644 index fd0196b94..000000000 --- a/dep/cppunitlite/build.gradle +++ /dev/null @@ -1,62 +0,0 @@ -import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils -import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig -import org.doomedsociety.gradlecpp.toolchain.icc.Icc -import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin -import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig -import org.gradle.nativeplatform.NativeBinarySpec -import org.gradle.nativeplatform.NativeLibrarySpec - -apply plugin: 'cpp' -apply plugin: IccCompilerPlugin -apply plugin: GccCompilerPlugin - -void setupToolchain(NativeBinarySpec b) { - def cfg = rootProject.createToolchainConfig(b) - - ToolchainConfigUtils.apply(project, cfg, b) -} - -model { - buildTypes { - debug - release - } - - platforms { - x86 { - architecture "x86" - } - } - - toolChains { - visualCpp(VisualCpp) - if (project.hasProperty("useGcc")) { - gcc(Gcc) - } else { - icc(Icc) - } - } - - components { - cppunitlite(NativeLibrarySpec) { - targetPlatform 'x86' - - sources { - cppul_main(CppSourceSet) { - source { - srcDir "src" - include "**/*.cpp" - } - - exportedHeaders { - srcDir "include" - } - } - } - - binaries.all { NativeBinarySpec b -> - project.setupToolchain(b) - } - } - } -} diff --git a/dep/cppunitlite/include/cppunitlite/Assertions.h b/dep/cppunitlite/include/cppunitlite/Assertions.h index 380012110..58da03a40 100644 --- a/dep/cppunitlite/include/cppunitlite/Assertions.h +++ b/dep/cppunitlite/include/cppunitlite/Assertions.h @@ -7,8 +7,8 @@ class Assertions { static void StringEquals(std::string message, std::string expected, std::string actual, const char* fileName, long lineNumber); static void StringEquals(std::string message, const char* expected, const char* actual, const char* fileName, long lineNumber); - - static void ConditionFailed(std::string message, std::string condition, const char* fileName, long lineNumber); + + static void ConditionFailed(std::string message, std::string condition, const char* fileName, long lineNumber, bool onlyWarning = false); static void LongEquals(std::string message, long expected, long actual, const char* fileName, long lineNumber); diff --git a/dep/cppunitlite/include/cppunitlite/Failure.h b/dep/cppunitlite/include/cppunitlite/Failure.h index 447c3de9b..8be49ec9e 100644 --- a/dep/cppunitlite/include/cppunitlite/Failure.h +++ b/dep/cppunitlite/include/cppunitlite/Failure.h @@ -6,12 +6,13 @@ class TestFailException : public std::exception { public: - TestFailException(std::string message, std::string fileName, long lineNumber) { + TestFailException(std::string message, std::string fileName, long lineNumber, bool onlyWarning = false) { std::stringstream ss; ss << message << " at " << fileName << " line " << lineNumber; this->message = ss.str(); this->fileName = fileName; this->lineNumber = lineNumber; + this->warning = onlyWarning; } virtual ~TestFailException() throw() { @@ -21,6 +22,7 @@ class TestFailException : public std::exception { std::string message; std::string fileName; long lineNumber; + bool warning; virtual const char * what() const throw() { return message.c_str(); @@ -35,6 +37,7 @@ class Failure { this->message = e.message; this->fileName = e.fileName; this->lineNumber = e.lineNumber; + this->warning = e.warning; } Failure (std::string message, std::string testName) { @@ -48,6 +51,7 @@ class Failure { std::string message; std::string fileName; long lineNumber; + bool warning; }; diff --git a/dep/cppunitlite/include/cppunitlite/GradleAdapter.h b/dep/cppunitlite/include/cppunitlite/MainAdapter.h similarity index 91% rename from dep/cppunitlite/include/cppunitlite/GradleAdapter.h rename to dep/cppunitlite/include/cppunitlite/MainAdapter.h index 8319d8639..bdf2488bd 100644 --- a/dep/cppunitlite/include/cppunitlite/GradleAdapter.h +++ b/dep/cppunitlite/include/cppunitlite/MainAdapter.h @@ -1,6 +1,6 @@ #pragma once -class GradleAdapter { +class MainAdapter { public: int writeAllTestsInfoToFile(const char* fname); int runTest(const char* groupName, const char* testName); diff --git a/dep/cppunitlite/include/cppunitlite/Test.h b/dep/cppunitlite/include/cppunitlite/Test.h index bd7acf051..6f1cefa37 100644 --- a/dep/cppunitlite/include/cppunitlite/Test.h +++ b/dep/cppunitlite/include/cppunitlite/Test.h @@ -20,7 +20,7 @@ class Test void setNext(Test *test); Test *getNext () const; void run(TestResult& result); - + const char* getName() { return name_.c_str(); } @@ -28,7 +28,7 @@ class Test const char* getGroup() { return group_.c_str(); } - + int getTimeout() { return timeout_; } @@ -47,7 +47,7 @@ class Test { public: testGroup##testName##Test () : Test (#testName , #testGroup , testTimeout) {} \ void runInternal (); } \ testGroup##testName##Instance; \ - void testGroup##testName##Test::runInternal() + void testGroup##testName##Test::runInternal() @@ -55,6 +55,9 @@ class Test } \ } +#define CHECK_WARNING_OUT(msg, condition) { if (!(condition)) { Assertions::ConditionFailed(msg,#condition, __FILE__, __LINE__, true); return; \ + } \ +} #define ZSTR_EQUAL(msg,expected,actual) { \ Assertions::StringEquals((msg), (expected), (actual), __FILE__, __LINE__); \ diff --git a/dep/cppunitlite/include/cppunitlite/TestResult.h b/dep/cppunitlite/include/cppunitlite/TestResult.h index a59c9aebe..f67bfa936 100644 --- a/dep/cppunitlite/include/cppunitlite/TestResult.h +++ b/dep/cppunitlite/include/cppunitlite/TestResult.h @@ -13,6 +13,10 @@ class TestResult int getFailureCount() { return failureCount; } + int getWarningCount() { + return warningCount; + } private: int failureCount; + int warningCount; }; diff --git a/dep/cppunitlite/msvc/cppunitlite.vcxproj b/dep/cppunitlite/msvc/cppunitlite.vcxproj index 01c982efe..e3cb49a66 100644 --- a/dep/cppunitlite/msvc/cppunitlite.vcxproj +++ b/dep/cppunitlite/msvc/cppunitlite.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -30,7 +30,7 @@ {CEB94F7C-E459-4673-AABB-36E2074396C0} Win32Proj cppunitlite - 12.0 + 12.0 @@ -42,15 +42,6 @@ v142 MultiByte - - StaticLibrary - true - v120 - v140 - v141 - v142 - MultiByte - StaticLibrary false @@ -78,7 +69,7 @@ Level3 Disabled - WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions) + WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebug $(ProjectDir)..\include\ CompileAsCpp diff --git a/dep/cppunitlite/msvc/cppunitlite.vcxproj.filters b/dep/cppunitlite/msvc/cppunitlite.vcxproj.filters index 54af26d70..2a8d9160f 100644 --- a/dep/cppunitlite/msvc/cppunitlite.vcxproj.filters +++ b/dep/cppunitlite/msvc/cppunitlite.vcxproj.filters @@ -27,7 +27,7 @@ include - + include @@ -44,7 +44,7 @@ src - + src diff --git a/dep/cppunitlite/src/Assertions.cpp b/dep/cppunitlite/src/Assertions.cpp index 1d79fc0c3..4eb90e1b3 100644 --- a/dep/cppunitlite/src/Assertions.cpp +++ b/dep/cppunitlite/src/Assertions.cpp @@ -27,13 +27,13 @@ void Assertions::StringEquals(std::string message, const char *expected, const c } } -void Assertions::ConditionFailed(std::string message, std::string condition, const char *fileName, long lineNumber) { +void Assertions::ConditionFailed(std::string message, std::string condition, const char *fileName, long lineNumber, bool onlyWarning) { std::stringstream ss; ss << message << " (condition failed: " << condition << ")"; - throw TestFailException(ss.str(), std::string(fileName), lineNumber); + throw TestFailException(ss.str(), std::string(fileName), lineNumber, onlyWarning); } -void Assertions::LongEquals(std::string message, long expected, long actual, const char *fileName, long lineNumber) { +void Assertions::LongEquals(std::string message, long expected, long actual, const char* fileName, long lineNumber) { if (expected != actual) { std::stringstream ss; ss << message << " (expected '" << expected << "', got '" << actual << "')"; @@ -41,7 +41,7 @@ void Assertions::LongEquals(std::string message, long expected, long actual, con } } -void Assertions::UInt32Equals(std::string message, unsigned int expected, unsigned int actual, const char *fileName, long lineNumber) { +void Assertions::UInt32Equals(std::string message, unsigned int expected, unsigned int actual, const char* fileName, long lineNumber) { if (expected != actual) { std::stringstream ss; ss << message << " (expected '" << expected << "', got '" << actual << "')"; @@ -49,7 +49,7 @@ void Assertions::UInt32Equals(std::string message, unsigned int expected, unsign } } -void Assertions::CharEquals(std::string message, char expected, char actual, const char *fileName, long lineNumber) { +void Assertions::CharEquals(std::string message, char expected, char actual, const char* fileName, long lineNumber) { if (expected != actual) { std::stringstream ss; ss << message << " (expected '" << expected << "', got '" << actual << "')"; @@ -57,15 +57,15 @@ void Assertions::CharEquals(std::string message, char expected, char actual, con } } -void Assertions::DoubleEquals(std::string message, double expected, double actual, double epsilon, const char *fileName, long lineNumber) { - if (std::abs(expected - actual) > epsilon) { +void Assertions::DoubleEquals(std::string message, double expected, double actual, double epsilon, const char* fileName, long lineNumber) { + if (std::fabs(expected - actual) > epsilon) { std::stringstream ss; ss << message << " (expected '" << expected << "', got '" << actual << "')"; throw TestFailException(ss.str(), std::string(fileName), lineNumber); } } -void Assertions::MemoryEquals(std::string message, void *expected, void *actual, int size, const char *fileName, long lineNumber) { +void Assertions::MemoryEquals(std::string message, void* expected, void* actual, int size, const char* fileName, long lineNumber) { if (memcmp(expected, actual, size)) { std::stringstream ss; ss << message << " (expected '"; diff --git a/dep/cppunitlite/src/GradleAdapter.cpp b/dep/cppunitlite/src/MainAdapter.cpp similarity index 76% rename from dep/cppunitlite/src/GradleAdapter.cpp rename to dep/cppunitlite/src/MainAdapter.cpp index 47dbd24c0..6c446a62e 100644 --- a/dep/cppunitlite/src/GradleAdapter.cpp +++ b/dep/cppunitlite/src/MainAdapter.cpp @@ -2,11 +2,11 @@ #include #include -#include "cppunitlite/GradleAdapter.h" +#include "cppunitlite/MainAdapter.h" #include "cppunitlite/Test.h" #include "cppunitlite/TestRegistry.h" -int GradleAdapter::writeAllTestsInfoToFile(const char *fname) { +int MainAdapter::writeAllTestsInfoToFile(const char *fname) { FILE *outFile = fopen(fname, "w"); if (!outFile) { return 1; @@ -32,7 +32,7 @@ int GradleAdapter::writeAllTestsInfoToFile(const char *fname) { return 0; } -int GradleAdapter::runTest(const char *groupName, const char *testName) { +int MainAdapter::runTest(const char *groupName, const char *testName) { Test *curTest = TestRegistry::getFirstTest(); while (curTest) { if (!strcmp(groupName, curTest->getGroup()) && !strcmp(testName, curTest->getName())) { @@ -52,14 +52,18 @@ int GradleAdapter::runTest(const char *groupName, const char *testName) { if (result.getFailureCount()) { return 1; } + else if (result.getWarningCount()) { + return 3; + } else { return 0; } } -int GradleAdapter::runGroup(const char *groupName) { +int MainAdapter::runGroup(const char *groupName) { Test *curTest = TestRegistry::getFirstTest(); int ranTests = 0; + int warnTest = 0; while (curTest) { if (strcmp(groupName, curTest->getGroup())) { curTest = curTest->getNext(); @@ -74,6 +78,10 @@ int GradleAdapter::runGroup(const char *groupName) { return 1; } + if (result.getWarningCount()) { + warnTest++; + } + curTest = curTest->getNext(); } @@ -82,13 +90,19 @@ int GradleAdapter::runGroup(const char *groupName) { return 2; } + if (warnTest > 0) { + printf("There were no test failures, but with warnings: %d; Tests executed: %d\n", warnTest, ranTests); + return 3; + } + printf("There were no test failures; Tests executed: %d\n", ranTests); return 0; } -int GradleAdapter::runAllTests() { +int MainAdapter::runAllTests() { Test *curTest = TestRegistry::getFirstTest(); int ranTests = 0; + int warnTest = 0; while (curTest) { TestResult result; curTest->run(result); @@ -98,14 +112,23 @@ int GradleAdapter::runAllTests() { return 1; } + if (result.getWarningCount()) { + warnTest++; + } + curTest = curTest->getNext(); } + if (warnTest > 0) { + printf("There were no test failures, but with warnings: %d; Tests executed: %d\n", warnTest, ranTests); + return 3; + } + printf("There were no test failures; Tests executed: %d\n", ranTests); return 0; } -int GradleAdapter::testsEntryPoint(int argc, char *argv[]) { +int MainAdapter::testsEntryPoint(int argc, char *argv[]) { if (argc < 2 || !strcmp(argv[1], "-all")) { return runAllTests(); } diff --git a/dep/cppunitlite/src/Test.cpp b/dep/cppunitlite/src/Test.cpp index 14eb5f073..3246868ca 100644 --- a/dep/cppunitlite/src/Test.cpp +++ b/dep/cppunitlite/src/Test.cpp @@ -3,9 +3,10 @@ #include "cppunitlite/Failure.h" #include +#include #include -Test::Test (const char* testName, const char* testGroup, int timeout) +Test::Test(const char *testName, const char *testGroup, int timeout) : name_ (testName), group_ (testGroup), timeout_(timeout) { next_ = nullptr; @@ -18,15 +19,17 @@ Test *Test::getNext() const } void Test::setNext(Test *test) -{ +{ next_ = test; } -void Test::run(TestResult &result) { +void Test::run(TestResult &result) +{ try { runInternal(); - } catch (TestFailException *e) { - result.addFailure(Failure(*e, name_)); + std::cout << "Test::run() > " << group_ << "::" << name_ << " Passed" << std::endl; + } catch (TestFailException &e) { + result.addFailure(Failure(e, name_)); } catch (std::exception &e) { std::stringstream ss; ss << "unexpected exception " << e.what(); diff --git a/dep/cppunitlite/src/TestRegistry.cpp b/dep/cppunitlite/src/TestRegistry.cpp index ce7c7b928..6f1f9ae4a 100644 --- a/dep/cppunitlite/src/TestRegistry.cpp +++ b/dep/cppunitlite/src/TestRegistry.cpp @@ -1,50 +1,44 @@ - - #include "cppunitlite/Test.h" #include "cppunitlite/TestResult.h" #include "cppunitlite/TestRegistry.h" - -void TestRegistry::addTest (Test *test) +void TestRegistry::addTest(Test *test) { - instance ().add (test); + instance().add(test); } - -void TestRegistry::runAllTests (TestResult& result) +void TestRegistry::runAllTests(TestResult &result) { - instance ().run (result); + instance().run(result); } -Test* TestRegistry::getFirstTest() { +Test *TestRegistry::getFirstTest() { return instance().tests; } - -TestRegistry& TestRegistry::instance () + +TestRegistry& TestRegistry::instance() { static TestRegistry registry; return registry; } - -void TestRegistry::add (Test *test) +void TestRegistry::add(Test *test) { if (tests == 0) { tests = test; return; } - - test->setNext (tests); + + test->setNext(tests); tests = test; } - -void TestRegistry::run (TestResult& result) +void TestRegistry::run(TestResult &result) { - result.testsStarted (); + result.testsStarted(); - for (Test *test = tests; test != 0; test = test->getNext ()) - test->run (result); - result.testsEnded (); -} + for (Test *test = tests; test; test = test->getNext()) + test->run(result); + result.testsEnded(); +} diff --git a/dep/cppunitlite/src/TestResult.cpp b/dep/cppunitlite/src/TestResult.cpp index a5aff8005..aebc9b19d 100644 --- a/dep/cppunitlite/src/TestResult.cpp +++ b/dep/cppunitlite/src/TestResult.cpp @@ -1,38 +1,48 @@ - #include "cppunitlite/TestResult.h" #include "cppunitlite/Failure.h" #include #include - -TestResult::TestResult () - : failureCount (0) +TestResult::TestResult() + : failureCount(0), warningCount(0) { } - -void TestResult::testsStarted () +void TestResult::testsStarted() { } - -void TestResult::addFailure (const Failure& failure) { +void TestResult::addFailure(const Failure& failure) +{ std::stringstream ss; - ss << "Failure in test '" << failure.testName << "' :" << failure.message; + ss << (failure.warning ? "Warning in test '" : "Failure in test '") << failure.testName << "' :" << failure.message; std::cout << ss.str() << std::endl; std::cout.flush(); - failureCount++; -} + if (failure.warning) { + warningCount++; + } + else + failureCount++; +} -void TestResult::testsEnded () { +void TestResult::testsEnded() +{ std::stringstream ss; if (failureCount > 0) { ss << "There were " << failureCount << " failures"; - } else { + if (warningCount > 0) { + ss << ", and " << warningCount << " warnings"; + } + } + else if (warningCount > 0) { + ss << "There were " << warningCount << " warnings"; + } + else { ss << "There were no test failures"; } + std::cout << ss.str() << std::endl; std::cout.flush(); } diff --git a/getucrtinfo.bat b/getucrtinfo.bat deleted file mode 100644 index 29f5bb163..000000000 --- a/getucrtinfo.bat +++ /dev/null @@ -1,19 +0,0 @@ -@echo off - -if defined VS150COMNTOOLS ( - if not exist "%VS150COMNTOOLS%vcvarsqueryregistry.bat" goto NoVS - call "%VS150COMNTOOLS%vcvarsqueryregistry.bat" - goto :run -) else if defined VS140COMNTOOLS ( - if not exist "%VS140COMNTOOLS%vcvarsqueryregistry.bat" goto NoVS - call "%VS140COMNTOOLS%vcvarsqueryregistry.bat" - goto :run -) - -:NoVS -echo Error: Visual Studio 2015 or 2017 required. -exit /b 1 - -:run -echo %UniversalCRTSdkDir% -echo %UCRTVersion% diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index b58725dd8..000000000 --- a/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -majorVersion=5 -minorVersion=20 -maintenanceVersion=0 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 175c642d9d335ec83dba0b6fa44b04fc18d7768b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52279 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 z 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 L@0Zq5qN+E_t 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 8a0b282aa..000000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/msvc/ReGameDLL.sln b/msvc/ReGameDLL.sln index 4b77eda3c..bd8d6aced 100644 --- a/msvc/ReGameDLL.sln +++ b/msvc/ReGameDLL.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31025.194 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReGameDLL", "..\regamedll\msvc\ReGameDLL.vcxproj", "{70A2B904-B7DB-4C48-8DE0-AF567360D572}" ProjectSection(ProjectDependencies) = postProject @@ -10,14 +10,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReGameDLL", "..\regamedll\m EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cppunitlite", "..\dep\cppunitlite\msvc\cppunitlite.vcxproj", "{CEB94F7C-E459-4673-AABB-36E2074396C0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gradle", "gradle", "{DB570330-2FEE-4C39-971B-340019B6E661}" - ProjectSection(SolutionItems) = preProject - ..\build.gradle = ..\build.gradle - ..\gradle.properties = ..\gradle.properties - ..\settings.gradle = ..\settings.gradle - ..\shared.gradle = ..\shared.gradle - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug Play|Win32 = Debug Play|Win32 @@ -51,4 +43,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E442B676-1D5A-48D0-BFCC-D5D3BAD32ECF} + EndGlobalSection EndGlobal diff --git a/publish.gradle b/publish.gradle deleted file mode 100644 index a0c1fc03f..000000000 --- a/publish.gradle +++ /dev/null @@ -1,142 +0,0 @@ -import org.doomedsociety.gradlecpp.GradleCppUtils -import org.apache.commons.io.FilenameUtils - -void _copyFileToDir(String from, String to) { - if (!project.file(from).exists()) { - println 'WARNING: Could not find: ' + from; - return; - } - - if (!project.file(to).exists()) { - project.file(to).mkdirs(); - } - - def dst = new File(project.file(to), FilenameUtils.getName(from)) - GradleCppUtils.copyFile(project.file(from), dst, false) -} - -void _copyFile(String from, String to) { - if (!project.file(from).exists()) { - println 'WARNING: Could not find: ' + from; - return; - } - - GradleCppUtils.copyFile(project.file(from), project.file(to), false) -} - -task publishPrepareFiles { - doLast { - def pubRootDir = project.file('publish/publishRoot') - if (pubRootDir.exists()) { - if (!pubRootDir.deleteDir()) { - throw new RuntimeException("Failed to delete ${pubRootDir}") - } - } - - pubRootDir.mkdirs() - project.file('publish/publishRoot/bin/win32/cstrike/dlls').mkdirs() - project.file('publish/publishRoot/bin/linux32/cstrike/dlls').mkdirs() - - // bugfixed binaries - _copyFile('publish/releaseRegamedllFixes/mp.dll', 'publish/publishRoot/bin/win32/cstrike/dlls/mp.dll') - _copyFile('publish/releaseRegamedllFixes/cs.so', 'publish/publishRoot/bin/linux32/cstrike/dlls/cs.so') - - // copy files from folder dist - copy { - from('dist') - into 'publish/publishRoot/bin/win32/cstrike' - } - - copy { - from('dist') - into 'publish/publishRoot/bin/linux32/cstrike' - } - - // cssdk - project.file('publish/publishRoot/cssdk').mkdirs() - copy { - from 'regamedll/extra/cssdk' - into 'publish/publishRoot/cssdk' - } - } -} - -task publishPackage(type: Zip, dependsOn: 'publishPrepareFiles') { - baseName = "regamedll-dist-${project.version}" - destinationDir file('publish') - from 'publish/publishRoot' -} - -publishing { - publications { - maven(MavenPublication) { - version project.version - artifact publishPackage - - pom.withXml { - asNode().children().last() + { - resolveStrategy = DELEGATE_FIRST - name project.name - description project.description - properties { - commitDate project.ext.regamedllVersionInfo.commitDate - commitSHA project.ext.regamedllVersionInfo.commitSHA - } - - //url github - //scm { - // url "${github}.git" - // connection "scm:git:${github}.git" - //} - /* - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - developers { - developer { - id 'dreamstalker' - name 'dreamstalker' - } - } - */ - } - } - } - } -} - -Properties repoCreds = new Properties() -project.ext.repoCreds = repoCreds -if (file('repo_creds.properties').exists()) { - println 'Loading maven repo credentials' - file('repo_creds.properties').withReader('UTF-8', { Reader r -> - repoCreds.load(r) - }) -} - -publishing { - repositories { - maven { - if (project.version.contains('dev')) { - url "http://nexus.rehlds.org/nexus/content/repositories/regamedll-dev/" - } else { - url "http://nexus.rehlds.org/nexus/content/repositories/regamedll-releases/" - } - credentials { - username repoCreds.getProperty('username') - password repoCreds.getProperty('password') - } - } - } -} - -task doPublish { - dependsOn 'publishPackage' - if (repoCreds.getProperty('username') && repoCreds.getProperty('password')) { - dependsOn 'publish' - } -} diff --git a/regamedll/build.gradle b/regamedll/build.gradle deleted file mode 100644 index 848bb01ed..000000000 --- a/regamedll/build.gradle +++ /dev/null @@ -1,444 +0,0 @@ -import gradlecpp.RegamedllPlayTestPlugin -import gradlecpp.RegamedllPlayTestTask -import gradlecpp.VelocityUtils - -import org.doomedsociety.gradlecpp.GradleCppUtils -import org.doomedsociety.gradlecpp.LazyNativeDepSet -import org.doomedsociety.gradlecpp.cfg.ToolchainConfig -import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils -import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig -import org.doomedsociety.gradlecpp.msvc.EnhancedInstructionsSet -import org.doomedsociety.gradlecpp.msvc.FloatingPointModel -import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig -import org.doomedsociety.gradlecpp.toolchain.icc.Icc -import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin -import org.gradle.language.cpp.CppSourceSet -import org.gradle.nativeplatform.NativeBinarySpec -import org.gradle.nativeplatform.NativeExecutableSpec -import org.gradle.nativeplatform.NativeLibrarySpec -import org.gradle.nativeplatform.SharedLibraryBinarySpec -import regamedll.testdemo.RegamedllDemoRunner -import versioning.RegamedllVersionInfo -import org.apache.commons.io.FilenameUtils -import org.apache.commons.compress.archivers.ArchiveInputStream - -apply plugin: 'cpp' -apply plugin: IccCompilerPlugin -apply plugin: GccCompilerPlugin -apply plugin: RegamedllPlayTestPlugin -apply plugin: gradlecpp.CppUnitTestPlugin - -repositories { - maven { - url 'http://nexus.rehlds.org/nexus/content/repositories/regamedll-releases/' - } -} - -configurations { - regamedll_tests -} - -dependencies { - regamedll_tests 'regamedll.testdemos:cstrike-basic:1.0' -} - -project.ext.dep_cppunitlite = project(':dep/cppunitlite') - -void createIntergrationTestTask(NativeBinarySpec b) { - boolean regamedllFixes = b.flavor.name.contains('regamedllFixes') - - if (!(b instanceof SharedLibraryBinarySpec)) return - if (!GradleCppUtils.windows) return - if (regamedllFixes) return - - String unitTestTask = b.hasProperty('cppUnitTestTask') ? b.cppUnitTestTask : null - - def demoItgTestTask = project.tasks.create(b.namingScheme.getTaskName('demoItgTest'), RegamedllPlayTestTask) - demoItgTestTask.with { - regamedllImageRoot = new File(project.projectDir, '_regamedllTestImg') - regamedllTestLogs = new File(this.project.buildDir, "_regamedllTestLogs/${b.name}") - testDemos = project.configurations.regamedll_tests - testFor = b - - // inputs/outputs for up-to-date check - inputs.files testDemos.files - outputs.dir regamedllTestLogs - - // dependencies on test executable - if (unitTestTask) { - dependsOn unitTestTask - } - - postExtractAction { - def binaryOutFile = GradleCppUtils.getBinaryOutputFile(b) - def binaryOutDir = new File(project.projectDir, '/_regamedllTestImg/cstrike/dlls') - GradleCppUtils.copyFile(binaryOutFile, new File(binaryOutDir, binaryOutFile.name), true) - } - } - - b.buildTask.dependsOn demoItgTestTask -} - -void postEvaluate(NativeBinarySpec b) { - - // attach generateAppVersion task to all 'compile source' tasks - GradleCppUtils.getCompileTasks(b).each { Task t -> - t.dependsOn project.generateAppVersion - } - - createIntergrationTestTask(b) -} - -void setupToolchain(NativeBinarySpec b) -{ - boolean useGcc = project.hasProperty("useGcc") - boolean useClang = project.hasProperty("useClang") - boolean unitTestExecutable = b.component.name.endsWith('_tests') - boolean regamedllFixes = b.flavor.name.contains('regamedllFixes') - - ToolchainConfig cfg = rootProject.createToolchainConfig(b) - cfg.projectInclude(project, '', '/engine', '/common', '/dlls', '/game_shared', '/pm_shared', '/regamedll', '/public', '/public/regamedll') - - if (unitTestExecutable) - { - cfg.projectInclude(dep_cppunitlite, '/include') - b.lib LazyNativeDepSet.create(dep_cppunitlite, 'cppunitlite', b.buildType.name, true) - } - - cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'REGAMEDLL_SELF', 'REGAMEDLL_API', 'CLIENT_WEAPONS', 'USE_QSTRING' - - if (cfg instanceof MsvcToolchainConfig) - { - cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( - enabled: true, - pchHeader: 'precompiled.h', - pchSourceSet: 'regamedll_pch' - ); - - cfg.singleDefines('_CRT_SECURE_NO_WARNINGS') - if (!regamedllFixes) - { - cfg.compilerOptions.floatingPointModel = FloatingPointModel.PRECISE - cfg.compilerOptions.enhancedInstructionsSet = EnhancedInstructionsSet.DISABLED - } - else { - cfg.compilerOptions.args '/Oi', '/GF', '/GS', '/GR' - } - - cfg.projectLibpath(project, '/lib') - cfg.extraLibs 'libacof32.lib' - } - else if (cfg instanceof GccToolchainConfig) - { - if (!useGcc && !useClang) - { - cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions( - enabled: true, - pchSourceSet: 'regamedll_pch' - ); - } - - cfg.compilerOptions.languageStandard = 'c++14' - cfg.defines([ - '_stricmp': 'strcasecmp', - '_strnicmp': 'strncasecmp', - '_strdup': 'strdup', - '_unlink': 'unlink', - '_vsnprintf': 'vsnprintf', - '_write' : 'write', - '_close' : 'close', - '_vsnwprintf' : 'vswprintf', - '_access' : 'access' - ]) - - if (useGcc || useClang) { - // Produce code optimized for the most common IA32/AMD64/EM64T processors. - // As new processors are deployed in the marketplace, the behavior of this option will change. - cfg.compilerOptions.args '-mtune=generic', '-msse3', '-Wno-write-strings', '-Wno-invalid-offsetof', '-fpermissive', '-Wno-switch', '-Wno-unused-value', '-Wno-enum-compare' - - if (useGcc) { - cfg.compilerOptions.args '-fno-devirtualize' - } - else { - cfg.compilerOptions.args '-fno-strict-vtable-pointers', '-Wno-overloaded-virtual' - } - - } else { - cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp' - - // Not use c++ class hierarchy for analyze and resolve C++ virtual function calls at compile time. - // - // Example issue: - // Expected: FF .. call dword ptr + offset, pEntity->Spawn(); - // Got: E8 .. call CBaseEntity::Spawn(); - cfg.linkerOptions.args '-qno-opt-class-analysis' - } - - if (cfg.linkerOptions.staticLibStdCpp) { - cfg.singleDefines 'BUILD_STATIC_LIBSTDC' - } - - cfg.compilerOptions.args '-g0', '-fno-exceptions' - cfg.projectLibpath(project, '/lib/linux32') - cfg.extraLibs 'dl', 'm', 'aelf32' - } - - if (GradleCppUtils.windows && !unitTestExecutable) { - cfg.linkerOptions.definitionFile = "${projectDir}\\msvc\\mp.def"; - } - - if (unitTestExecutable) { - cfg.singleDefines 'REGAMEDLL_UNIT_TESTS' - } - - if (regamedllFixes) { - cfg.singleDefines 'REGAMEDLL_FIXES', 'BUILD_LATEST', 'BUILD_LATEST_FIXES', 'REGAMEDLL_CHECKS', 'REGAMEDLL_ADD', 'UNICODE_FIXES', 'NDEBUG' - } else { - cfg.singleDefines 'PLAY_GAMEDLL' - } - - ToolchainConfigUtils.apply(project, cfg, b) - GradleCppUtils.onTasksCreated(project, 'postEvaluate', { - postEvaluate(b) - }) -} - -class RegamedllSrc { - static void regamedll_src(def h) { - h.engine_src(CppSourceSet) { - source { - srcDir "engine" - include "unicode_strtools.cpp" - } - } - - h.shared_src(CppSourceSet) { - source { - srcDirs "game_shared", "pm_shared", "regamedll", "public", "version" - - include "**/*.cpp" - - exclude "precompiled.cpp" - exclude "tier0/dbg.cpp", "utlsymbol.cpp", "utlbuffer.cpp" - - if (GradleCppUtils.windows) - { - exclude "tier0/platform_linux.cpp" - } - else - { - exclude "tier0/platform_win32.cpp" - exclude "classes_dummy.cpp" - } - } - } - - h.gamedll_src(CppSourceSet) { - source { - srcDirs "dlls", "dlls/API", "dlls/addons" - include "**/*.cpp" - } - } - } - - static void regamedll_pch(def h) { - h.regamedll_pch(CppSourceSet) { - source { - srcDir "regamedll" - include "precompiled.cpp" - } - } - } - - static void regamedll_tests_gcc_src(def h) { - h.regamedll_tests_gcc_src(CppSourceSet) { - source { - srcDir "unittests" - include "**/*.cpp" - exclude "mathfun_tests.cpp" - } - } - } - - static void regamedll_tests_src(def h) { - h.regamedll_tests_src(CppSourceSet) { - source { - srcDir "unittests" - include "**/*.cpp" - } - } - } -} - -model { - buildTypes { - debug - release - } - - platforms { - x86 { - architecture "x86" - } - } - - toolChains { - visualCpp(VisualCpp) { - } - if (project.hasProperty("useClang")) { - clang(Clang) - } - else if (project.hasProperty("useGcc")) { - gcc(Gcc) - } else { - icc(Icc) - } - } - - flavors { - regamedllNofixes - regamedllFixes - } - - components { - - regamedll_mp_gamedll(NativeLibrarySpec) { - targetPlatform 'x86' - baseName GradleCppUtils.windows ? 'mp' : 'cs' - sources { - RegamedllSrc.regamedll_pch(it) - RegamedllSrc.regamedll_src(it) - } - binaries.all { NativeBinarySpec b -> project.setupToolchain(b) } - } - - regamedll_mp_gamedll_tests(NativeExecutableSpec) { - targetPlatform 'x86' - sources { - RegamedllSrc.regamedll_pch(it) - RegamedllSrc.regamedll_src(it) - - if (project.hasProperty("useGcc")) { - RegamedllSrc.regamedll_tests_gcc_src(it) - } else { - RegamedllSrc.regamedll_tests_src(it) - } - } - - binaries.all { NativeBinarySpec b -> project.setupToolchain(b) } - } - } -} - -task buildFinalize << { - if (GradleCppUtils.windows) { - return; - } - - binaries.withType(SharedLibraryBinarySpec) { - def sharedBinary = it.getSharedLibraryFile(); - if (sharedBinary.exists()) { - sharedBinary.renameTo(new File(sharedBinary.getParent() + "/" + sharedBinary.getName().replaceFirst("^lib", ""))); - } - } -} - -task buildRelease { - dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib -> - blib.buildable && blib.buildType.name == 'release' - } -} - -task buildFixes { - dependsOn binaries.withType(SharedLibraryBinarySpec).matching { - SharedLibraryBinarySpec blib -> blib.buildable && blib.buildType.name == 'release' && blib.flavor.name == 'regamedllFixes' && blib.component.name == 'regamedll_mp_gamedll' - } -} - -task buildDebug { - dependsOn binaries.withType(SharedLibraryBinarySpec).matching { - SharedLibraryBinarySpec blib -> blib.buildable && blib.buildType.name == 'debug' && blib.flavor.name == 'regamedllFixes' && blib.component.name == 'regamedll_mp_gamedll' - } -} - -buildFixes.finalizedBy(buildFinalize); -buildDebug.finalizedBy(buildFinalize); -buildRelease.finalizedBy(buildFinalize); - -gradle.taskGraph.whenReady { graph -> - if (!graph.hasTask(buildFixes) && !graph.hasTask(buildDebug)) { - return; - } - - // skip all tasks with the matched substrings in the name like "test" - def tasks = graph.getAllTasks(); - tasks.findAll { it.name.toLowerCase().contains("test") }.each { task -> - task.enabled = false; - } -} - -task prepareDevEnvTests { - def regamedllTests = new File(project.projectDir, '_dev/testDemos') - - inputs.files configurations.regamedll_tests.files - outputs.dir regamedllTests - - doLast { - regamedllTests.mkdirs() - configurations.regamedll_tests.files.each { File f -> - def t = zipTree(f) - copy { - into new File(regamedllTests, FilenameUtils.getBaseName(f.absolutePath)) - from t - } - } - } -} - -task prepareDevEnvGamedll << { - ['_dev/regamedll', '_dev/regamedll_mp'].each { gamedllDir -> - def regamedllImage = new File(project.projectDir, gamedllDir) - regamedllImage.mkdirs() - def demoRunner = new RegamedllDemoRunner(project.configurations.regamedll_playtest_image.getFiles(), regamedllImage, null) - demoRunner.prepareEngine() - //demoRunner.prepareDemo() - } -} - -task prepareDevEnv { - dependsOn prepareDevEnvGamedll, prepareDevEnvTests -} - -tasks.clean.doLast { - project.file('version/appversion.h').delete() -} - -task generateAppVersion { - - RegamedllVersionInfo verInfo = (RegamedllVersionInfo)rootProject.regamedllVersionInfo - def tplFile = project.file('version/appversion.vm') - def renderedFile = project.file('version/appversion.h') - - // check to up-to-date - inputs.file tplFile - inputs.file project.file('gradle.properties') - outputs.file renderedFile - - // this will ensure that this task is redone when the versions change - inputs.property('version', rootProject.version) - inputs.property('commitDate', verInfo.asCommitDate()) - - println "##teamcity[buildNumber '" + verInfo.asMavenVersion(false) + "']"; - - doLast { - def templateCtx = [ - verInfo: verInfo - ] - - def content = VelocityUtils.renderTemplate(tplFile, templateCtx) - renderedFile.delete() - renderedFile.write(content, 'utf-8') - - println 'The current ReGameDLL maven version is ' + rootProject.version + ', url: (' + verInfo.commitURL + '' + verInfo.commitSHA + ')'; - } -} diff --git a/regamedll/dlls/API/CAPI_Impl.h b/regamedll/dlls/API/CAPI_Impl.h index cd69b345c..d967b5161 100644 --- a/regamedll/dlls/API/CAPI_Impl.h +++ b/regamedll/dlls/API/CAPI_Impl.h @@ -100,11 +100,21 @@ g_ReGameHookchains.m_##functionName.callChain(functionName##_OrigFunc, __VA_ARGS__);\ } +#define LINK_HOOK_VOID_CHAIN2(functionName)\ + void functionName() {\ + g_ReGameHookchains.m_##functionName.callChain(functionName##_OrigFunc);\ + } + #define LINK_HOOK_CHAIN(ret, functionName, args, ...)\ ret functionName args {\ return g_ReGameHookchains.m_##functionName.callChain(functionName##_OrigFunc, __VA_ARGS__);\ } +#define LINK_HOOK_CHAIN2(ret, functionName)\ + ret functionName() {\ + return g_ReGameHookchains.m_##functionName.callChain(functionName##_OrigFunc);\ + } + #define LINK_HOOK_GLOB_CLASS_VOID_CHAIN(className, functionName, args, ...)\ void className::functionName args {\ g_ReGameHookchains.m_##functionName.callChain(className::functionName##_OrigFunc, __VA_ARGS__);\ @@ -120,16 +130,7 @@ return g_ReGameHookchains.m_##customFuncName.callChain(functionName##_OrigFunc, __VA_ARGS__);\ } -#define LINK_HOOK_VOID_CHAIN2(functionName)\ - void functionName() {\ - g_ReGameHookchains.m_##functionName.callChain(functionName##_OrigFunc);\ - } - -#define LINK_HOOK_CHAIN2(ret, functionName)\ - ret functionName() {\ - return g_ReGameHookchains.m_##functionName.callChain(functionName##_OrigFunc);\ - } -#else +#else // REGAMEDLL_API #define __API_HOOK(fname)\ fname @@ -141,14 +142,19 @@ #define LINK_HOOK_CLASS_CHAIN3(...) #define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN(...) #define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2(...) +#define LINK_HOOK_CLASS_VOID_CUSTOM2_CHAIN(...) +#define LINK_HOOK_CLASS_VOID_CUSTOM2_CHAIN2(...) #define LINK_HOOK_CLASS_CUSTOM_CHAIN(...) #define LINK_HOOK_CLASS_CUSTOM_CHAIN2(...) +#define LINK_HOOK_CLASS_CUSTOM2_CHAIN(...) +#define LINK_HOOK_CLASS_CUSTOM2_CHAIN2(...) #define LINK_HOOK_VOID_CHAIN(...) #define LINK_HOOK_VOID_CHAIN2(...) #define LINK_HOOK_CHAIN(...) #define LINK_HOOK_CHAIN2(...) #define LINK_HOOK_GLOB_CLASS_VOID_CHAIN(...) #define LINK_HOOK_GLOB_CLASS_CHAIN(...) +#define LINK_HOOK_CUSTOM2_CHAIN(...) #endif // REGAMEDLL_API diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index f15919269..29cc90c1d 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -10082,13 +10082,13 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetSpawnProtection)(float flProtectionTime { #ifdef REGAMEDLL_ADD if (respawn_immunity_effects.value > 0) -#endif { pev->rendermode = kRenderTransAdd; pev->renderamt = 100.0f; } CSPlayer()->m_flSpawnProtectionEndTime = gpGlobals->time + flProtectionTime; +#endif } LINK_HOOK_CLASS_VOID_CHAIN2(CBasePlayer, RemoveSpawnProtection) @@ -10097,7 +10097,6 @@ void CBasePlayer::__API_HOOK(RemoveSpawnProtection)() { #ifdef REGAMEDLL_ADD if (respawn_immunity_effects.value > 0) -#endif { if (pev->rendermode == kRenderTransAdd && pev->renderamt == 100.0f) @@ -10108,6 +10107,7 @@ void CBasePlayer::__API_HOOK(RemoveSpawnProtection)() } CSPlayer()->m_flSpawnProtectionEndTime = 0.0f; +#endif } LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayer, DropIdlePlayer, (const char *reason), reason) diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp index 1fbdc231c..72c3eeacf 100644 --- a/regamedll/dlls/weapons.cpp +++ b/regamedll/dlls/weapons.cpp @@ -834,8 +834,9 @@ void CBasePlayerWeapon::HandleInfiniteAmmo() { m_iClip = iMaxClip(); } - else if ((nInfiniteAmmo == WPNMODE_INFINITE_BPAMMO && + else if ((nInfiniteAmmo == WPNMODE_INFINITE_BPAMMO #ifdef REGAMEDLL_API + && ((m_pPlayer->CSPlayer()->m_iWeaponInfiniteIds & (1 << m_iId)) || (m_pPlayer->CSPlayer()->m_iWeaponInfiniteIds <= 0 && !IsGrenadeWeapon(m_iId))) #endif ) @@ -1136,6 +1137,7 @@ void CBasePlayerItem::AttachToPlayer(CBasePlayer *pPlayer) void CBasePlayerWeapon::Spawn() { +#ifdef REGAMEDLL_API ItemInfo info; Q_memset(&info, 0, sizeof(info)); @@ -1144,6 +1146,7 @@ void CBasePlayerWeapon::Spawn() } CSPlayerWeapon()->m_bHasSecondaryAttack = HasSecondaryAttack(); +#endif } // CALLED THROUGH the newly-touched weapon's instance. The existing player weapon is pOriginal diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h index 6efc44f23..82257a64d 100644 --- a/regamedll/dlls/weapons.h +++ b/regamedll/dlls/weapons.h @@ -425,7 +425,7 @@ class CBasePlayerWeapon: public CBasePlayerItem int m_iShellId; float m_fMaxSpeed; bool m_bDelayFire; - int m_iDirection; + BOOL m_iDirection; bool m_bSecondarySilencerOn; float m_flAccuracy; float m_flLastFire; diff --git a/regamedll/msvc/PreBuild.bat b/regamedll/msvc/PreBuild.bat index ebb10a879..38dac0442 100644 --- a/regamedll/msvc/PreBuild.bat +++ b/regamedll/msvc/PreBuild.bat @@ -77,14 +77,6 @@ IF EXIST "%srcdir%\version.h" ( IF %%j==VERSION_MAINTENANCE set version_maintenance=%%k ) ) -) ELSE ( - FOR /F "usebackq tokens=1,2,3,* delims==" %%i in ("%repodir%..\gradle.properties") do ( - IF NOT [%%j] == [] ( - IF %%i==majorVersion set version_major=%%j - IF %%i==minorVersion set version_minor=%%j - IF %%i==maintenanceVersion set version_maintenance=%%j - ) - ) ) :: @@ -210,11 +202,5 @@ echo.>>"%srcdir%\appversion.h" echo #endif //__APPVERSION_H__>>"%srcdir%\appversion.h" echo.>>"%srcdir%\appversion.h" -:: -:: Do update of version.cpp file last modify time to force it recompile -:: -copy /b "%srcdir%\version.cpp"+,, "%srcdir%\version.cpp" -endlocal - :_exit exit /B 0 diff --git a/regamedll/msvc/ReGameDLL.vcxproj b/regamedll/msvc/ReGameDLL.vcxproj index 8ff292c80..41eb3d36d 100644 --- a/regamedll/msvc/ReGameDLL.vcxproj +++ b/regamedll/msvc/ReGameDLL.vcxproj @@ -31,10 +31,22 @@ - - - - + + + + + + + + + + + + + + + + @@ -580,7 +592,6 @@ true true - @@ -610,7 +621,10 @@ - + + + + @@ -781,22 +795,6 @@ - - - true - true - true - true - true - - - true - true - true - true - true - - {ceb94f7c-e459-4673-aabb-36e2074396c0} @@ -811,6 +809,7 @@ {70A2B904-B7DB-4C48-8DE0-AF567360D572} ReGameDLL 12.0 + 10.0 @@ -820,7 +819,7 @@ v120 v140 v141 - v142 + v142 DynamicLibrary @@ -829,7 +828,7 @@ v120 v140 v141 - v142 + v142 true @@ -839,7 +838,7 @@ v120 v140 v141 - v142 + v142 true @@ -849,7 +848,7 @@ v120 v140 v141 - v142 + v142 Application @@ -857,7 +856,7 @@ v120_xp v140_xp v141_xp - v142 + v142 MultiByte @@ -906,7 +905,7 @@ - filesystem_stdio + mp AllRules.ruleset @@ -921,7 +920,7 @@ Level3 Disabled true - REGAMEDLL_ADD;REGAMEDLL_API;REGAMEDLL_SSE;REGAMEDLL_FIXES;REGAMEDLL_SELF;BUILD_LATEST;BUILD_LATEST_FIXES;UNICODE_FIXES;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;USE_QSTRING;DEDICATED;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REGAMEDLL_ADD;REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SSE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;UNICODE_FIXES;BUILD_LATEST;BUILD_LATEST_FIXES;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Fast /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -957,7 +956,7 @@ Level3 Full true - REGAMEDLL_ADD;REGAMEDLL_SSE;REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SELF;REGAMEDLL_CHECKS;BUILD_LATEST;BUILD_LATEST_FIXES;UNICODE_FIXES;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;USE_QSTRING;DEDICATED;_CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions) + REGAMEDLL_ADD;REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SSE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;UNICODE_FIXES;BUILD_LATEST;BUILD_LATEST_FIXES;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions) Fast /arch:IA32 %(AdditionalOptions) MultiThreaded @@ -1002,7 +1001,7 @@ Level3 Full true - PLAY_GAMEDLL;REGAMEDLL_SELF;REGAMEDLL_API;REGAMEDLL_SSE;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;USE_QSTRING;DEDICATED;_CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions) + PLAY_GAMEDLL;REGAMEDLL_SELF;REGAMEDLL_CHECKS;REGAMEDLL_API;REGAMEDLL_SSE;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreaded @@ -1047,7 +1046,7 @@ Level3 Disabled true - PLAY_GAMEDLL;REGAMEDLL_SELF;REGAMEDLL_CHECKS;REGAMEDLL_API;REGAMEDLL_SSE;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;USE_QSTRING;DEDICATED;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + PLAY_GAMEDLL;REGAMEDLL_SSE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;REGAMEDLL_API;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -1083,7 +1082,7 @@ Level3 Disabled true - REGAMEDLL_FIXES;REGAMEDLL_SELF;UNICODE_FIXES;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SELF;REGAMEDLL_SSE;UNICODE_FIXES;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) MultiThreadedDebug Use precompiled.h diff --git a/regamedll/msvc/ReGameDLL.vcxproj.filters b/regamedll/msvc/ReGameDLL.vcxproj.filters index 900ba66cc..d8c27981d 100644 --- a/regamedll/msvc/ReGameDLL.vcxproj.filters +++ b/regamedll/msvc/ReGameDLL.vcxproj.filters @@ -10,10 +10,6 @@ {fe7a8e81-b7d4-4540-ab5b-457ed93672ce} - - {9de0de20-070f-4fae-a9df-3dca942e65a7} - false - {d74cb79e-afd5-4215-af0e-029e38925be0} @@ -76,9 +72,6 @@ - - version - regamedll @@ -1057,12 +1050,4 @@ dlls\addons - - - linux - - - linux - - \ No newline at end of file diff --git a/regamedll/unittests/TestRunner.cpp b/regamedll/unittests/TestRunner.cpp index e02dd5e5c..5964144b9 100644 --- a/regamedll/unittests/TestRunner.cpp +++ b/regamedll/unittests/TestRunner.cpp @@ -1,16 +1,10 @@ #include "precompiled.h" -#include "cppunitlite/GradleAdapter.h" +#include "cppunitlite/MainAdapter.h" int main(int argc, char *argv[]) { printf("TestRunner: main()\n"); - GradleAdapter a; - int res = a.testsEntryPoint(argc, argv); - -#ifdef _BUILD_FROM_IDE - system("PAUSE"); -#endif - - return res; + MainAdapter a; + return a.testsEntryPoint(argc, argv); } diff --git a/regamedll/version/appversion.sh b/regamedll/version/appversion.sh index 553e3311a..68c35862f 100755 --- a/regamedll/version/appversion.sh +++ b/regamedll/version/appversion.sh @@ -3,9 +3,9 @@ init() { SOURCE_DIR="$@" - GIT_DIR="$SOURCE_DIR/.." - VERSION_FILE="$GIT_DIR/gradle.properties" - APPVERSION_FILE="$SOURCE_DIR/version/appversion.h" + GIT_DIR=$SOURCE_DIR + VERSION_FILE=$SOURCE_DIR/regamedll/version/version.h + APPVERSION_FILE=$SOURCE_DIR/regamedll/version/appversion.h if test -z "`git --version`"; then echo "Please install git client" @@ -25,17 +25,17 @@ init() fi # Get major, minor and maintenance information from gradle.properties - MAJOR=$(sed -nr -e '/majorVersion/ s/.*\= *//p' "$VERSION_FILE" | tr -d '\n\r') + MAJOR=$(cat "$VERSION_FILE" | grep -wi 'VERSION_MAJOR' | sed -e 's/.*VERSION_MAJOR.*[^0-9]\([0-9][0-9]*\).*/\1/i' -e 's/\r//g') if [ $? -ne 0 -o "$MAJOR" = "" ]; then MAJOR=0 fi - MINOR=$(sed -nr -e '/minorVersion/ s/.*\= *//p' "$VERSION_FILE" | tr -d '\n\r') + MINOR=$(cat "$VERSION_FILE" | grep -wi 'VERSION_MINOR' | sed -e 's/.*VERSION_MINOR.*[^0-9]\([0-9][0-9]*\).*/\1/i' -e 's/\r//g') if [ $? -ne 0 -o "$MINOR" = "" ]; then MINOR=0 fi - MAINTENANCE=$(sed -nr -e '/maintenanceVersion/ s/.*\= *//p' "$VERSION_FILE" | tr -d '\n\r') + MAINTENANCE=$(cat "$VERSION_FILE" | grep -i 'VERSION_MAINTENANCE' | sed -e 's/.*VERSION_MAINTENANCE.*[^0-9]\([0-9][0-9]*\).*/\1/i' -e 's/\r//g') if [ $? -ne 0 -o "$MAINTENANCE" = "" ]; then MAINTENANCE=0 fi @@ -66,20 +66,37 @@ init() # Get remote url COMMIT_URL=$(git -C "$GIT_DIR/" config remote.$BRANCH_REMOTE.url) - # Strip prefix 'git@' - COMMIT_URL=${COMMIT_URL#git@} + URL_CONSTRUCT=0 - # Strip postfix '.git' - COMMIT_URL=${COMMIT_URL%.git} + if [[ "$COMMIT_URL" == *"git@"* ]]; then + URL_CONSTRUCT=1 - # Replace ':' to '/' - COMMIT_URL=${COMMIT_URL/:/\/} + # Strip prefix 'git@' + COMMIT_URL=${COMMIT_URL#git@} - # Append extra string - if [ $? -ne 0 -o "$COMMIT_URL" = "${COMMIT_URL/bitbucket.org}" ]; then - COMMIT_URL=$(echo https://$COMMIT_URL/commits/) - else - COMMIT_URL=$(echo https://$COMMIT_URL/commit/) + # Strip postfix '.git' + COMMIT_URL=${COMMIT_URL%.git} + + # Replace ':' to '/' + COMMIT_URL=${COMMIT_URL/:/\/} + + elif [[ "$COMMIT_URL" == *"https://"* ]]; then + URL_CONSTRUCT=1 + + # Strip prefix 'https://' + COMMIT_URL=${COMMIT_URL#https://} + + # Strip postfix '.git' + COMMIT_URL=${COMMIT_URL%.git} + fi + + if test "$URL_CONSTRUCT" -eq 1; then + # Append extra string + if [[ "$COMMIT_URL" == *"bitbucket.org"* ]]; then + COMMIT_URL=$(echo https://$COMMIT_URL/commits/) + else + COMMIT_URL=$(echo https://$COMMIT_URL/commit/) + fi fi # @@ -101,7 +118,7 @@ init() update_appversion() { - day=$(date +%m) + day=$(date +%d) year=$(date +%Y) hours=$(date +%H:%M:%S) month=$(LANG=en_us_88591; date +"%b") diff --git a/regamedll/version/appversion.vm b/regamedll/version/appversion.vm deleted file mode 100644 index 486e5d923..000000000 --- a/regamedll/version/appversion.vm +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __APPVERSION_H__ -\#define __APPVERSION_H__ - -// -// This file is generated automatically. -// Don't edit it. -// - -// Version defines -\#define APP_VERSION "$verInfo.asMavenVersion()" - -\#define APP_COMMIT_DATE "$verInfo.asCommitDate()" -\#define APP_COMMIT_TIME "$verInfo.asCommitTime()" - -\#define APP_COMMIT_SHA "$verInfo.commitSHA" -\#define APP_COMMIT_URL "$verInfo.commitURL" - -#endif //__APPVERSION_H__ diff --git a/regamedll/version/version.cpp b/regamedll/version/version.cpp deleted file mode 100644 index 5089a5f3e..000000000 --- a/regamedll/version/version.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* -* Version declaration dependency file -* -*/ - -// -// This file needed just to add the dependency and appversion.h -// -#include "precompiled.h" - diff --git a/regamedll/version/version.h b/regamedll/version/version.h new file mode 100644 index 000000000..8d97dcbf4 --- /dev/null +++ b/regamedll/version/version.h @@ -0,0 +1,10 @@ +/* +* Version declaration dependency file +* +*/ + +#pragma once + +#define VERSION_MAJOR 5 +#define VERSION_MINOR 20 +#define VERSION_MAINTENANCE 0 diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 84f53582e..000000000 --- a/settings.gradle +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = 'regamedll' -include 'dep/cppunitlite' -include 'regamedll' diff --git a/shared.gradle b/shared.gradle deleted file mode 100644 index 47ed31b10..000000000 --- a/shared.gradle +++ /dev/null @@ -1,54 +0,0 @@ -import org.doomedsociety.gradlecpp.cfg.BinaryKind -import org.doomedsociety.gradlecpp.toolchain.icc.Icc -import org.gradle.nativeplatform.NativeBinarySpec -import org.gradle.nativeplatform.NativeExecutableBinarySpec -import org.gradle.nativeplatform.SharedLibraryBinarySpec -import org.gradle.nativeplatform.StaticLibraryBinarySpec -import org.gradle.nativeplatform.toolchain.VisualCpp - -apply from: 'shared_msvc.gradle' -apply from: 'shared_icc.gradle' -apply from: 'shared_clang.gradle' -apply from: 'shared_gcc.gradle' - -rootProject.ext.createToolchainConfig = { NativeBinarySpec bin -> - BinaryKind binaryKind - if (bin instanceof NativeExecutableBinarySpec) - { - binaryKind = BinaryKind.EXECUTABLE - } - else if (bin instanceof SharedLibraryBinarySpec) - { - binaryKind = BinaryKind.SHARED_LIBRARY - } - else if (bin instanceof StaticLibraryBinarySpec) - { - binaryKind = BinaryKind.STATIC_LIBRARY - } - else - { - throw new RuntimeException("Unknown executable kind ${bin.class.name}") - } - - boolean releaseBuild = bin.buildType.name.toLowerCase() == 'release' - if (bin.toolChain instanceof VisualCpp) - { - return rootProject.createMsvcConfig(releaseBuild, binaryKind) - } - else if (bin.toolChain instanceof Icc) - { - return rootProject.createIccConfig(releaseBuild, binaryKind) - } - else if (bin.toolChain instanceof Clang) - { - return rootProject.createClangConfig(releaseBuild, binaryKind) - } - else if (bin.toolChain instanceof Gcc) - { - return rootProject.createGccConfig(releaseBuild, binaryKind) - } - else - { - throw new RuntimeException("Unknown native toolchain: ${bin.toolChain.class.name}") - } -} diff --git a/shared_clang.gradle b/shared_clang.gradle deleted file mode 100644 index 9891ea246..000000000 --- a/shared_clang.gradle +++ /dev/null @@ -1,55 +0,0 @@ -import org.doomedsociety.gradlecpp.cfg.BinaryKind -import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig -import org.doomedsociety.gradlecpp.gcc.OptimizationLevel - -rootProject.ext.createClangConfig = { boolean release, BinaryKind binKind -> - GccToolchainConfig cfg - if (release) { - cfg = new GccToolchainConfig( - compilerOptions: new GccToolchainConfig.CompilerOptions( - optimizationLevel: OptimizationLevel.LEVEL_3, - stackProtector: false, - noBuiltIn: true, - positionIndependentCode: false, - extraDefines: [ - '_GLIBCXX_USE_CXX11_ABI': 0, - ] - ), - - linkerOptions: new GccToolchainConfig.LinkerOptions( - stripSymbolTable: false, - staticLibGcc: false, - staticLibStdCpp: false, - ), - - librarianOptions: new GccToolchainConfig.LibrarianOptions( - - ) - ) - } else { - // debug - cfg = new GccToolchainConfig( - compilerOptions: new GccToolchainConfig.CompilerOptions( - optimizationLevel: OptimizationLevel.DISABLE, - stackProtector: true, - noBuiltIn: true, - extraDefines: [ - '_GLIBCXX_USE_CXX11_ABI': 0, - ] - ), - - linkerOptions: new GccToolchainConfig.LinkerOptions( - stripSymbolTable: false, - staticLibGcc: false, - staticLibStdCpp: false, - ), - - librarianOptions: new GccToolchainConfig.LibrarianOptions( - - ) - ) - } - - cfg.singleDefines('LINUX', '_LINUX') - return cfg -} diff --git a/shared_gcc.gradle b/shared_gcc.gradle deleted file mode 100644 index 0240e4018..000000000 --- a/shared_gcc.gradle +++ /dev/null @@ -1,55 +0,0 @@ -import org.doomedsociety.gradlecpp.cfg.BinaryKind -import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig -import org.doomedsociety.gradlecpp.gcc.OptimizationLevel - -rootProject.ext.createGccConfig = { boolean release, BinaryKind binKind -> - GccToolchainConfig cfg - if (release) { - cfg = new GccToolchainConfig( - compilerOptions: new GccToolchainConfig.CompilerOptions( - optimizationLevel: OptimizationLevel.LEVEL_3, - stackProtector: false, - noBuiltIn: true, - positionIndependentCode: false, - extraDefines: [ - '_GLIBCXX_USE_CXX11_ABI': 0, - ] - ), - - linkerOptions: new GccToolchainConfig.LinkerOptions( - stripSymbolTable: false, - staticLibGcc: false, - staticLibStdCpp: false, - ), - - librarianOptions: new GccToolchainConfig.LibrarianOptions( - - ) - ) - } else { - // debug - cfg = new GccToolchainConfig( - compilerOptions: new GccToolchainConfig.CompilerOptions( - optimizationLevel: OptimizationLevel.DISABLE, - stackProtector: true, - noBuiltIn: true, - extraDefines: [ - '_GLIBCXX_USE_CXX11_ABI': 0, - ] - ), - - linkerOptions: new GccToolchainConfig.LinkerOptions( - stripSymbolTable: false, - staticLibGcc: false, - staticLibStdCpp: false, - ), - - librarianOptions: new GccToolchainConfig.LibrarianOptions( - - ) - ) - } - - cfg.singleDefines('LINUX', '_LINUX') - return cfg -} diff --git a/shared_icc.gradle b/shared_icc.gradle deleted file mode 100644 index c1baf3e1a..000000000 --- a/shared_icc.gradle +++ /dev/null @@ -1,66 +0,0 @@ -import org.doomedsociety.gradlecpp.cfg.BinaryKind -import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig -import org.doomedsociety.gradlecpp.gcc.OptimizationLevel - -rootProject.ext.createIccConfig = { boolean release, BinaryKind binKind -> - GccToolchainConfig cfg - if (release) { - cfg = new GccToolchainConfig( - compilerOptions: new GccToolchainConfig.CompilerOptions( - optimizationLevel: OptimizationLevel.LEVEL_3, - stackProtector: false, - interProceduralOptimizations: true, // -ipo - - noBuiltIn: true, - - intelExtensions: false, - asmBlocks: true, - - positionIndependentCode: false, - - extraDefines: [ - '_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6 - ] - ), - linkerOptions: new GccToolchainConfig.LinkerOptions( - interProceduralOptimizations: true, // -ipo - stripSymbolTable: true, - staticLibStdCpp: false, - staticLibGcc: false, - staticIntel: true, - ), - librarianOptions: new GccToolchainConfig.LibrarianOptions( - ) - ) - } else { - // debug - cfg = new GccToolchainConfig( - compilerOptions: new GccToolchainConfig.CompilerOptions( - optimizationLevel: OptimizationLevel.DISABLE, - stackProtector: true, - interProceduralOptimizations: false, - - noBuiltIn: true, - intelExtensions: false, - asmBlocks: true, - - extraDefines: [ - '_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6 - ] - ), - linkerOptions: new GccToolchainConfig.LinkerOptions( - interProceduralOptimizations: false, - stripSymbolTable: false, - staticLibStdCpp: false, - staticLibGcc: false, - staticIntel: true, - ), - librarianOptions: new GccToolchainConfig.LibrarianOptions( - ) - ) - } - - cfg.singleDefines('REGAMEDLL_SSE') - cfg.singleDefines('LINUX', '_LINUX') - return cfg -} diff --git a/shared_msvc.gradle b/shared_msvc.gradle deleted file mode 100644 index b3275bf49..000000000 --- a/shared_msvc.gradle +++ /dev/null @@ -1,135 +0,0 @@ -import org.doomedsociety.gradlecpp.cfg.BinaryKind -import org.doomedsociety.gradlecpp.msvc.CallingConvention -import org.doomedsociety.gradlecpp.msvc.CodeGenerationKind -import org.doomedsociety.gradlecpp.msvc.CppExceptions -import org.doomedsociety.gradlecpp.msvc.DebugInfoFormat -import org.doomedsociety.gradlecpp.msvc.EnhancedInstructionsSet -import org.doomedsociety.gradlecpp.msvc.ErrorReporting -import org.doomedsociety.gradlecpp.msvc.FloatingPointModel -import org.doomedsociety.gradlecpp.msvc.LinkTimeCodeGenKind -import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig -import org.doomedsociety.gradlecpp.msvc.OptimizationLevel -import org.doomedsociety.gradlecpp.msvc.RuntimeChecks -import org.doomedsociety.gradlecpp.msvc.WarningLevel - -rootProject.ext.createMsvcConfig = { boolean release, BinaryKind binKind -> - MsvcToolchainConfig cfg - if (release) { - cfg = new MsvcToolchainConfig( - compilerOptions: new MsvcToolchainConfig.CompilerOptions( - codeGeneration: CodeGenerationKind.MULTITHREADED, - optimizationLevel: OptimizationLevel.FULL_OPTIMIZATION, - debugInfoFormat: DebugInfoFormat.PROGRAM_DATABASE, - runtimeChecks: RuntimeChecks.DEFAULT, - cppExceptions: CppExceptions.ENABLED_WITH_SEH, - warningLevel: WarningLevel.LEVEL_3, - callingConvention: CallingConvention.CDECL, - enhancedInstructionsSet: EnhancedInstructionsSet.SSE2, - floatingPointModel: FloatingPointModel.FAST, - - enableMinimalRebuild: false, - omitFramePointers: false, - wholeProgramOptimization: true, - enabledFunctionLevelLinking: true, - enableSecurityCheck: true, - analyzeCode: false, - sdlChecks: false, - treatWarningsAsErrors: false, - treatWchartAsBuiltin: true, - forceConformanceInForLoopScope: true, - - extraDefines: [ - 'WIN32': null, - '_MBCS': null, - 'NDEBUG': null, - ] - ), - linkerOptions: new MsvcToolchainConfig.LinkerOptions( - linkTimeCodeGenKind: LinkTimeCodeGenKind.USE_LTCG, - errorReportingMode: ErrorReporting.NO_ERROR_REPORT, - - enableIncrementalLinking: false, - eliminateUnusedRefs: true, - enableCOMDATFolding: true, - generateDebugInfo: true, - dataExecutionPrevention: true, - randomizedBaseAddress: true, - ), - librarianOptions: new MsvcToolchainConfig.LibrarianOptions( - linkTimeCodeGenKind: LinkTimeCodeGenKind.USE_LTCG - ), - generatePdb: true - ) - } else { - // debug - cfg = new MsvcToolchainConfig( - compilerOptions: new MsvcToolchainConfig.CompilerOptions( - codeGeneration: CodeGenerationKind.MULTITHREADED_DEBUG, - optimizationLevel: OptimizationLevel.DISABLED, - debugInfoFormat: DebugInfoFormat.PROGRAM_DATABASE, - runtimeChecks: RuntimeChecks.DEFAULT, - cppExceptions: CppExceptions.ENABLED_WITH_SEH, - warningLevel: WarningLevel.LEVEL_3, - callingConvention: CallingConvention.CDECL, - enhancedInstructionsSet: EnhancedInstructionsSet.SSE2, - floatingPointModel: FloatingPointModel.FAST, - - enableMinimalRebuild: true, - omitFramePointers: false, - wholeProgramOptimization: false, - enabledFunctionLevelLinking: true, - enableSecurityCheck: true, - analyzeCode: false, - sdlChecks: false, - treatWarningsAsErrors: false, - treatWchartAsBuiltin: true, - forceConformanceInForLoopScope: true, - - extraDefines: [ - 'WIN32': null, - '_MBCS': null, - '_DEBUG': null, - ] - ), - linkerOptions: new MsvcToolchainConfig.LinkerOptions( - linkTimeCodeGenKind: LinkTimeCodeGenKind.DEFAULT, - errorReportingMode: ErrorReporting.NO_ERROR_REPORT, - - enableIncrementalLinking: true, - eliminateUnusedRefs: false, - enableCOMDATFolding: false, - generateDebugInfo: true, - dataExecutionPrevention: true, - randomizedBaseAddress: true - ), - librarianOptions: new MsvcToolchainConfig.LibrarianOptions( - linkTimeCodeGenKind: LinkTimeCodeGenKind.USE_LTCG - ), - generatePdb: true - ) - - if (binKind == BinaryKind.STATIC_LIBRARY) { - cfg.compilerConfig.extraDefines['_LIB'] = null - } - } - - // Detect and setup UCRT paths - def ucrtInfo = "getucrtinfo.bat".execute().text - def m = ucrtInfo =~ /^(.*)\r\n(.*)?$/ - if (!m.find()) { - return cfg - } - - def kitPath = m.group(1) - def ucrtVersion = m.group(2) - def ucrtCheckFile = new File("${kitPath}Include/${ucrtVersion}/ucrt/stdio.h"); - if (!ucrtCheckFile.exists()) { - return cfg - } - - cfg.compilerOptions.args "/FS", "/I${kitPath}Include/${ucrtVersion}/ucrt"; - cfg.linkerOptions.args("/LIBPATH:${kitPath}Lib/${ucrtVersion}/ucrt/x86"); - cfg.singleDefines('REGAMEDLL_SSE') - - return cfg -}