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"モジュールに実装しました。 こうすることで、ファイル名の保持のしかたをメインルーチンが知る必要がありません。
最近のコメント