他にも述べたように、ヘッダーガードとして使用するものは本質的に重要ではありません。それだけで一緒に含めることができるヘッダーのセット全体で一意である必要があります。
UUIDまたはGUIDを作成し、それをヘッダーガード(またはMD5、SHA1、SHA2、SHA3など)のハッシュとして使用できます。唯一のトリックは、先行する数字の可能性を扱っています。これは簡単に回避できます(接頭辞としてH_
を使用しました)。
ほとんどの場合、私はファイル名に基づいて名前を使用し、通常はヘッダーの名前を頻繁に変更して問題になることはありません。ここで
は、私は与えられたヘッダファイルのヘッダーガードラインを生成するために使用hdrguard
と呼ばれるスクリプトです:
#!/bin/sh
#
# @(#)$Id: hdrguard.sh,v 1.8 2016/05/09 18:41:57 jleffler Exp $
#
# Generate #ifndef sequence to guard header against multiple inclusion
arg0=$(basename $0 .sh)
usestr="Usage: $arg0 [-bdfhimV] header.h [...]"
usage()
{
echo "$usestr" 1>&2
exit 1
}
help()
{
echo "$usestr"
echo
echo " -b Use base name of file for guard"
echo " -d Use _DOT_H after name (instead of _H)"
echo " -f Use specified path name of file for guard (default)"
echo " -h Print this help message and exit"
echo " -i Omit _INCLUDED after name"
echo " -m Generate MD5 hash value as header guard"
echo " -V Print version information and exit"
exit 0
}
opt_incl=yes
opt_base=no
opt_dot=no
opt_md5=no
while getopts bdfhimV opt
do
case "$opt" in
(b) opt_base=yes;;
(d) opt_dot=yes;;
(f) opt_base=no;;
(h) help;;
(i) opt_incl=no;;
(m) opt_md5=yes;;
(V) echo "$arg0: HDRGUARD Version "'$Revision: 1.8 $ ($Date: 2016/05/09 18:41:57 $)' | rcsmunger; exit 0;;
(*) usage;;
esac
done
shift $(($OPTIND - 1))
[ $# -eq 0 ] && usage
for i in "[email protected]"
do
if [ $opt_base = yes ]
then i=$(basename $i)
fi
if [ $opt_dot = yes ]
then i=$(echo "$i" | sed 's/\.h$/_dot_h/')
fi
i=$(echo $i | tr 'a-z' 'A-Z' | tr -s '/+.-' '____' | sed 's/^_//')
if [ $opt_incl = yes ]
then
case "$i" in
(*_INCLUDED)
: OK;;
(*)
i="${i}_INCLUDED";;
esac
fi
if [ $opt_md5 = yes ]
then
tmp=$(mktemp ./hdrgrd.XXXXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
echo "$i.$(isodate compact)" > "$tmp"
i=$(md5 "$tmp" | sed 'y/abcdef/ABCDEF/; s/\([^ ]*\) .*/H_\1/')
rm -f "$tmp"
trap 0 1 2 3 13 15
fi
echo
echo "#ifndef $i"
echo "#define $i"
echo
echo "#endif /* $i */"
echo
done
それはSHA1、SHA2またはSHA3のためのコードを持っていない - それは、必要に応じてMD5を使用しています(中コマンドの形式md5
)。代替ハッシュアルゴリズムのサポートを追加することは非常に難しくありません。ファイルが存在する必要はありません。
例は、使用:カーソルは、私は編集だヘッダに適したヘッダガードを生成するために、空の行にある間
$ hdrguard header.h
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#endif /* HEADER_H_INCLUDED */
$ hdrguard -m header.h
#ifndef H_6DC5070597F88701EB6D2CCAACC73383
#define H_6DC5070597F88701EB6D2CCAACC73383
#endif /* H_6DC5070597F88701EB6D2CCAACC73383 */
$
私はしばしば、!!hdrguard %
ようにコマンドを入力し、vim
内からそれを使用します。だからこそ空白行を上と下に生成しています。
このコマンドでは、スクリプトisodate
とrcsmunger
を使用しています。引数compact
で、isodate
コマンドは同等です:
date +'%Y%m%d.%H%M%S'
完全なコマンドは、代替フォーマットの数をサポートし、どこでもdate
コマンドを入力するよりも、より簡潔です。別のスクリプトの使用を止めて、表示されている拡張子をhdrguard
に埋め込むだけで自由に使えます。確かに、あなたはdate
だけを使用することができ、それは問題ありません。データをハッシュ化することを一意にするためのハッシュ操作のシード材料です。
$ isodate compact
20161228.185232
$
rcsmunger
コマンドはちょうど私がバージョン情報を報告するための好む形式にRCSのID文字列を変換します。たとえば
#!/usr/bin/env perl -p
#
# @(#)$Id: rcsmunger.pl,v 1.9 2015/11/02 23:54:32 jleffler Exp $
#
# Remove the keywords around the values of RCS keywords
use strict;
use warnings;
# Beware of RCS hacking at RCS keywords!
# Convert date field to ISO 8601 (ISO 9075) notation
s%\$(Date:) (\d\d\d\d)/(\d\d)/(\d\d) (\d\d:\d\d:\d\d) \$%\$$1 $2-$3-$4 $5 \$%go;
# Remove keywords
s/\$([A-Z][a-z]+|RCSfile): ([^\$]+) \$/$2/go;
:
$ hdrguard -V
hdrguard: HDRGUARD Version 1.8 (2016-05-09 18:41:57)
$
あなたはバージョン情報の印刷を考えることができます古い学校のバージョン管理として。 git
などのDVCSを使用すると、別の方法で実行する必要があります。これは、個人用ソフトウェアのコレクションとしてgit
への卸売りマイグレーションを行っていない理由の1つです。
厳密に言えば、名前を変更した後にヘッダーガードを変更する必要はありません。古い名前を引き継ぐ別のファイルがない限り、変更する必要はありません。 – Arkadiy
私は知っていますが、このように私は心配する必要はありません。 –
接頭辞にUUIDを加えた識別子を使用することができ、さらに心配はありません。 –