DFCommands.mesa
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) February 14, 1986 1:09:41 pm PST
Spreitzer, February 12, 1986 4:18:18 pm PST
DIRECTORY
Ascii USING [Lower],
BasicTime USING [GMT, nullGMT, Period],
Commander USING [CommandProc, Register, Handle],
CommandTool USING [ArgumentVector, Parse, Failed],
DFInternal USING [DefaultInteractionProc],
DFOperations USING [BringOver, BringOverAction, BringOverFilter, SModel, SModelAction, Verify],
FS USING [Error, FileInfo],
FileViewerOps USING [WaitUntilSaved],
IO USING [PutF, PutRope, STREAM],
Rope USING [Concat, Fetch, Find, Length, Match, ROPE, SkipTo, Substr],
VersionMap USING [MapAndNameList, ShortNameToNames],
VersionMapDefaults USING [GetMapList];
DFCommands:
CEDAR
PROGRAM
IMPORTS Ascii, BasicTime, Commander, CommandTool, DFInternal, DFOperations, FS, FileViewerOps, IO, Rope, VersionMap, VersionMapDefaults = BEGIN
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
DoBringover: Commander.CommandProc = {
PROC [cmd: Commander.Handle] RETURNS [result: REF ← NIL, msg: Rope.ROPE ← NIL]
errors, warnings, filesActedUpon: INT;
tryMap: BOOL ← FALSE;
oSwitch: BOOL ← FALSE;
touchy: BOOL ← FALSE;
out: STREAM = cmd.out;
filter: DFOperations.BringOverFilter ← [filterA: $all, filterB: $all, filterC: $all, list: NIL];
action: DFOperations.BringOverAction ← $enter;
dir: ROPE ← NIL;
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd
! CommandTool.Failed => {msg ← errorMsg; GO TO fail}];
IF argv = NIL OR argv.argc < 2 THEN {msg ← bringoverHelpText; GO TO fail};
FOR i:
NAT
IN [1..argv.argc)
DO
arg: ROPE ← argv[i];
IF Rope.Match["-*", arg]
THEN {
sense: BOOL ← TRUE;
FOR j:
INT
IN [1..Rope.Length[arg])
DO
c: CHAR ← Ascii.Lower[Rope.Fetch[arg, j]];
SELECT c
FROM
'b => filter.filterA ← $derived;
'f => action ← $fetch;
'm => tryMap ← sense;
'o => {oSwitch ← sense; filter.list ← NIL};
'p => filter.filterB ← $public;
'r => filter.filterC ← $imported;
's => filter.filterA ← $source;
't => touchy ← sense;
'u => {filter ← [filterA: $all, filterB: $all, filterC: $all, list: NIL]; action ← $enter};
'v => action ← $check;
'w => filter.filterC ← $defining;
'x => oSwitch ← sense;
'~ => {sense ← NOT sense; LOOP};
ENDCASE;
sense ← TRUE;
ENDLOOP;
LOOP;
};
IF oSwitch
AND i < argv.argc-1
THEN {
just add this file to the filter list
filter.list ← CONS[arg, filter.list];
LOOP;
};
SELECT
TRUE
FROM
Rope.Match["*/", arg], Rope.Match["*>", arg] => {
This is a directory, which will be applied to future files as needed.
dir ← arg;
LOOP;
};
ENDCASE;
At this point we can do the bringover of the file.
IF (arg ← CompleteDFFileName[arg, out, dir, tryMap]) = NIL THEN GO TO fail;
[errors, warnings, filesActedUpon] ← DFOperations.BringOver[
dfFile: arg, filter: filter, action: action,
interact: DFInternal.DefaultInteractionProc, clientData: NIL, log: out];
filter.list ← NIL;
oSwitch ← FALSE;
IF errors + warnings # 0
THEN
IO.PutF[out, "%g errors, %g warnings, %g files acted upon\n",
[integer[errors]], [integer[warnings]], [integer[filesActedUpon]]]
ELSE IO.PutF[out, "%g files acted upon\n", [integer[filesActedUpon]]];
IF errors # 0
OR touchy
AND warnings # 0
THEN {
msg ← "Command terminated.\n";
GO TO fail};
ENDLOOP;
EXITS fail => result ← $Failure;
};
DoSModel: Commander.CommandProc = {
PROC [cmd: Commander.Handle] RETURNS [result: REF ← NIL, msg: ROPE ← NIL]
errors, warnings, filesActedUpon: INT;
oSwitch: BOOL ← FALSE;
touchy: BOOL ← FALSE;
out: STREAM = cmd.out;
action: DFOperations.SModelAction ← [remoteCheck: TRUE, storeChanged: TRUE];
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd
! CommandTool.Failed => {msg ← errorMsg; GO TO fail}];
IF argv = NIL OR argv.argc < 2 THEN {msg ← smodelHelpText; GO TO fail};
FOR i:
NAT
IN [1..argv.argc)
DO
arg: ROPE ← argv[i];
IF Rope.Match["-*", arg]
THEN {
FOR j:
INT
IN [1..Rope.Length[arg])
DO
c: CHAR ← Ascii.Lower[Rope.Fetch[arg, j]];
SELECT c
FROM
'd => action.remoteCheck ← FALSE;
'n => action.storeChanged ← FALSE;
'u => action.storeChanged ← action.remoteCheck ← TRUE;
't => touchy ← TRUE;
ENDCASE;
ENDLOOP;
LOOP;
};
At this point we can do the smodel of the file.
IF (arg ← CompleteDFFileName[arg, out]) = NIL THEN GO TO fail;
[errors, warnings, filesActedUpon] ← DFOperations.SModel[
dfFile: arg, action: action,
interact: DFInternal.DefaultInteractionProc, clientData: NIL, log: out];
IF errors + warnings # 0
THEN IO.PutF[out, "%g errors, %g warnings, %g files acted upon\n", [integer[errors]], [integer[warnings]], [integer[filesActedUpon]]]
ELSE IO.PutF[out, "%g files acted upon\n", [integer[filesActedUpon]]];
IF errors # 0 OR touchy AND warnings # 0 THEN {msg ← "Command terminated.\n"; GO TO fail};
ENDLOOP;
EXITS fail => result ← $Failure;
};
DoVerifyDF: Commander.CommandProc = {
PROC [cmd: Commander.Handle] RETURNS [result: REF ← NIL, msg: Rope.ROPE ← NIL]
errors, warnings, filesActedUpon: INT;
oSwitch: BOOL ← FALSE;
touchy: BOOL ← FALSE;
out: STREAM = cmd.out;
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd
! CommandTool.Failed => {msg ← errorMsg; GO TO fail}];
IF argv = NIL OR argv.argc < 2 THEN {msg ← verifydfHelpText; GO TO fail};
FOR i:
NAT
IN [1..argv.argc)
DO
arg: ROPE ← argv[i];
IF Rope.Match["-*", arg]
THEN {
FOR j:
INT
IN [1..Rope.Length[arg])
DO
c: CHAR ← Ascii.Lower[Rope.Fetch[arg, j]];
SELECT c
FROM
't => touchy ← TRUE;
ENDCASE;
ENDLOOP;
LOOP;
};
At this point we can do the verification of the file.
IF (arg ← CompleteDFFileName[arg, out]) = NIL THEN GO TO fail;
[errors, warnings, filesActedUpon] ← DFOperations.Verify[
dfFile: arg,
interact: DFInternal.DefaultInteractionProc, clientData: NIL, log: out];
IF errors + warnings # 0
THEN IO.PutF[out, "%g errors, %g warnings, %g files acted upon\n", [integer[errors]], [integer[warnings]], [integer[filesActedUpon]]]
ELSE IO.PutF[out, "%g files acted upon\n", [integer[filesActedUpon]]];
IF errors # 0 OR touchy AND warnings # 0 THEN {msg ← "Command terminated.\n"; GO TO fail};
ENDLOOP;
EXITS fail => result ← $Failure;
};
CompleteDFFileName:
PROC [dfFileName:
ROPE, out:
STREAM, dir:
ROPE ←
NIL, tryMap:
BOOL ←
FALSE]
RETURNS [
ROPE] = {
length: INT = dfFileName.Length[];
msg: ROPE ← NIL;
SELECT
TRUE
FROM
Rope.Match["*.df", dfFileName, FALSE], Rope.Find[dfFileName, "!"] # -1 => {};
ENDCASE => dfFileName ← Rope.Concat[dfFileName, ".df"];
{
SELECT
TRUE
FROM
Rope.Match["[*", dfFileName], Rope.Match["[*", dfFileName] => {};
tryMap => {
A short name has been supplied and we are directed to use the VersionMap to determine the remote directory.
names: VersionMap.MapAndNameList ← VersionMap.ShortNameToNames[
VersionMapDefaults.GetMapList[$Source], dfFileName];
bestName: ROPE ← NIL;
bestDate: BasicTime.GMT ← BasicTime.nullGMT;
FOR each: VersionMap.MapAndNameList ← names, each.rest
WHILE each #
NIL
DO
name: ROPE ← each.first.name;
len: INT ← Rope.Length[name];
pos: INT ← Rope.SkipTo[name, 0, "!"];
date: BasicTime.GMT;
IF pos # len
THEN
We remove the version so we can get the most current one
name ← Rope.Substr[name, 0, pos];
[fullFName: name, created: date] ←
FS.FileInfo[name: name
! FS.Error => {msg ← error.explanation; GO TO oops}
];
IF bestName #
NIL
THEN
IF BasicTime.Period[from: date, to: bestDate] < 0
THEN
LOOP;
In this case we have found a less good DF file
bestName ← name;
bestDate ← date;
ENDLOOP;
IF bestName # NIL THEN RETURN [bestName];
};
ENDCASE;
dfFileName ←
FS.FileInfo[name: dfFileName, wDir: dir
!
FS.Error =>
IF error.group # bug
THEN {
SELECT error.code
FROM
$unknownFile => msg ← Rope.Concat[dfFileName, " not found"];
ENDCASE => msg ← error.explanation;
GO TO oops;
}
].fullFName;
FileViewerOps.WaitUntilSaved[dfFileName, out];
RETURN [dfFileName];
EXITS oops => {
IO.PutRope[out, msg];
IO.PutRope[out, ", ending command.\n"];
RETURN [NIL];
};
};
};
bringoverHelpText:
ROPE = "dfFile*
Fetches files under control of the given DF files.
-b derived files only
-f force fetch of files
-m try version maps
-o only bring selected files
-p public files only
-r imported files only
-s source files only
-t touchy (warnings cause failure)
-v check entered files against server
-w definied files only (no imports)";
smodelHelpText:
ROPE = "dfFile*
Stores files under control of the given DF files.
-d don't remote check
-n don't store
-u store changed and remote check (default)
-t touchy (warnings cause failure)";
verifydfHelpText:
ROPE = "dfFile*
Verifies a list of DF files.
-t touchy (warnings cause failure)";
Commander.Register["///Commands/Bringover", DoBringover, bringoverHelpText];
Commander.Register["///Commands/SModel", DoSModel, smodelHelpText];
Commander.Register["///Commands/VerifyDF", DoVerifyDF, verifydfHelpText];
END.