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"は、コードの最後の数行が欠落しています。編集ミスだと思います。 しかし、コードのコメントを読めば欠落している部分を補うことができます。 この外にも、バグを見つけました。それは、次回に報告します。
最近のコメント