Modula-2でプログラミング -- FileSearch ファイルを探すモジュールの修正 ― 2024年11月02日 10:29
前回、ファイルを探すモジュール"FileSearch"を制作しました。これを利用したプログラムを
いくつか作成して見た所、ファイル名リストのデータ構造の使い勝手が良くないことがわかりました
ので"FileSearch"モジュールを修正しました。
修正した"FileSearch"モジュールのDefinition Moduleです。
DEFINITION MODULE FileSearch;
FROM OpSys IMPORT FCB,FCBFileName;
EXPORT QUALIFIED pFileList,FileNameNode,DMA,
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 LoginDisk(FCBBuf: FCB): CHAR;
PROCEDURE MakeFileList(FIleMatch: ARRAY OF CHAR): pFileList;
PROCEDURE DumpFileList(pList: pFileList);
END FileSearch.
大きな変更点は、ファイル名の持ち方をべたな文字列にした点です。
修正したImprementation Moduleは、このとおり。
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 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.
大きな修正点は、見つかったファイルの名前をFCB形式からべたな文字列のファイル名に変換し、 それを保存している点です。 ファイル名の持ち方をべたな文字列にしたので、ファイル名を書き出すPROCEDURE "WriteFileName"を 修正しています。
他には、"BdosStruct"モジュールの使用をやめました。処理系が提供する Bdos関連機能の"OpSys"モジュールを一部修正し、"BdosStruct"モジュールが無くてもコンパイル できるようにしました。
Modula-2でプログラミング -- FileFindの制作 ― 2024年11月02日 11:36
FIleSearche"モジュールを利用した、ファイマッチで指定されたファイル一覧を書き出すプログラム "FileFind"を作ってみました。
使い方は、このようにします。
C0#filefind arguments>f*.mod *.def C:FIND.MOD C:FILEFIND.MOD C:FILESEAR.MOD C:CONIO.DEF C:ADD16.DEF C:SILLY.DEF C:FILESEAR.DEF C:STDFILEI.DEF C:BDOSSTRU.DEF C:BASICFIL.DEF C:CMDARGS.DEF C:SCREEN.DEF
探すファイル名は、ファイルマッチを指定できます。複数指定できます。 この引数を受け取るには、以前紹介した自作の"CmdArgs"モジュール を使用しています。
プログラムは、このようになりました。
MODULE FileFind;
FROM InOut IMPORT WriteString,WriteLn;
FROM CmdArgs IMPORT Argc,Argv;
FROM FileSearch IMPORT MakeFileList,DumpFileList;
CONST
MAXLINE = 128;
VAR
FileMatch: ARRAY [0..MAXLINE-1] OF CHAR;
nArgc: CARDINAL;
NthFile: CARDINAL;
PROCEDURE Usage();
BEGIN
WriteString('Usage: filefind filematch');WriteLn;
END Usage;
BEGIN
nArgc := Argc();
IF nArgc < 1 THEN
Usage();
HALT;
END;
NthFile := 0;
WHILE NthFile < nArgc DO
Argv(NthFile,FileMatch);
DumpFileList(MakeFileList(FileMatch));
INC(NthFile);
END;
END FileFind.
次々にファイルマッチを取り出し、該当するファイル名のリストを"MakeFileList"で作成し、 そのリストを"DumpFileLIst"で書き出します。"DumpFileList"は、"FileSearch"モジュールに実装しました。 こうすることで、ファイル名の保持のしかたをメインルーチンが知る必要がありません。
最近のコメント