DIRECTORY Atom, Ascii, BasicTime, Commander, CD, CDCells, CDBasics, CDDirectory, CDEnvironment, CDEvents, CDInstances, CDIO, CDSequencer USING [CheckAborted], CDOps USING [CreateDesign], CDOrient, CDPrivate, CDProperties, CDRects, CDValue, Convert, FileNames, FS, IO, PropertyLists, Rope, RuntimeError USING [UNCAUGHT], TerminalIO, TokenIO, CDOldInterestRects; CDIn: CEDAR MONITOR IMPORTS Atom, BasicTime, Commander, Convert, CD, CDBasics, CDCells, CDDirectory, CDEnvironment, CDEvents, CDInstances, CDIO, CDOps, CDOrient, CDPrivate, CDProperties, CDRects, CDSequencer, CDValue, FileNames, FS, IO, PropertyLists, Rope, RuntimeError, TerminalIO, TokenIO, CDOldInterestRects EXPORTS CDIO SHARES CD, CDDirectory, CDOldInterestRects = BEGIN xChipndaleFile: INT = 12121983; xVersion: INT = 15; versionKey: PUBLIC INT; designInReadOperation: PUBLIC CD.Design _ NIL; designVersionKey: Rope.ROPE _ NIL; binfile: IO.STREAM; IndexTable: TYPE = RECORD[table: SEQUENCE max: CARDINAL OF CD.Object]; TableTable: TYPE = RECORD[tt: SEQUENCE max: CARDINAL OF REF IndexTable]; fileName: Rope.ROPE; indexTable: REF IndexTable _ NIL; tableTable: REF TableTable _ NIL; maxTableSize: INT = 32000; GetTableEntry: PROC[i: INT] RETURNS [ob: CD.Object] = INLINE { ob _ IF i=maxTableSize THEN { tableTable _ NEW[TableTable[i/maxTableSize]]; FOR n: INT IN [0..i/maxTableSize) DO -- don't be picky with size if it is anyway as big tableTable.tt[n] _ NEW[IndexTable[maxTableSize]] ENDLOOP }; }; Write: PROC [r: Rope.ROPE] = { TerminalIO.WriteRope[r] }; signalOnPropertyProblem: BOOL _ TRUE; --set variable with debugger ReadProperties: PUBLIC PROC [] RETURNS [props: CD.PropList_NIL] = { PropertyProblem: PROC [skip: BOOL_FALSE] = { Write["**** property not readable"]; IF key#NIL THEN { TerminalIO.WriteRopes["; probably ", Atom.GetPName[key]]; }; TerminalIO.WriteLn[]; IF signalOnPropertyProblem THEN SIGNAL TokenIO.EncodingError; IF skip THEN SkipThrough; }; key: ATOM; propProcs: CDProperties.PropertyProcs; token: TokenIO.Token; DO token _ TokenIO.ReadToken[]; SELECT token.ref FROM $Property => { --with a write proc key _ TokenIO.ReadPushFlag[]; propProcs _ CDProperties.FetchProcs[key]; IF propProcs#NIL AND propProcs.internalRead#NIL THEN { props _ PropertyLists.PutProp[propList: props, prop: key, val: propProcs.internalRead[key]]; } ELSE IF versionKey>=12 THEN { n: Rope.ROPE _ Atom.GetPName[key]; TerminalIO.WriteRopes["**** property ", n, " not registered\n"]; CDEnvironment.ExecFileEntry[n, designInReadOperation.technology]; propProcs _ CDProperties.FetchProcs[key]; IF propProcs#NIL AND propProcs.internalRead#NIL THEN { props _ PropertyLists.PutProp[propList: props, prop: key, val: propProcs.internalRead[key]]; } ELSE { Write["failed"]; IF signalOnPropertyProblem THEN SIGNAL TokenIO.EncodingError; }; } ELSE { token _ TokenIO.ReadToken[]; IF token.kind=rope OR token.kind=atom OR token.kind=int THEN props _ PropertyLists.PutProp[propList: props, prop: key, val: token.ref] ELSE IF token.kind=popFlag THEN { TokenIO.ReadAgain[]; props _ PropertyLists.PutProp[propList: props, prop: key, val: key] } ELSE IF token.kind=pushFlag THEN { IF token.ref=NIL OR token.ref=$properties THEN { propertieProps: CD.PropList _ ReadProperties[]; props _ PropertyLists.PutProp[propList: props, prop: key, val: propertieProps]; } ELSE IF token.ref=$layer THEN { lev: CD.Layer _ ReadLayer[]; props _ PropertyLists.PutProp[propList: props, prop: key, val: CDPrivate.layers[lev]] } ELSE PropertyProblem[skip: FALSE]; token _ TokenIO.ReadToken[]; IF token.kind#popFlag THEN PropertyProblem[skip: TRUE] } ELSE PropertyProblem[] }; token _ TokenIO.ReadToken[]; IF token.kind#popFlag THEN PropertyProblem[skip: TRUE]; }; $DefaultProperty => { token _ TokenIO.ReadToken[]; key _ NARROW[token.ref]; propProcs _ CDProperties.FetchProcs[key]; IF propProcs#NIL AND propProcs.internalRead#NIL THEN { Write["**** property registered and not readable"]; PropertyProblem[]; }; IF token.kind=rope OR token.kind=atom OR token.kind=int THEN { token _ TokenIO.ReadToken[]; IF token.kind=rope OR token.kind=atom OR token.kind=int THEN props _ PropertyLists.PutProp[propList: props, prop: key, val: token.ref] ELSE PropertyProblem[]; } ELSE IF token.kind=pushFlag THEN { kind: ATOM _ TokenIO.ReadAtom[]; IF kind=$properties THEN { propertieProps: CD.PropList _ ReadProperties[]; props _ PropertyLists.PutProp[propList: props, prop: key, val: propertieProps]; } ELSE IF kind=$layer THEN { lev: CD.Layer _ ReadLayer[]; props _ PropertyLists.PutProp[propList: props, prop: key, val: CDPrivate.layers[lev]] } ELSE IF kind=$ropeList THEN { rList: LIST OF Rope.ROPE _ NIL; token _ TokenIO.ReadToken[]; WHILE token.kind=rope DO rList _ CONS[NARROW[token.ref, Rope.ROPE], rList]; token _ TokenIO.ReadToken[]; ENDLOOP; TokenIO.ReadAgain[]; props _ PropertyLists.PutProp[propList: props, prop: key, val: rList] } ELSE PropertyProblem[skip: FALSE]; token _ TokenIO.ReadToken[]; IF token.kind#popFlag THEN PropertyProblem[skip: TRUE] } ELSE PropertyProblem[] }; ENDCASE => { TokenIO.ReadAgain[]; RETURN [props]; }; ENDLOOP; }; SkipThrough: PROC [] = { token: TokenIO.Token; layer: INT _ 0; DO token _ TokenIO.ReadToken[]; IF token.kind=pushFlag THEN layer _ layer+1 ELSE IF token.kind=popFlag THEN layer _ layer-1; IF layer<0 THEN EXIT; ENDLOOP; }; SetName: PROC[me: CD.Object, r: Rope.ROPE] ~ INLINE { IF me.class.inDirectory THEN CDDirectory.ObToDirectoryProcs[me].setName[me, r] }; ReadObjectDefinition: PROC [pushRec: BOOL _ FALSE] RETURNS [obj: CD.Object_NIL] = { token: TokenIO.Token; index: INT _ -1; name: Rope.ROPE; atom: ATOM = TokenIO.ReadPushFlag[]; class: CD.ObjectClass _ CD.FetchObjectClass[atom, designInReadOperation.technology]; CDSequencer.CheckAborted[designInReadOperation]; IF class=NIL OR class.internalRead=NIL THEN { n: Rope.ROPE _ Atom.GetPName[atom]; TerminalIO.WriteRopes["object class ", n, " not registered\n"]; CDEnvironment.ExecFileEntry[n, designInReadOperation.technology]; class _ CD.FetchObjectClass[atom, designInReadOperation.technology]; }; IF class=NIL OR class.internalRead=NIL THEN { TerminalIO.WriteRopes["reading object class", Atom.GetPName[atom], " failed\n"]; SkipThrough[]; obj _ CDRects.CreateBareRect[[10, 10], CD.errorLayer]; RETURN }; IF versionKey>=15 THEN { IF class.inDirectory THEN { index _ TokenIO.ReadInt[]; } ELSE { token: TokenIO.Token _ TokenIO.ReadToken[]; IF token.ref=$CDIOUseTable THEN index _ TokenIO.ReadInt[] ELSE TokenIO.ReadAgain[] }; }; obj _ class.internalRead[]; IF obj=NIL OR obj.class=NIL THEN obj _ NEW[CD.ObjectRep _ CDRects.CreateRect[[10, 10], CD.errorLayer]^]; IF index>0 THEN SetTableEntry[index, obj]; IF versionKey>0 THEN { IF class.inDirectory THEN { name _ TokenIO.ReadRope[]; IF versionKey<=4 THEN [] _ TokenIO.ReadRope[]; --ignore an old versionkey feature }; }; token _ TokenIO.ReadToken[]; IF token.kind#popFlag THEN { TokenIO.ReadAgain[]; obj.properties _ ReadProperties[]; TokenIO.ReadPopFlag[]; IF versionKey<8 THEN CDOldInterestRects.AdjustInterest[obj]; IF versionKey=12 THEN { IF CDCells.IsCell[obj] AND CDProperties.GetObjectProp[obj, $border]#NIL THEN { CDProperties.PutProp[obj, $border, NIL]; CDCells.SetBorder[obj, TRUE]; } } }; IF obj.class.inDirectory THEN { SetName[obj, name]; IF versionKey>=15 THEN { IF ~IsOwner[obj, designInReadOperation] AND ~pushRec THEN [] _ CDDirectory.Include[designInReadOperation, obj, name]; }; }; }; ReadObject: PUBLIC PROC [] RETURNS [CD.Object] = { t: TokenIO.Token = TokenIO.ReadToken[]; IF t.kind=int THEN { -- instance ins: INT _ NARROW[t.ref, REF INT]^; RETURN [GetTableEntry[ins]] }; TokenIO.ReadAgain; RETURN [ReadObjectDefinition[]] }; setManually: INT _ 0; --used for saving old designs specialForVersion4: BOOL _ FALSE; ReadInstance: PUBLIC PROC [] RETURNS [CD.Instance] = { inst: CD.Instance; location: CD.Position _ ReadPos[]; orientation: CD.Orientation _ CDIO.ReadOrientation[]; properties: CD.PropList _ ReadProperties[]; ob: CD.Object _ ReadObject[]; IF versionKey>=9 THEN --this is the current truth and normal case inst _ NEW[CD.InstanceRep _ [ location: location, orientation: orientation, properties: properties, ob: ob ]] ELSE { OldNewInstIX: PROC [ob: CD.Object_NIL, location: CD.Position_[0,0], orientation: CD.Orientation_0, selected: BOOLEAN _ FALSE, properties: CD.PropList_NIL] RETURNS [CD.Instance] = { off: CD.Position = CDBasics.BaseOfRect[ CDOrient.MapRect[ itemInCell: CDOldInterestRects.InsideRect[ob], cellSize: ob.size, cellInstOrient: orientation, cellInstPos: [0, 0] ]]; a: CD.Instance = NEW[CD.InstanceRep _ CD.InstanceRep[ ob: ob, location: CDBasics.SubPoints[location, off], orientation: orientation, selected: selected, properties: properties ]]; RETURN [a] }; IF versionKey>=8 THEN inst _ NEW[CD.InstanceRep _ [ location: location, orientation: orientation, properties: properties, ob: ob ]] ELSE IF versionKey>=5 THEN inst _ OldNewInstIX[ob: ob, location: location, orientation: orientation, properties: properties] ELSE { --ancient cases absoluteMode: BOOL _ TRUE; IF versionKey<3 THEN absoluteMode_TRUE ELSE IF versionKey=4 THEN { IF specialForVersion4 THEN IF ob.class.inDirectory THEN absoluteMode_TRUE ELSE absoluteMode_FALSE ELSE absoluteMode_FALSE } ELSE IF versionKey=3 THEN { IF ob.class.inDirectory THEN absoluteMode_TRUE ELSE absoluteMode_FALSE }; IF setManually=1 THEN absoluteMode_TRUE ELSE IF setManually=2 THEN absoluteMode_FALSE ELSE IF setManually=3 THEN absoluteMode_ob.class.inDirectory; IF absoluteMode THEN inst _ NEW[CD.InstanceRep _ [ location: location, orientation: orientation, properties: properties, ob: ob, selected: FALSE]] ELSE inst _ OldNewInstIX[ob: ob, location: location, orientation: orientation, properties: properties]; }; }; RETURN [inst]; }; ReadInstanceList: PUBLIC PROC [] RETURNS [list: CD.InstanceList_NIL] = { num: INT = TokenIO.ReadInt[]; THROUGH [0..num) DO list _ CONS[ReadInstance[], list]; ENDLOOP }; ReadPos: PUBLIC PROC [] RETURNS [p: CD.Position] = { p.x _ TokenIO.ReadInt[]; p.y _ TokenIO.ReadInt[]; }; ReadRect: PUBLIC PROC [] RETURNS [r: CD.Rect] = { r.x1 _ TokenIO.ReadInt[]; r.y1 _ TokenIO.ReadInt[]; r.x2 _ TokenIO.ReadInt[]; r.y2 _ TokenIO.ReadInt[]; }; ReadPushRec: PROC [] RETURNS [pr: CD.PushRec] = { token: TokenIO.Token _ TokenIO.ReadToken[]; dummy: CD.Object; IF token.ref=$Nil THEN pr.mightReplace_NIL ELSE { TokenIO.ReadAgain[]; pr.mightReplace _ ReadInstance[]; }; dummy _ ReadObjectDefinition[pushRec: TRUE]; CDProperties.PutObjectProp[dummy, $dummyCell, $TRUE]; pr.changed _ pr.indirectlyChanged _ TRUE; pr.specific _ NARROW[dummy.specificRef, CD.CellPtr]; IF versionKey>=11 THEN { pr.specific.dIr _ ReadRect[]; IF pr.specific.useDIr THEN pr.specific.ir _ pr.specific.dIr; }; pr.dummyCell _ CDInstances.NewInst[ob: dummy]; }; ReadLayer: PUBLIC PROC [] RETURNS [CD.Layer] = { key: ATOM _ TokenIO.ReadAtom[]; IF CDIO.VersionKey[]<=12 THEN { -- New layer keys for CD 2.3 SELECT key FROM $combined => key _ $undefLayer; $highLightShade => key _ $shadeLayer; $highLightError => key _ $errorLayer; $backGround => key _ $backGround; ENDCASE => NULL; }; RETURN [CD.FetchLayer[designInReadOperation.technology, key]]; }; IsOwner: PROC [ob: CD.Object, d: CD.Design] RETURNS [BOOL] = { x: REF ~ (IF d=NIL THEN NIL ELSE d.reserved); RETURN [ CDProperties.GetObjectProp[ob, $OwnerDesign]=x ]; }; ReadSubObjects: PROC [] = { token: TokenIO.Token; obj: CD.Object; DO token _ TokenIO.ReadToken[]; TokenIO.ReadAgain[]; IF token.kind#pushFlag AND token.kind#int THEN EXIT; obj _ ReadObject[]; ENDLOOP; }; ReadDesignData: PROC [] = { index, directoryCount: INT; token: TokenIO.Token; obj: CD.Object; directoryCount _ TokenIO.ReadInt[]; AllocateTables[directoryCount+1]; IF versionKey>=15 THEN ReadSubObjects[] ELSE { FOR n: INT IN [1..directoryCount] DO index _ TokenIO.ReadInt[]; obj _ ReadObject[]; SetTableEntry[index, obj]; IF versionKey=0 THEN { token _ TokenIO.ReadToken[]; WHILE token.kind=rope DO name: Rope.ROPE = NARROW[token.ref]; obx: INT = TokenIO.ReadInt[]; [] _ CDDirectory.Include[designInReadOperation, GetTableEntry[obx], name]; token _ TokenIO.ReadToken[]; ENDLOOP; TokenIO.ReadAgain[]; } ELSE IF obj.class.inDirectory THEN { IF ~IsOwner[obj, designInReadOperation] THEN { name: Rope.ROPE = CDDirectory.Name[obj]; [] _ CDDirectory.Include[designInReadOperation, obj, name]; } } ENDLOOP; }; designInReadOperation.properties _ NEW[CD.PropList_ReadProperties[]]; CDProperties.PutDesignProp[designInReadOperation, $FileVersion, designVersionKey]; designInReadOperation.actual _ NIL; DO token _ TokenIO.ReadToken[]; IF token.ref#$Push THEN { TokenIO.ReadAgain[]; EXIT; }; designInReadOperation.actual _ CONS[ReadPushRec[], designInReadOperation.actual]; ENDLOOP; token _ TokenIO.ReadToken[]; IF token.ref#$EndOfDesign THEN SIGNAL TokenIO.EncodingError; }; ReadDesign: PUBLIC ENTRY PROC [from: REF_NIL, check: PROC [CD.Design] RETURNS [BOOL] _ NIL, wDir: Rope.ROPE _ NIL] RETURNS [CD.Design] = { ENABLE UNWIND => { indexTable _ NIL; tableTable _ NIL; designInReadOperation _ NIL; }; wDirUsed: Rope.ROPE _ NIL; design: CD.Design; -- is initialized before return only DoReadDesign: INTERNAL PROC [check: PROC [CD.Design] RETURNS [BOOL]] = { ENABLE { UNWIND => designInReadOperation _ NIL; TokenIO.EncodingError => { Write["** TokenIO encoding problem\n"]; REJECT; }; RuntimeError.UNCAUGHT => { Write["** problem while reading; abort or proceed\n"]; REJECT }; }; DoWhileAttached: INTERNAL PROC [] = { ENABLE UNWIND => { designInReadOperation _ NIL; TokenIO.ReleaseReader[]; }; TechnologyCheck: INTERNAL PROC [] = { ENABLE UNWIND => {designInReadOperation _ NIL}; dont: BOOL _ CDEvents.ProcessEvent[ ev: readEvent, design: designInReadOperation, x: NIL, listenToDont: TRUE ].dont; IF dont THEN { designInReadOperation _ NIL; Write["Technology rejects read\n"]; } }; VersionAndSealCheck: INTERNAL PROC [] = { IF TokenIO.ReadInt[]#xChipndaleFile THEN { Write["File is not a ChipNDale design\n"]; ERROR TokenIO.Error[other, "ChipNDale filekey"]; }; versionKey _ TokenIO.ReadInt[]; IF versionKey#xVersion THEN { IF versionKey>xVersion THEN { -- too new Write["design was written with newer ChipNDale version\n"]; Write["get a new ChipNDale version\n"]; ERROR TokenIO.Error[other, "ChipNDale versionkey"]; } ELSE IF versionKey IN [13..xVersion] THEN { -- not new but dont tell it NULL } ELSE IF versionKey IN [5..xVersion] THEN { -- not new but everything ok Write["design was written with older chipndaleversion\n"]; } ELSE IF versionKey=4 THEN { -- known problem versions Write["********\n"]; Write["design was written with old chipndaleversion; filekey = 4\n"]; Write["Please convert all your designs (by reading and subsequent writing)\n"]; Write["Check carefully the alignment of cells which have n-well\n"]; Write[" IF alignment is wrong THEN { try with a commandtool:\n"]; Write[" CD18InputToggle\n"]; Write[" and try again\n"]; Write[" }\n"]; Write["********\n"]; } ELSE IF versionKey=3 THEN { -- known problem versions Write["********\n"]; Write["design was written with old chipndaleversion; filekey = 3\n"]; Write["Please convert all your designs (by reading and subsequent writing)\n"]; Write["Check carefully the alignment of cells which have n-well"]; Write["********\n"]; } ELSE IF versionKey IN [0..xVersion] THEN { -- not new but please convert Write["********\n"]; Write["Design was written with old chipndaleversion\n"]; Write["Please convert all your designs (by reading and subsequent writing)\n"]; Write["********\n"]; } ELSE { -- too old Write["design was written with old chipndaleversion\n"]; Write["This version is no more supported\n"]; ERROR TokenIO.Error[other, "ChipNDale versionkey"]; }; }; IF versionKey>0 THEN { IF TokenIO.ReadInt[]#-1 THEN { Write["File had not been properly closed; has bad seal\n"]; ERROR TokenIO.Error[other, "file had not been properly closed"]; }; }; }; ReadVersionKeys: PROC [design: CD.Design] = { IF versionKey>=7 THEN { designVersionKey _ TokenIO.ReadRope[]; }; IF Rope.IsEmpty[designVersionKey] THEN designVersionKey _ Convert.RopeFromTime[from: BasicTime.Now[], end: seconds]; CDProperties.PutDesignProp[design, $FileVersion, designVersionKey]; }; ReadDesignName: PROC [] RETURNS [name: Rope.ROPE] = { name _ TokenIO.ReadRope[]; IF Rope.IsEmpty[name] THEN { name _ FileNames.GetShortName[fileName, TRUE]; name _ Rope.Substr[name, 0, Rope.Index[name, 0, ".dale", FALSE]] } }; VersionAndSealCheck[]; technologyKey _ TokenIO.ReadAtom[]; technologyName _ TokenIO.ReadRope[]; technology _ CDEnvironment.LoadTechnology[technologyKey, technologyName]; IF technology=NIL THEN GOTO NotDoneAndRelease; designInReadOperation _ CDOps.CreateDesign[technology]; TechnologyCheck[]; IF designInReadOperation=NIL THEN GOTO NotDoneAndRelease; designInReadOperation.name _ ReadDesignName[]; ReadVersionKeys[designInReadOperation]; --read before check, fixed again later IF check#NIL THEN { IF NOT check[designInReadOperation] THEN GOTO NotDoneAndRelease; }; ReadDesignData[]; CDEnvironment.SetWorkingDirectory[designInReadOperation, wDirUsed]; CDValue.Store[boundTo: designInReadOperation, key: $CDxFromFile, value: fileName]; CDValue.Store[boundTo: designInReadOperation, key: $CDxLastFile, value: fileName]; TokenIO.ReleaseReader[]; EXITS NotDoneAndRelease => { designInReadOperation _ NIL; TokenIO.ReleaseReader[]; }; }; technology: CD.Technology; technologyKey: ATOM; technologyName: Rope.ROPE; designInReadOperation _ NIL; TokenIO.AttachReader[binfile ! TokenIO.Error => { r: Rope.ROPE _ "bad explanation"; IF ISTYPE[explanation, Rope.ROPE] THEN r_NARROW[explanation]; TerminalIO.WriteRopes[r, "... not attached\n"]; GOTO NotAttached } ]; DoWhileAttached[]; EXITS NotAttached => RETURN }; iDidTheOpen: BOOL _ FALSE; name: Rope.ROPE; streamOptions: FS.StreamOptions _ ALL[TRUE]; streamOptions[tiogaRead] _ FALSE; streamOptions[commitAndReopenTransOnFlush] _ FALSE; streamOptions[truncatePagesOnClose] _ TRUE; streamOptions[finishTransOnClose] _ TRUE; streamOptions[closeFSOpenFileOnClose] _ TRUE; IF wDir=NIL THEN wDir _ FileNames.CurrentWorkingDirectory[]; IF from#NIL AND ISTYPE[from, IO.STREAM] THEN { fileName _ NIL; binfile _ NARROW[from, IO.STREAM] } ELSE { ReadName: PROC [wDir: Rope.ROPE] RETURNS [name: Rope.ROPE] = { Write[Rope.Cat[" input file (", wDir, ")"]]; name _ TerminalIO.RequestRope[" > "]; }; IF from=NIL THEN name _ ReadName[wDir] ELSE IF ISTYPE[from, Rope.ROPE] THEN { name _ NARROW[from, Rope.ROPE]; IF Rope.IsEmpty[name] THEN name _ ReadName[wDir]; } ELSE { Write["ReadDesign does not support type of 'from' parameter\n"]; GOTO NotOpened; }; fileName _ CDEnvironment.MakeName[name, "dale", wDir]; binfile _ FS.StreamOpen[fileName, $read, streamOptions ! FS.Error => IF error.group # bug THEN { Write[Rope.Cat[fileName, " not opened: ", error.explanation, "\n"]]; GOTO NotOpened; }]; wDirUsed _ FileNames.Directory[fileName]; iDidTheOpen _ TRUE; Write[Rope.Cat[fileName, " opened \n"]]; }; DoReadDesign[check]; design _ designInReadOperation; designInReadOperation _ NIL; indexTable _ NIL; tableTable _ NIL; IF iDidTheOpen THEN IO.Close[binfile]; [] _ CDEvents.ProcessEvent[ev: afterInputEvent, design: design, x: NIL, listenToDont: FALSE]; RETURN [design]; EXITS NotOpened => { indexTable _ NIL; tableTable _ NIL; designInReadOperation _ NIL; RETURN [NIL]; } }; ReadOrientation: PUBLIC PROC [] RETURNS [orientation: CD.Orientation] = { i: INT = TokenIO.ReadInt[]; IF versionKey<=3 THEN { IF i IN [0..15] THEN orientation _ i/4*2 + i MOD 2 ELSE SIGNAL TokenIO.EncodingError; } ELSE IF i IN [0..7] THEN orientation _ i ELSE SIGNAL TokenIO.EncodingError }; MakeName: PUBLIC PROC [base: Rope.ROPE, ext: Rope.ROPE_NIL, wDir: Rope.ROPE_NIL, modifier: Rope.ROPE_NIL] RETURNS [Rope.ROPE] = { RETURN [CDEnvironment.MakeName[base, ext, wDir, modifier]]; }; SetWorkingDirectory: PUBLIC PROC [design: REF, wDir: Rope.ROPE] = { CDEnvironment.SetWorkingDirectory[design, wDir]; }; GetWorkingDirectory: PUBLIC PROC [design: REF] RETURNS [wDir: Rope.ROPE_NIL] = { RETURN [CDEnvironment.GetWorkingDirectory[design]]; }; MakeShortName: PUBLIC PROC [design: CD.Design] RETURNS [name: Rope.ROPE _ NIL] = { TrailingDot: PROC [base: Rope.ROPE] RETURNS [INT] = { len: INT _ Rope.Length[base]; pos: INT _ len; WHILE pos > 0 DO SELECT Rope.Fetch[base, pos _ pos - 1] FROM '. => RETURN [pos]; '!, '], '>, '/ => EXIT; ENDCASE; ENDLOOP; RETURN [len]; }; SuggestedModule: PROC [base: Rope.ROPE] RETURNS [Rope.ROPE] = { len, dot: INT; base _ FileNames.GetShortName[base]; len _ Rope.Length[base]; dot _ TrailingDot[base]; IF len>dot AND Rope.Equal[Rope.Substr[base, dot+1], "dale", FALSE] THEN base _ Rope.Substr[base, 0, dot]; RETURN [base] }; WITH CDValue.Fetch[boundTo: design, key: $CDxFromFile] SELECT FROM r: Rope.ROPE => name _ SuggestedModule[r]; ENDCASE => NULL; IF name=NIL THEN name _ design.name; IF name=NIL THEN name _ "noname" }; CD18Input: Commander.CommandProc = { specialForVersion4 _ ~specialForVersion4; IF specialForVersion4 THEN cmd.out.PutRope["Fileformat: switch to old version of cd18\n"] ELSE cmd.out.PutRope["Fileformat: switch to last version of cd18\n"]; }; readEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$ReadTechnologyPrivate]; afterInputEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$AfterInput]; Commander.Register["///Commands/CD18InputToggle", CD18Input, "toggle input mode of cd18"]; END. ΆCDIn.mesa Copyright c 1983, 1986 by Xerox Corporation. All rights reserved. Last Edited by: Kimr, November 28, 1983 10:22 am Last Edited by: Jacobi, February 8, 1984 9:41 am Last Edited by: Christian Jacobi, September 2, 1986 2:53:49 pm PDT gbb April 4, 1986 3:21:48 pm PST --RELEASE: search for the string "RELEASE" -- global vars --border was'nt a very public feature in 12; might be removed The layer keys have changed from ChipNDale 2.2 to ChipNDale 2.3. The following is a nasty hack to fix it. Note that this is only a translation of the leyer keys. It does not contemplate the conversion from whatever to the new comment layer The layer keys have changed from ChipNDale 2.2 to ChipNDale 2.3. The following is a nasty hack to fix it. Note that this is only a translation of the leyer keys. It does not contemplate the conversion from whatever to the new comment layer --hack to simplify some read procedures... --this overwrites an previous $FileVersion property read in the normal (wrong) way --from is either a IO.STREAM, a Rope.ROPE, or NIL --check: (called if non NIL), is called after technology and design-name is initialized -- read proceeds only if check returns TRUE --returns NIL if design not read in successfully --viewer is not opened -- all internal routines use designInReadOperation in place of design -- result design returned in designInReadOperation -- handles all the TokenIO business --and always Release --Side-effect: if bad, designInReadOperation is set to NIL --ChipNDale check --version check --seal check -- DoWhileAttached -- DoReadDesign -- begin ReadDesign -- open file; assign fileName and binfile -- do the actual work -- finalize --position of last dot --given a filename, suggests a modulename --MakeShortName --fix an old old problem Version history versionKey 0 versionKey 1: objects with children carry names versionKey 2: versionKey 3: June 15, 1984 3:46:13 pm PDT; instances position is its innerrect; this allows to shrink or grow the nwell from cmos versionKey 4: October 20, 1984 9:36:34 am PDT; orientation changed probably while lifetime of 4: properties which are propertylists are automatically included versionKey 5: December 14, 1984 10:07:59 am PST; insiderect for cells no more done with properties; key is removed versionKey 6: February 1, 1985 4:43:29 pm PST; properties which are layers are automatically included versionKey 7: March 26, 1985 12:33:22 pm PST; file versionkey property included versionKey 8: April 15, 1985 3:26:35 pm PST; cd-coords base to file again... cells get origin and interestrect imports get interestrect versionKey 9: May 29, 1985 7:51:45 pm PDT; CD21 versionKey 10: May 29, 1985 7:51:45 pm PDT; CD22 Atomicobject have the interest rect on the file versionKey 11: May 29, 1985 7:51:45 pm PDT; (CD22) pushed records get the default interest rect versionKey 12: January 28, 1986 2:23:27 pm PST; (CD22) default properties get $DefaultProperty key versionKey 13: March 11, 1986 4:17:16 pm PST; (CD23) cells may have drawBorder field gbb April 4, 1986 3:19:31 pm PST The atoms for the keys of the technology independent layers have changed. changes to: ReadLayer: if versionKey[]<=12 translate atoms. versionKey 15: June 20, 1986 9:53:19 am PDT; Global changes Number of object for object table is now inside object definition Directory include is performed for all objects in directory, independent of source. Objects not in directory have special option to be put in table. Κ– "cedar" style˜code™ Kšœ Οmœ7™BK™0K™0K™BK™ K™—šΟk ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšžœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ K˜ Kšžœ˜Kšœ žœ˜!Kšœžœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšžœ˜Kšžœ˜K˜Kšœ˜Kšœžœžœ˜Kšœ ˜ Kšœ˜Kšœ˜—K˜šΠblœžœž˜Kš žœ&žœHžœVžœžœL˜£Kšžœž˜ Kšžœ&˜,—Kšž˜K™Kšœ*™*K˜Kšœžœ ˜Kšœ žœ˜K˜K™Kšœ žœžœ˜Kšœžœžœ žœ˜.Kšœžœžœ˜"Kšœ žœžœ˜K˜Kš œ žœžœžœžœžœžœ ˜FKš œ žœžœžœžœžœžœ ˜HKšœžœ˜K˜Kšœ žœžœ˜!Kšœ žœžœ˜!K˜Kšœžœ ˜K˜š Οn œžœžœžœžœ žœ˜>šœ˜Kšžœžœ˜*Kšžœ)žœ˜?—Kšžœžœžœ+˜9Kšœ˜—K˜š   œžœžœžœ žœ˜5Kšžœžœ˜/Kšžœ)žœ˜CKšœ˜—K˜š œžœžœ˜ Kšœ žœ žœ˜4šžœžœ˜Kšœ žœ˜-š žœžœžœžœΟc2˜XKšœžœ˜0Kšž˜—Kšœ˜—Kšœ˜K˜—K˜š œžœ žœ˜Kšœ˜Kšœ˜—K˜Kšœžœžœ‘˜BK˜š  œžœžœžœ žœ žœ˜CK˜š œžœžœžœ˜,Kšœ$˜$šžœžœžœ˜Kšœ9˜9K˜—Kšœ˜Kšžœžœžœ˜=Kšžœžœ ˜K˜—K˜Kšœžœ˜ K˜&Kšœ˜šž˜Kšœ˜šžœ ž˜šœ‘˜"K˜K˜)š žœ žœžœžœžœ˜6Kšœ\˜\K˜—šžœžœžœ˜Kšœžœ˜"Kšœ@˜@KšœA˜AK˜)š žœ žœžœžœžœ˜6Kšœ\˜\K˜—šžœ˜Kšœ˜Kšžœžœžœ˜=K˜—K˜—šžœ˜Kšœ˜šžœžœžœž˜Kšœ˜šžœžœžœž˜Kšœ˜—K˜š  œžœžœ žœ žœžœ˜>Kš œžœžœžœžœžœžœ ˜-Kšžœ4˜:K˜—K˜š œžœ˜Kšœžœ ˜&šž˜Kšœ˜Kšœ˜Kšžœžœžœžœ˜4Kšœ˜Kšžœ˜—Kšœ˜—K˜š œžœ˜Kšœžœ˜K˜Kšœžœ˜Kšœ#˜#Kšœ"˜"Kšžœžœ˜'šžœ˜šžœžœžœž˜$Kšœ˜Kšœ˜Kšœ˜šžœžœ˜Kšœ˜šžœž˜Kšœ žœžœ ˜$Kšœžœ˜KšœJ˜JKšœ˜Kšžœ˜—Kšœ˜K˜—šžœžœžœ˜%Kšœ+™+šžœ&žœ˜.Kšœ žœ˜(Kšœ;˜;K˜—K˜—Kšžœ˜—K˜—Kšœ#žœžœ˜EKšœR™RKšœR˜RKšœžœ˜#šž˜Kšœ˜šžœžœ˜K˜Kšžœ˜K˜—Kšœžœ.˜QKšžœ˜—Kšœ˜Kšžœžœžœ˜=Kšœ˜—K˜š  œžœžœžœžœžœ žœžœ žœžœžœ žœžœžœžœ ˜ŠK™1KšœW™WKšœ-™-K™0Kšœ™šžœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœ˜—K˜Kšœžœž˜Kšœžœ ‘$˜7KšœE™EK˜š  œžœžœ žœžœ žœžœ˜HKšœ2™2K™#šžœ˜Kšžœžœ˜&šœ˜Kšœ'˜'Kšžœ˜Kšœ˜—šœ žœ˜Kšœ6˜6Kšž˜Kšœ˜—K˜K˜—š œžœžœ˜%Kšœ™šžœžœ˜Kšœžœ˜Kšœ˜K˜—K˜š œžœžœ˜%Kšœ:™:Kšžœžœžœ˜/šœžœ˜#Kšœ˜Kšœ˜Kšœžœ˜Kšœž˜Kšœ˜—šžœžœ˜Kšœžœ˜Kšœ#˜#K˜—Kšœ˜—K˜š œžœžœ˜)Kšœ™šžœ"žœ˜*Kšœ*˜*Kšžœ.˜3—Kšœ™Kšœ˜šžœžœ˜šžœžœ‘ ˜(Kšœ;˜;Kšœ'˜'Kšžœ.˜3Kšœ˜—š žœžœ žœžœ‘˜GKšž˜K˜—š žœžœ žœžœ‘˜GKšœ:˜:K˜—šžœžœžœ‘˜5Kšœ˜KšœE˜EKšœO˜OKšœD˜DKšœC˜CKšœ ˜ Kšœ˜Kšœ˜Kšœ˜K˜—šžœžœžœ‘˜5Kšœ˜KšœE˜EKšœO˜OKšœB˜BKšœ˜K˜—š žœžœ žœžœ‘˜HKšœ˜Kšœ8˜8KšœO˜OKšœ˜K˜—šžœ‘ ˜Kšœ8˜8Kšœ-˜-Kšžœ.˜3K˜—Kšœ˜—Kšœ ™ šžœžœ˜šžœžœ˜Kšœ;˜;Kšžœ;˜@Kšœ˜—K˜—Kšœ˜K˜š œžœ žœ ˜-šžœžœ˜Kšœ&˜&K˜—šžœ žœ˜'KšœM˜M—KšœC˜CKšœ˜—K˜š œžœžœ žœ˜5Kšœ˜šžœžœ˜Kšœ(žœ˜/Kšœ9žœ˜@K˜—Kšœ˜—K˜—Kšœ™Kšœ˜Kšœ#˜#Kšœ$˜$KšœI˜IKšžœ žœžœžœ˜.Kšœ7˜7Kšœ˜Kšžœžœžœžœ˜9Kšœ.˜.Kšœ(‘&˜Nšžœžœžœ˜Kšžœžœžœžœ˜@K˜—Kšœ˜KšœC˜CKšœR˜RKšœR˜RKšœ˜šž˜šœ˜Kšœžœ˜Kšœ˜K˜——Kšœ˜K˜—Kšœ™Kšœ žœ ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜šœ˜šœ˜Kšœžœ˜!Kš žœžœžœžœžœ˜=Kšœ1˜1Kšžœ ˜Kšœ˜—Kšœ˜—Kšœ˜šž˜Kšœž˜—Kšœ˜—K˜Kšœ™Kšœ žœžœ˜Kšœ žœ˜šœžœžœžœ˜,Kšœžœ˜!Kšœ-žœ˜3Kšœ&žœ˜+Kšœ$žœ˜)Kšœ(žœ˜-—Kšœ)™)Kšžœžœžœ,˜<šžœžœžœžœžœžœžœ˜.Kšœ žœ˜Kšœ žœžœžœ˜!K˜—šžœ˜š  œžœ žœžœ žœ˜>Kšœ,˜,Kšœ&˜&Kšœ˜—Kšžœžœžœ˜&š žœžœžœ žœžœ˜&Kšœžœ žœ˜Kšžœžœ˜1K˜—šžœ˜Kšœ@˜@Kšžœ ˜K˜—Kšœ6˜6šœ žœ-žœ ˜Ešžœžœ˜KšœD˜DKšžœ ˜Kšœ˜——Kšœ)˜)Kšœžœ˜Kšœ(˜(K˜—K˜Kšœ™K˜Kšœ˜K˜Kšœ ™ Kšœžœžœžœ˜@Kšžœ žœžœ˜&KšœCžœžœ˜^Kšžœ ˜šž˜šœ˜Kšœ žœžœžœ˜@Kšžœžœ˜ K˜——Kšœ˜—K˜š  œžœžœžœžœ˜IKšœžœ˜šžœžœ˜Kš žœžœ žœžœžœžœ˜VK˜—šžœ˜Kš žœžœžœžœžœ˜E—Kšœ˜—K™š œžœžœ žœ žœžœ žœžœžœžœžœžœ˜Kšžœ5˜;Kšœ˜—K˜š  œžœžœ žœ žœ˜CKšœ0˜0Kšœ˜—K˜š œžœžœ žœžœ žœžœ˜PKšžœ-˜3Kšœ˜—K˜š  œžœžœ žœ žœ žœžœ˜RK˜š   œžœ žœžœžœ˜5Kšœ™Kšœžœ˜Kšœžœ˜šžœ ž˜šžœ!ž˜+Kšœžœ˜Kšœžœ˜Kšžœ˜—Kšžœ˜—Kšžœ˜ K˜K˜—š  œžœ žœžœžœ˜?Kšœ)™)Kšœ žœ˜Kšœ$˜$Kšœ˜Kšœ˜šžœ žœ.žœžœ˜HKšœ!˜!—Kšžœ˜ K˜—K˜Kšœ™šžœ3žœžœ˜CKšœžœ˜*Kšžœžœ˜—Kšžœžœžœ˜$Kšžœžœžœ˜ Kšœ˜K˜—K™šΠbn œ˜$Kšœ™Kšœ)˜)šžœž˜Kšœ>˜>—šž˜Kšœ@˜@—Kšœ˜—K˜Kšœ[˜[KšœV˜VKšœZ˜ZKšžœ˜K˜š’™K™Kšœ ™ šœ™Kšœ!™!—Kšœ™šœ.™.KšœV™V—šœ0™0Kšœ™—šœ™Kšœ=™=—šœ2™2KšœA™A—šœ0™0Kšœ6™6—šœ/™/K™!—šœ.™.K™K™!K™—šœ,™,K™—šœ-™-K™K™/—šœ-™-K™K™,—šœ1™1K™Kšœ+™+—šœ/™/K™K™—™ K™IKšœ Οr œΟeœ™;—šœ.™.K™K™AK™TK™A——K™K™—…—UD‚