DIRECTORY Ascii, Atom, CD, CDBasics, CDCells, CDCommandOps, CDErrors, CDExtras, CDInstances, CDMenus, CDProperties, CDSequencer, CDSymbolicObjects, CDTexts, CDOps, IO, Rope, TerminalIO; CDPCommands: CEDAR PROGRAM IMPORTS Ascii, Atom, CDBasics, CDCells, CDCommandOps, CDErrors, CDExtras, CDInstances, CDMenus, CDProperties, CDSequencer, CDSymbolicObjects, CDTexts, CDOps, IO, Rope, TerminalIO = BEGIN PropertyRec: TYPE = RECORD [key: ATOM_NIL, value: REF_NIL, onOb: BOOL_FALSE]; PutPropFromPropertyRec: PROC [inst: CD.Instance, prop: PropertyRec] = BEGIN IF prop.onOb THEN { IF inst.ob.class.inDirectory THEN CDProperties.PutProp[onto: inst.ob, prop: prop.key, val: prop.value] } ELSE CDProperties.PutProp[onto: inst, prop: prop.key, val: prop.value] END; SetPropsFromTextsComm: PROC [comm: CDSequencer.Command] = BEGIN n, m: INT; TerminalIO.WriteRope["propertize all texts"]; n _ SetPropsFromTexts[comm.design]; TerminalIO.WriteRope["; now check\n"]; m _ CheckProps[comm.design, NIL]; TerminalIO.WriteF[" %g texts propertized; %g mismatch(es) found\n", IO.int[n], IO.int[m]]; END; PutPropOnSelectedComm: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["propertize selected\n"]; PutPropOnSelected[comm.design]; TerminalIO.WriteRope[" end\n"]; END; CheckPropsFromTextsComm: PROC [comm: CDSequencer.Command] = BEGIN n: INT; TerminalIO.WriteRope["check properties\n"]; n _ CheckProps[comm.design, NIL]; TerminalIO.WriteF[" %g unmatched text(s) found\n", IO.int[n]]; END; CellCheckPropsComm: PROC [comm: CDSequencer.Command] = BEGIN inst: CD.Instance _ CDCommandOps.TheInstance[comm: comm, text: "check properties"]; IF inst#NIL THEN { no: INT _ 0; IF ~CDCells.IsCell[inst.ob] THEN { TerminalIO.WriteRope[" not done: selected object is not cell\n"]; RETURN; }; no _ CheckProps[comm.design, inst.ob]; TerminalIO.WriteF[" %g unmatched text(s) found\n", IO.int[no]]; }; END; SimilarRopes: PROC [x, y: REF] RETURNS [BOOL_FALSE] = { IF x=y THEN RETURN [TRUE]; IF ISTYPE[x, Rope.ROPE] AND ISTYPE[y, Rope.ROPE] THEN { RETURN [ Rope.Equal[ NARROW[x, Rope.ROPE], NARROW[y, Rope.ROPE] ] ] }; }; SelectFromPropertyComm: PROC [comm: CDSequencer.Command] = BEGIN pRec: PropertyRec _ [$SignalName, NIL, FALSE]; inst: CD.Instance _ CDCommandOps.TheInstance[comm: comm, text: "select from property"]; IF inst#NIL THEN { design: CD.Design _ comm.design; no: INT _ 0; IF MyKindOfText[inst.ob] THEN pRec _ TextToPropRec[inst.ob] ELSE IF inst.ob.class.wireTyped OR CDSymbolicObjects.IsSymbolicOb[inst.ob] THEN { pRec.key _ $SignalName; pRec.value _ CDProperties.GetProp[from: inst, prop: pRec.key]; } ELSE { TerminalIO.WriteRope[" not done: selected object is not text (Helvetica*I) or rectangle\n"]; RETURN; }; IF pRec.key=NIL THEN { TerminalIO.WriteRope[" not done: property key is NIL\n"]; RETURN; }; TerminalIO.WriteF[" select using property: %g, value: %g\n", IO.atom[pRec.key], IO.rope[(IF pRec.value=NIL THEN "NIL" ELSE CDExtras.ToRope[pRec.value])]]; FOR l: CD.InstanceList _ CDOps.InstList[design], l.rest WHILE l#NIL DO x: REF _ CDProperties.GetProp[l.first, pRec.key]; IF SimilarRopes[x, pRec.value] THEN { l.first.selected _ TRUE; CDCommandOps.RedrawInstance[design, l.first, FALSE]; no _ no+1 }; ENDLOOP; IF no>0 AND CDTexts.IsText[inst.ob] THEN { inst.selected _ FALSE; CDCommandOps.RedrawInstance[design, inst]; }; TerminalIO.WriteF[" %g instance(s) selected\n", IO.int[no]]; }; END; PropagateSignalNameComm: PROC [comm: CDSequencer.Command] = BEGIN inst: CD.Instance _ CDCommandOps.TheInstance[comm: comm, text: "propagate signal name"]; IF inst#NIL THEN { design: CD.Design _ comm.design; il: CD.InstanceList _ CDOps.InstList[design]; foundL: CD.InstanceList _ LIST[inst]; no: INT _ 1; value: REF _ CDProperties.GetProp[from: inst, prop: $SignalName]; IF value=NIL THEN { TerminalIO.WriteRope[" not done: no signal name\n"]; RETURN; }; WHILE foundL#NIL DO curr: CD.Instance _ foundL.first; currR: CD.Rect _ CDInstances.InstRectI[curr]; foundL _ foundL.rest; FOR l: CD.InstanceList _ il, l.rest WHILE l#NIL DO IF ~l.first.selected AND l.first.ob.class.wireTyped AND l.first.ob.layer=curr.ob.layer THEN { IF CDBasics.Intersect[currR, CDInstances.InstRectI[l.first]] THEN { foundL _ CONS[l.first, foundL]; l.first.selected _ TRUE; no _ no+1; CDProperties.PutProp[l.first, $SignalName, value]; CDCommandOps.RedrawInstance[design, l.first, FALSE]; }; } ENDLOOP; ENDLOOP; TerminalIO.WriteF[" %g instance(s) selected\n", IO.int[no]]; }; END; SetPropsFromTexts: PROC [design: CD.Design] RETURNS [n: INT_0] = BEGIN HandleOneText: PROC [inst: CD.Instance, design: CD.Design] RETURNS [someFound: BOOL_FALSE] = BEGIN IF MyKindOfText[inst.ob] THEN { pRec: PropertyRec _ TextToPropRec[inst.ob]; r: CD.Rect _ CDInstances.InstRectI[inst]; IF pRec.key=NIL OR ~PublicProperty[pRec.key] THEN RETURN; FOR l: CD.InstanceList _ CDOps.InstList[design], l.rest WHILE l#NIL DO IF ~CDTexts.IsText[l.first.ob] AND CDBasics.Intersect[r, CDInstances.InstRectI[l.first]] THEN { someFound _ TRUE; PutPropFromPropertyRec[l.first, pRec] } ENDLOOP; } END; FOR l: CD.InstanceList _ CDOps.InstList[design], l.rest WHILE l#NIL DO IF MyKindOfText[l.first.ob] THEN IF HandleOneText[l.first, design].someFound THEN n _ n+1; ENDLOOP; END; TextToPropRec: PROC [ob: CD.Object] RETURNS [pRec: PropertyRec _ [NIL, NIL, FALSE]] = BEGIN RopeToPropRec: PROC [text: Rope.ROPE] RETURNS [pRec: PropertyRec _ [$SignalName, NIL, FALSE]] = BEGIN keyPart: Rope.ROPE; val: Rope.ROPE; n: INT _ Rope.SkipTo[s: text, skip: ":"]; IF n RETURN [tp.text] ENDCASE => NULL; END; RETURN [RopeToPropRec[TextRope[ob]]] END; MyKindOfText: PROC [ob: CD.Object] RETURNS [BOOL_FALSE] = BEGIN ThatIsMyFont: PROC [name: Rope.ROPE] RETURNS [BOOL] = BEGIN RETURN [ Rope.Match[object: name, pattern: "Xerox/TiogaFonts/Helvetica*", case: FALSE] AND Ascii.Upper[Rope.Fetch[name, Rope.Length[name]-1]]='I ] END; WITH ob.specificRef SELECT FROM tp: CDTexts.TextPtr => RETURN [ThatIsMyFont[tp.cdFont.supposedName]] ENDCASE => NULL; END; PutPropOnSelected: PROC [design: CD.Design] = BEGIN Occurs: PROC [list: LIST OF PropertyRec, key: ATOM] RETURNS [BOOL_FALSE] = BEGIN FOR pl: LIST OF PropertyRec _ list, pl.rest WHILE pl#NIL DO IF pl.first.key=key THEN RETURN [TRUE] ENDLOOP; END; doList: LIST OF PropertyRec_NIL; FOR l: CD.InstanceList _ CDOps.InstList[design], l.rest WHILE l#NIL DO IF l.first.selected AND MyKindOfText[l.first.ob] THEN { pr: PropertyRec _ TextToPropRec[l.first.ob]; IF pr.key=NIL THEN { TerminalIO.WriteRope["unknown property\n"]; [] _ CDErrors.IncludeMessage[design: design, ob: NIL, rect: CDInstances.InstRectI[l.first], message: "bad property key", owner: $PropertyChecker] } ELSE IF Occurs[doList, pr.key] THEN { TerminalIO.WriteF[" ** property: %g, value: %g twice or contradicting! ignored\n", IO.atom[pr.key], IO.rope[(IF pr.value=NIL THEN "NIL" ELSE CDExtras.ToRope[pr.value])]] } ELSE { doList _ CONS[pr, doList]; TerminalIO.WriteF[" property: %g, value: %g\n", IO.atom[pr.key], IO.rope[(IF pr.value=NIL THEN "NIL" ELSE CDExtras.ToRope[pr.value])]]; } } ENDLOOP; IF doList=NIL THEN TerminalIO.WriteRope["no text (in Helvetica*I) selected"] ELSE { FOR il: CD.InstanceList _ CDOps.InstList[design], il.rest WHILE il#NIL DO IF il.first.selected AND ~CDTexts.IsText[il.first.ob] THEN { FOR pl: LIST OF PropertyRec _ doList, pl.rest WHILE pl#NIL DO PutPropFromPropertyRec[il.first, pl.first] ENDLOOP; } ENDLOOP; } END; CheckProps: PROC [design: CD.Design, cell: CD.Object] RETURNS [cnt: INT_0] = BEGIN BlownIntersection: PROC [r1, r2: CD.Rect, blow: CD.Number] RETURNS [CD.Rect] = { RETURN [ CDBasics.Intersection[CDBasics.Extend[r1, blow], CDBasics.Extend[r2, blow]] ]; }; CheckPropsOfOneText: PROC [inst: CD.Instance, design: CD.Design, cell: CD.Object] RETURNS [ok: BOOL_TRUE] = BEGIN IF MyKindOfText[inst.ob] THEN { r: CD.Rect _ CDInstances.InstRectI[inst]; pRec: PropertyRec _ TextToPropRec[inst.ob]; cellPtr: CD.CellPtr _ IF cell=NIL THEN design.actual.first.specific ELSE NARROW[cell.specificRef]; val: REF; IF pRec.key=NIL THEN RETURN; FOR l: CD.InstanceList _ cellPtr.contents, l.rest WHILE l#NIL DO IF ~CDTexts.IsText[l.first.ob] AND CDBasics.Intersect[r, CDInstances.InstRectI[l.first]] THEN { IF pRec.onOb THEN val _ CDProperties.GetProp[from: l.first.ob, prop: pRec.key] ELSE val _ CDProperties.GetProp[from: l.first, prop: pRec.key]; IF ~SimilarRopes[val, pRec.value] THEN { errR: CD.Rect _ BlownIntersection[r, CDInstances.InstRectI[l.first], design.technology.lambda]; [] _ CDErrors.IncludeMessage[design: design, ob: cell, rect: r, message: "property missmatch", owner: $PropertyChecker]; RETURN [ok_FALSE] } }; ENDLOOP; } END; cellPtr: CD.CellPtr _ IF cell=NIL THEN design.actual.first.specific ELSE NARROW[cell.specificRef]; CDErrors.RemoveMessages[design: design, ob: cell, owner: $PropertyChecker]; FOR l: CD.InstanceList _ cellPtr.contents, l.rest WHILE l#NIL DO IF CDTexts.IsText[l.first.ob] THEN IF ~CheckPropsOfOneText[inst: l.first, design: design, cell: cell] THEN cnt _ cnt+1 ENDLOOP; END; PublicProperty: PROC [key: ATOM] RETURNS [BOOL_TRUE] = { pType: CDProperties.PropertyProcs _ CDProperties.FetchProcs[key]; RETURN [ pType=NIL OR ~pType.exclusive ]; }; RemoveTrailingBlanks: PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = { n: INT _ Rope.Length[r]; WHILE n>0 AND Rope.Fetch[r, n-1]=' DO n _ n-1 ENDLOOP; RETURN [Rope.Substr[base: r, start: 0, len: n]]; }; RemoveLeadingBlanks: PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = { RETURN [Rope.Substr[base: r, start: Rope.SkipOver[s: r, skip: " "]]] }; RemoveBlanksFromBothEnds: PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = { RETURN [RemoveLeadingBlanks[RemoveTrailingBlanks[r]]] }; CDSequencer.ImplementCommand[a: $AllPropertize, p: SetPropsFromTextsComm, queue: doQueue]; CDSequencer.ImplementCommand[a: $SelPropertize, p: PutPropOnSelectedComm, queue: doQueue]; CDSequencer.ImplementCommand[a: $PropSel, p: SelectFromPropertyComm, queue: doQueue]; CDSequencer.ImplementCommand[a: $PropTextCheckCell, p: CellCheckPropsComm, queue: doQueue]; CDSequencer.ImplementCommand[a: $PropTextCheck, p: CheckPropsFromTextsComm, queue: doQueue]; CDSequencer.ImplementCommand[a: $PropSig, p: PropagateSignalNameComm, queue: doQueue]; [] _ CDMenus.CreateMenu["Names & Properties", $NameMenu]; CDMenus.ImplementMenuCommand[$NameMenu, $NameMenu]; CDMenus.CreateEntry[menu: $NameMenu, entry: "properties from intersecting Texts", key: $AllPropertize]; CDMenus.CreateEntry[menu: $NameMenu, entry: "propertize selected from Text(s)", key: $SelPropertize]; CDMenus.CreateEntry[menu: $NameMenu, entry: "select all having property (Text)", key: $PropSel]; CDMenus.CreateEntry[menu: $NameMenu, entry: "check properties (top level)", key: $PropTextCheck]; CDMenus.CreateEntry[menu: $NameMenu, entry: "check properties (selected CELL)", key: $PropTextCheckCell]; CDMenus.CreateEntry[menu: $NameMenu, entry: "propagate SignalName of selected", key: $PropSig]; CDMenus.CreateEntry[menu: $NameMenu, entry: "other entries", key: $NameMenu2]; END. lCDPCommands.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. by Ch. Jacobi, November 20, 1985 7:59:40 pm PST Last Edited by: Jacobi, November 26, 1985 11:07:31 am PST --SetPropsFromTexts --key nil means bad syntax --TextToPropRec --MyKindOfText --PutPropOnSelected --build list of properties -- put properties on instances --CheckProps Κ€code˜šœ™Jšœ Οmœ1™˜>K˜—šžœ˜Kšœ]˜]Kšžœ˜K˜—šžœ žœžœ˜Kšœ:˜:Kšžœ˜K˜—Kš œ>žœžœžœ žœžœžœ ˜›š žœžœ/žœžœž˜FKšœžœ+˜1šžœžœ˜%Kšœžœ˜Kšœ-žœ˜4Kšœ ˜ Kšœ˜—Kšžœ˜—šžœžœžœ˜*Kšœžœ˜Kšœ*˜*K˜—Kšœ1žœ ˜=Kšœ˜—Kšžœ˜—K˜š œžœ˜;Kšž˜KšœžœP˜Xšžœžœžœ˜Kšœžœ˜ Kšœžœ'˜-Kšœžœžœ˜%Kšœžœ˜ Kšœžœ7˜Ašžœžœžœ˜Kšœ5˜5Kšžœ˜K˜—šžœžœž˜Kšœžœ˜!Kšœ-˜-Kšœ˜š žœžœžœžœž˜2šžœžœžœ žœ˜]šžœ;žœ˜CKšœ žœ˜Kšœžœ˜Kšœ ˜ Kšœ2˜2Kšœ-žœ˜4K˜—K˜—Kšžœ˜—Kšžœ˜—Kšœ1žœ ˜=Kšœ˜—Kšžœ˜—K˜š  œžœ žœ žœžœ˜@Kšž˜K˜š  œžœžœžœ žœ žœžœ˜\Kšž˜šžœžœ˜Kšœ+˜+Kšœžœ$˜)Kš žœ žœžœžœžœ˜9š žœžœ/žœžœž˜Fšžœžœ7žœ˜_Kšœ žœ˜Kšœ%˜%K˜—Kšžœ˜—Kšœ˜—Kšžœ˜—Kšœ™š žœžœ/žœžœž˜Fšžœžœ˜!Kšžœ*žœ ˜9—Kšžœ˜—Kšžœ˜—K˜K˜š  œžœžœ žœžœžœžœ˜UKšž˜K˜š   œžœ žœžœ$žœžœ˜_Kšœ™Kšž˜Kšœžœ˜Kšœ žœ˜Kšœžœ#˜)šžœžœ˜KšœN˜NKšœ+˜+Kšžœžœ žœ˜.Kšžœ#˜'K˜—Kšœ%˜%Kšžœžœ˜+Kšžœ˜—K˜š  œžœžœ žœ žœžœ˜˜OKšžœ;˜?šžœ žœ˜(KšœžœW˜_Jšœx˜xKšžœžœ˜K˜—Kšœ˜—Kšžœ˜—Kšœ˜—Kšžœ˜—K™Kšœ ™ Kš œ žœ žœžœžœžœžœ˜bKšœK˜Kš žœžœ)žœžœž˜@šžœžœ˜#KšžœAžœ ˜S—Kšžœ˜—Kšžœ˜—K˜š  œžœžœžœžœžœ˜8KšœA˜AKšžœ žœžœ˜)Kšœ˜—K˜š  œžœ žœžœžœ˜AKšœžœ˜Kšžœžœžœ žœ˜7Kšžœ*˜0K˜—K˜š  œžœ žœžœžœ˜@Kšžœ>˜DK˜—K˜š  œžœ žœžœžœ˜EKšžœ/˜5K˜—K˜KšœZ˜ZKšœZ˜ZKšœU˜UKšœ[˜[Kšœ\˜\KšœV˜VK˜Kšœ9˜9Kšœ3˜3K˜Kšœg˜gKšœe˜eKšœ`˜`Kšœa˜aKšœi˜iKšœ_˜_KšœN˜NKšžœ˜—…—,Έ<Θ