DIRECTORY EditAddrs, NodeAddrs, NodeProps, TextNode; EditAddrsImpl: MONITOR IMPORTS npI:NodeProps, TextNode, NodeAddrs EXPORTS EditAddrs = BEGIN OPEN EditAddrs; Create: PUBLIC PROC RETURNS [Ref] = { RETURN [TextNode.pZone.NEW[Body]] }; FindPair: PROC [ref: Ref, addr: REF] RETURNS [Pair] = { IF ref#NIL THEN FOR p: Pair _ ref.addrs, p.next UNTIL p=NIL DO IF p.addr = addr THEN RETURN [p]; ENDLOOP; RETURN [NIL] }; PutAddr: PUBLIC PROC [ref: Ref, addr: REF, location: Offset] = { p: Pair; IF (p _ FindPair[ref, addr])=NIL THEN ref.addrs _ TextNode.pZone.NEW[PairBody _ [ref.addrs, addr, location]] ELSE p.location _ location }; RemAddr: PUBLIC PROC [ref: Ref, addr: REF] = { p, prev: Pair; IF ref=NIL OR (p _ ref.addrs)=NIL THEN RETURN; IF p.addr=addr THEN { ref.addrs _ p.next; RETURN }; DO prev _ p; p _ p.next; IF p=NIL THEN RETURN; IF p.addr=addr THEN { prev.next _ p.next; RETURN }; ENDLOOP }; GetAddr: PUBLIC PROC [ref: Ref, addr: REF] RETURNS [location: Offset] = { p: Pair; IF (p _ FindPair[ref, addr])=NIL THEN ERROR AddrNotFound; RETURN [p.location] }; TryGetAddr: PUBLIC PROC [ref: Ref, addr: REF] RETURNS [found: BOOLEAN, location: Offset] = { p: Pair; IF (p _ FindPair[ref, addr])=NIL THEN RETURN [FALSE, 0]; RETURN [TRUE, p.location] }; AddrNotFound: PUBLIC ERROR = CODE; MapAddrs: PUBLIC PROC [ref: Ref, action: MapAddrsAction] RETURNS [BOOLEAN] = { IF ref#NIL THEN { p: Pair _ ref.addrs; UNTIL p=NIL DO next: Pair _ p.next; IF action[p.addr, p.location] THEN RETURN [TRUE]; p _ next; ENDLOOP}; RETURN [FALSE] }; notify: LIST OF AddrNotifyProc; unlocked: CONDITION; lockCount: INTEGER _ 0; Lock: ENTRY PROC = { lockCount _ lockCount+1 }; Unlock: ENTRY PROC = { IF (lockCount _ lockCount-1) <= 0 THEN { lockCount _ 0; BROADCAST unlocked }}; AddNotifyProc: PUBLIC ENTRY PROC [proc: AddrNotifyProc] = { ENABLE UNWIND => NULL; notify _ CONS[proc, notify]; }; RemoveNotifyProc: PUBLIC ENTRY PROC [proc: AddrNotifyProc] = { ENABLE UNWIND => NULL; prev: LIST OF AddrNotifyProc; IF notify = NIL THEN RETURN; IF notify.first = proc THEN { notify _ notify.rest; RETURN }; WHILE lockCount > 0 DO WAIT unlocked; ENDLOOP; prev _ notify; FOR l: LIST OF AddrNotifyProc _ notify.rest, l.rest UNTIL l = NIL DO IF l.first = proc THEN { prev.rest _ l.rest; RETURN }; prev _ l; ENDLOOP; }; Notify: AddrNotifyProc = { ENABLE UNWIND => Unlock[]; Lock[]; FOR l: LIST OF AddrNotifyProc _ notify, l.rest UNTIL l = NIL DO l.first[node, new]; ENDLOOP; Unlock[] }; GetAddrs: PROC [n: RefTextNode] RETURNS [Ref] = { RETURN [IF n.props = NIL THEN NIL ELSE NARROW[npI.GetProp[n,addrsProp]]] }; addrsProp: ATOM _ NodeAddrs.AddrsProp[]; Replace: PUBLIC PROC [node: RefTextNode, start, len, newlen: Offset] = { replace: PROC [old: Offset] RETURNS [Offset] = { RETURN [AfterReplace[old, start, len, newlen]] }; end: Offset _ start+len; ref: Ref = GetAddrs[node]; Notify[node, replace]; IF ref=NIL THEN RETURN; FOR p: Pair _ ref.addrs, p.next UNTIL p=NIL DO SELECT p.location FROM >= end => p.location _ p.location-len+newlen; >= start => p.location _ start; ENDCASE; ENDLOOP }; AfterReplace: PUBLIC PROC [initLoc, start, len, newlen: Offset] RETURNS [newLoc: Offset] = { newLoc _ SELECT initLoc FROM >= start+len => initLoc-len+newlen, >= start => start, ENDCASE => initLoc}; Start: PUBLIC PROC = { }; END. ¾-- EditAddrsImpl.Mesa -- written by Paxton. March 1981 -- last written by Paxton. October 18, 1982 11:14 am -- **** Persistent addressing **** -- assigns addr to location in ref -- ok if addr was previously assigned elsewhere -- removes the given addr -- generates ERROR AddrNotFound if the addr is not in the mapping -- apply the action to each addr&location pair for the ref -- returns true if&when an action returns true -- **** notify proc registration **** -- **** Editing Operations for persistent addrs **** -- replace chars in [start..start+len) by newlen chars -- addrs that are in the replaced section move to start -- add (newlen-len) to locations that are after the replaced section Êú˜JšÏc™Jš!™!Jš4™4J˜Jš"™"J˜JšÏk ˜ J˜ J˜ J˜ J˜ J˜šœž˜Jšžœ#˜*Jšžœ ˜—Jšžœžœ ˜J˜Jš Ïnœžœžœžœ žœžœ ˜JJ˜šŸœžœžœžœ ˜7šžœžœž˜šžœžœžœž˜.Jšžœžœžœžœ˜*——Jšžœžœ˜J˜—šŸœžœžœžœ˜AJš"™"Jš/™/J˜šžœžœž˜%Jšœžœ(˜F—Jšžœ˜J˜—šŸœžœžœžœ˜.Jš™J˜Jš žœžœžœžœžœžœ˜.Jšžœ žœžœ˜3šž˜J˜Jšžœžœžœžœ˜Jšžœ žœžœ˜3Jšžœ˜ J˜——š Ÿœžœžœžœžœ˜IJšA™AJ˜Jšžœžœžœžœ˜9Jšžœ˜J˜—šŸ œžœžœžœ˜-Jšžœ žœ˜.J˜Jš žœžœžœžœžœ˜8Jšžœžœ˜J˜—Jšœžœžœžœ˜"J˜šŸœžœžœ#˜8Jšžœžœ˜Jš:™:Jš.™.šžœžœžœ˜J˜šžœžœž˜J˜Jšžœžœžœžœ˜1J˜ Jšžœ˜ ——Jšžœžœ˜J˜—Jš%™%J˜Jšœžœžœ˜J˜Jšœ ž œ˜Jšœ žœ˜J˜JšŸœžœžœ˜/J˜šŸœžœžœ˜šžœ žœ˜(Jšœž œ ˜%——J˜šŸ œžœžœžœ˜;Jšžœžœžœ˜Jšœ žœ˜J˜J˜—šŸœžœžœžœ˜>Jšžœžœžœ˜Jšœžœžœ˜Jšžœ žœžœžœ˜Jšžœžœžœ˜=Jšžœžœžœ žœ˜.J˜š žœžœžœ&žœžœž˜DJšžœžœžœ˜6J˜ Jšžœ˜—J˜J˜—šœ˜Jšžœžœ ˜J˜š žœžœžœ!žœžœž˜?Jšœžœ˜—šœ ˜ J˜——Jš4™4J˜šŸœžœžœ ˜1Jšžœžœ žœžœžœžœžœ˜KJ˜—Jšœ žœ˜(J˜šŸœžœžœ4˜HJš6™6Jš7™7JšD™Dšœ žœžœ ˜0Jšžœ+˜1—J˜J˜J˜Jšžœžœžœžœ˜šžœžœžœž˜.šžœ ž˜J˜-J˜Jšžœ˜—Jšžœ˜ J˜——šŸ œžœžœ&˜?Jšžœ˜šœ žœ ž˜J˜#J˜Jšžœ ˜J˜——šŸœžœžœ˜J˜J˜—Jšžœ˜J˜—…— ô¬