Skip to content

Instantly share code, notes, and snippets.

@urasandesu
Created January 4, 2014 06:53
Show Gist options
  • Save urasandesu/8252521 to your computer and use it in GitHub Desktop.
Save urasandesu/8252521 to your computer and use it in GitHub Desktop.
# +実行には、事前に PSAnonym(https://github.com/urasandesu/PSAnonym) のインストールが必要。
# +また、PSAnonym は PowerShell v2 でしか動作しないため、このコード片を実行するには、
# PS C:\> powershell -version 2
# する等して、プロンプトの実行環境を合わせてやる必要がある。
Import-Module Urasandesu.PSAnonym
# -----------------------------------------------------------------------------------------------
#
# テンプレートエンジンを構成するプロトタイプ群
#
# -----------------------------------------------------------------------------------------------
# ファイルを表すプロトタイプ
$File =
Prototype File {
# 設定値
Field Properties ([String[]].Default)
# コンストラクタ
New {
$Me.Properties = $Params
}
# 相対パス
Property Path {
$result = $Me.FullNames -join '/'
$result + ($Me.Remains -join '')
}
# 完全修飾名
Property FullName {
$Me.SkipEmptySymbol($Me.Properties[0..3]) -join '::'
}
# 型名
Property Name {
$Me.Properties[3]
}
# プロトタイプ名
Property PrototypeName {
$Me.GetPrototypeName($Me.Properties)
}
# 参照時のエイリアス名
Property Alias {
$Me.Name + $Me.PrototypeName
}
# 名前空間の要素
Property Namespaces {
$Me.SkipEmptySymbol($Me.Properties[0..2])
}
# 完全修飾名の要素
Property FullNames {
$Me.SkipEmptySymbol($Me.Properties[0..3])
}
# 残りの要素(サフィックス + 拡張し)
Property Remains {
$Me.SkipEmptySymbol($Me.Properties[4..($Me.Properties.Length - 1)])
}
# 拡張子
Property Extension {
$Me.Properties[-1]
}
# 設定値からプロトタイプ名を取得
Method GetPrototypeName {
$properties = $Me.EraseEmptySymbol($Params)
$properties[-1] = $properties[-1] -replace '\.', ''
$properties[-2] + $properties[-1]
}
# 設定値から空記号を消去
Method EraseEmptySymbol {
foreach ($property in $Params) {
$property -replace '/', ''
}
} -Hidden
# 設定値から空記号を除外
Method SkipEmptySymbol {
foreach ($property in $Params) {
if ('/' -ne $property) {
$property
}
}
} -Hidden
}
# ヘッダーファイルを表すプロトタイプ
$HeaderFile =
$File |
Prototype HeaderFile {
# インクルードガード
Property IncludeGuard {
$result = $Me.ToIncludeGuardElems($Me.FullNames) -join '_'
$result + ($Me.ToIncludeGuardElems($Me.Remains) -join '')
}
# 要素をインクルードガード用に変換
Method ToIncludeGuardElems {
foreach ($param in $Params) {
$param = $param -replace '\.', '_'
$param.ToUpper()
}
} -Hidden
}
# ヘッダーファイルの内、前方宣言を行うファイルを表すプロトタイプ
$Fwdh = $HeaderFile | Prototype Fwdh
# ヘッダーファイルの内、型の定義を行うファイルを表すプロトタイプ
$h = $HeaderFile | Prototype h
# ソースファイル(コンパイル単位)を表すプロトタイプ
$cpp = $File | Prototype cpp
# 自動生成可能なことを表すプロトタイプ
$AutoGen =
Prototype AutoGen {
# 依存するヘッダー
Field DependentHeaders ([Object[]].Default)
Property FormattedDependency {
if ($null -ne $Me.DependentHeaders) {
$Me.DependentHeaders | % { @"
#ifndef $($_.IncludeGuard)
#include <$($_.Path)>
#endif
"@ }
}
}
# テンプレート
AbstractProperty Template -Getter
# 出力処理
Method Generate {
param (
[string]
$OutputPath
)
$outputDir = Split-Path $OutputPath -Parent
New-Item $outputDir -ItemType Directory -Force | Out-Null
Set-Content $OutputPath $Me.Template -Encoding UTF8
}
}
# 自動生成されるヘッダーファイルの内、前方宣言を行うファイルを表すプロトタイプ
$AutoGenFwdh =
$HeaderFile, $AutoGen |
Prototype AutoGenFwdh {
OverrideProperty Template {
@"
#pragma once
#ifndef $($Me.IncludeGuard)
#define $($Me.IncludeGuard)
$($Me.FormattedDependency)
namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Namespaces[2]) {
class $($Me.Name);
}}} // namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Namespaces[2]) {
#endif // $($Me.IncludeGuard)
"@
}
}
# 自動生成されるヘッダーファイルの内、型の定義を行うファイルを表すプロトタイプ
$AutoGenh =
$HeaderFile, $AutoGen |
Prototype AutoGenh {
OverrideProperty Template {
@"
#pragma once
#ifndef $($Me.IncludeGuard)
#define $($Me.IncludeGuard)
$($Me.FormattedDependency)
namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Namespaces[2]) {
class $($Me.Name)
{
public:
$($Me.Name)();
~$($Me.Name)();
};
}}} // namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Namespaces[2]) {
#endif // $($Me.IncludeGuard)
"@
}
}
# 自動生成されるソースファイル(コンパイル単位)を表すプロトタイプ
$AutoGencpp =
$File, $AutoGen |
Prototype AutoGencpp {
OverrideProperty Template {
@"
#include "stdafx.h"
$($Me.FormattedDependency)
namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Namespaces[2]) {
$($Me.Name)::$($Me.Name)()
{
}
~$($Me.Name)::$($Me.Name)()
{
}
}}} // namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Namespaces[2]) {
"@
}
}
# -----------------------------------------------------------------------------------------------
#
# テンプレートエンジン設定情報記述のための関数群
#
# -----------------------------------------------------------------------------------------------
# 設定値を保存するハッシュテーブル
New-Variable Records @{ } -Option ReadOnly -Force
# 共通に使われるヘッダのインポートを宣言するための関数
function New-ImportCommon {
[CmdletBinding()]
param (
[parameter(Mandatory = $true, ValueFromRemainingArguments = $true)]
[String[]]
$Properties
)
$prototypeName = $File.GetPrototypeName($Properties)
$common = Invoke-Expression ('${0}.New($Properties)' -f $prototypeName)
$Records[$common.Alias] = $common
}
New-Alias Import New-ImportCommon -Force
# 生成するファイルの定義を宣言するための関数
function New-Declaration {
[CmdletBinding()]
param (
[parameter(Mandatory = $true, ValueFromRemainingArguments = $true)]
[String[]]
$Properties
)
$prototypeName = $File.GetPrototypeName($Properties)
$declaration = Invoke-Expression ('$AutoGen{0}.New($Properties)' -f $prototypeName)
$Records[$declaration.Alias] = $declaration
}
New-Alias Declare New-Declaration -Force
# 依存関係の定義を宣言するための関数
function New-Dependency {
[CmdletBinding()]
param (
[parameter(Mandatory = $true, Position = 0)]
[String]
$TargetAlias,
[parameter(ValueFromRemainingArguments = $true)]
[String[]]
$Aliases
)
if ($null -ne $Aliases) {
$Records[$TargetAlias].DependentHeaders = @(foreach ($alias in $Aliases) { $Records[$alias] })
}
}
New-Alias DependsOn New-Dependency -Force
# -----------------------------------------------------------------------------------------------
#
# テンプレートエンジンへの設定情報(共通のヘッダ、生成するファイルの宣言、依存関係の定義)
#
# -----------------------------------------------------------------------------------------------
# 共通に使われるヘッダの宣言
Import Urasandesu CppAnonym / SimpleHeapProvider / .h
Import Urasandesu CppAnonym / SmartHeapProvider / .h
Import Urasandesu CppAnonym / PersistableHeapProvider / .h
Import Urasandesu CppAnonym / DisposableHeapProvider / .h
Import Urasandesu CppAnonym / EmptyHeapProvider / .h
# 生成するファイルの宣言
Declare Urasandesu Swathe Hosting HostInfo Fwd .h
Declare Urasandesu Swathe Hosting HostInfo / .h
Declare Urasandesu Swathe Hosting HostInfo / .cpp
Declare Urasandesu Swathe Hosting RuntimeHost Fwd .h
Declare Urasandesu Swathe Hosting RuntimeHost / .h
Declare Urasandesu Swathe Hosting RuntimeHost / .cpp
# 依存関係の定義
DependsOn HostInfoh HostInfoFwdh
DependsOn HostInfocpp HostInfoh DisposableHeapProviderh
DependsOn RuntimeHosth RuntimeHostFwdh HostInfoh
DependsOn RuntimeHostcpp RuntimeHosth SmartHeapProviderh
# -----------------------------------------------------------------------------------------------
#
# 出力処理
#
# -----------------------------------------------------------------------------------------------
$RootDirectory = Join-Path $PWD ('Published_' + [DateTime]::Now.ToString('yyyyMMddHHmmss'))
foreach ($target in $Records.GetEnumerator() |
% { $_.Value } | ? { $_.pstypenames -contains $AutoGen.pstypenames[0] }) {
$target.Generate((Join-Path $RootDirectory $target.Path))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment