コンパイルとソース修正の自動化
コンパイルでエラーが出たらソースの修正、そしてまたコンパイル……と、プログラムが完成するまで同じような処理を繰り返します。単純な作業は自動化しましょう。
コマンドラインでのコンパイルは面倒
プログラムの完成まで、エラーを確認しては怪しい箇所を探してソースを修正し、再コンパイル……というサイクルを繰り返していく訳ですが、修正するたびにエディタを起動し、次いでコンパイルのコマンドを入力するのは面倒です。
この
コンパイル→エラー→ソース修正→再コンパイル
という繰り返しを自動的に実行できれば、最も重要なソースの修正に集中できます。
統合環境であれば、エラーが発生すれば修正して再ビルド……と、効率的な作業が行えます。面倒なのはコマンドラインでの処理です。コマンドラインで同じような作業環境を作ってみましょう。
処理の流れを把握する
コマンドライン版のコンパイラ・ドライバでは、コンパイラやリンカのエラーメッセージが標準出力(ディスプレイ)に出力されます。プログラマーはそれを手がかりに、ソースファイルをエディタで開いて、修正しなければなりません。
前回紹介したように、コンパイラやリンカの出力したエラーメッセージは、リダイレクトによってテキストファイルに記録できます。さらに多くのエディタでは、エラーメッセージを元にタグジャンプ機能を使い、指摘されたソースの行に移動できます。
そこで、上述したコンパイルからエディタによるソース編集……という流れを、自動的にこなせるようにしてみます。プログラムの実行を制御するには、DOSではバッチファイル、UNIX系OSではシェルスクリプトを使います。
処理の流れは以下のようになります。
(1)エディタでソースを入力
(2)コンパイル
(処理分岐)
(2-1)エラーなし→実行ファイル生成
(3-1)終了
(2-2)コンパイルまたはリンクエラー発生
(3-2)エラーメッセージをエディタで表示
(4)ソースを修正
(5)→(2)に戻る
終了コードを調べる
プログラムは終了時に終了コードと呼ばれる数値を、その呼び出し元(シェル──DOSならCOMMAND.COM)に返します。終了コードは、一般に正常終了すれば0、エラーで終了すれば0以外(-1、あるいは各種エラーの内容を示す数値)となっています。
LSI-Cのコンパイラ・ドライバLCCやLinux系OSのGCCも同じで、エラーなく終了して実行ファイルが生成できれば0、エラーがあって実行ファイルを生成できなければ0以外の数値を返します。これを利用し、
コンパイラの終了コードが0でなければ
エディタでエラーメッセージをリダイレクトした
テキストファイルを開く
ようにすれば、自動処理ができ上がります。
エラーメッセージを参照してソースを修正したら、続けて再度コンパイルを行います。このとき、無条件にコンパイラを動かすと、場合によっては延々と同じ処理を繰り返すループとなるため、「再コンパイルするか」ユーザーに確認を求めるプログラムが必要になります。
Y/N入力を処理するプログラムを作る
ユーザーに確認を求めるため、
「はい」(Yes)なら“Y”(または“y”)を
「いいえ」(No)ならそれ以外の1文字を
受け取って、
“Y”(または“y”)の場合は0
それ以外なら1を終了コードとして返す
プログラムが必要になります。
リスト1のようなソースです。動作の詳細は回を追って説明しましょう。今の段階では、このツールをそのまま使用してください。なお、リスト1のソースはLSI-CでもGCCでもコンパイルできます。もちろんVisual C++でも可能ですが、その場合はこれまでに説明したように#includeで取り込むヘッダファイルとmain関数の先頭を書き換えることに注意してください。
ソースファイルは“yesno.c”とします(DOSでは実行ファイル名が“yesno.exe”となります)。
リスト1:プロンプトを表示して'y'または'n'の入力を受け付ける~(yesno.c)
/* -----------------------------------------------------------------------
yesno.c -- メッセージを表示してY/Nの入力を待つ。
[Y]なら0、[N]なら1を終了コードとして返す。
----------------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char strMessage[255] = "Are you ready?";
int chAnswer;
if (argc > 1)
strcpy(strMessage, argv[1]);
strcat(strMessage, " <y/n>");
puts(strMessage);
chAnswer = getchar();
if (chAnswer == 'y' || chAnswer == 'Y')
return(0);
else
return(1);
}
|
|
|