DIRECTORY AMBridge USING [GetWorld, IsStarted, TVForFrame, TVForGFHReferent, TVForProc, TVForRemoteFrame, TVForRemoteGFHReferent, TVToCardinal], AMEvents USING [BreakID, ClearBreak, SetBreak], AMTypes USING[Globals, IndexToName, IndexToTV, NComponents, TVType], BBBugOut USING[ShowChar, ShowCR, ShowDecimal, ShowOctal, ShowRope, ShowRopes], BBContext USING [Context, GetContents, FindAction, FindMatchingGlobalFrames], BBEmptyReturn USING [TheEmptyReturn], BBEval USING [Eval, EvalHead, Tree], BBEvalQuote USING [EvalQuoteProc, Register], BBEvalUtil USING [TreeToRope, WorldFromHead], BBSafety USING [IsValidAddr, Mother], Commander USING [Handle], Convert USING [MapValue], IO USING [CreateViewerStreams, PutChar, STREAM], List USING [Assoc], PPLeaves USING [LTIndex], PPTreeOps USING [NSons, NthSon, OpName], PrincOps USING [FrameCodeBase], PrintTV USING [NullPutClosure, Print, PutClosure, PutProc], ProcessProps USING [GetPropList], Rope USING [Fetch, Flatten, Match, ROPE, SkipTo, Size], RTBasic USING [TV, Type], TVGuide USING [RegisterTV], WorldVM; OctalCommands: CEDAR MONITOR IMPORTS AMBridge, AMEvents, AMTypes, BBBugOut, BBContext, BBEmptyReturn, BBEval, BBEvalQuote, BBEvalUtil, BBSafety, Convert, IO, List, PPTreeOps, PrintTV, ProcessProps, Rope, TVGuide, WorldVM SHARES BBContext = BEGIN OPEN PrintTV, Rope, RTBasic, WorldVM; STREAM: TYPE = IO.STREAM; ShortAddrHack: CARDINAL = 100000B; Bit1: TYPE = CARDINAL [0..2); Bit2: TYPE = CARDINAL [0..4); Bit4: TYPE = CARDINAL [0..16); Bit8: TYPE = CARDINAL [0..256); Array1: TYPE = PACKED ARRAY [0..16) OF Bit1; Array2: TYPE = PACKED ARRAY [0..8) OF Bit2; Array4: TYPE = PACKED ARRAY [0..4) OF Bit4; Array8: TYPE = PACKED ARRAY [0..2) OF Bit8; Pair: TYPE = MACHINE DEPENDENT RECORD [lo,hi: CARDINAL]; safetyCheck: BOOL _ TRUE; FindMatching: PROC [name: ROPE, world: WorldVM.World _ NIL] = TRUSTED { put: PutClosure _ GetPutClosure[NIL]; pos: INT _ name.SkipTo[0, "."]; globalName: ROPE _ name.Flatten[0, pos]; localName: ROPE _ IF (pos _ pos + 1) >= name.Size THEN NIL ELSE name.Flatten[pos]; tryElem: PROC [glob: TV, index: INT] = TRUSTED { elem: TV _ NIL; innerElem: PROC = TRUSTED { elem _ AMTypes.IndexToTV[glob, index]; PrintTV.Print[elem, put]; BBBugOut.ShowRope["\n", put]; }; msg: ROPE _ BBSafety.Mother[innerElem]; IF msg # NIL THEN BBBugOut.ShowRopes[r1: "--{", r2: msg, r3: "}--\n", put: put]; }; eachMatch: BBContext.FindAction = TRUSTED { inner: PROC = TRUSTED { glob: TV _ AMTypes.Globals[gf]; globType: Type _ AMTypes.TVType[glob]; n: NAT _ AMTypes.NComponents[globType]; first: BOOL _ TRUE; FOR i: INT IN [1..n] DO compName: ROPE _ AMTypes.IndexToName[globType, i]; IF NOT localName.Match[compName, FALSE] THEN LOOP; IF first THEN {BBBugOut.ShowRope["\n", put]; showGF[]; first _ FALSE}; BBBugOut.ShowRope[" ", put]; BBBugOut.ShowRope[compName, put]; BBBugOut.ShowRope[": ", put]; tryElem[glob, i]; ENDLOOP; }; showGF: PROC = TRUSTED { BBBugOut.ShowRope[" ", put]; PrintTV.Print[gf, put]; IF NOT AMBridge.IsStarted[gf] THEN BBBugOut.ShowRope["~", put]; BBBugOut.ShowRope["\n", put]; }; msg: ROPE _ NIL; IF localName = NIL THEN {showGF[]; RETURN}; msg _ BBSafety.Mother[inner]; IF msg # NIL THEN BBBugOut.ShowRopes[r1: " --{", r2: msg, r3: "}--\n", put: put]; }; IF world = NIL THEN world _ WorldVM.LocalWorld[]; BBContext.FindMatchingGlobalFrames[world, globalName, eachMatch]; }; OctalRead: PUBLIC PROC [ addr: LONG CARDINAL _ 0, len: CARDINAL _ 4, width: CARDINAL _ 16, base: CARDINAL _ 8, offset: CARDINAL _ 0] = TRUSTED { world: WorldVM.World _ GetDefaultWorld[]; p: Address _ addr; pos: CARDINAL _ 0; poslim: CARDINAL _ 8; put: PutClosure _ GetPutClosure[NIL]; IF base NOT IN [1..36] THEN { OctalOut["invalid base", base, put]; RETURN}; SELECT width FROM 1,2,4,8,16,32 => {}; ENDCASE => {OctalOut["invalid width", width, put]; RETURN}; IF base < 8 OR width = 32 THEN poslim _ 4; -- hack! IF base = 1 THEN width _ 8; -- another hack! SELECT LOOPHOLE[p, Pair].hi FROM 0 => { p _ WorldVM.Long[world, p]}; ShortAddrHack => { LOOPHOLE[p, Pair].hi _ 0; }; ENDCASE; WHILE len > 0 DO card: LONG CARDINAL _ 0; pp: Address _ p; pint: INT _ 0; lo: CARDINAL _ 0; SELECT width FROM 1 => pp _ p + offset / 16; 2 => pp _ p + offset / 8; 4 => pp _ p + offset / 4; 8 => pp _ p + offset / 2; 16 => pp _ p + offset; 32 => pp _ p + offset + offset; ENDCASE => ERROR; IF safetyCheck AND NOT BBSafety.IsValidAddr[world, pp] THEN { OctalOut["invalid address: %B", pp, put]; RETURN}; card _ WorldVM.Read[world, pp]; lo _ LOOPHOLE[card, Pair].lo; SELECT width FROM 1 => { a: Array1 _ LOOPHOLE[lo]; card _ a[offset MOD 16]}; 2 => { a: Array2 _ LOOPHOLE[lo]; card _ a[offset MOD 8]}; 4 => { a: Array4 _ LOOPHOLE[lo]; card _ a[offset MOD 4]}; 8 => { a: Array8 _ LOOPHOLE[lo]; card _ a[offset MOD 2]}; 16 => {}; 32 => { IF safetyCheck AND NOT BBSafety.IsValidAddr[world, pp+1] THEN { OctalOut["invalid address: %B", pp+1, put]; RETURN}; LOOPHOLE[card, Pair].hi _ WorldVM.Read[world, pp+1]; }; ENDCASE => ERROR; IF pos = poslim THEN { pos _ 0; IF base = 1 THEN BBBugOut.ShowChar['", put]; BBBugOut.ShowCR[put]}; IF pos = 0 THEN { OctalOut["%B: ", pp, put]; IF base = 1 THEN BBBugOut.ShowChar['", put]; } ELSE IF base # 1 THEN BBBugOut.ShowChar[' , put]; pos _ pos + 1; SELECT base FROM 10 => BBBugOut.ShowDecimal[LOOPHOLE[card, INT], put]; 8 => OctalOut["%B", card, put]; 1 => { -- print the ASCII value short: CARDINAL _ card; IF short IN [40B..176B] THEN { c: CHAR _ LOOPHOLE[short]; IF c = '" OR c = '\\ THEN BBBugOut.ShowChar['\\, put]; BBBugOut.ShowChar[c, put]} ELSE OctalOut["\\%", card, put]}; ENDCASE => { put1: SAFE PROC [c: CHAR] = CHECKED {BBBugOut.ShowChar[c, put]}; Convert.MapValue[put1, [unsigned[card, base]]]}; offset _ offset + 1; len _ len - 1; ENDLOOP; IF base = 1 THEN BBBugOut.ShowChar['", put]; BBBugOut.ShowChar['\n, put]; }; OctalReadShort: PROC [ addr: CARDINAL _ 0, len: CARDINAL _ 4, width: CARDINAL _ 16, base: CARDINAL _ 8, offset: CARDINAL _ 0] = { p: Pair _ [lo: addr, hi: ShortAddrHack]; OctalRead[LOOPHOLE[p], len, width, base, offset]; }; OctalWrite: PROC [ addr: LONG CARDINAL _ 0, word: CARDINAL _ 0, len: INT _ 1] = TRUSTED { world: WorldVM.World _ GetDefaultWorld[]; pair: Pair _ LOOPHOLE[addr]; p: WorldVM.Address _ LOOPHOLE[addr]; fault: WorldVM.Address _ 0; SELECT pair.hi FROM 0 => { p _ WorldVM.Long[world, p]}; ShortAddrHack => { pair.hi _ 0; p _ LOOPHOLE[pair]; }; ENDCASE; IF addr = 0 OR p = 0 THEN { put: PutClosure _ GetPutClosure[NIL]; BBBugOut.ShowRope["can't write through NIL", put]; }; FOR i: INT IN [0..len) DO ENABLE { ABORTED => GO TO abort; ANY => {fault _ p+i; EXIT}; }; WorldVM.Write[world, p+i, word]; ENDLOOP; IF fault # 0 THEN { put: PutClosure _ GetPutClosure[NIL]; OctalOut["invalid address: %B", LOOPHOLE[fault], put]; }; EXITS abort => ERROR ABORTED; }; OctalWriteShort: PROC [ addr: CARDINAL _ 0, word: CARDINAL _ 0, len: INT _ 1] = { p: Pair _ [lo: addr, hi: ShortAddrHack]; OctalWrite[LOOPHOLE[p], word]; }; AsciiRead: PROC [addr: LONG CARDINAL _ 0, bytes: NAT _ 8] = { IF addr = 0 THEN RETURN; OctalRead[addr, bytes, 8, 1, 0]; }; AsciiReadShort: PROC [addr: CARDINAL _ 0, bytes: NAT _ 8] = { p: Pair _ [lo: addr, hi: ShortAddrHack]; OctalRead[LOOPHOLE[p], bytes, 8, 1, 0]; }; OctalReadCode: PROC [gf,pc: CARDINAL, bytes: CARDINAL _ 8] = TRUSTED { OctalRead[GetCodeBase[GetDefaultWorld[], gf], bytes, 8, 8, pc]; }; OctalFindCode: PROC [ gf: CARDINAL, pc: CARDINAL _ 0, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9: CARDINAL _ 0] = TRUSTED { put: PutClosure _ GetPutClosure[NIL]; addr: Address _ 0; world: World _ GetDefaultWorld[]; {ENABLE InvalidAddress => { OctalOut["invalid address: %B", LOOPHOLE[bad], put]; GO TO bye}; target: ARRAY [0..10) OF CARDINAL = [b0,b1,b2,b3,b4,b5,b6,b7,b8,b9]; len: CARDINAL _ 10; addr _ GetCodeBase[world, gf]; WHILE len > 0 DO IF target[len-1] # 0 THEN EXIT; len _ len - 1; ENDLOOP; IF len = 0 THEN RETURN; DO IF ReadByte[world, addr, pc] = b0 THEN { found: BOOL _ TRUE; FOR i: CARDINAL IN [1..len) WHILE found DO found _ ReadByte[world, addr, pc+i] = target[i]; ENDLOOP; IF found THEN EXIT}; pc _ pc + 1; ENDLOOP; OctalOut["pc = %B, ", pc, put]; OctalRead[addr + (pc/2), len, 8, 8, pc MOD 2] }; EXITS bye => {}; }; FindMatchingHelper: BBEvalQuote.EvalQuoteProc = TRUSTED { world: WorldVM.World _ BBEvalUtil.WorldFromHead[head]; arg: BBEval.Tree _ GetArg[tree, 1]; rope: ROPE _ BBEvalUtil.TreeToRope[arg]; IF rope = NIL THEN WITH arg SELECT FROM lit: PPLeaves.LTIndex => WITH lit.value SELECT FROM ropeVal: ROPE => rope _ ropeVal; ENDCASE; ENDCASE; FindMatching[rope]; RETURN [BBEmptyReturn.TheEmptyReturn[]]; }; GetArg: PROC [tree: BBEval.Tree, which: NAT] RETURNS [son: BBEval.Tree _ NIL] = { args: BBEval.Tree _ PPTreeOps.NthSon[tree, 2]; IF PPTreeOps.OpName[args] = list THEN { IF which IN [1..PPTreeOps.NSons[args]] THEN son _ PPTreeOps.NthSon[args, which]} ELSE IF which = 1 THEN son _ args; }; InvalidAddress: ERROR [bad: Address] = CODE; ReadByte: PROC [world: World, addr: Address, pc: CARDINAL] RETURNS [Bit8] = TRUSTED { card: CARDINAL _ 0; addr _ addr + (pc / 2); IF safetyCheck AND NOT BBSafety.IsValidAddr[world, addr] THEN ERROR InvalidAddress[addr]; pc _ pc MOD 2; card _ WorldVM.Read[world, addr]; RETURN [LOOPHOLE[card, Array8][pc]]; }; SetOctalBreak: PUBLIC PROC [gf,pc: CARDINAL] = TRUSTED { world: WorldVM.World _ GetDefaultWorld[]; put: PutClosure _ GetPutClosure[NIL]; id: AMEvents.BreakID _ NIL; msg: ROPE _ NIL; inner: PROC = TRUSTED { tv: TV _ IF world = WorldVM.LocalWorld[] THEN AMBridge.TVForGFHReferent[LOOPHOLE[gf]] ELSE AMBridge.TVForRemoteGFHReferent [[world, WorldVM.CurrentIncarnation[world], gf]]; id _ NewBreak[tv, gf, pc]; }; OctalOut["Break at (gf: %B", gf, put]; OctalOut[", pc: %B) ", pc, put]; msg _ BBSafety.Mother[inner]; IF id # NIL THEN BBBugOut.ShowRope["set.\n", put] ELSE { IF msg = NIL THEN msg _ "duplicate break"; BBBugOut.ShowRope["NOT set (", put]; BBBugOut.ShowRope[msg, put]; BBBugOut.ShowRope[").\n", put] }; }; localBreakList: LocalBreakList; LocalBreakList: TYPE = LIST OF LocalBreakEntry; LocalBreakEntry: TYPE = RECORD [ id: AMEvents.BreakID, world: WorldVM.World, gf,pc: CARDINAL]; NewBreak: ENTRY PROC [tv: TV, gf,pc: CARDINAL] RETURNS [id: AMEvents.BreakID _ NIL] = TRUSTED { ENABLE UNWIND => NULL; world: WorldVM.World _ AMBridge.GetWorld[tv]; FOR list: LocalBreakList _ localBreakList, list.rest UNTIL list = NIL DO IF pc = list.first.pc AND gf = list.first.gf AND world = list.first.world THEN RETURN; ENDLOOP; id _ AMEvents.SetBreak[world, GetCodeBase[world, gf], pc, $OctalCommands]; localBreakList _ CONS[[id: id, world: world, gf: gf, pc: pc], localBreakList]; }; GetCodeBase: PROC [world: WorldVM.World, gfh: CARDINAL] RETURNS [addr: WorldVM.Address] = TRUSTED { ENABLE UNWIND => NULL; addr _ WorldVM.Long[world, gfh] + 1; addr _ WorldVM.LongRead[world, addr]; -- code base LOOPHOLE[addr, PrincOps.FrameCodeBase].out _ FALSE; -- stupid code traps! }; FindBreak: ENTRY PROC [tv: TV, gf,pc: CARDINAL, delete: BOOL _ FALSE] RETURNS [id: AMEvents.BreakID _ NIL] = TRUSTED { ENABLE UNWIND => NULL; lag: LocalBreakList _ NIL; world: WorldVM.World _ AMBridge.GetWorld[tv]; FOR list: LocalBreakList _ localBreakList, list.rest UNTIL list = NIL DO IF pc = list.first.pc AND gf = list.first.gf AND world = list.first.world THEN { id _ list.first.id; IF delete THEN { IF lag = NIL THEN localBreakList _ list.rest ELSE lag.rest _ list.rest; AMEvents.ClearBreak[id]; }; RETURN; }; lag _ list; ENDLOOP; }; ClearOctalBreak: PUBLIC PROC [gf,pc: CARDINAL] = TRUSTED { world: WorldVM.World _ GetDefaultWorld[]; put: PutClosure _ GetPutClosure[NIL]; id: AMEvents.BreakID _ NIL; msg: ROPE _ NIL; inner: PROC = TRUSTED { tv: TV _ IF world = WorldVM.LocalWorld[] THEN AMBridge.TVForGFHReferent[LOOPHOLE[gf]] ELSE AMBridge.TVForRemoteGFHReferent [[world, WorldVM.CurrentIncarnation[world], gf]]; id _ FindBreak[tv, gf, pc, TRUE] }; OctalOut["Break at (gf: %B", gf, put]; OctalOut[", pc: %B) ", pc, put]; msg _ BBSafety.Mother[inner]; IF id # NIL THEN { BBBugOut.ShowRope["cleared.\n", put] } ELSE { IF msg = NIL THEN msg _ "not found"; BBBugOut.ShowRope["NOT cleared (", put]; BBBugOut.ShowRope[msg, put]; BBBugOut.ShowRope[").\n", put] }; }; ListOctalBreaks: PUBLIC ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; put: PutClosure _ GetPutClosure[NIL]; IF localBreakList = NIL THEN { BBBugOut.ShowRope["No current octal breaks.\n", put]; RETURN}; BBBugOut.ShowRope["Current octal breaks:\n", put]; FOR list: LocalBreakList _ localBreakList, list.rest UNTIL list = NIL DO OctalOut[" Break at (gf: %B", list.first.gf, put]; OctalOut[", pc: %B)\n", list.first.pc, put]; ENDLOOP; }; PrintLocalFrame: PROC [lf: CARDINAL] = TRUSTED { put: PutClosure _ GetPutClosure[NIL]; tv: TV = TrustLocalFrame[lf]; oct: CARDINAL _ 0; PrintTV.Print[tv: tv, put: put, verbose: TRUE]; }; PrintGlobalFrame: PROC [gf: CARDINAL] = TRUSTED { put: PutClosure _ GetPutClosure[NIL]; tv: TV = TrustGlobalFrame[gf]; PrintTV.Print[tv: tv, put: put, verbose: TRUE]; }; TrustLocalFrame: PROC [lf: CARDINAL] RETURNS [tv: TV] = TRUSTED { world: WorldVM.World _ GetDefaultWorld[]; IF world = WorldVM.LocalWorld[] THEN tv _ AMBridge.TVForFrame[fh: LOOPHOLE[lf]] ELSE tv _ AMBridge.TVForRemoteFrame[[ world: world, worldIncarnation: WorldVM.CurrentIncarnation[world], fh: LOOPHOLE[lf]]]; }; TrustGlobalFrame: PROC [gf: CARDINAL] RETURNS [tv: TV] = TRUSTED { world: WorldVM.World _ GetDefaultWorld[]; IF world = WorldVM.LocalWorld[] THEN tv _ AMBridge.TVForGFHReferent[gfh: LOOPHOLE[gf]] ELSE tv _ AMBridge.TVForRemoteGFHReferent[[ world: world, worldIncarnation: WorldVM.CurrentIncarnation[world], gfh: LOOPHOLE[gf]]]; }; TrustLocalFrameHelper: BBEvalQuote.EvalQuoteProc = TRUSTED { world: WorldVM.World _ BBEvalUtil.WorldFromHead[head]; arg: BBEval.Tree _ GetArg[tree, 1]; tv: TV _ BBEval.Eval[arg, head, target]; RETURN [TrustLocalFrame[AMBridge.TVToCardinal[tv]]]; }; TrustGlobalFrameHelper: BBEvalQuote.EvalQuoteProc = TRUSTED { world: WorldVM.World _ BBEvalUtil.WorldFromHead[head]; arg: BBEval.Tree _ GetArg[tree, 1]; tv: TV _ BBEval.Eval[arg, head, target]; RETURN [TrustGlobalFrame[AMBridge.TVToCardinal[tv]]]; }; OctalOut: PROC [msg: ROPE, x: INT _ 0, put: PutClosure _ NullPutClosure] = { pos: INT _ 0; lim: INT _ msg.Size[]; WHILE pos < lim DO c: CHAR _ msg.Fetch[pos]; pos _ pos + 1; IF c = '% THEN BBBugOut.ShowOctal[x, put] ELSE BBBugOut.ShowChar[c, put]; ENDLOOP; }; GetDefaultWorld: PROC RETURNS [world: World _ NIL] = TRUSTED { head: BBEval.EvalHead = NARROW[List.Assoc[$EvalHead, ProcessProps.GetPropList[]]]; IF head # NIL THEN { context: BBContext.Context = head.context; IF context # NIL THEN world _ BBContext.GetContents[context].world; }; IF world = NIL THEN world _ WorldVM.LocalWorld[]; }; hackDefaultStream: STREAM _ NIL; GetPutClosure: PROC [stream: STREAM] RETURNS [pc: PutClosure _ NullPutClosure] = TRUSTED { IF stream = NIL THEN { command: Commander.Handle = NARROW[List.Assoc[$CommanderHandle, ProcessProps.GetPropList[]]]; IF command # NIL THEN stream _ command.out; }; IF stream = NIL THEN { IF hackDefaultStream = NIL THEN hackDefaultStream _ IO.CreateViewerStreams["Octal.log"].out; stream _ hackDefaultStream; }; pc _ [PutChar, stream]; }; PutChar: PrintTV.PutProc = { IO.PutChar[NARROW[data], c]; }; RegisterCommands: PROC = { RegisterOne[OctalRead, "&or[ptr,len]\tOctal Read"]; RegisterOne[OctalReadShort, "&ors[ptr,len]\tOctal Read Short"]; RegisterOne[OctalWrite, "&ow[ptr,word,len]\tOctal Write"]; RegisterOne[OctalWriteShort, "&ows[ptr,word,len]\tOctal Write Short"]; RegisterOne[AsciiRead, "&ar[ptr,len]\tAscii Read"]; RegisterOne[AsciiReadShort, "&ars[ptr,len]\tAscii Read Short"]; RegisterOne[OctalReadCode, "&orc[gf,pc,len]\tOctal Read Code"]; RegisterOne[OctalFindCode, "&ofc[gf,pc,...]\tOctal Find Code"]; RegisterOne[SetOctalBreak, "&sob[gf,pc]\tSet Octal Break"]; RegisterOne[ClearOctalBreak, "&clob[gf,pc]\tCLear Octal Break"]; RegisterOne[ListOctalBreaks, "&lob[]\tList Octal Breaks"]; RegisterOne[FindMatching, "&fm[pattern]\tFind Matching"]; RegisterOne[TrustLocalFrame, "&tlf[lf]\tTrust Local Frame"]; RegisterOne[TrustGlobalFrame, "&tgf[gf]\tTrust Global Frame"]; RegisterOne[PrintLocalFrame, "&plf[lf]\tPrint Local Frame"]; RegisterOne[PrintGlobalFrame, "&pgf[gf]\tPrint Global Frame"]; BBEvalQuote.Register["&fm", FindMatchingHelper]; BBEvalQuote.Register["&tlf", TrustLocalFrameHelper]; BBEvalQuote.Register["&tgf", TrustGlobalFrameHelper]; }; RegisterOne: PROC [proc: PROC ANY RETURNS ANY _ NIL, help: ROPE _ NIL] = TRUSTED { [] _ TVGuide.RegisterTV[ name: help.Flatten[0, help.SkipTo[0, "["]], tv: AMBridge.TVForProc[proc], help: help]; }; RegisterCommands[ ! ANY => CONTINUE]; END. ²OctalCommands.mesa: wizards debugging aids Russ Atkinson, May 18, 1983 8:42 pm [gf: TV, name: ROPE], where gf is the global frame hack to lengthen the pointer special hack for the short octal read hack to lengthen the pointer special hack for the short octal read [head: BBEval.EvalHead, tree: BBEval.Tree, target: Type _ nullType, data: REF _ NIL] RETURNS [return: TV] ... adds a new break to the local list of octal breaks. It will get a private error out of AMEventsImpl if FrameBreak can't handle setting the break, including the case where there are duplicate breaks. This means that the caller has to be able to handle ANY error (sigh). ... gets the code base for the octal gfh, clearing out the code trap bit to be safe. This procedure just runs around trying to find the given break. If one is found, it removes it if delete is TRUE, and calls AMEvents.ClearBreak to clear the succker. Since AMEvents can barf at this request, we have to be able to handle this problem. [head: BBEval.EvalHead, tree: BBEval.Tree, target: Type _ nullType, data: REF _ NIL] RETURNS [return: TV] [head: BBEval.EvalHead, tree: BBEval.Tree, target: Type _ nullType, data: REF _ NIL] RETURNS [return: TV] ÊÓ˜Jšœ*™*Jšœ#™#J˜šÏk ˜ šœ ˜Jšœw˜w—Jšœ œ!˜/Jšœœ7˜DJšœ œ@˜NJšœ œ>˜MJšœœ˜%Jšœœ˜$Jšœ œ˜,Jšœ œ˜-Jšœ œ˜%Jšœ œ ˜Jšœœ ˜Jšœœ œ˜0Jšœœ ˜Jšœ œ ˜Jšœ œ˜(Jšœ œ˜Jšœœ.˜;Jšœ œ˜!Jšœœœ˜7Jšœœœ˜Jšœœ˜šœ˜J˜——šœœ˜š˜Jšœuœ@˜·—Jšœ ˜Jšœœœ!˜-J˜Jšœœœœ˜J˜Jšœœ ˜"J˜Jšœœœ˜Jšœœœ˜Jšœœœ ˜Jšœœœ ˜J˜Jš œœœœ œ˜,Jš œœœœœ˜+Jš œœœœœ˜+Jš œœœœœ˜+J˜Jš œœœ œœ œ˜8J˜Jšœ œœ˜J˜—J˜š Ïn œœœœœ˜GJšœ œ˜%Jšœœ˜Jšœ œ˜(Jš œ œœœœœ˜Rš œ œœ œœ˜0Jšœœœ˜šœ œœ˜J˜&J˜J˜J˜—Jšœœ˜'šœœ˜J˜>—J˜—šœ"œ˜+Jšœ2™2šœœœ˜Jšœœ˜J˜&Jšœœ!˜'Jšœœœ˜šœœœ˜Jšœ œ$˜2Jš œœœœœ˜2Jšœœ2œ˜FJ˜J˜!J˜J˜Jšœ˜—J˜—šœœœ˜J˜J˜šœœ˜"J˜—J˜J˜—Jšœœœ˜Jšœ œœ œ˜+J˜šœœ˜J˜@—J˜—Jšœ œœ˜1J˜AJ˜J˜—šž œœœ˜Jšœœœ œ˜+Jšœœ œ˜)Jšœœœ˜!J˜)J˜Jšœœ˜Jšœœ˜Jšœ œ˜%šœœœ œ˜Jšœ$˜$Jšœ˜—šœ˜J˜Jšœ,œ˜;—Jšœ œ œÏc˜4Jšœ œ Ÿ˜,šœœ ˜ šœ˜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šœ,˜4J˜—Jšœœ˜—šœœ˜Jšœ˜Jšœ œ˜,Jšœ˜—šœ˜ šœ˜Jšœ˜Jšœ œ˜,J˜—Jšœœ œ˜1—J˜šœ˜˜Jšœœœ˜/—˜J˜—šœ˜JšŸ˜Jšœœ˜šœœ ˜šœ˜Jšœœœ˜šœœ ˜J˜—J˜—Jšœ˜!——šœ˜ Jš œœœœœ˜@J˜0——J˜J˜Jšœ˜—Jšœ œ˜,J˜J˜J˜—šžœœ˜Jšœœ œ˜&Jšœœ œœ ˜CJšœ(˜(Jšœ œ˜1J˜J˜—šž œœ˜Jš œœœ œ œœ˜FJ˜)Jšœ œ˜Jšœœ˜$Jšœ˜šœ ˜šœ˜Jšœ™J˜—˜Jšœ%™%Jšœ ˜ Jšœœ˜J˜—Jšœ˜—šœ œœ˜Jšœ œ˜%Jšœ2˜2Jšœ˜—šœœœ ˜šœ˜Jšœœœ˜Jšœœ˜J˜—Jšœ ˜ Jšœ˜—šœ œ˜Jšœ œ˜%Jšœ œ˜6J˜—Jšœ œœ˜J˜J˜—šžœœ˜Jšœœ œ œ ˜9Jšœ(˜(Jšœ œ ˜J˜J˜—šž œ˜Jšœœœ œ ˜-Jšœ œœ˜J˜ J˜J˜—šžœ˜Jšœœ œ ˜(Jšœ(˜(Jšœ œ˜'J˜J˜—šž œ˜Jšœœ œœ˜2Jšœ?˜?J˜J˜—šž œœ˜Jšœœœ˜ Jšœœœ˜8Jšœ œ˜%J˜J˜!šœœ˜Jšœ œ ˜4Jšœœ˜ Jšœœ œœ#˜DJšœœ˜Jšœ˜šœ ˜Jšœœœ˜J˜Jšœ˜—Jšœ œœ˜š˜šœ œ˜(Jšœœœ˜š œœœ œ˜*J˜0Jšœ˜—Jšœœœ˜—J˜ Jšœ˜—J˜Jšœ'œ˜-J˜—š˜J˜ —J˜J˜—šœ0œ˜9Jšœi™iJšœ6˜6Jšœ#˜#Jšœœ˜(šœœ˜šœœ˜šœ˜šœ œ˜Jšœ œ˜ Jšœ˜——Jšœ˜——Jšœ˜Jšœ"˜(J˜J˜—š žœœœœœ˜QJ˜.šœ˜ šœ˜šœœ˜+J˜$——Jšœœ œ ˜"—J˜J˜—Jšœœœ˜,š žœœ#œœ œ˜UJšœœ˜J˜šœ œœ#˜=Jšœ˜—Jšœœ˜J˜!Jšœœ˜$J˜J˜—š ž œœœ œœ˜8J˜)Jšœ œ˜%Jšœœ˜Jšœœœ˜šœœœ˜šœœ˜ šœ˜Jšœœ˜,šœ ˜$J˜1———Jšœ˜J˜—Jšœ&˜&Jšœ ˜ J˜šœ˜ Jšœ!˜%šœ˜Jšœœœ˜*Jšœ$˜$Jšœ˜Jšœ˜J˜——Jšœ˜J˜—Jšœ˜Jšœœœœ˜/šœœœ˜ Jšœ3œ˜=—J˜šžœœ˜Jš œœ œœœœ˜JJšœ’™’Jšœœœ˜Jšœ-˜-šœ2œœ˜HJš œœœœœ˜VJšœ˜—JšœJ˜JJšœœ9˜NJšœ˜J˜—šž œ˜Jšœœœœ˜QJšœT™TJšœœœ˜J˜$Jšœ&Ÿ ˜2Jšœ%œŸ˜IJšœ˜J˜—šž œœ˜Jš œœ œ œœ˜/Jšœœœ˜0Jšœü™üJšœœœ˜Jšœœ˜Jšœ-˜-šœ2œœ˜Hšœœœœ˜PJ˜šœœ˜Jšœœœœ˜GJšœ˜J˜—Jšœ˜J˜—Jšœ ˜ Jšœ˜—Jšœ˜J˜—š žœœœ œœ˜:J˜)Jšœ œ˜%Jšœ˜Jšœœœ˜šœœœ˜šœœ˜ šœ˜Jšœœ˜,šœ ˜$J˜1———Jšœœ˜ Jšœ˜—Jšœ&˜&Jšœ ˜ J˜šœ˜ šœ˜Jšœ$˜$J˜—šœ˜Jšœœœ˜$Jšœ(˜(Jšœ˜Jšœ˜J˜——J˜J˜—š žœœœœœ˜.Jšœœœ˜Jšœ œ˜%šœœœ˜Jšœ5˜5Jšœ˜—Jšœ2˜2šœ2œœ˜HJšœ3˜3Jšœ,˜,Jšœ˜—J˜J˜—šžœœœœ˜0Jšœ œ˜%Jšœœ˜Jšœœ˜Jšœ)œ˜0J˜J˜—šžœœœœ˜1Jšœ œ˜%Jšœœ˜Jšœ)œ˜0J˜J˜—š žœœœœœœ˜AJ˜)šœ˜Jšœœ˜/š˜šœ ˜ Jšœ ˜ Jšœ4˜4Jšœœ˜———J˜J˜—š žœœœœœœ˜BJ˜)šœ˜Jšœ%œ˜6š˜šœ&˜&Jšœ ˜ Jšœ4˜4Jšœœ˜———J˜J˜—šœ3œ˜Jšœœ4˜Ršœœœ˜J˜*Jšœ œœ.˜CJ˜—Jšœ œœ˜1J˜J˜—Jšœœœ˜ šž œ˜Jšœ œœ%œ˜Gšœ œœ˜˜Jšœ;˜A—Jšœ œœ˜+J˜—šœ œœ˜šœœ˜Jšœœ&˜<—Jšœ˜J˜—J˜J˜J˜—˜Jšœ œ ˜J˜J˜—šžœœ˜J˜3J˜?J˜:J˜FJ˜3J˜?J˜?J˜?J˜;J˜@J˜:J˜9J˜Jšœ1˜1Jšœ5˜5Jšœ6˜6J˜J˜—šž œœœœœœœœœœ˜Ršœ˜Jšœ+˜+Jšœ˜Jšœ ˜ —J˜J˜—Jšœœœ˜%J˜šœ˜J˜J˜J˜——…—A[Ÿ