-- CreateAlpineFileImpl.Mesa
-- last edited November 18, 1983 1:44 pm by Karen Kolling.
-- edited 2-Dec-81 1:09:36 by Paul Rovner.

DIRECTORY
AlpineEnvironment USING[VolumeID],
Commander USING[CommandProc, Register],
File USING[Create, Delete, Error, FindVolumeFromName, FP, GetVolumeID, Handle,
Info, NullVolumeRep, Volume],
FileInternal USING[Object],
FS USING[StreamOpen],
IO
USING[card, Close, GetCard, GetCedarTokenRope, int, PutF, PutRope, STREAM],
Rope USING[Equal, ROPE];

CreateAlpineFileImpl: PROGRAM
IMPORTS Commander, File, FS, IO, Rope
SHARES File

= BEGIN OPEN AE: AlpineEnvironment;

filePages: NAT;

FileIsContiguousOnDisk: PROCEDURE[fileHandle: File.Handle] RETURNS[contiguous:
BOOLEAN] =
BEGIN
longPointerFileInternalObject: LONG POINTER TO FileInternal.Object ← LOOPHOLE[fileHandle];
RETURN[longPointerFileInternalObject.runTable.nRuns = 1];
END;


-- Commander.CommandProc TYPE = PROC [cmd: Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL];

Main
: Commander.CommandProc = TRUSTED
BEGIN
success: BOOLEANFALSE;
volume: File.Volume;
volumeID: AE.VolumeID;
volumeName: Rope.ROPE;
fileHandle: File.Handle ← NIL;
fp: File.FP;
fileArrayMaxLength: NAT = 40;
fileArray: ARRAY [0..fileArrayMaxLength) OF File.Handle ← ALL[NIL];
index: NAT ← 0;
answer: Rope.ROPE;
resultsStreamHandle: IO.STREAM ← FS.StreamOpen["CreateAlpineContiguousFiles.Results", $create];

cmd.out.PutRope["
Please type volume name: "];
volumeName ← cmd.in.GetCedarTokenRope[].token;
volume ← File.FindVolumeFromName[volumeName];
volumeID ← LOOPHOLE[File.GetVolumeID[volume]];
resultsStreamHandle.PutF["\n%g ", IO.card[LOOPHOLE[volumeID, File.NullVolumeRep].a]];
resultsStreamHandle.PutF["%g ", IO.card[LOOPHOLE[volumeID, File.NullVolumeRep].b]];
resultsStreamHandle.PutF["%g ", IO.card[LOOPHOLE[volumeID, File.NullVolumeRep].c]];
resultsStreamHandle.PutF["%g ", IO.card[LOOPHOLE[volumeID, File.NullVolumeRep].d]];
resultsStreamHandle.PutF["%g\n", IO.card[LOOPHOLE[volumeID, File.NullVolumeRep].e]];

DO
cmd.out.PutRope["
Please type desired file size in pages: "];
filePages ← cmd.in.GetCard[];
success ← FALSE;
index ← 0;
DO
fileHandle ← File.Create[volume, filePages ! File.Error => IF why = volumeFull THEN EXIT;];
IF FileIsContiguousOnDisk[fileHandle] THEN BEGIN success ← TRUE; EXIT; END;
fileArray[index] ← fileHandle;
index ← index + 1;
IF index >= fileArrayMaxLength THEN EXIT;
ENDLOOP;
FOR i: NAT IN [0..index)
DO File.Delete[fileArray[i]];
ENDLOOP;
IF NOT success
THEN BEGIN cmd.out.PutRope["
Failure. The volume is fragmented enough that you'll have to erase it and start from fresh to create the Alpine file.
"];
EXIT;
END

ELSE cmd.out.PutRope["
Success. File has been created.
"];
fp ← File.Info[fileHandle].fp;
resultsStreamHandle.PutF["%g ", IO.int[LOOPHOLE[fp.id]]];
resultsStreamHandle.PutF["%g \n", IO.int[LOOPHOLE[fp.da]]];
cmd.out.PutRope["
Another file (y or n): "];
answer ← cmd.in.GetCedarTokenRope[].token;
IF
Rope.Equal[answer, "y", FALSE] THEN LOOP;
EXIT;
ENDLOOP;

resultsStreamHandle.Close[];

END
;



-- START HERE

Commander.Register[key: "Main", proc: Main];

END.