RepeatCommandImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Carl Hauser, May 7, 1986 5:23:26 pm PDT
DIRECTORY
BasicTime USING [GMT, Now, Period, Update, nullGMT],
Commander USING [CommandProc, Handle, Register],
CommandTool USING [DoCommand, ArgumentVector, Failed, Parse],
Convert USING [Error, IntFromRope],
List USING [Assoc],
Process USING [Pause, SecondsToTicks],
ProcessProps USING [GetPropList],
Rope USING [Cat, ROPE],
RepeatCommand,
Tempus USING [Parse, Unintelligible];
RepeatCommandImpl: CEDAR PROGRAM
IMPORTS BasicTime, Commander, CommandTool, Convert, List, Process, ProcessProps, Rope, Tempus
EXPORTS RepeatCommand
~ BEGIN
OPEN RepeatCommand;
doc: Rope.ROPE = "\"Command line to be performed\" [period [\"Start time interpretable by Tempus\" [nTimes]]]
 period defaults to 24*60*60 (one day)
 startTime defaults to BasicTime.Now[]
 nTimes defaults to LAST[INT]";
Repeat: PUBLIC PROC [cmd: Rope.ROPE, period: INT ← Days, start: BasicTime.GMT ← Immediately, nTimes: INT ← Forever] ~ {
nextTime: BasicTime.GMTIF start = BasicTime.nullGMT THEN BasicTime.Now[] ELSE start;
FOR i: INT IN [0..nTimes) DO
WaitForTime[nextTime];
[] ← CommandTool.DoCommand[commandLine: cmd, parent: NARROW[List.Assoc[$CommanderHandle, ProcessProps.GetPropList[]]]];
nextTime ← BasicTime.Update[nextTime, period];
ENDLOOP;
};
WaitForTime: PROC [time: BasicTime.GMT] ~ {
timeLeft: INT;
WHILE (timeLeft ← BasicTime.Period[ from: BasicTime.Now[], to: time ]) > 0 DO
Process.Pause[Process.SecondsToTicks[MIN[timeLeft, 1000]]];
ENDLOOP;
};
RepeatCommandProc: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd: cmd, starExpand: FALSE
! CommandTool.Failed => {msg ← Rope.Cat[ "usage: ", doc]; GO TO failed}];
When parsing the command line, be prepared for failure. The error is reported to the user.
argc: NAT ← argv.argc;
commandLine: Rope.ROPE;
startTime: BasicTime.GMT ← BasicTime.nullGMT;
period: INT ← Days;
nTimes: INTLAST[INT];
IF argc < 2 THEN {msg ← Rope.Cat[ "usage: ", doc]; GO TO failed};
commandLine ← argv[1];
IF argc >= 3 THEN period ← Convert.IntFromRope[argv[2] ! Convert.Error => {
msg ← Rope.Cat[ "Can't Parse \"", argv[2], "\" as an INT"]; GO TO failed}];
IF argc >= 4 THEN startTime ← Tempus.Parse[argv[3] ! Tempus.Unintelligible => {
msg ← Rope.Cat[ "Can't Parse \"", argv[3], "\" as a time"]; GO TO failed}].time;
IF argc >= 5 THEN nTimes ← Convert.IntFromRope[argv[4] ! Convert.Error => {
msg ← Rope.Cat[ "Can't Parse \"", argv[4], "\" as an INT"]; GO TO failed}];
Repeat[commandLine, period, startTime, nTimes];
EXITS
failed => {result ← $Failure};
};
Initialization
Commander.Register[
key: "///Commands/Repeat",
proc: RepeatCommandProc,
doc: doc,
clientData: NIL,
interpreted: TRUE
];
END.