Split.mesa
Copyright © 1985, Xerox Corporation. All rights reserved.
Eric Nickell, June 11, 1985 11:59:12 am PDT
DIRECTORY
Commander USING [CommandProc, Register],
CommandTool USING [ParseToList],
Convert USING [RopeFromInt],
FS USING [StreamOpen],
IO USING [Close, EndOfStream, GetChar, PutChar, STREAM],
Rope USING [Cat, Find, ROPE, Substr],
UserProfile USING [Number]
;
Split: CEDAR PROGRAM
IMPORTS Commander, CommandTool, Convert, FS, IO, Rope, UserProfile
= BEGIN
ROPE: TYPE ~ Rope.ROPE;
splitDefaultSize: INT ~ 179968;
HeadAndTail: PROC [file: ROPE] RETURNS [head, tail: ROPE] ~ {
pos: INT ~ Rope.Find[file, "."];
IF pos=-1 THEN RETURN [file, NIL];
head ← Rope.Substr[base: file, len: pos];
tail ← Rope.Substr[base: file, start: pos];
};
PadWithNulls: PROC [s: IO.STREAM, alreadyIn: INT] ~ {
padTo: INT ~ UserProfile.Number["Split.Pad", -1];
IF padTo<0 THEN RETURN;
THROUGH ((alreadyIn-1) MOD padTo..padTo) DO
IO.PutChar[s, '\000];
ENDLOOP;
};
SplitCmd: Commander.CommandProc ~ {
files: LIST OF ROPE ~ CommandTool.ParseToList[cmd].list;
size: INT ~ UserProfile.Number["Split.Size", splitDefaultSize];
from, to: IO.STREAM;
byteCount: INT;
FOR each: LIST OF ROPE ← files, each.rest UNTIL each=NIL DO
ENABLE IO.EndOfStream => {PadWithNulls[to, byteCount]; IO.Close[to]; IO.Close[from]; LOOP};
file: ROPE ~ each.first;
segmentNumber: INT ← 1;
head, tail: ROPE;
from ← FS.StreamOpen[file];
[head, tail] ← HeadAndTail[file];
DO
to ← FS.StreamOpen[Rope.Cat[head, "-", Convert.RopeFromInt[segmentNumber], tail], create];
byteCount ← 0;
THROUGH [1..size] DO
IO.PutChar[to, IO.GetChar[from]];
byteCount ← byteCount+1;
ENDLOOP;
segmentNumber ← segmentNumber+1;
IO.Close[to];
ENDLOOP;
ENDLOOP;
};
Init: PROC ~ {
Commander.Register[key: "Split", proc: SplitCmd, doc: "Splits a file into a number of file."];
};
Init[];
END.