-- BringOverExecImpl.Mesa, last edit April 12, 1983 9:40 am by Paul Rovner

DIRECTORY
 BringOverCall: TYPE USING[CedarBringOver],
CIFS: TYPE USING[GetWDir],
 Commander: TYPE USING[CommandProc, Register],
IO: TYPE USING[card, Handle, PutF, rope, STREAM, UserAbort, ResetUserAbort, PutRope],
 IOMisc: TYPE USING[AskUser],
 Resource: TYPE USING[Acquire, Release, AbortProc],
 Rope: TYPE USING[Cat, Equal, Fetch, Find, Flatten, Length, ROPE, Text],
 RopeInline: TYPE USING[InlineFlatten],
 Time: TYPE USING[Current],
UECP: TYPE USING[Argv, Parse];

BringOverExecImpl: CEDAR PROGRAM
IMPORTS BringOverCall, CIFS, Commander, IO, IOMisc, Resource, Rope, RopeInline, Time, UECP
= {

-- MDS usage!

abortProc: Resource.AbortProc = {
--PROC [data: REF ANY] RETURNS[abort: BOOL];
in: IO.STREAM = NARROW[data, IO.STREAM];
abort ← in.UserAbort[];
IF abort THEN in.ResetUserAbort[];
};

Main: Commander.CommandProc = {
--PROC [cmd: Handle];
 tok, wdir: Rope.ROPE;
 starttime: LONG CARDINAL ← TimeCurrent[];
 argv: UECP.Argv ← UECP.Parse[cmd.commandLine];
 parm: CARDINAL ← 1;
 switches: ARRAY CHAR['a .. 'z] OF BOOLALL[FALSE];
 usingListOfRopes, listOfFiles: LIST OF Rope.Text;
 in, out: IO.Handle;

 {
ENABLE UNWIND => [] ← Resource.Release[resource: $BringOver];
 success: BOOLFALSE;
 otherOwner: Rope.ROPENIL;
 in ← cmd.in;
 out ← cmd.out;
 [success, otherOwner] ← Resource.Acquire[resource: $BringOver,
  owner: "BringOver",
  waitForIt: FALSE];
IF NOT success
THEN {
  out.PutRope[Rope.Cat["Waiting for ", otherOwner, " to finish..."]];
  [success, ] ← Resource.Acquire[resource: $BringOver,
  owner: "BringOver",
  waitForIt: TRUE,
  abortProc: abortProc,
  abortProcData: in
  ];
IF NOT success THEN {
  out.PutRope["ABORTED\n"];
RETURN;
  } ELSE out.PutRope["proceeding\n"];
  };

DO
  IF parm >= argv.argc THEN EXIT;
  tok ← argv[parm];
  IF tok.Fetch[0] = '- OR tok.Fetch[0] = '/ THEN
   SELECT tok.Fetch[1] FROM
   'a, 'A => switches['a] ← TRUE;
   'b, 'B => switches['b] ← TRUE;
   'f, 'F => switches['f] ← TRUE;
   'o, 'O => {
    parm ← parm + 1;
    IF parm >= argv.argc THEN {
     out.PutF["Error - /o must be followed by file name.\n"];
     GOTO leave;
     };
    FOR p: CARDINAL IN [parm .. argv.argc - 1) DO
     tok ← argv[p];
     IF tok.Fetch[tok.Length[]-1] = ', THEN-- strip trailing comma
      tok ← tok.Flatten[0, tok.Length[] - 1];
     IF Rope.Find[tok, "."] = -1 THEN
      tok ← Rope.Cat[tok, ".Mesa"];
     usingListOfRopes ← CONS[RopeInline.InlineFlatten[tok], usingListOfRopes];
     ENDLOOP;
     parm ← argv.argc - 1;
     LOOP;
     };
   'p, 'P => switches['p] ← TRUE;
   'r, 'R => switches['r] ← TRUE;
   's, 'S => switches['s] ← TRUE;
   'u, 'U => switches['u] ← TRUE;
   'v, 'V => switches['v] ← TRUE;
   'w, 'W => switches['w] ← TRUE;
   ENDCASE => out.PutF["Unknown flag '%s'\n", IO.rope[tok]]
  ELSE {
   IF Rope.Find[tok, "."] = -1 THEN
    tok ← Rope.Cat[tok, ".DF"];
   listOfFiles ← CONS[RopeInline.InlineFlatten[tok], listOfFiles];
   };
  parm ← parm + 1;
  ENDLOOP;
 wdir ← CIFS.GetWDir[];
IF NOT Rope.Equal[wdir, "/local", FALSE] THEN {
  out.PutF["Warning - working directory is %s, not /local.\n",
    IO.rope[wdir]];
  IF NOT switches['a]
   AND NOT IOMisc.AskUser[msg: "Confirm this is ok ",
    in: in,
    out: out,
    defaultKey: $Yes] = $Yes
   THEN GOTO leave;
  };
IF listOfFiles = NIL THEN
  out.PutF["Error - No DF file specified.\n"]
ELSE
  BringOverCall.CedarBringOver
   [listOfFiles: listOfFiles, usingListOfRopes: usingListOfRopes,
   switches: switches, useCIFS: TRUE, in: in, out: out, confirmData: NIL,
   Confirm: MyConfirm];
EXITS
 leave => NULL;
 };
 starttime ← TimeCurrent[] - starttime;
 out.PutF["\nTotal elapsed time for BringOver %r.\n",IO.card[starttime]];
 [] ← Resource.Release[resource: $BringOver];
 };

TimeCurrent: PROC RETURNS[LONG CARDINAL] = TRUSTED {
RETURN[Time.Current[]];
 };

MyConfirm: PROC[in, out: IO.Handle, data: REF ANY, msg: Rope.ROPE, dch: CHAR]
RETURNS[CHAR] = {
 value: ATOM;
 value ← IOMisc.AskUser[msg: msg, in: in, out: out,
keyList: LIST[$Yes, $No, $All, $Quit]]; -- order is important
SELECT value FROM
 $All => RETURN['a];
 $No => RETURN['n];
 $Quit => RETURN['q];
 $Yes => RETURN['y];
ENDCASE => ERROR;
 };

-- start code
Commander.Register[key: "BringOver", proc: Main, doc: "retrieve files named in a .df file"];
}.