<> <> <> <> <<>> 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 = { <> 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 { <> filter.list _ CONS[arg, filter.list]; LOOP; }; SELECT TRUE FROM Rope.Match["*/", arg], Rope.Match["*>", arg] => { <> dir _ arg; LOOP; }; ENDCASE; <> 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 = { <> 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; }; <> 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 = { <> 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; }; <> 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 => { <> 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 <> 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; <> 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.