-- BringOverFrontEndImpl.Mesa, last edit February 25, 1983 2:10 pm -- BringOverInterface is no longer exported DIRECTORY BareBringOver: TYPE USING[BringOverDF, CheckThisFile, RecursiveLoop, State, StateRecord], BringOverCall: TYPE USING[], CWF: TYPE USING[SetWriteProcedure, WF0, WF1, WF2], DFSubr: TYPE USING [AllocateDFSeq, AppendToUsingSeq, Criterion, DF, DFSeq, FreeDFSeq, NextDF, StripLongName, UsingSeq], IO: TYPE USING[Handle, PutChar, PutF, ResetUserAbort, UserAborted], Rope: TYPE USING[ROPE, Text], Space: TYPE USING[Create, Delete, GetHandle, Handle, Map, nullHandle, PageFromLongPointer, virtualMemory], UnsafeSTP: TYPE USING[Error], STPSubr: TYPE USING[SetUseOfCIFS, StopSTP], Subr: TYPE USING [AbortMyself, CopyString, debugflg, EndsIn, errorflg, FindMappedSpace, LongZone, MakeTTYProcs, numberofleaders, PrintGreeting, strcpy, SubrInit, SubrStop, TTYProcs]; BringOverFrontEndImpl: PROGRAM IMPORTS BareBringOver, CWF, DFSubr, IO, Space, STP: UnsafeSTP, STPSubr, Subr EXPORTS BringOverCall = { -- MDS usage! stdout: IO.Handle; -- end of MDS usage CedarBringOver: PUBLIC SAFE PROC[listOfFiles: LIST OF Rope.Text, usingListOfRopes: LIST OF Rope.Text, switches: ARRAY CHAR['a .. 'z] OF BOOL, useCIFS: BOOL, in, out: IO.Handle, confirmData: REF ANY, Confirm: PROC[in, out: IO.Handle, data: REF ANY, msg: Rope.ROPE, dch: CHAR] RETURNS[CHAR]] = TRUSTED { h: Subr.TTYProcs ← Subr.MakeTTYProcs[in, out, confirmData, Confirm]; dfseq: DFSubr.DFSeq ← NIL; usingSeq: DFSubr.UsingSeq ← NIL; longzone: UNCOUNTED ZONE; ldspace: Space.Handle ← Space.Create[size: 1, parent: Space.virtualMemory]; stateRecord: BareBringOver.StateRecord ← []; state: BareBringOver.State ← @stateRecord; OP: PROC[CHAR] ← NIL; Cleanup: PROC = { IF ldspace ~= Space.nullHandle THEN Space.Delete[ldspace]; ldspace ← Space.nullHandle; DFSubr.FreeDFSeq[@dfseq]; STPSubr.StopSTP[]; Subr.SubrStop[]; IF OP ~= NIL THEN [] ← CWF.SetWriteProcedure[OP]; OP ← NIL; }; { ENABLE { STP.Error => { CWF.WF0["FTP Error. "L]; IF error ~= NIL THEN CWF.WF2["message: %s, code %u in Stp.Mesa\n"L, error, @code]; Subr.errorflg ← TRUE; GOTO leave; }; BareBringOver.CheckThisFile => -- if it gets here then there is no infinite recursive loop RESUME; BareBringOver.RecursiveLoop => { CWF.WF1["Error - infinite recursive nesting of DF files using @.\n\tOne of the files involved is %s.\n"L, loopfilename]; ERROR Subr.AbortMyself; }; Subr.AbortMyself, IO.UserAborted => { out.ResetUserAbort[]; CWF.WF0["\nBringOver Aborted.\n"L]; GOTO leave; }; UNWIND => { out.ResetUserAbort[]; Cleanup[]; }; }; stdout ← h.out; OP ← CWF.SetWriteProcedure[MyPutChar]; STPSubr.SetUseOfCIFS[useCIFS]; Subr.SubrInit[256]; longzone ← Subr.LongZone[]; Subr.errorflg ← FALSE; Subr.debugflg ← FALSE; IF switches['a] THEN state.mustconfirm ← FALSE; IF switches['b] THEN state.justObjects ← TRUE; IF switches['f] THEN state.forceRetrieval ← TRUE; IF switches['p] THEN state.publicOnly ← TRUE; IF switches['r] THEN state.justReadOnlys ← TRUE; IF switches['s] THEN state.justSources ← TRUE; IF switches['u] THEN state.updateOnly ← TRUE; IF switches['v] THEN state.verify ← TRUE; IF switches['w] THEN state.justNonReadOnlys ← TRUE; state.useCIFS ← useCIFS; Subr.PrintGreeting["BringOver"L]; Subr.numberofleaders ← 0; Space.Map[ldspace]; FOR l: LIST OF Rope.Text ← usingListOfRopes, l.rest UNTIL l = NIL DO usingSeq ← DFSubr.AppendToUsingSeq[usingSeq, LOOPHOLE[l.first], longzone]; ENDLOOP; FOR l: LIST OF Rope.Text ← listOfFiles, l.rest UNTIL l = NIL DO dfseq ← AppendToFakeDFSeq[dfseq, LOOPHOLE[l.first], usingSeq]; usingSeq ← NIL; ENDLOOP; BareBringOver.BringOverDF[dfseq: dfseq, state: state, ldspace: ldspace, h: h]; EXITS leave => NULL; }; IF Subr.errorflg THEN CWF.WF0["\tErrors logged.\n"L]; Cleanup[]; }; MyPutChar: PROC[ch: CHAR] = { stdout.PutChar[ch]; }; AppendToFakeDFSeq: PROC[oldDFSeq: DFSubr.DFSeq, fileName: LONG STRING, usingSeq: DFSubr.UsingSeq] RETURNS[newDFSeq: DFSubr.DFSeq] = { host: STRING ← [30]; directory: STRING ← [100]; shortname: STRING ← [100]; version: CARDINAL; df: DFSubr.DF; IF oldDFSeq = NIL THEN newDFSeq ← DFSubr.AllocateDFSeq[maxEntries: 50, zoneType: shared] ELSE IF oldDFSeq.size >= oldDFSeq.maxsize THEN { space: Space.Handle; newDFSeq ← DFSubr.AllocateDFSeq[maxEntries: oldDFSeq.size+50, zoneType: shared]; newDFSeq.size ← oldDFSeq.size; newDFSeq.trailingcomment ← oldDFSeq.trailingcomment; FOR i: CARDINAL IN [0 .. newDFSeq.size) DO newDFSeq[i] ← oldDFSeq[i]; ENDLOOP; space ← Subr.FindMappedSpace[Space.GetHandle[Space.PageFromLongPointer[oldDFSeq]]]; Space.Delete[space]; } ELSE newDFSeq ← oldDFSeq; version ← DFSubr.StripLongName[fileName, host, directory, shortname]; IF shortname.length = 0 THEN SIGNAL Subr.AbortMyself; IF host.length = 0 AND directory.length ~= 0 THEN Subr.strcpy[host, "Indigo"L]; -- no host, with directory, is defaulted to Indigo df ← DFSubr.NextDF[newDFSeq]; df.host ← IF host.length = 0 THEN NIL ELSE Subr.CopyString[host, newDFSeq.dfzone]; df.directory ← IF directory.length = 0 THEN NIL ELSE Subr.CopyString[directory, newDFSeq.dfzone]; df.shortname ← Subr.CopyString[shortname, newDFSeq.dfzone]; df.version ← version; df.createtime ← 0; df.criterion ← none; df.using ← usingSeq; -- this is the using list for /o df.atsign ← Subr.EndsIn[shortname, ".DF"L]; }; }.