<> <> <> <> <> <<>> <> <> <<>> DIRECTORY CStrings, IncrementalLoad USING [LookupSymEntryByValue, SETypeMODULE, SymEntry], InstallationComforts, InstallationBasicComforts, InstallationSupportPrivate, IO, MesaLoadState, Rope, UXIO, UXStrings; InstallationComfortsImpl: CEDAR PROGRAM IMPORTS CStrings, IncrementalLoad, IO, MesaLoadState, Rope, UXIO, UXStrings EXPORTS InstallationBasicComforts, InstallationComforts, InstallationSupportPrivate, MesaLoadState ~ { OPEN InstallationSupportPrivate; <> InterfaceRecord: PUBLIC TYPE ~ InstallationSupportPrivate.InterfaceRecord; ConfigRep: PUBLIC TYPE ~ InstallationSupportPrivate.ConfigRep; ProgramRep: PUBLIC TYPE ~ InstallationSupportPrivate.ProgramRep; <> ROPE: TYPE ~ Rope.ROPE; CString: TYPE ~ CStrings.CString; Interface: TYPE ~ InstallationSupportPrivate.Interface; Config: TYPE ~ InstallationSupportPrivate.Config; Program: TYPE ~ InstallationSupportPrivate.Program; <> InterfaceFromConfig: PUBLIC PROC [interfaceName: ROPE, context: Config] RETURNS [foundInterface: Interface] ~ { cInterfaceName: CString ¬ UXStrings.Create[from: interfaceName]; EachInterface: MesaLoadState.InterfaceProc ~ { IF foundInterface=NIL AND NOT transparent THEN { IF CStrings.Strcmp[interface.key.name, cInterfaceName]=0 THEN { foundInterface ¬ interface; }; }; }; IF context=NIL THEN context ¬ MesaLoadState.GlobalConfig[]; MesaLoadState.EnumerateInterfaces[context, EachInterface]; RETURN[foundInterface]; }; ChildProgramFromConfig: PUBLIC PROC [ programName: ROPE, context: Config] RETURNS [Program] ~ { cProgramName: CString ¬ UXStrings.Create[from: programName]; foundProgram: Program ¬ NIL; EachChild: MesaLoadState.ChildProc ~ { IF foundProgram=NIL THEN { WITH child SELECT FROM prog: MesaLoadState.ProgramOrConfig.program => { IF CStrings.Strcmp[prog.program.name, cProgramName]=0 THEN { foundProgram ¬ prog.program; }; }; ENDCASE => NULL; }; }; IF context=NIL THEN context ¬ MesaLoadState.GlobalConfig[]; MesaLoadState.EnumerateChildren[context, EachChild]; RETURN[foundProgram]; }; ChildConfigFromConfig: PUBLIC PROC [configName: ROPE, context: Config] RETURNS [Config] ~ { cConfigName: CString ¬ UXStrings.Create[from: configName]; foundConfig: Config ¬ NIL; EachChild: MesaLoadState.ChildProc ~ { IF foundConfig=NIL THEN { WITH child SELECT FROM conf: MesaLoadState.ProgramOrConfig.config => { IF CStrings.Strcmp[conf.config.name, cConfigName]=0 THEN { foundConfig ¬ conf.config; }; }; ENDCASE => NULL; }; }; IF context=NIL THEN context ¬ MesaLoadState.GlobalConfig[]; MesaLoadState.EnumerateChildren[context, EachChild]; RETURN[foundConfig] }; <> ProcFromInterface: PUBLIC PROC [interface: Interface, procName: ROPE] RETURNS [PROC ANY RETURNS ANY] ~ { IF interface#NIL THEN { <> aux: AuxInterface ¬ interface.aux; <> <> FOR i: CARD IN [0..aux.nItems) DO SELECT aux.items[i].itemTag FROM startTrap => TRUSTED { IF Match[ProcNameOnly[LOOPHOLE[interface.items[i], LinkItem.startTrap].trap.shadowedProc], procName] THEN RETURN[LOOPHOLE[interface.items[i], LinkItem.proc].proc]; }; bound => { IF Match[ProcNameOnly[LOOPHOLE[interface.items[i], LinkItem.proc].proc], procName] THEN RETURN[LOOPHOLE[interface.items[i], LinkItem.proc].proc]; }; ENDCASE => NULL; ENDLOOP; }; <> RETURN[NIL]; }; BasicProcFromNamedInterface: PUBLIC PROC [interfaceName, procName: ROPE] RETURNS [PROC ANY RETURNS ANY] ~ { foundInterface: Interface ~ InterfaceFromConfig[interfaceName, NIL]; RETURN[ProcFromInterface[foundInterface, procName]]; }; ProcFromNamedInterface: PUBLIC PROC [interfaceName, procName: ROPE, context: Config] RETURNS [PROC ANY RETURNS ANY] ~ { foundInterface: Interface ~ InterfaceFromConfig[interfaceName, context]; RETURN[ProcFromInterface[foundInterface, procName]]; }; ProcName: PUBLIC PROC [p: PROC ANY RETURNS ANY] RETURNS [ROPE] ~ { mod: ROPE ¬ ModuleName[p]; RETURN [Rope.Cat[mod, ".", ProcNameOnly[p]]]; }; BasicProcName: PUBLIC PROC [p: PROC ANY RETURNS ANY] RETURNS [ROPE] ~ { mod: ROPE ¬ ModuleName[p]; RETURN [Rope.Cat[mod, ".", ProcNameOnly[p]]]; }; ProcNameOnly: PROC [p: PROC ANY RETURNS ANY] RETURNS [proc: ROPE] ~ { sym: IncrementalLoad.SymEntry; start: INT ¬ 0; TRUSTED { sym ¬ IncrementalLoad.LookupSymEntryByValue[LOOPHOLE[LOOPHOLE[p, POINTER TO ProcDescriptor]­.code]]; proc ¬ UXStrings.ToRope[from: sym.name]; }; IF proc.Fetch[0] = '_ THEN start ¬ 1; proc ¬ Rope.Substr[proc, start, Rope.Index[s1: proc, pos1: start, s2: "_"]-start]; }; BasicModuleName: PUBLIC PROC [p: PROC ANY RETURNS ANY] RETURNS [ROPE] ~ { RETURN[ModuleName[p]] }; ModuleName: PUBLIC PROC [p: PROC ANY RETURNS ANY] RETURNS [ROPE] ~ TRUSTED { codeP: CARD32 ¬ LOOPHOLE[LOOPHOLE[p, POINTER TO ProcDescriptor]­.code]; modEntry: IncrementalLoad.SymEntry ¬ ImproveModEntry[ILGetMatchingSymEntryByValue[NIL, codeP, IncrementalLoad.SETypeMODULE, 0, 0]]; -- the preceding "module" symbol mod: ROPE ¬ UXStrings.ToRope[from: modEntry.name]; RETURN[Rope.Substr[mod, 0, Rope.Index[s1: mod, s2: "."]]]; }; PutProblems: PUBLIC PROC [s: IO.STREAM, problems: MesaLoadState.InstallationProblems] ~ { lagInterface: MesaLoadState.Interface ¬ NIL; lagItem: INT ¬ 0; lagProgram: MesaLoadState.Program ¬ NIL; FOR l: MesaLoadState.InstallationProblems ¬ problems, l.rest WHILE l#NIL DO a: MesaLoadState.InstallationProblem ¬ l.first; WITH a SELECT FROM me: MesaLoadState.InstallationProblem.multipleExports => { IF lagInterface#me.interface OR lagItem#me.item THEN { IO.PutRope[s, "\n Multiple exports: "]; IO.PutRope[s, MesaLoadState.InterfaceName[me.interface]]; IO.PutF1[s, "[%g] exported from", [integer[me.item]]]; }; IO.PutF1[s, "\n %g", [rope[MesaLoadState.QualifiedName[[program[me.exporter]]]]]]; lagProgram ¬ me.exporter; }; re: MesaLoadState.InstallationProblem.reExport => { IF lagInterface#re.interface OR lagItem#re.item THEN { IO.PutRope[s, "\n Re-export: "]; IO.PutRope[s, MesaLoadState.InterfaceName[re.interface]]; IO.PutF1[s, "[%g] exported from", [integer[re.item]]]; }; IO.PutF1[s, "\n %g", [rope[MesaLoadState.QualifiedName[[program[re.exporter]]]]]]; lagProgram ¬ re.exporter; }; ui: MesaLoadState.InstallationProblem.unboundImport => { IF lagInterface#ui.interface OR lagItem#ui.item THEN { IO.PutRope[s, "\n Unbound imports from "]; IO.PutRope[s, MesaLoadState.InterfaceName[ui.interface]]; IO.PutF1[s, "[%g]; importer(s):", [integer[ui.item]]]; }; IO.PutF1[s, "\n %g", [rope[MesaLoadState.QualifiedName[[program[ui.importer]]]]]]; lagProgram ¬ ui.importer; }; ivm: MesaLoadState.InstallationProblem.interfaceVersionMismatch => { IO.PutRope[s, "\n Interface version mismatch: "]; IO.PutRope[s, MesaLoadState.InterfaceName[ivm.interface]]; lagProgram ¬ NIL; }; tc: MesaLoadState.InstallationProblem.typeClash => { IO.PutF[s, "\n Type clash exporting %g from %g (already exported by %g).", [rope[tc.typeName]], [rope[MesaLoadState.QualifiedName[[program[tc.now]]]]], [rope[MesaLoadState.QualifiedName[[program[tc.already]]]]] ]; lagProgram ¬ NIL; }; ENDCASE => NULL; lagInterface ¬ l.first.interface; lagItem ¬ l.first.item; ENDLOOP; }; <> DefaultProblemPrinter: PUBLIC PROC [problems: InstallationProblems] ~ { IF problems# NIL THEN { s: IO.STREAM ~ UXIO.CreateStandardStream[output]; IO.PutRope[s, "Problems during installation:\n"]; PutProblems[s, problems]; IO.PutRope[s, "\n"]; IO.Close[s]; }; }; <> ImproveModEntry: PROC [mod: IncrementalLoad.SymEntry] RETURNS [IncrementalLoad.SymEntry] ~ TRUSTED { tempMod: IncrementalLoad.SymEntry ¬ mod; WHILE (tempMod#NIL) AND (tempMod.value = mod.value) DO IF LooksLikeRealName[tempMod.name] THEN RETURN [tempMod]; tempMod ¬ ILGetMatchingSymEntryByValue[tempMod, 0, IncrementalLoad.SETypeMODULE, 0, -1]; ENDLOOP; RETURN [mod]; }; maxReasonableRun: INT = 5; LooksLikeRealName: PROC [s: CString] RETURNS [BOOL ¬ TRUE] ~ { r: ROPE ¬ UXStrings.ToRope[s]; numRun: INT ¬ 0; len: INT ¬ r.Length[]; FOR i: INT IN [0..len) DO IF r.Fetch[i] IN ['0..'9] THEN { numRun ¬ numRun+1; IF numRun > maxReasonableRun THEN RETURN [FALSE]; } ELSE numRun ¬ 0; ENDLOOP; }; ILGetMatchingSymEntryByValue: PROC [ilse: IncrementalLoad.SymEntry, val: CARD, wantedTypes: CARD, ignoredClasses: CARD, numToSkip: INT] RETURNS [IncrementalLoad.SymEntry] ~ TRUSTED MACHINE CODE { "XR_ILGetMatchingSymEntryByValue" }; XRPrefix: ROPE ~ "_XR_"; Match: PROC [symName, procName: ROPE] RETURNS [BOOL ¬ FALSE] ~ { sn: ROPE ¬ IF Rope.IsPrefix[XRPrefix, symName] THEN Rope.Substr[symName, 4] ELSE IF symName.Fetch[0] = '_ THEN Rope.Substr[symName, 1] ELSE symName; <> RETURN[Rope.Equal[sn, procName]]; }; <> <<>> <> }.