-- BringOverFrontEndImpl.Mesa
-- last edit February 25, 1983 2:10 pm
-- last edit May 22, 1983 3:57 pm, Russ Atkinson
-- 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, 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];
};
}.