DIRECTORY BasicTime USING [ Now, nullGMT ], Commander USING [ CommandProc, Handle, Register ], CommandTool USING [ DoCommand, NextArgument ], IO, Nice, RefID USING [ Reseal ], RefTab USING [ Create, Fetch, Ref, Store ], Rope USING [ Cat, ROPE ], SafeStorage USING [ GetCanonicalReferentType, NarrowRefFault, Type, unspecType ], Thrush USING [ Epoch, nullHandle, ThHandle ], ThNet, ThParty USING [ DescribeParty ], ThPartyPrivate USING [ PartyData, SmartsData ], ThSmartsPrivate USING [ SmartsInfo ], Triples USING [ Any, Erase, Foreach, ForeachProc, Item, Make, Select, SelectCandidate ], TU, VoiceUtils USING [ MakeAtom, pd ] ; TUImpl: CEDAR MONITOR IMPORTS BasicTime, Commander, CommandTool, IO, Nice, RefID, RefTab, Rope, SafeStorage, ThParty, Triples, VoiceUtils EXPORTS Thrush, ThNet, TU = { epoch: PUBLIC Thrush.Epoch; ePoch: Thrush.Epoch; pERROR: PUBLIC ERROR = CODE; gsI: INT_0; nameToValueTab: RefTab.Ref; valueToNameTab: RefTab.Ref; pd: PUBLIC REF ThNet.PD _ NEW[ThNet.PD_[ debug: FALSE, encryptionRequested: TRUE, encryptVoice: TRUE ]]; ThHandle: TYPE = Thrush.ThHandle; nullHandle: ThHandle = Thrush.nullHandle; ROPE: TYPE = Rope.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] = { Triples.Erase[att, obj, Triples.Any]; Triples.Make[att, obj, val]; }; Any: Triples.Item = Triples.Any; AllAbout: PROC [cmd: Commander.Handle, subject: ROPE] = { OPEN IO; o: IO.STREAM = cmd.out; iD: REF _ RefFromRope[subject]; Country: Triples.ForeachProc= { o.PutF["%g[ %g ] = %g\n", RefAddr[trip.att], RefAddr[trip.obj], RefAddr[trip.val]]; Triples.Foreach[Any, trip.val, Any, Country]; }; Triples.Foreach[iD, Any, Any, Country]; Triples.Foreach[Any, iD, Any, Country]; Triples.Foreach[Any, Any, iD, Country]; o.PutRope["--------------\n\n"]; }; Show: PROC[cmd: Commander.Handle, iD: ROPE, name: ROPE_NIL] = TRUSTED { OPEN IO; []_CommandTool.DoCommand[ IO.PutFR["_ &%g _ TU.RefFromRope[""%g""]", rope[IF name#NIL THEN name ELSE "v"], rope[iD]], cmd]; }; Ref: PUBLIC PROC[iD: ATOM] RETURNS [r: REF] = { OPEN IO; r_nameToValueTab.Fetch[iD].val; IF r=NIL THEN r_iD; -- assume we want to talk about the id itself. }; RefFromRope: PUBLIC PROC[iD: ROPE] RETURNS [REF] = { RETURN[Ref[VoiceUtils.MakeAtom[iD, TRUE]]]; }; RefAddr: PUBLIC PROC[r: REF] RETURNS [IO.Value] = { id: ATOM_NIL; IF r=NIL THEN RETURN[IO.refAny[NIL]]; id _ NARROW[r!SafeStorage.NarrowRefFault => CONTINUE]; IF id=NIL THEN id_NARROW[valueToNameTab.Fetch[r].val]; IF id=NIL THEN { id_Gensym[r, 'R]; []_nameToValueTab.Store[id, r]; []_valueToNameTab.Store[r, id]; }; RETURN [IO.atom[id]]; }; NewNames: PROC = { gsI_0; nameToValueTab _ RefTab.Create[113]; valueToNameTab _ RefTab.Create[113]; }; Gensym: PROC[r: REF, c: CHAR] RETURNS [ATOM] = { OPEN IO; symName: ROPE_WITH r SELECT FROM ref: RefTab.Ref => "abcde", 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[VoiceUtils.MakeAtom[symName]]; }; Smarts: PROC[smarts:ThPartyPrivate.SmartsData,qual: ROPE_"sm"]RETURNS[name:ROPE_NIL]= { party: ThPartyPrivate.PartyData _ NARROW[Triples.Select[$Smarts, Any, smarts]]; IF party#NIL THEN name_Party[party, qual]; RETURN[name]; }; Party: PROC[party: ThPartyPrivate.PartyData, qual: ROPE_"pt"] RETURNS[name: ROPE_NIL] = { OPEN IO; moreQual: ROPE_"."; SELECT party.type FROM $trunk => { name _ ThParty.DescribeParty[partyID: RefID.Reseal[party]].description; moreQual_".k"; }; $service => name _ IO.PutFR["Srv%02d(%g)", int[gsI_gsI+1], rope[party.serviceName]]; ENDCASE => { name_ThParty.DescribeParty[ partyID: RefID.Reseal[party]].description; IF party.type=$individual THEN qual _ Rope.Cat["i", qual]; }; IF name=NIL THEN RETURN; name_name.Cat[moreQual, qual]; }; AllAboutCmd: Commander.CommandProc = { AllAbout[cmd, CommandTool.NextArgument[cmd]]; }; WorldClear: Commander.CommandProc = { NewNames[]; }; ShowCmd: Commander.CommandProc = { Show[cmd, CommandTool.NextArgument[cmd], CommandTool.NextArgument[cmd]]; }; ViewCmd: Commander.CommandProc = { Nice.View[pd, "Thrush-wide PD"]; Nice.View[VoiceUtils.pd, "Log PD"]; }; epoch_BasicTime.Now[]; ePoch _ epoch; NewNames[]; Commander.Register["AllAbout", AllAboutCmd, "Print Thrush World relating to atom or invented name"]; Commander.Register["Show", ShowCmd, "Show [] sets &v or & to the value of , which is an atom or an invented name"]; Commander.Register["WorldClear", WorldClear, "Forget invented names"]; Commander.Register["VuThrush", ViewCmd, "Program Management variables for Thrush and VoiceUtils"]; }. ξTU.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last modified by D. Swinehart, May 17, 1986 5:18:21 pm PDT 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 Initialization Debugging nonsense Swinehart, May 16, 1985 9:14:29 am PDT Cedar 6.0 changes to: DIRECTORY (CommandToolExtras => ...Tool), TUImpl, ShowCmd Κ k˜šœ™Icodešœ Οmœ1™˜>Jšžœžœ˜ —Jšžœ žœžœ žœ*˜HJšžœ˜%Jšœ˜—J˜š œžœ(žœžœžœžœžœ˜WJšœ"žœ'˜OJšžœžœžœ˜*Jšžœ˜ J˜—J˜š  œžœ(žœžœžœžœ˜YJšžœžœ˜Jšœ žœ˜šžœ ž˜šœ ˜ šœ˜Jšœ@˜@—J˜J˜—Jšœžœ?˜Tšžœ˜ šœ˜Jšœ*˜*—Jšžœžœ˜:J˜——Jšžœžœž œ˜Jšœ˜J˜—J˜—™J™šœ&˜&Jšœ-˜-Jšœ˜J˜—šœ%˜%J˜ Jšœ˜J˜—šœ"˜"JšœH˜HJšœ˜J˜—J™šœ"˜"Jšœ ˜ Jšœ#˜#Jšœ˜—J˜Jšœ˜J˜J˜ Jšœd˜dJšœŒ˜ŒJšœF˜FJšœb˜bJ˜—J˜J˜™&K™ Kšœ Οr œ‘™E—K™—…—Μ&%