TransTiogaImpl.mesa
Copyright Ó 1985, 1993 by Xerox Corporation. All rights reserved.
Bloomenthal, May 8, 1989 12:20:19 pm PDT
Willie-s, January 18, 1993 1:14 pm PST
DIRECTORY Ascii, CedarProcess, Commander, CommanderOps, FileNames, FS, IO, Rope, TiogaAccess;
TransTiogaImpl: CEDAR PROGRAM
IMPORTS Ascii, CedarProcess, Commander, CommanderOps, FileNames, FS, IO, Rope, TiogaAccess
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
Reader: TYPE ~ TiogaAccess.Reader;
TiogaChar: TYPE ~ TiogaAccess.TiogaChar;
CharSequence: TYPE ~ RECORD [seq: SEQUENCE maxLength: CARDINAL OF CHAR];
TiogaCharSequence: TYPE ~ RECORD [seq: SEQUENCE maxLength: CARDINAL OF TiogaChar];
Performing substitutions on Tioga documents
TransTiogaCommand: Commander.CommandProc ~ {
out: IO.STREAM ¬ cmd.out;
argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd];
IF argv.argc < 4 THEN RETURN[$Failure, usage];
FOR i: NAT IN [3..argv.argc) DO
Reverse: PROC [list: LIST OF ROPE] RETURNS [rev: LIST OF ROPE] ~ {
FOR l: LIST OF ROPE ¬ list, l.rest WHILE l # NIL DO rev ¬ CONS[l.first, rev]; ENDLOOP;
};
Each: PROC [name: ROPE] RETURNS [BOOL ¬ TRUE] ~ {names ¬ CONS[name, names]};
names: LIST OF ROPE ¬ NIL;
pattern: ROPE ¬ IF Rope.Equal[FileNames.StripVersionNumber[argv[i]], argv[i]]
THEN Rope.Concat[argv[i], "!H"]
ELSE argv[i];
FS.EnumerateForNames[pattern, Each ! FS.Error => LOOP];
IF names = NIL
THEN IO.PutRope[out, Rope.Cat["No such files: ", argv[i], "\n"]]
ELSE FOR l: LIST OF ROPE ¬ Reverse[names], l.rest WHILE l # NIL DO
nSubs: NAT;
reader: Reader ¬ TiogaAccess.FromFile[l.first ! FS.Error => LOOP];
IO.PutRope[out, Rope.Cat["Translating ", FileNames.GetShortName[l.first, FALSE], ": "]];
nSubs ¬ TransTioga[reader, l.first, argv[1], argv[2]];
IO.PutF[out, "%g substitution%g\n",
IO.int[nSubs], IO.rope[IF nSubs = 1 THEN NIL ELSE "s"]];
ENDLOOP;
ENDLOOP;
};
TransTioga: PROC [reader: Reader, fileName, key, sub: ROPE] RETURNS [nSubs: NAT ¬ 0] ~ {
IF NOT Rope.IsEmpty[key] AND NOT Rope.IsEmpty[sub] THEN {
writer: TiogaAccess.Writer ¬ TiogaAccess.Create[];
firstKeyChar: CHAR ¬ Ascii.Lower[Rope.Fetch[key]];
keyLen: NAT ¬ Rope.Length[key];
subLen: NAT ¬ Rope.Length[sub];
keyChars: REF CharSequence ¬ NEW[CharSequence[keyLen]];
subChars: REF CharSequence ¬ NEW[CharSequence[subLen]];
tiogaChars: REF TiogaCharSequence ¬ NEW[TiogaCharSequence[keyLen]];
FOR n: NAT IN [0..keyLen) DO keyChars[n] ¬ Ascii.Lower[Rope.Fetch[key, n]]; ENDLOOP;
FOR n: NAT IN [0..subLen) DO subChars[n] ¬ Rope.Fetch[sub, n]; ENDLOOP;
DO
tiogaChar: TiogaChar;
CedarProcess.CheckAbort[];
IF TiogaAccess.EndOf[reader]
THEN {
IF nSubs > 0 THEN TiogaAccess.WriteFile[writer, fileName];
EXIT;
};
tiogaChar ¬ tiogaChars[0] ¬ TiogaAccess.Get[reader];
IF Ascii.Lower[tiogaChar.char] = firstKeyChar
THEN {
FOR n: NAT IN [1..keyLen) DO
IF TiogaAccess.EndOf[reader] THEN EXIT;
tiogaChars[n] ¬ TiogaAccess.Get[reader];
IF Ascii.Lower[tiogaChars[n].char] # keyChars[n] THEN {
FOR i: INT IN [0..n] DO TiogaAccess.Put[writer, tiogaChars[i]]; ENDLOOP;
EXIT;
};
REPEAT
FINISHED => {
nSubs ¬ nSubs+1;
subChars[0] ¬ SELECT tiogaChar.char FROM
IN ['A..'Z] => Ascii.Upper[subChars[0]],
IN ['a..'z] => Ascii.Lower[subChars[0]],
ENDCASE => subChars[0];
FOR n: NAT IN [0..subLen) DO
tiogaChar.char ¬ subChars[n];
TiogaAccess.Put[writer, tiogaChar];
ENDLOOP;
};
ENDLOOP;
}
ELSE TiogaAccess.Put[writer, tiogaChar];
ENDLOOP;
};
};
Start Code
usage: ROPE ¬ "TransTioga <key> <replacement> <file1> . . . <fileN>";
Commander.Register["TransTioga", TransTiogaCommand, usage];
END.