DIRECTORY Atom, FileWriter, FS, InterFile, IO, NameSymbolTable, NodeProps, OtherNode, Rope, RopeEdit, RopeReader, RunReader, TextLooks, TextNode; PutInterFileImpl: CEDAR PROGRAM IMPORTS Atom, FileWriter, FS, NameSymbolTable, npI:NodeProps, OtherNode, Rope, RopeEdit, RopeReader, RunReader, TextLooks, TextNode EXPORTS InterFile SHARES Rope = BEGIN OPEN InterFile, TextNode; ToRope: PUBLIC PROC [node: Ref, flatten: BOOL _ TRUE] RETURNS [output: ROPE] = { data: FileWriter.Ref = FileWriter.ToRope[FALSE].data; Header[data]; Finish[data,node,flatten]; Trailer[data]; output _ FileWriter.Close[NIL,NIL,data,FALSE].output }; ToStream: PUBLIC PROC [stream: IO.STREAM, node: Ref, flatten: BOOL _ TRUE] RETURNS [count: Offset] = { data: FileWriter.Ref = FileWriter.ToStream[stream,FALSE].data; Header[data]; Finish[data,node,flatten]; Trailer[data]; count _ FileWriter.Close[NIL,NIL,data,FALSE].count; }; ToFile: PUBLIC PROC [fileName: ROPE, node: Ref, start: Offset _ 0, flatten: BOOL _ TRUE] RETURNS [count: Offset] = { file: FS.OpenFile = FS.Open[fileName, write]; data: FileWriter.Ref = FileWriter.OpenC[file,start,FALSE].data; Header[data]; Finish[data,node,flatten]; Trailer[data]; count _ FileWriter.Close[NIL,NIL,data,FALSE].count; FS.Close[file]; }; Header: PROC [data: FileWriter.Ref] = { WC['{,data]; FileWriter.WriteText["Interdoc/Interchange/0.0",data]; WC[15C,data]; }; Trailer: PROC [data: FileWriter.Ref] = { WC['},data] }; WC: PROC [c: CHAR, data: FileWriter.Ref] = { FileWriter.WriteChar[c,data] }; Finish: PROC [data: FileWriter.Ref, root: Ref, flatten: BOOL, runReader: RunReader.Ref _ NIL, ropeReader: RopeReader.Ref _ NIL, nameText: REF TEXT _ NIL, indent: NAT _ 0] = { WriteChar: PROC [c: CHAR] = { FileWriter.WriteChar[c,data] }; WriteAtom: PROC [atom: ATOM] = { WriteRope[Atom.GetPName[atom]] }; WriteText: PROC [txt: REF READONLY TEXT] = { FOR i: NAT IN [0..txt.length) DO char: CHAR; SELECT char _ txt[i] FROM '>, '# => WriteInt[char]; ENDCASE => FileWriter.WriteChar[char,data]; ENDLOOP }; WriteRope: PROC [r: ROPE] = { WriteChar['<]; WriteSimpleRope[r]; WriteChar['>] }; WriteSimpleRope: PROC [r: ROPE] = { size: Offset _ RopeEdit.Size[r]; RopeReader.SetPosition[ropeReader,r]; FOR i: Offset IN [0..size) DO char: CHAR; SELECT char _ RopeReader.Get[ropeReader] FROM '>, '# => WriteInt[char]; ENDCASE => FileWriter.WriteChar[char,data]; ENDLOOP }; WriteInt: PROC [c: CHAR] = { i: [0..255] _ LOOPHOLE[c]; WriteChar['#]; WriteChar['A + i/16]; WriteChar['A + i MOD 16]; WriteChar['#] }; NameText: PROC [name: NameSymbolTable.Name] = { OPEN NameSymbolTable; FromName[name,nameText ! TextOverflow => { nameText _ pZone.NEW[TEXT[nameText.length*2]]; RETRY } ]}; WriteLooks: PROC [lks: TextLooks.Looks] = { Look: TYPE = TextLooks.Look; WriteText["looks=<"]; FOR c:Look IN Look DO IF lks[c] THEN WriteChar[c]; ENDLOOP; WriteChar['>] }; WriteProp: PROC [name: ATOM, value: REF] RETURNS [BOOL] = { WritePropName: PROC = { WriteAtom[name]; WriteChar['=] }; WITH value SELECT FROM x:Ref => { -- prop value is a node WritePropName; Finish[data,x,flatten, runReader,ropeReader,nameText,indent+nesting]; LineBreak }; ENDCASE => { -- write specs as a rope specs: ROPE _ npI.GetSpecs[name,value]; IF specs # NIL THEN { WritePropName; WriteRope[specs]; LineBreak }}; RETURN [FALSE] }; LineBreak: PROC = { WriteChar[15C]; FOR i: NAT IN [0..indent) DO WriteChar[' ]; ENDLOOP }; nesting: NAT = 4; -- number of spaces per level of nesting typename: TypeName; terminal: BOOL; node,nodeChild: Ref; freeRunReader, freeRopeReader: BOOL _ TRUE; RopeRep: TYPE = Rope.RopeRep; substr: REF substr node RopeRep; IF runReader=NIL THEN runReader _ RunReader.GetRunReader[] ELSE freeRunReader _ FALSE; IF ropeReader=NIL THEN ropeReader _ RopeReader.GetRopeReader[] ELSE freeRopeReader _ FALSE; IF nameText=NIL THEN nameText _ pZone.NEW[TEXT[32]]; node _ root; DO -- start the node LineBreak; WriteChar['{]; IF (typename _ node.typename) # nullTypeName THEN { NameText[typename]; WriteText[nameText]; LineBreak }; IF node.props # NIL THEN [] _ npI.MapProps[node,WriteProp]; TRUSTED {WITH n:node SELECT FROM text => { -- write the text rope: ROPE; size: Offset; runs: TextLooks.Runs; IF flatten THEN { -- flatten rope and runs n.rope _ RopeEdit.Flatten[n.rope]; n.runs _ TextLooks.Flatten[n.runs] }; rope _ n.rope; size _ Rope.Size[rope]; IF (runs _ n.runs) = NIL THEN WriteRope[rope] ELSE { -- write each run separately loc, cnt, numRuns: Offset _ 0; [numRuns,,] _ TextLooks.CountRuns[runs,0,size]; RunReader.SetPosition[runReader,runs,0]; IF substr = NIL THEN substr _ pZone.NEW[substr node RopeRep _ [node[substr[0,NIL,0,0]]]]; substr.base _ rope; substr.depth _ 1+RopeEdit.Depth[rope]; WHILE (cnt_cnt+1) <= numRuns DO looks: TextLooks.Looks; len: Offset; [len,looks] _ RunReader.MergedGet[runReader]; substr.size _ len; substr.start _ loc; IF looks = TextLooks.noLooks THEN WriteRope[substr] ELSE { WriteChar['{]; WriteLooks[looks]; WriteRope[substr]; WriteChar['}] }; loc _ loc+len; ENDLOOP; IF loc # size THEN ERROR }}; other => { WriteAtom[n.variety]; WriteChar['[]; WriteRope[OtherNode.GetSpecs[@n]]; WriteChar[']] }; ENDCASE => ERROR}; terminal _ (nodeChild_FirstChild[node])=NIL; IF ~terminal THEN { node _ nodeChild; indent _ indent+nesting } ELSE { -- node has no children WriteChar['}]; DO IF node=root THEN GOTO Finis; IF ~IsLastSibling[node] THEN { node _ Next[node]; EXIT }; node _ Parent[node]; WriteChar['}]; indent _ indent-nesting; ENDLOOP }; REPEAT Finis => { IF freeRunReader THEN RunReader.FreeRunReader[runReader]; IF freeRopeReader THEN RopeReader.FreeRopeReader[ropeReader] }; ENDLOOP }; StartPutFile: PUBLIC PROC = { }; END. PutInterFileImpl.Mesa written by Paxton. May 1981 McGregor. September 10, 1982 1:17 pm Maxwell, January 5, 1983 12:59 pm Russ Atkinson, July 25, 1983 2:58 pm -- write type -- write node props -- now write contents -- move to the next node -- ***** Initialization ʇ˜šœ™Jšœ™Jšœ$™$Jšœ!™!J™$J™—šÏk ˜ J˜J˜ Jšœ˜J˜ Jšœ˜J˜J˜ J˜ J˜J˜ J˜ J˜ J˜ J˜ —J˜šœ ˜š˜Jšœœg˜{—Jšœ ˜Jšœ˜ Jšœœœ˜!—J˜šÏnœœœœœœ œ˜PJšœ)œ˜5J˜ J˜J˜Jšœœœœ ˜7J˜—šžœœ˜Jš œ œœœœ˜PJšœ2œ˜>J˜ J˜J˜Jšœœœœ˜3Jšœ˜J˜—šžœœ˜Jš œ œ)œœœ˜`Jšœœ œ˜-Jšœ3œ˜?J˜ J˜J˜Jšœœœœ˜3Jšœ ˜Jšœ˜J˜—šžœœ˜'Jšœ ˜ J˜6Jšœ ˜ Jšœ˜J˜—šžœœ˜(Jšœ ˜J˜—Jšœœœ;˜LJ˜šžœœ,œ˜=Jšœœœ˜AJš œ œœœ œ ˜.J˜Jšž œœœ%˜=J˜šž œœœ˜ J˜!J˜—š ž œœœœœ˜,šœœœ˜ Jšœœ˜ šœ˜J˜Jšœ$˜+—Jšœ˜ J˜——šž œœœ˜J˜3J˜—šžœœœ˜#J˜ J˜%šœ œ ˜Jšœœ˜ šœ#˜-J˜Jšœ$˜+—Jšœ˜ J˜——šžœœœ˜Jšœœ˜J˜J˜Jšœœ˜J˜J˜—šžœœ!˜/Jšœ˜˜Jšœ#œœœ˜LJ˜——šž œœ˜+Jšœœ˜J˜Jš œœœœœœ˜;J˜J˜—š ž œœœ œœœ˜;šž œœ˜J˜J˜—šœœ˜šœ Ïc˜"J˜˜J˜.—J˜ —šœŸ˜%Jšœœ˜'šœ œœ˜J˜J˜J˜ ———Jšœœ˜J˜—šž œœ˜J˜Jš œœœ œœ˜6J˜—Jšœ œŸ(˜:J˜Jšœ œ˜J˜Jšœœœ˜+Jšœ œ˜Jšœœ˜ J˜Jšœ œœ%˜:Jšœœ˜Jšœ œœ(˜>Jšœœ˜Jš œ œœœœ˜4J˜J˜ šœŸ˜J˜JšŸ ™ šœ+œ˜3J˜5—JšŸ™Jšœœœ#˜;JšŸ™Jšœœœ˜ šœ Ÿ˜Jšœœ˜ J˜ J˜šœ œŸ˜*J˜"J˜%—J˜&Jšœœœ˜-šœŸ˜#J˜J˜/J˜(šœ œ˜šœœ˜(Jšœœ ˜——J˜J˜&šœ˜J˜J˜ J˜-J˜J˜Jšœœ˜3šœ˜J˜J˜J˜J˜—J˜Jšœ˜—Jšœ œœ˜——˜ J˜J˜J˜"J˜—Jšœœ˜JšŸ™Jšœ(œ˜-Jšœ œ.˜?šœŸ˜J˜šœœ œœ˜ Jšœœœ˜9J˜