Comme d'autres l'ont noté, ce que vous utilisez comme une garde d'en-tête n'est pas intrinsèquement important; il doit juste être unique dans l'ensemble des en-têtes qui pourraient être inclus.
Vous pouvez créer un UUID ou un GUID et l'utiliser comme garde d'en-tête (ou un hachage quelconque - MD5, SHA1, SHA2, SHA3, ...). Le seul truc consiste à traiter la possibilité d'un chiffre principal; cela est facile à contourner (j'ai utilisé H_
comme préfixe). Mais généralement, j'utilise un nom basé sur le nom du fichier, et ne renomme pas assez souvent les en-têtes, ce qui est un problème.
Voici un script appelé hdrguard
que j'utilise pour générer les lignes de garde d'en-tête d'un fichier d'en-tête donné:
#!/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
Il n'a pas de code pour SHA1, SHA2 ou SHA-3 - il utilise en option MD5 (en la forme d'une commande md5
). Il ne serait pas très difficile d'ajouter du support pour des algorithmes de hachage alternatifs. Il ne nécessite pas l'existence du fichier.
Exemple utilise:
$ 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 */
$
J'utilise souvent de l'intérieur vim
, en tapant une commande telle que !!hdrguard %
lorsque le curseur est sur une ligne vide pour générer un garde d'en-tête approprié pour l'en-tête, je suis édition. C'est pourquoi il génère aussi les lignes vides en haut et en bas. La commande utilise les scripts isodate
et rcsmunger
.Avec l'argument compact
, la commande isodate
équivaut à:
date +'%Y%m%d.%H%M%S'
La commande complète prend en charge un certain nombre de formats alternatifs et est plus succinct que d'avoir à taper la commande date
partout. Vous êtes entièrement libre de renoncer à l'utilisation d'un script séparé et de simplement intégrer l'extension affichée dans hdrguard
. En effet, vous pourriez utiliser seulement date
et ce serait OK; c'est juste le matériel de graine pour l'opération de hachage pour rendre les données étant hashed uniques.
$ isodate compact
20161228.185232
$
La commande rcsmunger
convertit simplement les chaînes d'identification RCS dans un format que je préfère pour signaler les informations de version:
#!/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;
Par exemple:
$ hdrguard -V
hdrguard: HDRGUARD Version 1.8 (2016-05-09 18:41:57)
$
Vous pouvez considérer l'impression des informations sur la version comme contrôle de version old-school; il doit être fait différemment si vous utilisez un DVCS tel que git
, qui est l'une des raisons pour lesquelles je n'ai pas fait une migration en gros à git
pour ma collection de logiciels personnels.
Strictement parlant, vous n'avez pas besoin de changer de garde-tête après le changement de nom - à moins que vous n'ayez un autre fichier qui reprend l'ancien nom. – Arkadiy
Je sais, mais de cette façon je peux être sans souci (sic). –
Vous pouvez utiliser un identifiant avec un préfixe plus un UUID et être encore plus sans souci. –