久しぶりに、Modula-2でプログラミング -- その3 -- "CmdLine.mod"モジュールの応用"Find.mod"の紹介 ― 2023年01月26日 11:18
先に公開しました"CmdLine.mod"モジュールを使った応用を紹介します。
応用モジュール"Find.mod"は、指定された文字列をファイル中から探し表示します。このような感じです。
文字列"WriteLn"をファイル"find.mod"、"cmdargs.def"、"tstargs.mod"から探して表示します。
C0#find
arguments>WriteLn find.mod cmdargs.def tstargs.mod
find.mod[3]FROM InOut IMPORT Write,WriteCard,WriteString,WriteLn;
find.mod[35] WriteLn;
find.mod[87] WriteString('find');WriteLn;
find.mod[88] WriteString(' TargetString File1 File2 FIle3,,,,');WriteLn;
tstargs.mod[2]FROM InOut IMPORT Write,WriteInt,WriteLn,WriteString;
tstargs.mod[13] WriteString('Argc:=');WriteInt(Argc,3);WriteLn;
tstargs.mod[20] Write(']');WriteLn;
このように、ファイル名、出現した行番号、出現した行を表示します。"CmdArgs.def"には、該当する文字列がありませんでした。
では、"Find.mod"モジュールの内容です。文字列の検索は"FindTarget()"手続きでします。
ストレートに書き下しましたので、ロジックを追えることと思います。
Find.mod
MODULE Find;
FROM CmdArgs IMPORT Argc,Argv;
FROM InOut IMPORT Write,WriteCard,WriteString,WriteLn;
FROM ASCII IMPORT nul,lf;
FROM Files IMPORT FILE,FileState,Open,Close,Read;
FROM OpSys IMPORT Bdos,BdosFunctions;
FROM SYSTEM IMPORT WORD;
CONST
EOS = nul;
MAXLINE = 128;
FILENAMESIZE = 15;
EOFMARK = 32C;
VAR
FileName: ARRAY [0..FILENAMESIZE] OF CHAR;
Target: ARRAY [0..MAXLINE] OF CHAR;
LineBuffer: ARRAY [0..MAXLINE] OF CHAR;
FileNumber,LineNumber: CARDINAL;
inFile: FILE;
EndOfFile: BOOLEAN;
fs: FileState;
BdosCmd: RECORD
CASE BOOLEAN OF
TRUE: Func: BdosFunctions;
| FALSE: Cmd: WORD;
END;
END;
PROCEDURE putLine(Name:ARRAY OF CHAR;Line:CARDINAL;Buffer:ARRAY OF CHAR);
BEGIN
WriteString(Name);
Write('[');WriteCard(Line,1);Write(']');
WriteString(Buffer);
WriteLn;
END putLine;
PROCEDURE ReBoot();
VAR
junk: WORD;
BEGIN
BdosCmd.Func := boot;
Bdos(BdosCmd.Cmd,junk,junk);
END ReBoot;
PROCEDURE findTarget(Target,Line:ARRAY OF CHAR): BOOLEAN;
VAR
t,l: CARDINAL;
found: BOOLEAN;
BEGIN
found := FALSE;
t := 0; l := 0;
WHILE (Line[l] # EOS) AND (NOT found) DO
IF Line[l] = Target[0] THEN
t := 1;
WHILE Line[l+t] = Target[t] DO
INC(t);
END;
IF Target[t] = EOS THEN
found := TRUE;
END;
END;
INC(l);
END;
RETURN found;
END findTarget;
PROCEDURE ReadLine(f:FILE;VAR Line:ARRAY OF CHAR);
VAR
c: CARDINAL;
BEGIN
c := 0;
Read(f,Line[c]);
WHILE (Line[c] # lf) AND (NOT EndOfFile) DO
IF Line[c] = EOFMARK THEN
EndOfFile := TRUE;
ELSE
INC(c);
Read(f,Line[c]);
END;
END;
Line[c] := EOS;
END ReadLine;
PROCEDURE Usage();
BEGIN
WriteString('find');WriteLn;
WriteString(' TargetString File1 File2 FIle3,,,,');WriteLn;
END Usage;
BEGIN
IF Argc < 1 THEN
Usage();
ReBoot();
END;
Argv(0,Target);
FileNumber := 1;
WHILE FileNumber < Argc DO
Argv(FileNumber,FileName);
fs := Open(inFile,FileName);
IF fs = FileOK THEN
EndOfFile := FALSE;
LineNumber := 1;
WHILE NOT EndOfFile DO
ReadLine(inFile,LineBuffer);
IF findTarget(Target,LineBuffer) THEN
putLine(FileName,LineNumber,
LineBuffer);
END;
INC(LineNumber);
END;
fs := Close(inFile);
END;
INC(FileNumber);
END;
END Find.
コメントをどうぞ
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。