ODImpl.mesa
Octal dump
Last Edited by: Stewart, March 19, 1983 7:20 pm
DIRECTORY
Commander USING [CommandProc, Register],
CommandTool USING [ArgumentVector, Failed, Parse],
Convert: TYPE USING [IntFromRope],
FS: TYPE USING [StreamOpen],
IO,
Rope;
ODImpl: PROGRAM
IMPORTS Commander, CommandTool, Convert, FS, IO, Rope
= {
Type a file
OD: Commander.CommandProc = TRUSTED {
inputSTREAM: IO.STREAM;
outputSTREAM: IO.STREAM;
inputFileName: Rope.ROPE;
outputFileName: Rope.ROPE;
outputRadix: NAT;
createViewer: BOOLFALSE;
argv: CommandTool.ArgumentVector;
bytesRead: NAT;
buffer: REF TEXTNEW[TEXT[256]];
argIndex: NAT ← 1;
token: Rope.ROPE;
filePos: INT ← 0;
words: BOOLFALSE;
word: CARDINAL;
chars: STRING ← [16];
out: IO.STREAM ← cmd.out;
NextToken: PROC RETURNS [t: Rope.ROPE] = {
IF argIndex >= argv.argc THEN RETURN [NIL];
t ← argv[argIndex];
argIndex ← argIndex + 1;
};
Case: PROC [c: Rope.ROPE] RETURNS [BOOL] = {
RETURN [Rope.Equal[c, token, FALSE]];
};
OutByte: PROC [c: CHAR] = {
IF (filePos MOD 16) = 0 THEN outputSTREAM.PutF[IF filePos > LAST[CARDINAL] THEN " %08x" ELSE " %04x", IO.card[filePos]];
chars[filePos MOD 16] ← IF c IN [40C..176C] THEN c ELSE '.;
IF words THEN word ← word * 256 + LOOPHOLE[c, CARDINAL];
SELECT TRUE FROM
words AND (filePos MOD 2) = 1 => outputSTREAM.PutF[" %04x", IO.card[word]];
NOT words => outputSTREAM.PutF[" %02x", IO.card[LOOPHOLE[c, CARDINAL]]];
ENDCASE;
IF (filePos MOD 16) = 15 THEN {
outputSTREAM.PutF[" "];
FOR j: NAT IN [0..16) DO outputSTREAM.PutChar[chars[j]]; ENDLOOP;
outputSTREAM.PutChar['\n];
};
filePos ← filePos + 1;
};
chars.length ← 16;
argv ← CommandTool.Parse[cmd ! CommandTool.Failed => {msg ← errorMsg; CONTINUE; }];
IF argv = NIL THEN RETURN[$Failure, msg];
DO
token ← NextToken[];
IF token.Length[]=0 THEN EXIT;
SELECT TRUE FROM
Case["-if"] => inputFileName ← NextToken[];
Case["-of"] => outputFileName ← NextToken[];
Case["-base"] => outputRadix ← Convert.IntFromRope[NextToken[]];
Case["-bytes"] => words ← FALSE;
Case["-words"] => words ← TRUE;
Case["-viewer"] => createViewer ← TRUE;
ENDCASE => {
out.PutF["Unknown switch token: %s\n", IO.rope[token]];
LOOP;
};
ENDLOOP;
{
ENABLE {
IO.EndOfStream => {
out.PutChar['\n];
CONTINUE;
};
};
IF inputFileName.Length[] = 0 OR outputFileName.Length[] = 0 THEN RETURN;
inputSTREAM ← FS.StreamOpen[fileName: inputFileName, streamOptions: [FALSE, TRUE, TRUE, TRUE, TRUE]];
outputSTREAM ← FS.StreamOpen[fileName: outputFileName, accessOptions: $create];
DO
bytesRead ← inputSTREAM.GetBlock[buffer];
FOR i: NAT IN [0..bytesRead) DO OutByte[buffer[i]]; ENDLOOP;
IF bytesRead # 256 THEN EXIT;
ENDLOOP;
};
IF inputSTREAM#NIL THEN inputSTREAM.Close[];
IF outputSTREAM#NIL THEN outputSTREAM.Close[];
};
Mainline
Commander.Register["OD.~", OD, "Dump file in radix"];
}.