久しぶりに、Modula-2でプログラミング2023年01月18日 06:46

CP/Mは、よくできたDOSですが、いくつか不満があります。そのひとつに、コマンド行パラメーターが すべて大文字になってしまうのです。これでは、findやsedのような文字列を検索したり、置換したりする アプリケーションで小文字を入力できないので、困ってしまいます。CP/Mが盛んに使われた時代を考えると 仕方のないことですが、何とかしたいものです。

入力されたコマンド行パラメーター入力をすべて小文字にするのは乱暴すぎます。折衷案として パラメータの入力を促し読みとる仕組みを作ることにしました。ついでに、少し賢い引数分解の仕組みを 組み込みました。

作成した仕組み"CmdArgs"は以下のルールで、引数を分解します。

  • 引数は、区切り文字(コンマ、スペース、タブ)で区切られる。
  • 最初のコンマの前が、スペース、タブである場合は、第一番目の引数は、ヌル文字列とみなす。
  • 最後の文字がコンマの場合は、最後に、ヌル文字列があるものとみなす。
  • 引数は、クオート文字('、または、")でくくることができる。 コンマ、スペース、タブを含むことができる。
  • クオート文字で始まる引数は、行末までにクオート文字が出現しない場合、行末末までのすべての文字を 含む。

プログラムは、"MODULA-2 Compiler for Z80-CP/M Version 2.01"で作成しました。

まずは、テストプログラム"TstArgs.mod"で、実際に引き数の入力や分解をみてください。

C0#tstargs
arguments>one  , two three "ONE TWO  ", '   THREE FOUR' four
Argc:=  6
  0[one]
  1[two]
  2[three]
  3[ONE TWO  ]
  4[   THREE FOUR]
  5[four]            

C0#tstargs
arguments>  , one two three   ,      <---カンマ直後に改行
Argc:=  5
  0[]
  1[one]
  2[two]
  3[three]
  4[] 

C0#tstargs
arguments> one  two 'Three,Four Five   <--- Fiveの後ろにはスペースがある
Argc:=  3
  0[one]
  1[two]
  2[Three,Four Five     ]

テストプログラム"TstArgs.mod"は、このようになります。

MODULE TstArgs;
FROM InOut IMPORT Write,WriteInt,WriteLn,WriteString;
FROM CmdArgs IMPORT Argc,Argv;   <--- コマンド行の引数を処理するモジュールを取り込む

CONST
        MAXSTRINGLENGTH = 80;

VAR
        Arg: ARRAY [0..MAXSTRINGLENGTH] OF CHAR;
        nArgs: CARDINAL;

BEGIN
        WriteString('Argc:=');WriteInt(Argc,3);WriteLn;
        nArgs := 0;
        WHILE nArgs < Argc DO
                WriteInt(nArgs,3);
                Write('[');
                Argv(nArgs, Arg);
                WriteString(Arg);
                Write(']');WriteLn;
                INC(nArgs);
        END;
END TstArgs.

コマンド行を処理するモジュール"CmdArgs.mod"については、分量があるので、次回に公開します。