Как уже отмечалось, то, что вы используете в качестве защитника заголовка, не имеет принципиального значения; он просто должен быть уникальным во множестве заголовков, которые могут быть включены одновременно.
Вы можете создать 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, УВХ2 или SHA-3 - это необязательно использует 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 */
$
Я часто использую его изнутри vim
, набрав команду, такие как !!hdrguard %
, когда курсор находится на пустой строке, чтобы генерировать охранник заголовок, подходящий для заголовка я редактирования. Вот почему он также создает пустые строки сверху и снизу.
Команда использует сценарии isodate
и rcsmunger
.С аргументом compact
команда isodate
эквивалентна:
date +'%Y%m%d.%H%M%S'
Полной команда поддерживает ряд альтернативных форматов и более емкие, чем того, чтобы набрать команду date
везде. Вы полностью можете отказаться от использования отдельного сценария и просто вставить расширение, показанное на hdrguard
. В самом деле, вы можете использовать только date
, и все будет в порядке; это всего лишь материал семян для операции хеширования, чтобы сделать хеширование данных уникальным.
$ isodate compact
20161228.185232
$
Команда rcsmunger
просто преобразует строки ID RCS в формат, я предпочитаю для представления информации о версии:
#!/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)
$
Вы можете рассматривать печать информации о версии как контроль версий старой школы; это нужно сделать по-другому, если вы используете DVCS, например git
, что является одной из причин, по которым я не совершил оптовую миграцию до git
для моей личной коллекции программного обеспечения.
Строго говоря, вы не _need_, чтобы изменить защиту заголовка после переименования - если только у вас нет другого файла, который использует старое имя. – Arkadiy
Я знаю, но таким образом я могу быть беззаботным (sic). –
Вы можете использовать идентификатор с префиксом плюс UUID и быть еще более беззаботным. –