DIRECTORY NodeProps, TextNode, PGSupport, RefTab, NameSymbolTable, Rope; NodePropsImpl: CEDAR PROGRAM IMPORTS NameSymbolTable, RefTab, Rope, TextNode EXPORTS TextNode, NodeProps = BEGIN OPEN NodeProps; Prop, Props: TYPE = REF NodePropsBody; NodePropsBody: PUBLIC TYPE = RECORD [ name: ATOM, -- name of the property next: Props, -- points to next property value: REF ]; commentAtom: ATOM = $Comment; commentName: ROPE = "Comment"; typeAtom: ATOM = $Format; typeName: ROPE = "Format"; styleDefAtom: ATOM = $StyleDef; styleDefName: ROPE = "StyleDef"; prefixAtom: ATOM = $Prefix; prefixName: ROPE = "Prefix"; postfixAtom: ATOM = $Postfix; postfixName: ROPE = "Postfix"; ObjectRec: TYPE = RECORD [rope: ROPE, object: Object]; true: PUBLIC REF BOOLEAN _ NEW[BOOLEAN _ TRUE]; false: PUBLIC REF BOOLEAN _ NEW[BOOLEAN _ FALSE]; ReadComment: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] = { RETURN [IF Rope.Equal[specs,"TRUE",FALSE] THEN true ELSE false] }; WriteComment: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] = { specs _ "FALSE"; IF value # NIL THEN WITH value SELECT FROM x: REF BOOLEAN => IF x^ THEN specs _ "TRUE"; ENDCASE }; CopyComment, CopyPfix: PROC [name: ATOM, value: REF] RETURNS [new: REF] = { RETURN [value] }; ReadPfix: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] = { RETURN [specs] }; WritePfix: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] = { RETURN [NARROW[value]] }; PrefixName: PUBLIC PROC RETURNS [ROPE] = { RETURN [prefixName] }; PrefixAtom: PUBLIC PROC RETURNS [ATOM] = { RETURN [prefixAtom] }; PostfixName: PUBLIC PROC RETURNS [ROPE] = { RETURN [postfixName] }; PostfixAtom: PUBLIC PROC RETURNS [ATOM] = { RETURN [postfixAtom] }; GetPrefixObject: PUBLIC PROCEDURE [n: TextNode.Ref] RETURNS [ob: Object] = { RETURN [GetPFix[n,prefixAtom]] }; GetPostfixObject: PUBLIC PROCEDURE [n: TextNode.Ref] RETURNS [ob: Object] = { RETURN [GetPFix[n,postfixAtom]] }; GetPFix: PROC [n: TextNode.Ref, name: ATOM] RETURNS [Object] = { prop: Prop _ FindName[n, name, FALSE]; val: REF ObjectRec; IF prop=NIL OR (val _ NARROW[prop.value])=NIL THEN RETURN [NameSymbolTable.NullObject[]]; RETURN [val.object] }; FindName: PROC [n: TextNode.Ref, name: ATOM, remove: BOOLEAN] RETURNS [prop: Prop] = { lst, prev: Props; IF n=NIL THEN RETURN [NIL]; lst _ n.props; prop _ NIL; prev _ NIL; WHILE lst#NIL DO IF lst.name = name THEN { prop _ lst; EXIT }; prev _ lst; lst _ lst.next; ENDLOOP; IF prop#NIL AND remove THEN IF prev#NIL THEN prev.next _ prop.next ELSE n.props _ prop.next }; PutProp: PUBLIC PROCEDURE [n: TextNode.Ref, name: ATOM, value: REF] = { prop: Prop _ FindName[n, name, FALSE]; PFix: PROC = TRUSTED { rope: ROPE _ NARROW[value]; -- value is rope for the prefix/postfix ob: Object _ NameSymbolTable.MakeObject[LOOPHOLE[Rope.Flatten[rope]]]; value _ TextNode.pZone.NEW[ObjectRec _ [rope, ob]] }; IF value = NIL THEN { IF prop#NIL THEN prop.value _ NIL; SELECT name FROM styleDefAtom => n.hasstyledef _ FALSE; prefixAtom => n.hasprefix _ FALSE; postfixAtom => n.haspostfix _ FALSE; typeAtom => n.typename _ TextNode.nullTypeName; commentAtom => { txt: TextNode.RefTextNode _ TextNode.NarrowToTextNode[n]; IF txt#NIL THEN txt.comment _ FALSE }; ENDCASE; RETURN }; SELECT name FROM styleDefAtom => n.hasstyledef _ TRUE; prefixAtom => { PFix; n.hasprefix _ TRUE }; postfixAtom => { PFix; n.haspostfix _ TRUE }; typeAtom => { WITH value SELECT FROM x: Rope.ROPE => TRUSTED {n.typename _ NameSymbolTable.MakeName[LOOPHOLE[Rope.Flatten[x]]]}; ENDCASE => ERROR; RETURN }; commentAtom => { -- simply set the bit in the node txt: TextNode.RefTextNode _ TextNode.NarrowToTextNode[n]; WITH value SELECT FROM x: REF BOOLEAN => txt.comment _ x^; ENDCASE => ERROR; RETURN }; ENDCASE; IF prop#NIL THEN { prop.value _ value; RETURN }; n.props _ TextNode.pZone.NEW[NodePropsBody _ [name, n.props, value]] }; GetProp: PUBLIC PROCEDURE [n: TextNode.Ref, name: ATOM] RETURNS [value: REF] = { prop: Prop _ FindName[n, name, FALSE]; PFix: PROC RETURNS [REF] = { val: REF ObjectRec _ NARROW[prop.value]; RETURN [IF val=NIL THEN NIL ELSE val.rope] }; IF prop # NIL THEN SELECT name FROM prefixAtom, postfixAtom => value _ PFix[]; ENDCASE => value _ prop.value ELSE IF name = commentAtom THEN { txt: TextNode.RefTextNode _ TextNode.NarrowToTextNode[n]; value _ IF txt # NIL AND txt.comment THEN true ELSE false } ELSE IF name = typeAtom THEN value _ IF n.typename = TextNode.nullTypeName THEN NIL ELSE NameSymbolTable.RopeFromName[n.typename] }; RemProp: PUBLIC PROCEDURE [n: TextNode.Ref, name: ATOM] = { [] _ FindName[n, name, TRUE]; -- removes the value SELECT name FROM styleDefAtom => n.hasstyledef _ FALSE; prefixAtom => n.hasprefix _ FALSE; postfixAtom => n.haspostfix _ FALSE; typeAtom => n.typename _ TextNode.nullTypeName; commentAtom => { txt: TextNode.RefTextNode _ TextNode.NarrowToTextNode[n]; IF txt#NIL THEN txt.comment _ FALSE }; ENDCASE }; MapProps: PUBLIC PROCEDURE [n: TextNode.Ref, action: MapPropsAction, typeFlag, commentFlag: BOOLEAN _ TRUE] RETURNS [BOOLEAN] = { props: Props; next: Props; name: ATOM; value: REF; txt: TextNode.RefTextNode; IF n=NIL THEN RETURN [FALSE]; props _ n.props; IF typeFlag AND action[typeAtom,NameSymbolTable.RopeFromName[n.typename]] THEN RETURN [TRUE]; IF commentFlag AND (txt _ TextNode.NarrowToTextNode[n]) # NIL THEN IF action[commentAtom,IF txt.comment THEN true ELSE false] THEN RETURN [TRUE]; WHILE props#NIL DO next _ props.next; -- get it now in case action deletes current prop SELECT name _ props.name FROM prefixAtom, postfixAtom => { x: REF ObjectRec _ NARROW[props.value]; value _ IF x=NIL THEN NIL ELSE x.rope }; ENDCASE => value _ props.value; IF action[name,value] THEN RETURN [TRUE]; props _ next; ENDLOOP; RETURN [FALSE]}; ReaderProcRef: TYPE = REF ReaderProcRec; ReaderProcRec: TYPE = RECORD [proc: ReadSpecsProc]; WriterProcRef: TYPE = REF WriterProcRec; WriterProcRec: TYPE = RECORD [proc: WriteSpecsProc]; CopierProcRef: TYPE = REF CopierProcRec; CopierProcRec: TYPE = RECORD [proc: CopyInfoProc]; readerTable: RefTab.Ref _ RefTab.Create[]; writerTable: RefTab.Ref _ RefTab.Create[]; copierTable: RefTab.Ref _ RefTab.Create[]; Register: PUBLIC PROC [name: ATOM, reader: ReadSpecsProc, writer: WriteSpecsProc, copier: CopyInfoProc] = { IF name=NIL THEN RETURN; [] _ RefTab.Store[readerTable,name,TextNode.pZone.NEW[ReaderProcRec _ [reader]]]; [] _ RefTab.Store[writerTable,name,TextNode.pZone.NEW[WriterProcRec _ [writer]]]; [] _ RefTab.Store[copierTable,name,TextNode.pZone.NEW[CopierProcRec _ [copier]]] }; NullRead: PUBLIC PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] = { RETURN [NIL] }; NullWrite: PUBLIC PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] = { RETURN [NIL] }; NullCopy: PUBLIC PROC [name: ATOM, value: REF] RETURNS [new: REF] = { RETURN [NIL] }; DoSpecs: PUBLIC PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] = { procRef: ReaderProcRef; proc: ReadSpecsProc; value _ IF name=NIL OR (procRef _ NARROW[RefTab.Fetch[readerTable,name].val])=NIL OR (proc _ procRef.proc)=NIL THEN specs ELSE proc[name,specs] }; GetSpecs: PUBLIC PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] = { procRef: WriterProcRef; proc: WriteSpecsProc; IF name=NIL OR (procRef _ NARROW[RefTab.Fetch[writerTable,name].val])=NIL OR (proc _ procRef.proc)=NIL THEN IF value=NIL THEN specs _ NIL ELSE WITH value SELECT FROM rope: ROPE => specs _ rope; ENDCASE => specs _ NIL ELSE specs _ proc[name,value] }; CopyInfo: PUBLIC PROC [name: ATOM, value: REF] RETURNS [new: REF] = { procRef: CopierProcRef; proc: CopyInfoProc; new _ IF name=NIL OR (procRef _ NARROW[RefTab.Fetch[copierTable,name].val])=NIL OR (proc _ procRef.proc)=NIL THEN value ELSE proc[name,value] }; StartNodeProps: PUBLIC PROC = { Register[prefixAtom, ReadPfix, WritePfix, CopyPfix]; Register[postfixAtom, ReadPfix, WritePfix, CopyPfix]; Register[commentAtom, ReadComment, WriteComment, CopyComment] }; END. HNodePropsImpl.Mesa written by Paxton. January 1981 Paxton. December 28, 1982 11:12 am Maxwell, January 5, 1983 12:53 pm Russ Atkinson, July 26, 1983 6:01 pm apply the action to each name & value pair for the node returns true if&when an action returns true -- ***** read, write, copy props -- registers these procs for this variety of node -- they will be called by DoSpecs, GetSpecs, and CopyInfo -- used when reading files -- calls the registered reader for this property name -- returns specs if no reader is registered -- used when writing files -- calls the registered writer for this property name -- if no writer is registered, returns value if it is a rope, NIL otherwise -- used when copying nodes -- calls the registered copier for this property name -- if no copier is registered, returns value -- ***** Initialization Ê s˜šÏc™Jš ™ Jš"™"J™!J™$J™—šÏk ˜ 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šœ žœžœžœ˜6J˜Jš œžœžœžœžœžœžœ˜/Jš œžœžœžœžœžœžœ˜1J˜š Ïn œžœžœ žœžœ žœ˜DJš žœžœžœžœžœ ˜BJ˜—š Ÿ œžœžœ žœžœ žœ˜EJ˜š žœ žœžœžœžœž˜*Jš œžœžœžœžœ˜,Jšžœ˜ J˜——š œ Ÿœžœžœ žœžœžœ˜KJšžœ ˜J˜—š Ÿœžœžœ žœžœ žœ˜AJšžœ ˜J˜—š Ÿ œžœžœ žœžœ žœ˜BJšžœžœ ˜J˜—š Ÿ œžœžœžœžœ˜*Jšžœ˜J˜—š Ÿ œžœžœžœžœ˜*Jšžœ˜J˜—š Ÿ œžœžœžœžœ˜+Jšžœ˜J˜—š Ÿ œžœžœžœžœ˜+Jšžœ˜J˜—šŸœžœž œ˜3Jšžœ˜Jšžœ˜!J˜—šŸœžœž œ˜4Jšžœ˜Jšžœ˜"J˜—šŸœžœžœžœ ˜@Jšœžœ˜&Jšœžœ ˜š žœžœžœžœ žœž˜2Jšžœ ˜&—Jšžœ˜J˜—šŸœžœžœ žœ˜=Jšžœ˜J˜Jš žœžœžœžœžœ˜J˜Jšœžœ žœ˜šžœžœž˜Jšžœžœžœ˜-J˜Jšžœ˜—šžœžœžœž˜Jšžœžœžœ˜&Jšžœ˜J˜——š Ÿœžœž œžœ žœ˜GJšœžœ˜&šŸœžœžœ˜Jšœžœžœ '˜CJšœ(žœ˜FJšœžœ˜5—šžœ žœžœ˜Jšžœžœžœžœ˜"šžœž˜Jšœ žœ˜&Jšœžœ˜"Jšœžœ˜$J˜/˜J˜9Jšžœžœžœžœ˜&—Jšžœ˜—Jšžœ˜ —šžœž˜Jšœ žœ˜%Jšœ$žœ˜+Jšœ&žœ˜-˜ šžœžœž˜Jšœžœžœ(žœ˜[Jšžœžœ˜—Jšžœ˜ —šœ!˜2J˜9šžœžœž˜Jšœžœžœ˜#Jšžœžœ˜—Jšžœ˜ —Jšžœ˜—Jšžœžœžœžœ˜0Jšœžœ+˜GJ˜—šŸœžœž œžœ˜7Jšžœ žœ˜Jšœžœ˜&šŸœžœžœžœ˜Jšœžœ žœ ˜(Jš žœžœžœžœžœžœ ˜-—š žœžœžœžœž˜#J˜*Jšžœ˜—šžœžœžœ˜!J˜9Jš œžœžœžœ žœžœ˜;—šžœžœž˜šœžœ$žœžœž˜;J˜+J˜———šŸœžœž œžœ˜;Jšœžœ˜2šžœž˜Jšœ žœ˜&Jšœžœ˜"Jšœžœ˜$J˜/˜J˜9Jšžœžœžœžœ˜&—Jšžœ˜ —J˜—š Ÿœžœž œBžœžœ˜kJšžœžœ˜Jšœ7™7Jšœ+™+J˜ J˜ Jšœžœ˜ Jšœžœ˜ J˜Jš žœžœžœžœžœ˜J˜Jš žœ žœ;žœžœžœ˜]šžœ žœ(žœž˜BJšžœžœ žœžœžœžœžœ˜N—šžœžœž˜Jšœ1˜Dšžœž˜˜Jšœžœ žœ˜'Jš œžœžœžœžœžœ ˜(—Jšžœ˜—Jšžœžœžœžœ˜)J˜ Jšžœ˜—Jšžœžœ˜J˜J˜—Jš ™ J˜Jšœžœžœ˜(Jšœžœžœ˜3J˜Jšœžœžœ˜(Jšœžœžœ˜4J˜Jšœžœžœ˜(Jšœžœžœ˜2J˜J˜*J˜*J˜*J˜šŸœžœžœžœ˜"J˜J˜J˜Jš1™1Jš:™:Jšžœžœžœžœ˜Jšœ2žœ˜QJšœ2žœ˜QJšœ2žœ˜SJ˜—šŸœžœžœžœ žœžœ žœ˜HJšžœžœ˜J˜—šŸ œžœžœžœ žœžœ žœ˜IJšžœžœ˜J˜—šŸœžœžœžœ žœžœžœ˜EJšžœžœ˜J˜—šŸœžœžœžœ žœžœ žœ˜GJš™Jš5™5Jš+™+J˜J˜šœžœžœž˜Jšœ žœ&žœž˜=Jšœž˜Jšžœžœ˜#J˜——šŸœžœžœžœ žœžœ žœ˜HJš™Jš5™5JšK™KJ˜J˜šžœžœž˜Jšœ žœ&žœž˜=Jšœž˜—š žœžœžœžœ ž˜"šžœžœžœž˜Jšœžœ˜Jšžœ ž˜——Jšžœ˜ J˜—šŸœžœžœžœ žœžœžœ˜EJš™Jš5™5Jš,™,J˜J˜šœžœžœž˜Jšœ žœ&žœž˜=Jšœž˜Jšžœžœ˜#J˜J˜——Jš™J˜šŸœžœžœ˜J˜4J˜5J˜@J˜—Jšžœ˜J˜—…—æ.¡