久しぶりに、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.
最近のコメント