Skip to content

Instantly share code, notes, and snippets.

@hach-que
Last active June 29, 2024 11:40
Show Gist options
  • Save hach-que/4ec1f2a12d131d45e730de91b1c30ff4 to your computer and use it in GitHub Desktop.
Save hach-que/4ec1f2a12d131d45e730de91b1c30ff4 to your computer and use it in GitHub Desktop.
A PowerShell script that can insert and sync file IDs into namespacing macros
#
# This script updates plugin code to apply some pre-build transformations.
#
param()
$ErrorActionPreference = "Stop"
$FileNsIdRegex = [regex]"REDPOINT_EOS_FILE_NS_ID\((\s*)([`$A-Za-z0-9_:/]+)(\s*,\s*)([A-Za-z0-9_:]+)(\s*)\)"
$FileNsExportRegex = [regex]"REDPOINT_EOS_FILE_NS_EXPORT\((\s*)([`$A-Za-z0-9_:/]+)(\s*,\s*)([A-Za-z0-9_:]+)(\s*,\s*)([A-Za-z0-9_:]+)(\s*)\)"
$FileNsForwardDeclRegex = [regex]"REDPOINT_EOS_FILE_NS_FORWARD_DECLARE_CLASS\((\s*)([`$A-Za-z0-9_:/]+)(\s*,\s*)([A-Za-z0-9_:]+)(\s*,\s*)([A-Za-z0-9_:]+)(\s*)\)"
$AllDeclarations = @{}
function Process-File-Pass1($Path) {
try {
if ((Get-Item $Path).Name -eq "BuildEnvironment.h") {
# Skip file which defines these macros.
return 0
}
$RawContent = (Get-Content -Path $Path -Raw)
if ($RawContent -eq $null) {
# Skip file if we can't get the content.
return 0
}
if (!$RawContent.Contains("REDPOINT_EOS_FILE_NS_ID") -and
!$RawContent.Contains("REDPOINT_EOS_FILE_NS_EXPORT")) {
# Skip this file if it isn't using file namespaces.
return 0
}
# Compute file ID.
$NestedPath = $Path.Substring((Get-Item "$PSScriptRoot\..\Source").FullName.Length + 1)
$NestedPath = $NestedPath.Substring(0, $NestedPath.Length - [System.IO.Path]::GetExtension($Path).Length)
$NestedPath = $NestedPath.Replace('\', '/')
$NestedPath = $NestedPath.Replace("/Public/", "/Hashed/").Replace("/Private/", "/Hashed/")
$NestedPathBytes = [System.Text.Encoding]::UTF8.GetBytes($NestedPath)
$Sha1 = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider
$Sha1ShortHash = ($Sha1.ComputeHash($NestedPathBytes) | Select-Object -First 4)
$ResultHash = [BitConverter]::ToUInt32($Sha1ShortHash, 0).ToString()
$Components = $NestedPath.Split('/')
# Process export identifiers.
$OriginalRawContent = $RawContent
$RawContent = $FileNsIdRegex.Replace($RawContent, "REDPOINT_EOS_FILE_NS_ID(`${1}${ResultHash}`$3`$4`$5)")
$RawContent = $FileNsExportRegex.Replace($RawContent, "REDPOINT_EOS_FILE_NS_EXPORT(`${1}${ResultHash}`$3`$4`$5`$6`$7)")
# Record exports.
foreach ($Match in $FileNsExportRegex.Matches($RawContent)) {
$AllDeclarations["$($Match.Groups[4].Value)::$($Match.Groups[6].Value)"] = "${ResultHash}"
}
# Update the file if the content needs to change.
if ($RawContent -ne $OriginalRawContent) {
Write-Host "Syncing file IDs: $Path"
Set-Content -Value ($RawContent.TrimEnd()) -Path $Path
}
return 0
} catch {
Write-Host $_
return 1
}
}
function Process-File-Pass2($Path) {
try {
if ((Get-Item $Path).Name -eq "BuildEnvironment.h") {
# Skip file which defines these macros.
return 0
}
$RawContent = (Get-Content -Path $Path -Raw)
if ($RawContent -eq $null) {
# Skip file if we can't get the content.
return 0
}
if (!$RawContent.Contains("REDPOINT_EOS_FILE_NS_FORWARD_DECLARE_CLASS")) {
# Skip this file if it isn't using forward declarations.
return 0
}
# Iterate through forward declarations and update their file IDs.
$OriginalRawContent = $RawContent
$RawContent = $FileNsForwardDeclRegex.Replace($RawContent, {
$_1 = $($args[0].Groups[1].Value)
$_3 = $($args[0].Groups[3].Value)
$_4 = $($args[0].Groups[4].Value)
$_5 = $($args[0].Groups[5].Value)
$_6 = $($args[0].Groups[6].Value)
$_7 = $($args[0].Groups[7].Value)
$Target = "$_4::$_6"
$FileId = $AllDeclarations[$Target]
return "REDPOINT_EOS_FILE_NS_FORWARD_DECLARE_CLASS(${_1}$FileId${_3}${_4}${_5}${_6}${_7})"
})
# Update the file if the content needs to change.
if ($RawContent -ne $OriginalRawContent) {
Write-Host "Syncing forward declarations: $Path"
Set-Content -Value ($RawContent.TrimEnd()) -Path $Path
}
return 0
} catch {
Write-Host $_
return 1
}
}
$RootPath = "$PSScriptRoot\..\Source"
$SourceFiles = (Get-ChildItem -Recurse -Path $RootPath -Filter *.cpp)
$HeaderFiles = (Get-ChildItem -Recurse -Path $RootPath -Filter *.h)
# Go through and sync file IDs on the declaration and export side.
foreach ($File in $SourceFiles) {
$Result = (Process-File-Pass1 -Path ($File.FullName))
if ($Result -ne 0) {
exit $Result
}
}
foreach ($File in $HeaderFiles) {
$Result = (Process-File-Pass1 -Path ($File.FullName))
if ($Result -ne 0) {
exit $Result
}
}
# Go through and sync forward declarations now that we've collected all exports.
foreach ($File in $SourceFiles) {
$Result = (Process-File-Pass2 -Path ($File.FullName))
if ($Result -ne 0) {
exit $Result
}
}
foreach ($File in $HeaderFiles) {
$Result = (Process-File-Pass2 -Path ($File.FullName))
if ($Result -ne 0) {
exit $Result
}
}
exit 0
// Macro definitions
#define REDPOINT_EOS_FILE_NS_ID(FileId, Ns) __File##FileId##_##Ns
#define REDPOINT_EOS_FILE_NS_EXPORT(FileId, Ns, Export) using __File##FileId##_##Ns::Export;
#define REDPOINT_EOS_FILE_NS_FORWARD_DECLARE_CLASS(FileId, Ns, Export) \
namespace __File##FileId##_##Ns \
{ \
class Export; \
} \
namespace Ns \
{ \
using __File##FileId##_##Ns::Export; \
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment