前回紹介した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は、以下のとおり。
セコメントをする