DIRECTORY CD, CDBottomUp, CDCells, CDCommandOps, CDDirectory, CDImports, CDOps, CDProperties, CDSequencer, CDSimpleRules, IO, RefTab, Rope, TerminalIO; CDFeatureCheckImpl: CEDAR PROGRAM IMPORTS CD, CDBottomUp, CDCells, CDCommandOps, CDDirectory, CDImports, CDOps, CDProperties, CDSequencer, CDSimpleRules, IO, RefTab, Rope, TerminalIO = BEGIN MsgProc: TYPE = PROC [ob: CD.Object] RETURNS [msg: Rope.ROPE_NIL]; State: TYPE = RefTab.Ref; FeatureTab: PROC [state: State] RETURNS [featureTab: RefTab.Ref] = INLINE { featureTab _ NARROW[state]; }; ReadOnlyCell: PROC [ob: CD.Object] RETURNS [readOnlyCell: CD.Object_NIL] = { readOnlyCell _ ob; WHILE ob#NIL AND ob.class.composed AND ~CDCells.IsCell[ob] DO readOnlyCell _ CDDirectory.Expand1[ob, NIL, NIL, FALSE].new; IF readOnlyCell=ob OR readOnlyCell=NIL THEN readOnlyCell _ CDDirectory.Expand1ByDraw[ob]; ob _ readOnlyCell; ENDLOOP; }; CheckClass: PROC [ob: CD.Object] RETURNS [msg: Rope.ROPE_NIL] = { WITH CDProperties.GetObjectProp[ob, $CDFeatureCheck] SELECT FROM mp: REF MsgProc => RETURN [mp[ob]]; r: Rope.ROPE => RETURN [r]; ENDCASE => WITH CDProperties.GetProp[ob.class, $CDFeatureCheck] SELECT FROM mp: REF MsgProc => RETURN [mp[ob]]; ENDCASE => RETURN [NIL] }; BadLayer: PROC [ob: CD.Object] RETURNS [msg: Rope.ROPE] = { msg _ Rope.Cat["layer ", CDOps.LayerRope[ob.layer], " used in ", CD.Describe[ob]] }; CheckContainer: PROC [state: State, ob: CD.Object] RETURNS [msg: Rope.ROPE _ NIL] = { recurse: BOOL_FALSE; mustCheckLayer: BOOL_FALSE; layerFound: BOOL_FALSE; CheckRef: PROC [val: REF] = { IF val=NIL THEN { IF ~ob.class.composed AND ~ob.class.symbolic THEN { IF recurse OR (val_RefTab.Fetch[FeatureTab[state], $CDFeatureCheckOthers].val)#NIL THEN msg _ Rope.Cat["class not enabled: ", CD.Describe[ob]] ELSE {recurse _ TRUE; CheckRef[val]} }; } ELSE WITH val SELECT FROM a: ATOM => { IF a=$T THEN layerFound _ TRUE ELSE IF a=CD.LayerKey[ob.layer] THEN layerFound _ TRUE ELSE mustCheckLayer _ TRUE }; lora: LIST OF REF ANY => FOR l: LIST OF REF ANY _ lora, l.rest WHILE (l#NIL AND msg=NIL) DO CheckRef[l.first]; ENDLOOP; loa: LIST OF ATOM => {layerKey: ATOM ~ CD.LayerKey[ob.layer]; FOR ll: LIST OF ATOM _ loa, ll.rest WHILE ll#NIL DO IF layerKey=ll.first OR ll.first=$T THEN {layerFound _ TRUE; EXIT}; ENDLOOP; mustCheckLayer _ TRUE; }; mp: REF MsgProc => msg _ mp[ob]; rp: REF CD.Rect => { sz: CD.Position _ CD.InterestSize[ob]; IF sz.xrp.x2 OR sz.y>rp.y2 THEN msg _ Rope.Cat[CD.Describe[ob], " too large"]; }; r: Rope.ROPE => IF ~Rope.IsEmpty[r] THEN msg _ Rope.Cat[CD.Describe[ob], " ", r]; ENDCASE => msg _ Rope.Cat["class forbidden: ", CD.Describe[ob]]; }; CheckRef[RefTab.Fetch[FeatureTab[state], ob.class.objectType].val]; IF Rope.IsEmpty[msg] AND mustCheckLayer AND ~layerFound THEN msg _ BadLayer[ob]; IF Rope.IsEmpty[msg] THEN msg _ CheckClass[ob]; IF Rope.IsEmpty[msg] THEN msg _ NIL; }; CheckTopChilds: PROC [state: State, ob: CD.Object] RETURNS [msg: Rope.ROPE _ NIL] = { cnt: INT _ 0; ob1: CD.Object _ ReadOnlyCell[ob]; IF ob1=NIL THEN msg _ "failed to expand" ELSE { EachInst: CDCells.InstEnumerator = { IF ~inst.ob.class.composed THEN { msg1: Rope.ROPE _ CheckContainer[state, inst.ob]; IF msg1#NIL THEN { cnt _ cnt+1; IF cnt<4 THEN msg _ Rope.Cat[msg, "\n | ", msg1] ELSE IF cnt=4 THEN msg _ Rope.Cat[msg, "\n |"] ELSE msg _ Rope.Cat[msg, "|"] }; } }; [] _ CDCells.EnumerateInstances[ob1, EachInst]; }; }; CheckOneLevel: PROC [state: State, ob: CD.Object] RETURNS [msg: Rope.ROPE _ NIL] = { msg _ CheckContainer[state, ob]; IF Rope.IsEmpty[msg] THEN msg _ CheckTopChilds[state, ob]; }; DoExt: CDBottomUp.DoProc = { msg: Rope.ROPE _ NIL; TerminalIO.PutRopes["checking ", CD.Describe[ob: ob, design: handle.design]]; IF CDImports.IsImport[ob] THEN { ip: CDImports.ImportSpecific _ NARROW[ob.specific]; IF ip.boundOb=NIL THEN msg _ "not bound" }; IF msg=NIL THEN msg _ CheckOneLevel[NARROW[handle.data], ob]; IF msg=NIL THEN TerminalIO.PutRope[" ok\n"] ELSE { handle.cnt _ handle.cnt+1; TerminalIO.PutRopes["\n ** ", msg, "\n"] }; val _ msg; IF handle.design#NIL THEN CDSequencer.CheckAborted[handle.design]; }; ReUseExt: CDBottomUp.ReUseProc = { TerminalIO.PutRopes["previously checked ", CD.Describe[ob: ob, design: handle.design]]; WITH previousVal SELECT FROM r: Rope.ROPE => { handle.cnt _ handle.cnt+1; TerminalIO.PutRopes["\n ** ", r, "\n"] }; ENDCASE => TerminalIO.PutRope[" ok\n"]; IF handle.design#NIL THEN CDSequencer.CheckAborted[handle.design]; }; HierarchicalFeatureCheckComm: PROC [comm: CDSequencer.Command] = { HierarchicalFeatureCheck: PROC [featureChecker: CDBottomUp.Class, design: CD.Design, state: RefTab.Ref, ob: CD.Object] = { h: CDBottomUp.Handle _ CDBottomUp.StartRecurse[featureChecker, ob, design, state].handle; IF h.cnt=0 THEN TerminalIO.PutRope["no errors found\n"] ELSE TerminalIO.PutF1["error(s) found in %g object(s)\n", [integer[h.cnt]]] }; key: ATOM _ NIL; x: REF _ CDProperties.GetProp[comm.design, $DesignRules]; inst: CD.Instance _ CDOps.TheInstance[comm.design, "hierarchical feature checking\n"]; IF inst#NIL THEN { IF ~inst.ob.class.composed THEN { TerminalIO.PutRopes[" object not composed\n"]; RETURN }; IF x=NIL THEN x _ comm.design.technology; key _ CDSimpleRules.GetRulesKey[x ! CDSimpleRules.NotKnown => CONTINUE]; IF key#NIL THEN { TerminalIO.PutF[" try design rules: %g\n", IO.atom[key]]; x _ CDSimpleRules.GetRulesProp[key, $CDFeatureCheck]; }; IF x=NIL THEN { x _ CDProperties.GetAtomProp[$CDFeatureCheck, $CDFeatureCheck]; IF x#NIL THEN TerminalIO.PutRope[" try globally stored design rules set\n"] }; WITH x SELECT FROM rt: RefTab.Ref => { featureChecker: CDBottomUp.Class; key: REF _ rt.Fetch[$CDFeatureCheckKey].val; text: Rope.ROPE _ CDOps.ToRope[rt.Fetch[$CDFeatureCheckName].val]; IF key=NIL THEN key_NEW[INT]; TerminalIO.PutRopes["feature set used: [", text, "]\n"]; IF ISTYPE[key, ATOM] THEN TerminalIO.PutRopes[" [ key = ", CDOps.ToRope[key], " ]\n"]; featureChecker _ CDBottomUp.Register[do: DoExt, reUse: ReUseExt, key: key, reRegistrationKey: $CDFeatureCheck, xDesign: TRUE ! CD.Error => GOTO oops]; HierarchicalFeatureCheck[featureChecker, comm.design, rt, inst.ob]; }; ENDCASE => TerminalIO.PutRope[" no feature table is assigned\n"] } EXITS oops => TerminalIO.PutRope[" failed to read parameters\n"] }; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "Feature checking", doc: "needs commandfile be previously set up", proc: HierarchicalFeatureCheckComm, key: $HFCheck]; END. œCDFeatureCheckImpl.mesa Copyright c 1986, 1987 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, December 12, 1985 2:19:57 pm PST Last edited by: Christian Jacobi, February 13, 1987 1:10:29 pm PST This tool allows the user to check whether certain features are used or not. It can be used as a mean for subclassing technologies. --this is independent of particular design rules Κ ˜codešœ™Kšœ Οmœ7™BK™=K™BK™K™†—K˜šΟk ˜ Kšžœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ ˜ K˜ K˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ —K˜šΟbœžœž˜!Kšžœ˜–—Kšžœ˜K˜Kš œ žœžœžœ žœ žœžœ˜BK˜Kšœžœ˜K˜šΟn œžœžœžœ˜KKšœ žœ˜Kšœ˜K˜—š   œžœžœ žœžœžœ˜LKšœ˜š žœžœžœžœž˜=Kšœ'žœžœžœ˜<šžœžœžœžœ˜,Kšœ-˜-—Kšœ˜Kšžœ˜—Kšœ˜—K˜š   œžœžœ žœ žœžœ˜AKšΟc0™0šžœ1žœž˜@Kšœžœ žœ ˜#Kšœžœžœ˜šžœ˜ šžœ1žœž˜@Kšœžœ žœ ˜#Kšžœžœžœ˜———Kšœ˜—K˜š  œžœžœ žœ žœ˜;KšœQ˜QKšœ˜—K˜š  œžœžœ žœ žœžœ˜UKšœ žœžœ˜Kšœžœžœ˜Kšœ žœžœ˜K˜š œžœžœ˜šžœžœžœ˜šžœžœžœ˜3šžœ ˜ KšžœBžœžœ˜MKšœ6˜6—Kšžœ žœ˜$K˜—K˜—šžœžœžœž˜šœžœ˜ Kšžœžœž˜Kš žœžœžœžœž˜6Kšžœž˜Kšœ˜—š œžœžœžœžœ˜šžœžœžœžœžœžœžœžœžœž˜BKšœ˜Kšžœ˜ ——š œžœžœžœžœžœ˜=š žœžœžœžœžœžœž˜3Kš žœžœ žœžœžœ˜CKšžœ˜—Kšœžœ˜Kšœ˜—Kšœžœ˜ šœžœžœ ˜Kšœžœ žœ˜&Kšžœ žœ žœ/˜OKšžœ žœ žœ/˜OKšœ˜—Kšœžœžœžœ*˜RKšžœ9˜@—Kšœ˜—K˜KšœC˜CKšžœžœžœ žœ˜PKšžœžœ˜/Kšžœžœžœ˜$Kšœ˜—K˜š  œžœžœ žœ žœžœ˜UKšœžœ˜ Kšœžœ˜"Kšžœžœžœ˜(šžœ˜š œ˜$šžœžœ˜!Kšœ žœ"˜1šžœžœžœ˜Kšœ ˜ Kšžœžœ%˜2Kšžœžœžœ˜0Kšžœ˜K˜—K˜—Kšœ˜—Kšœ/˜/K˜—Kšœ˜—K˜š   œžœžœ žœ žœžœ˜TKšœ ˜ Kšžœžœ!˜:Kšœ˜—K˜šŸœ˜Kšœ ž œ˜KšœM˜Mšžœžœ˜ Kšœžœ˜3Kšžœ žœžœ˜(K˜—Kšžœžœžœžœ˜=Kšžœžœžœ˜,šžœ˜Kšœ˜Kšœ*˜*K˜—Kšœ ˜ Kšžœžœžœ)˜BKšœ˜—K˜šŸœ˜"KšœW˜Wšžœ žœž˜šœžœ˜Kšœ˜Kšœ(˜(K˜—Kšžœ!˜(—Kšžœžœžœ)˜BKšœ˜—K˜šΠbnœžœ ˜BK˜š œžœ,žœ žœ ˜zKšœY˜YKšžœ žœ(˜7KšžœG˜KKšœ˜—K˜Jšœžœžœ˜Kšœžœ3˜9KšœžœN˜Všžœžœžœ˜šžœžœ˜!Kšœ/˜/Kšž˜K˜—Kšžœžœžœ˜)Kšœ>žœ˜Hšžœžœžœ˜Kšœ+žœ˜;Kšœ5˜5K˜—šžœžœžœ˜Kšœ?˜?Kšžœžœžœ?˜LK˜—šžœžœž˜˜Kšœ!˜!Kšœžœ$˜,Kšœ žœ3˜BKš žœžœžœžœžœ˜Kšœ8˜8šžœžœžœžœ˜Kšœ@˜@—šœxžœ˜}Kšœžœ žœ˜—KšœC˜CK˜—Kšžœ:˜A—K˜—Kšžœ<˜AKšœ˜—K˜K˜Kšœ―˜―Kšžœ˜K˜—…— $C