IDEその後 ― 2018年03月26日 15:58
Open WATCOM C/C++のIDEを使って、前回説明したルールに沿って PC-DOS SHELLの製作を続けています。
幾つかサンプルを示します。
今回、製作するプロジェクト名は、"SHELL"とします。作業デイレクトリーは"C:\SHELL"です。 また、プロジェクトのターゲットは、3つです。完成品"SH.EXE"、デバッグ用ターゲット"DEBMAIN.EXE"。 いずれも、DOS 16ビットの実行モジュールです。 この外に、テキストでは、ライブラリー"SHELLIB.LIB"を作りますので、 これもターゲットとします。
さて、さきに決めたコーデイングルールに従い、プリグラムを書いていきます。幾つかサンプルを示します。
関数の頭書きの例です。オリジナルはこのようになっています。
/* cpy.c */
char *cpy(dest,src)
register char *dest,*src;
{
:
(中略)
:
return dest;
}
これ下記のようにすると同時にヘッダーファイルを追加します。
/* cpy.c */
char *cpy(char *dest,char *src) {
:
(中略)
:
return dest;
}
ヘッダーファイルは以下のとおりです。これを必要に応じてインクルードします。
/* cpy.h */ extern char *cpy(char*,char*);
型を省略された引数は、きちんと宣言します。例えば、
/* next.c */
char *next(**linep,delim,esc) {
char **linep;
{
:
(中略)
:
return start;
}
これは、このようにします。もちろん、ヘッダーファイルも同様です。
/* next.c */
char *next(char **linep,char delim,char esc) {
{
:
(中略)
:
return start;
}
/* next.h */ extern char *next(char **,char,char);
標準関数の定義は、本書では以下のようにしていますが、 ヘッダーファイルをインクルードするようにします。下記の例には、strlen()の宣言に誤植があります。 引数が一つなのにカンマが付いています。おそらく、版下を作成するのに、ソースファイルを 手書きで入力したのでしょう。現代ならば、インクルードして組み込むでしょうね。
/* strsave.c */
extern int strcpy (char*, char*);
extern char *malloc(unsigned );
extern int strlen (char*, );
char *strsave(str)
char *str;
{
:
(中略)
:
return NULL;
}
これは、下記のように記述しました。
/* strsave.c */ #include#include char *strsave(char *str) { : (中略) : return NULL; }
static宣言された関数は、そのままでは、別のコンパイル単位からは見えなくなります。 これでは、デバッグをしずらいので、コンパイル時に文字列"DEBUG"が定義されている時は、 static宣言をはずすようにします。例えば下記の場合は、
/* reargv.c */
:
(中略)
:
extern unsigned char _osmajor;
static int Envlen;
:
(中略)
:
/* --------------------------------------------------------------------- */
static char *nextarg(pp)
char **pp;
{
:
(中略)
:
return start;
}
/* --------------------------------------------------------------------- */
int reargv(argcp,argvp)
char *(**argvp);
int *( argcp);
{
:
(中略)
:
return 1;
}
/* --------------------------------------------------------------------- */
int envlen(void) {
:
(中略)
:
return Envlen;
}
このようにします。
/* reargv.c */
:
(中略)
:
extern unsigned char _osmajor;
static int Envlen;
:
(中略)
:
/* --------------------------------------------------------------------- */
#ifndef DEBUG
static
#endif
char *nextarg(char **pp) {
:
(中略)
:
return start;
}
/* --------------------------------------------------------------------- */
int reargv(int *argcp,char *(**argvp)) {
:
(中略)
:
return 1;
}
/* --------------------------------------------------------------------- */
int envlen(void) {
:
(中略)
:
return Envlen;
}
リスト中、MS-C依存の変数"_osmajor"があります。幸いなことに、Open WATCOM C/C++でも、 サポートされています。
"DEBUG"の宣言は、IDEの"C Compiler Switches"の "Macro Definitions: [-d]"欄に"DEBUG"と書きコンパイルします。デバッグが終わったら、 "DEBUG"を取り去り、再コンパイルしときます。
MS-Cに依存している個所は、もう一つありました。アセンブラーで一部書かれています。 その中で、MS-C独自の内部関数"__chkstk"関数を呼び出しています。これは、 実行時にスタックオーバーフローの検出をするルーチンです。Open WATCOM C/C++にはありません。 "__STK"が、同等の機能を果たすものと思われますが、仕様が公開されていません。今回は、 "__chkstk"を無視する事とします。
このテキスト中、"isdir.c"は、コードの最後の数行が欠落しています。編集ミスだと思います。 しかし、コードのコメントを読めば欠落している部分を補うことができます。 この外にも、バグを見つけました。それは、次回に報告します。
コメントをどうぞ
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。