新たに学ぶ言語では大抵真っ先に遊ぶ個人的サンプル(Cのヘッダファイル生成)

特にスクリプト言語の場合って、「何某かの自動処理」をしたくて取り組んでいる場合がほとんど、であろ?

これまでもずっとそうだったんだけど、だいたい以下出力を作れるものを作ってみるのね、あたし:

1 #ifndef _HOGE_H_371B5C68_AA02_449E_AA0C_98D3234AFA92__
2 #define _HOGE_H_371B5C68_AA02_449E_AA0C_98D3234AFA92__
3 
4 
5 /* TODO */
6 
7 
8 #endif /* _HOGE_H_371B5C68_AA02_449E_AA0C_98D3234AFA92__ */

そう、C/C++の二重インクルード防止、ね。Visual Studio の IDE とか Eclipse とかの外で自動生成なんかしようとするときには、実際にこれに近いことをするわけね。大昔の Microsoft Visual Studio と Microsoft Platform SDK ってさ、確か MkGuidGen.exe って「GUI」しかなくて、自動処理には使えなかったのね。ただ、今は uuidgen.exe が SDK には付属みたいなんで…、なので誰も「これはオイシイ」とは思わないだろうなぁ、と思いつつ…。

「371B5C68_AA02_449E_AA0C_98D3234AFA92」部分が GUID (UUID4) なのは、「Microsoft 流儀」で、個人的に昔から「やりすぎだよな」と思っているけれど、スタイルは同じ方が良かろう、と思うなら、GUID 使えばいいね、と。GUID 生成は:

なので…

newguid.ps1
1 $g = [System.Guid]::NewGuid()
2 [Console]::WriteLine($g)

て感じな。

あとはコマンドライン引数の受け取り方とか System.String の使い方とかを C# での記憶と Microsoft のドキュメントをあさりつつ、ひとまず目的のものが以下:

mk_c_header.ps1
 1 Param(
 2     [string]$name
 3 )
 4 
 5 $rs = [System.Guid]::NewGuid().ToString().ToUpper().Replace('-', '_')
 6 $def = "_" + $name.ToUpper().Replace('.', '_') + "_" + $rs + "__"
 7 [System.Console]::WriteLine("#ifndef " + $def)
 8 [System.Console]::WriteLine("#define " + $def)
 9 [System.Console]::WriteLine("
10 
11 /* TODO */
12 
13 ")
14 [System.Console]::WriteLine("#endif /* " + $def + " */")

なお、Python で同じことをするには uuid.uuid4() です。

ちなみに「やりすぎだよな」について。「二重インクルード防止」の観点から言って、「define の絶対的唯一性」が必要なのではないのよね。そうでもいいんだけど、「コピペ野郎」はファイルごとコピーするところから始めちゃうから、この define も書き換えもせずに残る、ことにはどのみち耐えられんでしょ。だので、「世界で唯一の識別子」であることの価値なんかないのね。それよりは「同じファイル名 ~.h に対して常に同じ結果、かつ、人間には簡単には作れない識別子」であるほうがマシで、そういうわけで、アタシは最近は UUID4 ではなくファイル名に対する MD5 (等のハッシュ)を使ってます。






動くサンプルで学べるWindows PowerShellコマンド&スクリプティングガイド[本/雑誌] / 五十嵐貴之/著

【送料無料】 Windows PowerShellクックブック / リー・ホームズ 【単行本】