DIRECTORY Atom USING [ MakeAtom ], IO, Log, Nice, Rope USING [ Cat, Substr ], SafeStorage USING [ GetCanonicalReferentType, NarrowRefFault, Type, unspecType ], BasicTime USING [ Now, nullGMT ], Thrush USING [ Epoch, H, nullHandle, ROPE, ServerProblem, ThHandle], ThNet, ThParty USING [ DescribeParty ], ThPartyPrivate USING [ PartyData, SmartsData ], ThSmartsPrivate USING [ SmartsInfo ], Triples USING [ Any, Erase, Foreach, ForeachProc, Item, Make, Select, SelectCandidate ], TU, Commander USING [ CommandProc, GetProperty, PutProperty, Handle, Register ], CommandTool USING [ Parse, ArgumentVector ] ; TUImpl: CEDAR MONITOR IMPORTS Atom, IO, Nice, Log, Rope, ThParty, SafeStorage, BasicTime, Thrush, Triples, Commander, CommandTool EXPORTS Thrush, ThNet, TU = { epoch: PUBLIC Thrush.Epoch; ePoch: Thrush.Epoch; ServerError: PUBLIC ERROR[code: Thrush.ServerProblem] = CODE; pERROR: PUBLIC ERROR = CODE; pd: PUBLIC REF ThNet.PD _ NEW[ThNet.PD_[ debug: FALSE, encryptionRequested: TRUE, encryptVoice: TRUE ]]; ThHandle: TYPE = Thrush.ThHandle; nullHandle: ThHandle = Thrush.nullHandle; ROPE: TYPE = Thrush.ROPE; HandleRef: TYPE = REF HandleValue; HandleValue: TYPE = RECORD [ epoch: Thrush.Epoch, type: SafeStorage.Type -- concrete type -- ]; Enhandle: PUBLIC ENTRY PROC[r: REF] RETURNS [Thrush.ThHandle] = TRUSTED { ENABLE UNWIND=>NULL; h: HandleRef; IF r=NIL THEN RETURN[Thrush.nullHandle]; h _ NARROW[Triples.Select[$Handle, r, Triples.Any! SafeStorage.NarrowRefFault=>ERROR HandleFault[LOOPHOLE[h]]]]; IF h=NIL THEN { h _ NEW[HandleValue _ [epoch: ePoch, type: SafeStorage.GetCanonicalReferentType[ref: r]]]; Triples.Make[$Handle, r, h]; }; RETURN[LOOPHOLE[r]]; }; Dehandle: PUBLIC ENTRY PROC[h: ThHandle, type: SafeStorage.Type, insist: BOOLEAN] RETURNS [LONG UNSPECIFIED] = { ENABLE UNWIND=>NULL; RETURN[DoDehandle[h, type, insist]]; }; DoDehandle: INTERNAL PROC[h: ThHandle, type: SafeStorage.Type, insist: BOOLEAN] RETURNS [REF] = TRUSTED { r, hrc: REF; hr: HandleRef; NoGood: PROC RETURNS[REF]=TRUSTED{ IF insist THEN ERROR HandleFault[h]; RETURN[NIL]; }; IF h=nullHandle THEN RETURN[NIL]; [r, hrc] _ Triples.SelectCandidate[$Handle, h]; IF hrc=NIL THEN RETURN[NoGood[]]; hr_NARROW[hrc!SafeStorage.NarrowRefFault=>CONTINUE]; IF hr=NIL OR ePoch # hr.epoch OR type#hr.type AND type#SafeStorage.unspecType THEN RETURN[NoGood[]]; RETURN[r]; }; KillHandle: PUBLIC ENTRY PROC[h: ThHandle, type: SafeStorage.Type] = TRUSTED { OPEN Triples; ENABLE UNWIND=>NULL; r: REF; hr: HandleRef; IF h=nullHandle THEN RETURN; r _ DoDehandle[h, type, TRUE]; -- blows up if not of correct type. hr _ NARROW[Select[$Handle, r, -- hr--]]; hr.epoch_BasicTime.nullGMT; -- no longer a valid-looking handle. Erase[$Handle, r, hr]; }; HandleFault: PUBLIC ERROR[h: ThHandle] = CODE; MakeUnique: PUBLIC PROC [att, obj, val: Triples.Item] = TRUSTED { Triples.Erase[att, obj, Triples.Any]; Triples.Make[att, obj, val]; }; Ref: PUBLIC UNSAFE PROC[whatever: LONG CARDINAL] RETURNS [REF] = UNCHECKED {RETURN[LOOPHOLE[whatever]]}; DH: PUBLIC PROC[h: ThHandle] RETURNS [REF] = TRUSTED { RETURN[Dehandle[h, SafeStorage.unspecType, FALSE]]; }; -- for debugging Pun: PUBLIC PROC[x: UNSPECIFIED] RETURNS [CARDINAL] = TRUSTED {RETURN[x]}; Shaggy: PUBLIC PROC[x: LONG UNSPECIFIED] RETURNS [LONG CARDINAL] = TRUSTED {RETURN[x]}; ORef: PUBLIC PROC[o: IO.STREAM, r: REF, d: NAT_2] = TRUSTED { o.Put[IO.refAny[r]]; }; Any: Triples.Item = Triples.Any; gsI: INT_0; World: PUBLIC PROC [o: IO.STREAM] = TRUSTED { OPEN IO; Country: Triples.ForeachProc= TRUSTED { IF trip.att#$iD THEN o.PutF["%g[ %g ] = %g\n", RefAddr[trip.att], RefAddr[trip.obj], RefAddr[trip.val]]; }; gsI_0; Triples.Erase[$iD, Any, Any]; -- from last time! o.PutF["------- World as of %g -------\n", time[]]; Triples.Foreach[Any, Any, Any, Country]; o.PutRope["--------------\n\n"]; }; Show: PUBLIC PROC[o: IO.STREAM, iD: ATOM] = TRUSTED { OPEN IO; obj: REF_Triples.Select[$iD, --obj--, iD]; IF obj=NIL THEN obj_iD; -- assume we want to talk about the id itself. o.PutF["%g (%d):\n %g\n", refAny[iD], card[LOOPHOLE[obj]], refAny[obj]!ANY=>{o.PutRope["...failed...\n"];CONTINUE}]; }; AsgnRef: PROC[iD: ATOM] = TRUSTED { OPEN IO; obj: REF_Triples.Select[$iD, --obj--, iD]; IF obj=NIL THEN obj_iD; -- assume we want to talk about the id itself. Log.Report["Sorry -- StuffIt and interp/commander equivalence went away", $Cmd]; }; RefAddr: PUBLIC SAFE PROC[r: REF] RETURNS [IO.Value] = TRUSTED { id: ATOM_NIL; IF r=NIL THEN RETURN[IO.refAny[NIL]]; id_NARROW[r!ANY=>CONTINUE]; -- not an atom, get its id. IF id=NIL THEN id_NARROW[Triples.Select[$iD, r, --id--]]; IF id=NIL THEN { id_Gensym[r, 'R]; Triples.Make[$iD, r, id]; }; RETURN [IO.atom[id]]; }; Gensym: PROC[r: REF, c: CHAR] RETURNS [ATOM] = TRUSTED { OPEN IO; symName: ROPE_WITH r SELECT FROM party: ThPartyPrivate.PartyData => Party[party], smarts: ThPartyPrivate.SmartsData => Smarts[smarts], info: ThSmartsPrivate.SmartsInfo => Smarts[info.smarts, "si"], ENDCASE=>NIL; IF symName=NIL THEN symName_IO.PutFR["%c%02d", char[c], int[gsI_gsI+1]]; RETURN[Atom.MakeAtom[symName]]; }; Smarts: PROC[smarts:ThPartyPrivate.SmartsData,qual: ROPE_"sm"]RETURNS[name:ROPE_NIL]= TRUSTED { party: ThPartyPrivate.PartyData _ NARROW[Triples.Select[$VoiceTerminal, Any, smarts]]; IF party#NIL THEN name_Party[party, qual]; RETURN[name]; }; Party: PROC[party: ThPartyPrivate.PartyData, qual: ROPE_"pt"] RETURNS[name: ROPE_NIL] = TRUSTED { OPEN IO; moreQual: ROPE_"."; SELECT party.type FROM trunk => { party _ NARROW[Triples.Select[$TrunkParty, --owner--, party]]; moreQual_".k"; }; recording => name _ IO.PutFR["Rec%02d", int[gsI_gsI+1]]; ENDCASE; IF name=NIL THEN { name_ThParty.DescribeParty[partyID: Thrush.H[party]]; name_name.Substr[len: 3]; }; IF name=NIL THEN RETURN; name_name.Cat[moreQual, qual]; }; WorldCmd: Commander.CommandProc = TRUSTED { World[Log.FindWhere[$Cmd, NIL]]; }; ShowCmd: Commander.CommandProc = TRUSTED { Show[Log.FindWhere[$Cmd, NIL], Atom.MakeAtom[Arg[cmd,1]]]; }; RefCmd: Commander.CommandProc = TRUSTED { AsgnRef[Atom.MakeAtom[Arg[cmd,1]]]; }; Arg: PUBLIC PROC[cmd: Commander.Handle, index: NAT, sameCmd: BOOL_FALSE] RETURNS[ROPE] = { argv: CommandTool.ArgumentVector; IF sameCmd THEN argv _ NARROW[Commander.GetProperty[$ArgumentVector, cmd.propertyList]]; argv _ CommandTool.Parse[cmd]; IF argv#NIL THEN []_Commander.PutProperty[$ArgumentVector, argv, cmd.propertyList]; IF argv=NIL OR argv.argc < index THEN RETURN[NIL]; RETURN[argv[index]]; }; epoch_BasicTime.Now[]; ePoch _ epoch; Commander.Register["world", WorldCmd, "Print Thrush World"]; Commander.Register["show", ShowCmd, "Describe Item"]; Commander.Register["ref", RefCmd, "Assign Item to next Exec event"]; Nice.View[pd, "Thrush-wide PD"]; Nice.View[Log.pd, "Log PD"]; }. ÈTU.mesa Last modified by D. Swinehart, December 28, 1983 10:10 pm BodyDefs USING [ maxRNameLength ], Obligatory concrete Copies ThHandle types and procedures Rehandle, H: PUBLIC PROC[r: REF] RETURNS [ThHandle] = INLINE { RETURN[LOOPHOLE[r]]; }; Can be used if one obtained r from Dehandle, or knows it was obtained that way. The next Dehandle will check the handle's validity again. Validates type if not RTTypesBasic.unspecType, then returns REF as unspecified. Virtually any Handle value may be supplied to this procedure without breaking the RTTypes system!! Handles that are or were once valid are preferred! Fails with ERROR if insist is TRUE, else by returning NIL. KillHandle makes the handle invalid, but does not eliminate it. PurgeHandle does that. Miscellaneous routines Procedures for debugging only UserExec.StuffIt[ UserExec.GetExecHandle[process: NIL], IO.PutFR["_TU.Ref[%d]\n", int[LOOPHOLE[obj, INT]]]]; Initialization Debugging nonsense Ê U˜Jšœ™Jšœ9™9J˜šÏk ˜ Jšœœ˜Jšœ"™"Jšœ˜J˜J˜Jšœœ˜Jšœ œ@˜QJšœ œ˜!šœœ˜Jšœœ˜5—J˜Jšœœ˜ Jšœœ˜/Jšœœ˜%šœœ˜J˜H—J˜Jšœ œ=˜LJšœ œ˜+J˜J˜—šœœ˜š˜J˜Jšœ˜J˜J˜J˜J˜J˜ J˜ J˜J˜J˜ J˜ —Jšœ˜J˜—šœ™J˜Jšœœ˜J˜Jšœ œœœ˜=Jšœœœœ˜J˜š œœœœœœ˜(Jšœœ˜ Jšœœ˜Jšœ˜J˜—J˜—šœ™˜Jšœ œ˜!J˜)Jšœœ œ˜J˜—J˜—™J˜Jšœ œœ ˜"šœ œœ˜J˜JšœÏcœ˜-J˜—šÏnœœœœœœœ˜IJšœœœ˜J˜ Jšœœœœ˜(šœœ(˜2Jšœœ œ˜=—šœœœ˜šœœ˜$J˜5—J˜—Jšœœ˜J˜—š Ÿ œ œœœ™Jšœœ˜ —Jšœ œœ œ*˜HJšœ˜Jšœ˜—J˜šŸœœ(œœœœœ˜_Jšœ"œ.˜VJšœœœ˜*Jšœ˜ J˜—J˜šŸœœ(œœœœœ˜aJšœœ˜Jšœ œ˜šœ ˜šœ ˜ Jšœœž œ ˜>J˜J˜—Jšœœ"˜8Jšœ˜—šœœœ˜Jšœ+œ ˜5J˜J˜—Jšœœ œ˜Jšœ˜J˜—J˜—™J™šœ"œ˜+Jšœœ˜ Jšœ˜J˜—šœ!œ˜*Jšœœ˜:Jšœ˜J˜—šœ œ˜)Jšœ&˜&—J˜š Ÿœ œœ œœ˜HJšœœ˜J˜!šœ ˜Jšœœ;˜H—J˜JšœœœC˜SJš œœœœœœ˜2Jšœ˜J˜J˜—Jšœ˜J˜Jšœ<˜