Modula-2 でプログラミング -- 文字列探索プログラム find の製作 (その3) --
2025-01-05


前回紹介したfindプログラムは、FileSearchモジュールの不備で、ファイル一覧の構造が 丸見えになっていました。FileSearchモジュールに2つ手続きを追加して不具合を解消しました。

新しいFileSearchモジュールの定義モジュールは以下の通り。

DEFINITION MODULE FileSearch;

FROM OpSys IMPORT FCB,FCBFileName;

EXPORT QUALIFIED pFileList,FileNameNode,
        GetNextFile,GetFileName,LoginDisk,MakeFileList,DumpFileList;

CONST
        DMABufferSize = 128;
        FileNameSize = 14;

TYPE
        pFileList = POINTER TO FileNameNode;
        FileNameNode = RECORD
                FileName: ARRAY [0..FileNameSize] OF CHAR;
                Next: pFileList
        END;
        DMA = ARRAY [0..DMABufferSize-1] OF CHAR;

PROCEDURE GetNextFile(FileLIst: pFileList): pFileList;
PROCEDURE GetFileName(FileList: pFileList;VAR FileName: ARRAY OF CHAR);
PROCEDURE LoginDisk(FCBBuf: FCB): CHAR;
PROCEDURE MakeFileList(FIleMatch: ARRAY OF CHAR): pFileList;
PROCEDURE DumpFileList(pList: pFileList);
END FileSearch.
手続き、次のファイルを取り出すGetNextFileとファイル名を取り出すGetFileNameを追加しました。 実現モジュールは以下の通り。
IMPLEMENTATION MODULE FileSearch;
FROM InOut IMPORT WriteHex,Write,WriteString,WriteLn;
FROM OpSys IMPORT FCB,FCBFileName,BdosFunctions,Bdos;
FROM SYSTEM IMPORT ALLOCATE,TSIZE,ADR,WORD;
FROM FileNames IMPORT StrToFCB,FCBToStr,NameState;

CONST
        EOS = 0C;

PROCEDURE GetNextFile(FileList: pFileList): pFileList;
BEGIN
        RETURN FileList^.Next
END GetNextFile;

PROCEDURE GetFileName(FileList: pFileList; VAR FileName: ARRAY OF CHAR);
VAR
        i: CARDINAL; 
BEGIN
        i := 0;
        WHILE ( FileList^.FileName[i] # EOS ) DO
                FileName[i] := FileList^.FileName[i];
                INC(i)
        END;
        FileName[i] := EOS
END GetFileName;

PROCEDURE LoginDisk(FCBBuf: FCB): CHAR;
VAR
        DiskCode: CARDINAL;
        Junk: WORD;

BEGIN
        IF FCBBuf.name.disk = 0C THEN
                Bdos(retCDsk,Junk,DiskCode);
                RETURN (CHR(ORD(DiskCode)+ORD('A')));
        ELSE
                RETURN (CHR(ORD(FCBBuf.name.disk)+ORD('A')-1));
        END;
END LoginDisk;

PROCEDURE MakeFileList(FileMatch: ARRAY OF CHAR): pFileList;
VAR
        Disk: CHAR;
        FCBBuffer: FCB;
        BdosRc: CARDINAL;
        DMABuffer: DMA;
        CPos: CARDINAL;
        NameStatus: NameState;
        pList: pFileList;
        pNewFileName: pFileList;
        FCBFile: FCBFileName;
        Formatted: BOOLEAN;
        Junk: WORD;

BEGIN
        pList := NIL;

        (* Clear FCB Buffer and set file name *)
        FCBBuffer.name.text := '';
        FCBBuffer.rest := '';
        NameStatus := StrToFCB(FileMatch,FCBBuffer.name);

        Disk := LoginDisk(FCBBuffer);

        (* set DMA Bufer *)
        Bdos(setDMA,ADR(DMABuffer),Junk);

        (* find first much file *)
        Bdos(searchFst,ADR(FCBBuffer),BdosRc);
        WHILE BdosRc # 255 DO
                ALLOCATE(pNewFileName,TSIZE(FileNameNode));
                FOR CPos := 0 TO 11 DO
                        FCBFile.text[CPos]
                                := DMABuffer[CPos+BdosRc*32]
                END;
                FCBFile.disk := CHR(ORD(Disk) - ORD('A') + 1);
                FCBToStr(FCBFile,pNewFileName^.FileName,FALSE);
                pNewFileName^.Next := pList;
                pList := pNewFileName;

                (* find next file *)
                Bdos(searchNxt,Junk,BdosRc);
        END;    
        RETURN pList
END MakeFileList;

PROCEDURE WriteFileName(FileName: ARRAY OF CHAR);
BEGIN
        WriteString(FileName);
        WriteLn
END WriteFileName;

PROCEDURE DumpFileList(pList: pFileList);
BEGIN
        WHILE pList # NIL DO
                WriteFileName(pList^.FileName);
                pList := pList^.Next;
        END;
END DumpFileList;
END FileSearch.

これらの変更を反映したfindは、以下のとおり。



続きを読む

[コンピューター]
[CP/M]
[Modula-2]

コメント(全0件)
コメントをする


記事を書く
powered by ASAHIネット