今関わっているプロジェクトでは、C言語でソースを記述しています。
ヘッダファイル内で以下のような define を設定することにより、
/* この機能を使う場合には define して下さい */
#define SW_A
/* この時間を 10~100の間で設定して下さい */
#define TIME_A 100
生成物を configuration しています。
今は、ヘッダファイル内で設定されている define名 を抽出するために、以下
の手順で shell script を組んでいます。
1. ヘッダファイルから define を grep する。
2. 1.の出力から define名 を取り出すために、awk で grep の次のワードを
取り出し出力。
(define /* */ SW のようにされているとdefine名を取り出せないが、その
よう書式はないと仮定)
3. 2.の出力をから uniq -d で重複している define を出力。
4. 2.の出力と 3. の重複している define名を取り除きユニークなdefine名の
みにする。
(自作コマンドにて対処。)
5. header を hoge.c に include し gcc -P -E -dN $CCDEFINES hoge.c でプ
リプロセッサにかけて出力。
6. 4. の各行の define名を1つづつ 5.の出力にあるかを grep で確認。
というような手順です。
この手順だと、設定値がある
#define TIME_A 100
のような場合、TIME_Aのdefine名が設定されていることで、抽出はできますが、
設定値の100 が出力する事ができません。
プリプロセッセなどをうまく使い define名だけでなく設定値をうまく出力す
る方法があれば、御教授お願いします。
どっかの仕事と似通った話だ...
In article <m2pscth9z0.wl%yama...@u08.itscom.net>, Takahiro Yamaguchi <yama...@u08.itscom.net> writes
> #define TIME_A 100
>
> のような場合、TIME_Aのdefine名が設定されていることで、抽出はできますが、
> 設定値の100 が出力する事ができません。
>
> プリプロセッセなどをうまく使い define名だけでなく設定値をうまく出力す
> る方法があれば、御教授お願いします。
自明な方法はないです。だから、const int TIME_A = 100; みたいな
方法が推奨されているわけでさ。
コンパイラ側から見ても、プリプロセッサが、定数と字面の対応を
断ち切ってしまうので、復旧するのは難しいです。
#define TIME_A ((void *)100)
みたいな形をしていることも多く、
printf("TIME_A=%d\n",(int)TIEM_A);
を生成するみたいな方法でも逃げるのは難しいですね。そもそも、
タイプがわからんし。
なんだけど、実は、手元の自作Cコンパイラでは、マクロ処理と
構文解析を1 path で行っているので、
定義されたマクロ名を全て集めて、
それを一旦生成した後、構文解析して、
構文エラーなく定数だったら、それを計算して表示する
ってなことは、やろうと思えば可能です。似たようなことやれって
言っている人達もいるので、やってみてもいいかな。「エラーなく」
ってあたりが難しいが。
コード中で定数生成されたソースの起点と終点を特定して、
その定数とソースの対応を示す
てなことを要求されていて、まぁ、出来なくもないんだけど、
めんどくさいので拒否っているところです。構文木に、ソース
へのポインタを入れないと出来ないので...
---
Shinji KONO @ Information Engineering, University of the Ryukyus
河野真治 @ 琉球大学工学部情報工学科
> 山口と申します。
(snip)
> プリプロセッセなどをうまく使い define名だけでなく設定値をうまく出力す
> る方法があれば、御教授お願いします。
grepの出力に対して、sedで、"s/#define *//g"してやるのはだめですか?
#uniqの前にsortしましょう。
--
--
I LOVE SNOOPY! でつ
Yoshitaka Ikeda mailto:ik...@4bn.ne.jp
My Honeypot: ho...@4bn.ne.jp <-don't send this address
At Mon, 16 Oct 2006 00:31:15 +0900,
Takahiro Yamaguchi wrote:
[...]
>
> 今は、ヘッダファイル内で設定されている define名 を抽出するために、以下
> の手順で shell script を組んでいます。
>
> 1. ヘッダファイルから define を grep する。
> 2. 1.の出力から define名 を取り出すために、awk で grep の次のワードを
> 取り出し出力。
> (define /* */ SW のようにされているとdefine名を取り出せないが、その
> よう書式はないと仮定)
> 3. 2.の出力をから uniq -d で重複している define を出力。
> 4. 2.の出力と 3. の重複している define名を取り除きユニークなdefine名の
> みにする。
> (自作コマンドにて対処。)
> 5. header を hoge.c に include し gcc -P -E -dN $CCDEFINES hoge.c でプ
> リプロセッサにかけて出力。
gcc -P -E -dD $CCDEFINES hoge.c
-dNから-dDに変更
-dDにすると、#define TIME_A 100 と出力されるのが分かったので、
> 6. 4. の各行の define名を1つづつ 5.の出力にあるかを grep で確認。
に追加で、
7. 5.の出力にあった場合、awkを使用し第3フィールド以降も出力する。
line=`grep -w 4.の各行のdefine名 5.の出力ファイル | head -1` >> /dev/null
grep -w 4.の各行のdefine名 5.の出力ファイル >> /dev/null
# 上の行のコマンド2回同じ事をしているのがださい!
if [ $? -eq 0 ]; then
echo $line |\
awk '{
printf("*,%s,",$2)
printf(" ")
for (i = 3; i <= NF; i++) {
printf("%s ",$i)
}
printf(" ")
printf("\n")
}'
else
...
fi
で、
*,SW_A,
*,TIME_A, 100
(* は defineが設定されているという意味で出力しています。)
で、何とか私のプロジェクトでは事足りるようになりました。