マニュアルページ fpp.1
名前
fpp - Fortran 言語プリプロセッサ (FORTRAN 77 および Fortran
95 対応)
形式
fpp [ <オプション> ] [ input-file [ output-file ] ]
機能説明
fpp は、FORTRAN 77 と Fortran 95 のプリプロセッサ (前処理系)
です。 fpp には、引数として 2 つのファイル名を必要に応じて指
定することができます。input-file と output-file は、それぞれ
プリプロセッサが読み取る入力ファイルと書き込む出力ファイルで
す。デフォルトでは標準入力と標準出力が使用されます。Sun FOR-
TRAN 95 コンパイラを使用する場合は、cpp プリプロセッサではな
く fpp を使用することをお勧めします。
オプション
-c_com={yes|no}
デフォルトでは、C 形式のコメントが認識されます。これを
無効にするには -c_com=no を指定します。
-Dname
プリプロセッサ変数である name の値を 1 として定義しま
す。これは -Dname=1 というオプションを fpp コマンド行で
指定した場合と同じです。または、 fpp が処理するソース
ファイルの中に
#define name 1
という行を指定した場合と同じです。
-Dname=def
name を #define 指令による定義と同じように定義します。
これは、 fpp が処理するソースファイルの中に
#define name def
という行を指定した場合と同じです。 -D オプションよりも
-U オプションの指定の方が優先されます。つまり、 -U オプ
ションと -D オプションの両方に同じ名前が指定されている
場合、オプションの指定順序に関係なくこの名前は未定義と
なります。
-fixed
入力ソースを固定書式として解釈します。
-free
入力ソースを自由書式として解釈します。
-Idirectory
名前が `/' で始まっていない #include ファイルの検索パス
に directory を挿入します。 directory は、インクルード
ディレクトリの標準リストの先頭に挿入されます。したがっ
て、名前が二重引用符 (") で囲まれている #include ファイ
ルは、まずその #include 行があるファイルと同じディレク
トリで検索され、次に -I オプションで指定されたディレク
トリの中で検索され、最後に標準リストのディレクトリで検
索されます。名前が山括弧 (<>) で囲まれている #include
ファイルは、その #include 行があるファイルと同じディレ
クトリの検索は行われません。
-M メークファイルの依存関係のリストを作成して標準出力に書
き込みます。このリストは、入力ファイルから生成されるオ
ブジェクトファイルが、参照されているインクルードファイ
ルだけでなく、入力ファイルにも依存することを示します。
-macro={yes|no_com|no}
デフォルトでは、どこに記述されているマクロでも展開され
ます。コメント内のマクロ展開を抑止するには、
-macro=no_com を指定します。すべてのマクロ展開を抑止す
るには、-macro=no を指定します。
-P 行番号を付ける指令を出力ファイルに書き込みません。これ
は次のような形式の指令です。
#行番号 ファイル名
-Uname
name が特定のプリプロセッサによって事前定義された fpp
変数である場合に、その name の初期定義を削除します。以
下に、システムのアーキテクチャに応じて事前定義されてい
る可能性があるシンボルの一部を示します。
オペレーティングシステム:
unix、 __unix、 __SVR4
ハードウェア: sun、 __sun、 sparc、
__sparc
-undef
すべての事前定義済みシンボルの初期定義を削除します。
-w0 fpp からの警告を標準エラー出力に出力しません。
-Xu 大文字を小文字に変換します。ただし、文字列定数は変換し
ません。デフォルトでは、大文字から小文字への変換は行い
ません。
-Xw 固定書式ソースファイル (下記を参照) の場合に、 fpp はス
ペース文字に特別な意味はないと解釈します。この書式のデ
フォルトでは、スペース文字はトークンの区切り文字となり
ます。
-Ydirectory
#include ファイルの検索時に、ここで指定された directory
を標準ディレクトリのリストの代わりに使用します。
fpp は、次の f95 コンパイラオプションも認識します (f95 (1)
を参照)。
-e 拡張されたソース行を受け付けます (最高 132 文字)。
-w 警告を標準エラー出力に出力しません。
使用法
ソースファイル
fpp は、固定書式と自由書式の両方のソースファイルに対して機能
します。デフォルトでは、.F という拡張子が付いたファイルは固
定書式であると解釈され、.F90 および F95 という拡張子 (および
その他すべての拡張子) が付いたファイルは自由書式であると解釈
されます。-fixed オプションを指定すると Fortran 95 で固定書
式を使用できます。 fpp は、固定書式の場合はタブ書式のソース
行を認識します。
ソースファイルには fpp トークンを含めることができます。 fpp
トークンは Fortran のトークンと類似しています。 fpp トークン
は以下のとおりです。
- fpp指令の名前。
- シンボル名 (Fortran のキーワードなど)。 fppでは、
Fortran で使用可能なすべてのシンボルを名前の中で使
用できます。
- 定数。整数、整数、実数、倍精度、4 倍精度、2 進数、
8 進数、16 進数 (代替表記を含む)、文字およびホレリ
ス。
- コメント。Fortran コメントと fpp コメントがありま
す。
- その他。特殊文字、スペース、タブ、復帰改行など。
出力
出力には、入力を処理した結果と、次の形式の行が含まれていま
す。
#行番号 ファイル名
この行は、これに続く出力行に対応する入力ファイルのソース行番
号とファイル名を示します。-P オプション (上記を参照) を使用
すれば、この行の生成は抑止することができます。
指令
fpp 指令の構文と意味は cpp 指令と同じです ( cpp(1) を参照)。
fpp 指令はすべてハッシュ記号 (#) で始まります。この記号を行
の先頭文字として指定します。先頭の # の後に空白 (スペース文
字またはタブ文字) を追加して字下げを揃えることもできます。指
令は次のような種類に分類できます。
- マクロ定義
- 条件付きソースコード選択
- 外部ファイルの取り込み
- 行制御
マクロ定義
#define 指令を使用すると、単純な文字列変数と複雑なマクロの両
方を定義することができます。
#define name token-string
これは fpp 変数の定義です。ソース行でこの定義の後にある名前
name は、トークン token-string で置き換えられます。
#define name(argument [, argument] ... ) token-string
これは関数形式のマクロの定義です。マクロ名 name の後にコンマ
で区切った引数リストを括弧で囲んで続けた記述が現れると、この
マクロ定義から生成されるトークン文字列で置き換えられます。マ
クロ定義の引数リストに指定された引数識別子は、対応するマクロ
実引数を表わすトークンの並びで置き換えられます。
マクロ置換演算子 # と ## のオペランド以外のマクロ引数は、置
換トークンリストへの置換前に、再帰的に展開されます。
文字列リテラルへの引数置換を許可するには、# マクロ置換演算子
を使用します。
#define a(x) #x
...
a(actual argument)
次の文字列を生成します。
'actual argument'
(1 つまたは両方が引数である) 2 つのトークンをマクロ定義で結
合するには、## マクロ置換演算子を使用します。
#define cat(x,y) x##y x##b a##y
#define ab ok
...
cat(a,b)
次の文字列を生成します。
ok ok ok
これらの定義では、マクロ名と ( 記号の間に空白を入れないでく
ださい。マクロ名の後に空白があると、その指令はマクロ定義では
なく fpp 変数定義であると解釈され、( 記号で始まる行の残りの
部分がトークン文字列であると解釈されてしまうからです。
#undef name
name の定義 (-D オプション、#define 指令、またはデフォルトで
生成された定義) をすべて削除します。指令行の name の後には何
もトークンを追加しないでください。
外部ファイルの取り込み
ファイルを取り込む (インクルードする) 形式は 2 つあります。
#include "filename"
#include <filename>
filename の内容をこの位置に読み込みます。ファイルから読み込
まれる行は、 fpp によって (現在のファイルの一部であるかのよ
うに) 処理されます。
<filename> という表記を使用すると、filename は標準のインク
ルードディレクトリの中でのみ検索されます。詳細は、上記の -I
オプションおよび -Y オプションを参照してください。指令行の最
後の " または > の後には何もトークンを追加してはいけません。
行制御
#line-number "filename" または、
#line line-number "filename"
次のコンパイラパスのために行制御情報を生成します。整数定数
line-number は次の行の行番号として解釈され、 filename その行
が取り出されたファイルの名前として解釈されます。"filename"
が指定されていない場合、現在のファイル名は変更されていませ
ん。
ソーステキストの条件付き選択
ソーステキストの条件付き選択には、次の 2 つの形式がありま
す。
1) #if 条件 1
ブロック 1
#elif 条件 2
ブロック 2
#else
ブロック n
#endif
2) #ifdef 名前
ブロック 1
#elif 条件
ブロック 2
#else
ブロック n
#endif
または
#ifndef 名前
ブロック 1
#elif 条件
ブロック 2
#else
ブロック n
#endif
else と elif の部分の指定は任意です。elif の部分は複数指定す
ることができます。条件は、 fpp 定数、マクロ、および組み込み
関数から構成される式として指定できます。条件式は cpp の式と
同様であり、任意の cpp 演算子とオペランドを指定できますが、C
の long 型、8 進、および 16 進の定数は使用できません。そのほ
か、 fpp は Fortran の論理演算子 .NOT. .AND. .OR. .EQV.
.NEQV. .GT. .LT. .LE. .GE. などと論理定数 .TRUE. .FALSE. を
受け付けて評価します。
詳細
マクロまたは変数の定義のスコープ
定義のスコープは、その定義の行から始まり、現在のファイルの末
尾までのすべてのソース行 (およびインクルードされたファイルか
ら取り込まれたソース行) に及びます。
fpp 定義によって影響を受けるスコープには次の例外があります。
- Fortran の INCLUDE 文で取り込まれたファイル
- fpp と Fortran のコメント
- IMPLICIT 文の 1 文字仕様
- FORMAT 文の書式仕様
- 数値定数、型のない定数、および文字定数
マクロのスコープは #undef 指令を使用することで制限できます。
マクロ定義の終わり
マクロ定義の長さは任意であり、復帰改行記号が現れるまで継続し
ます。マクロは複数の行にわたって定義できます。マクロを次の行
に継続させるには '\' を挿入します。したがって、マクロ継続記
号なしで復帰改行が現れると、マクロ定義の終わりになります。
例:
#define long_macro_name(x,\
y) x*y
固定形式の Fortran 77 ソースファイルでは、マクロの展開とし
て、複数の行または文を生成する必要がある場合があります。別の
行に生成する文を区切るには、次のように「;」を使用します。
#define init_i_j(x,y) i=x; j=y
...
init_i_j(1,2)
次の文字列を生成します。
i=1
#2
j=2
関数形式のマクロ定義
マクロ呼び出しの引数の数は、対応するマクロ定義の引数の数と同
じでなければなりません。同じでない場合はエラーが通知されま
す。
両方の種類のマクロ定義の取り消し
#undef name
この指令の後、name は fpp によってマクロ名または変数名として
解釈されなくなります。この名前が前にマクロ名として定義されて
いない場合は、この指令を指定しても何も効果はありません。
条件付きソースコード選択
#ifdef const-expr
対応する #else、#elif、または #endif 指令までの間に記述
された行が出力中に現われるのは、その定数式 const-expr
の値が真 (.TRUE.) になる場合だけです。
#elif 指令の後の行が出力中に現れるのは、以下の 3 つの条
件のすべてに該当する場合だけです。
- 先行する #if 指令の定数式の評価結果が .FALSE. に
なったか、または先行する #ifdef 指令の中の名前が定
義されていないか、または先行する #ifndef 指令の中
の名前が定義されている。
- それまでの間にあるすべての #elif 指令の定数式の評
価結果が .FALSE. になった。
- 現在の定数式の評価結果が .TRUE. である。
定数式の評価結果が .TRUE. になると、後続の #elif と
#else 指令は対応する #endif まで無視されます。#if 指令
の中で指定できる定数式はすべて #elif 指令中でも指定でき
ます。
組み込み関数 defined を定数式の中でも使用することができ
ます。
以下の要素を使用できます。
- C 言語の演算子: <、>、==、!=、>=、<=、+、-、/、*、
%、<<、>>、&、~、|、&&、||
fpp はこれらを C 言語の意味論に従って解釈します (
この機能は cpp を使用する古い Fortran プログラムと
の互換性を維持するために提供されています)。
- Fortran 言語の演算子: .AND.、.OR.、.NEQV.、.XOR.、
.EQV.、.NOT.、 、.GT.、.LT.、.LE.、.GE.、.NE.、
.EQ.、** (累乗)
- Fortran の論理定数: .TRUE. , .FALSE.
定数式の中で使用できるのは、これらの要素と、整数定数、
および名前だけです。名前が -D オプション、#define 指
令、またはデフォルトによって定義されていない場合、その
名前の値は 0 になります。C 演算子 != (等しくない) は
#if および #elif 指令の中では使用できますが、#define 指
令の中では使用できません。#define 指令では記号 ! が
Fortran のコメント記号であると見なされるからです。
#ifdef name
対応する #else、#elif、または #endif までの間に記述され
た行が出力中に現れるのは、名前 name が #define 指令また
は -D オプションによって定義されており、それまでの間に
その定義を削除する #undef 指令が存在しない場合だけで
す。指令行の name の後にはトークンを指定することはでき
ません。
#ifndef name
対応する #else、#elif、または #endif までの間に記述され
た行が出力中に現れるのは、名前 name が定義されていない
場合か、またはその定義が #undef 指令によって削除されて
いる場合だけです。指令行の name の後にはトークンを指定
することはできません。
#elif const-expr
#if、#ifdef、または #ifndef 指令とそれに対応する #else
または #endif 指令の間には任意の数の #elif 指令を指定で
きます。
#else
これは条件指令が真でない場合という意味になります。先行
する条件指令が行を取り込むことを示す場合は、#else とそ
れに対応する #endif の間の行は無視されます。先行する条
件指令が行を無視することを示す場合は、#else の後の行が
出力中に取り込まれます。
条件指令とそれに対応する #else 指令は入れ子にすることが
できます。
#endif
#if、#ifdef、または #ifndef のいずれかの条件指令で開始
した行セクションを終了します。これらの各指令には対応す
る #endif を必ず指定する必要があります。
外部ファイルの取り込み
cpp の場合と同じです。ファイルは、次のように検索されます。
#include "filename" の場合:
- 処理対象のファイルが存在しているディレクトリを検索
- -I オプションで指定されたディレクトリを検索
- デフォルトのディレクトリを検索
#include <file_name> の場合:
- -I オプションで指定されたディレクトリを検索
- デフォルトディレクトリを検索
fpp 指令 (行の先頭が # 記号で始まる記述) は、ソースコード内
の任意の位置に指定できます。特に、Fortran 継続行の前に記述で
きます。ただし唯一の例外として、継続記号を使用して複数の行に
分けられたマクロ呼び出しの中では fpp 指令を使用することはで
きません。
コメント
fpp では、2 種類のコメントを使用することができます。
1) Fortran 言語のコメント。'C'、'c'、'*'、'd'、または 'D' と
いうシンボルのいずれかが先頭にあるソース行は、コメント行であ
ると見なされます。このような行の中では、マクロの展開は実行さ
れません。'!' という記号は、行末まで続くコメントの開始である
と解釈されます。ただし、この記号が #if および #elif 指令内の
定数式の中にある場合だけは例外です (上記を参照)。
2) fpp コメント。これは '/*' と '*/' というシンボルで囲まれ
たテキストです。このコメントは出力から除外され、これらのシン
ボルの中ではマクロ展開が実行されません。 fpp コメントは入れ
子にすることができます。各シンボル '/*' ごとに、対応するシン
ボル '*/' を必ず記述する必要があります。 fpp コメントは、
コードの広範囲にわたる部分をコンパイルから除外するのに適して
います。Fortran コメント記号では、すべての行をコメントにしな
ければならないからです。
組み込み関数
組み込み関数 defined(name) または defined name は、以下の値
を返します。
.TRUE. - 名前 name がマクロとして定義されている場合
.FALSE.- 名前 name が未定義の場合
マクロ展開
マクロ展開の際に、行の長さが 72 桁 (固定書式) または 132 桁
(自由書式) を超える場合、 fpp は適当な継続行を挿入します。
固定書式の場合、名前フィールド (1 桁目から 5 桁目) でのマク
ロ展開には次の制約があります。
- マクロ呼び出し (引数があればそれも含む) は 5 桁目
を超えないようにする必要があります。
- 名前が Fortran のコメント記号で始まるマクロの呼び
出しはコメントの一部であるとみなされます。
- マクロ展開から生成されるテキストが 5 桁目を超える
場合には、警告が出力されます。
固定書式で -Xw オプションが指定されている場合、マクロ呼び出
しが文の位置に記述され、マクロ名全体またはマクロ名の先頭部分
が Fortran のキーワードと一致していると、プリプロセッサがそ
の箇所の解釈を確定できないことがあります。たとえば、次の場合
を考えてみます。
#define callp(x) call f(x)
call p(0)
fpp は 'call p' というトークンの並びを一意に解釈することがで
きません。マクロ名であるとも解釈できるからです。これは、現在
の実装では次のように処理されます。
- 長い方の識別子が選択されます (この例では
"callp")。
- この識別子から、最も長いマクロ名またはキーワードを
抽出します。
- マクロ名が抽出された場合は、マクロ展開が実行されま
す。名前がキーワードと同じ文字列で始まる場合は、
fpp は警告を出力します。
- 識別子の残りの部分は、その全体が 1 つの識別子であ
るとみなされます。
上の例では、マクロ展開が行われ、次のような警告が出力されるこ
とになります。
warning: possibly incorrect substitution of macro callp
(警告: マクロ callp の置換が正しくない可能性があります)
なお、このような状況が発生するのは、固定書式のソースコードを
前処理する場合に、スペース(空白)文字がトークンの区切り文字と
して解釈されない場合だけです。また、次のようにマクロ名がキー
ワードの先頭部分と一致する場合、
#define INT INTEGER*8
INTEGER k
上で説明したアルゴリズムに従って INTEGER キーワードの方がマ
クロ名 INT よりも先に検出されます。したがって、このようなマ
クロ定義の前処理で警告が出力されることはありません。
診断
診断メッセージは次の 3 種類です。
- 警告。ソースコードの前処理は続行され、戻り値は 0
のままです。
- エラー。 fpp は前処理を続行しますが、戻り値をゼロ
以外の値に設定します。この値はエラーの個数を表しま
す。
- 致命的なエラー。 fpp は前処理を中止して、ゼロ以外
の戻り値を返します。
fpp が生成するメッセージは、そのメッセージだけで理解できる内
容になっています。エラーが発生した場所の行番号とファイル名も
示されます。
関連項目
cpp(1)、f95(1)
fpp のソースコードは、次の URL からダウンロードできます。
http://www.netlib.org/fortran/