2016-12-28 4 views
-1

-ヘッダーファイルの名前を変更したときに変更する必要のないヘッダーガードを実装する方法はありますか?現在、私が使用<em>test_header.h</em>という名前のヘッダファイルのための

#ifndef TEST_HEADER_H 
#define TEST_HEADER_H 
/* code */ 
#endif /* TEST_HEADER_H */ 

私が欲しいものは、直接ファイル名を使用していないヘッダガードです。 (すなわち、希望的観測の粗仮想的なソリューション)のような何かが -

#if __FILE__ not in INCLUDE_LIST 
#APPEND(INCLUDE_LIST, __FILE__) 
/* code */ 
#endif 
+3

厳密に言えば、名前を変更した後にヘッダーガードを変更する必要はありません。古い名前を引き継ぐ別のファイルがない限り、変更する必要はありません。 – Arkadiy

+0

私は知っていますが、このように私は心配する必要はありません。 –

+2

接頭辞にUUIDを加えた識別子を使用することができ、さらに心配はありません。 –

答えて

2

他にも述べたように、ヘッダーガードとして使用するものは本質的に重要ではありません。それだけで一緒に含めることができるヘッダーのセット全体で一意である必要があります。

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内からそれを使用します。だからこそ空白行を上と下に生成しています。

このコマンドでは、スクリプトisodatercsmungerを使用しています。引数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つです。

4

あなたが好きなヘッダーガードに名前を付けることができます。その後

  • あなたのヘッダーは、特定のトピックに関連している場合は、名前それはすなわちLIST_OPERATIONS
  • は警備員を省略し、現在のファイル名に基づいてそれらを挿入するスクリプトを記述します。コンパイルする前に、このスクリプトをビルドプロセスの一部として実行してください。 (変更されたコピーを作成するか、ビルド後にインクルードを削除することを忘れないでください。そうしないと、ヘッダーにインクルードガードがたくさんあります)
  • プロジェクトで使用するコンパイラによっては、#pragma onceアプローチ。
+0

あなたのスクリプトは、独自のフォーマットを持っている場合は古いインクルードガードを削除することもできます。右ガードがすでに存在する場合は何もしません。 – Arkadiy

3

#pragma once

それはすべての主要なコンパイラで十分にサポートされ、非常にポータブルだし、14のコンパイラ(according to Wikipedia)のうち13による。

#pragma once vs include guards?もチェックしてください。

+1

しかし、#pragma onceを使用するプログラムは厳密には適合しません。あなたの目的が移植可能なコードを書くことであるならば、それをサポートするメジャーなコンパイラの割合にもかかわらず、あなたはそれを使用しません。 –

関連する問題