久しぶりに、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の入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://kida.asablo.jp/blog/2023/01/26/9558317/tb