DIRECTORY Atom, CD, CDApplications, CDDirectory, CDEvents, CDExtras, CDIO, CDIOExtras, CDOps USING [CreateDesign], CDPrivate, CDProperties, CDRects, CDValue, FileNames, FS, IO, Rope USING [ROPE, IsEmpty, Length, Fetch], RuntimeError USING [UNCAUGHT], TerminalIO, TokenIO; CDIn: CEDAR MONITOR IMPORTS Atom, CD, CDApplications, CDDirectory, CDEvents, CDExtras, CDIO, CDOps, CDPrivate, CDProperties, CDRects, CDValue, FileNames, FS, IO, Rope, RuntimeError, TerminalIO, TokenIO EXPORTS CDIO, CDIOExtras SHARES CDDirectory = BEGIN xChipndaleFile: INT = 12121983; xVersion: INT = 3; versionKey: PUBLIC INT; designInReadOperation: PUBLIC CD.Design _ NIL; binfile: IO.STREAM; fileName: Rope.ROPE; indexTable: REF IndexTable _ NIL; IndexTable: TYPE = RECORD[table: SEQUENCE max: CARDINAL OF CD.ObPtr]; ReadProperties: PUBLIC PROC [] RETURNS [props: CD.Properties_NIL] = BEGIN key: ATOM; propProcs: CDProperties.PropertyProcs; token: TokenIO.Token; DO token _ TokenIO.ReadToken[]; IF token.ref#$Property THEN { TokenIO.ReadAgain[]; RETURN [props]; }; key _ TokenIO.ReadPushFlag[]; propProcs _ CDProperties.FetchProcs[key]; IF propProcs#NIL AND propProcs.internalRead#NIL THEN { props _ Atom.PutPropOnList[propList: props, prop: key, val: propProcs.internalRead[key]]; } ELSE { token _ TokenIO.ReadToken[]; IF token.kind=rope OR token.kind=atom OR token.kind=int THEN props _ Atom.PutPropOnList[propList: props, prop: key, val: token.ref] ELSE IF token.kind=popFlag THEN { TokenIO.ReadAgain[]; props _ Atom.PutPropOnList[propList: props, prop: key, val: key] } ELSE { TerminalIO.WriteRope["**property not readable \n"]; ERROR TokenIO.EncodingError; }; }; TokenIO.ReadPopFlag[]; ENDLOOP; END; SkipThrough: PROC [] = BEGIN token: TokenIO.Token; level: INT _ 0; DO token _ TokenIO.ReadToken[]; IF token.kind=pushFlag THEN level _ level+1 ELSE IF token.kind=popFlag THEN level _ level-1; IF level<0 THEN EXIT; ENDLOOP; END; SetName: PROC[me: CD.ObPtr, r: Rope.ROPE] ~ INLINE { IF me.p.hasChildren THEN CDDirectory.ObToDirectoryProcs[me].setName[me, r] }; SetKey: PROC[me: CD.ObPtr, r: Rope.ROPE] ~ INLINE { IF me.p.hasChildren THEN CDDirectory.ObToDirectoryProcs[me].setKey[me, r] }; ReadObjectDefinition: PROC [] RETURNS [obj: CD.ObPtr_NIL] = BEGIN token: TokenIO.Token; atom: ATOM = TokenIO.ReadPushFlag[]; p: REF READONLY CD.ObjectProcs _ CD.FetchObjectProcs[atom, designInReadOperation.technology]; IF p=NIL OR p.internalRead=NIL THEN { TerminalIO.WriteRope["unknown object "]; TerminalIO.WriteRope[Atom.GetPName[atom]]; TerminalIO.WriteLn[]; SkipThrough[]; obj _ CDRects.CreateBareRect[[10, 10], CD.highLightError]; } ELSE { obj _ p.internalRead[]; IF obj=NIL THEN obj _ CDRects.CreateBareRect[[10, 10], CD.highLightError]; IF versionKey>0 THEN { IF p.hasChildren THEN { name: Rope.ROPE _ TokenIO.ReadRope[]; key: Rope.ROPE _ TokenIO.ReadRope[]; SetName[obj, name]; SetKey[obj, key]; }; }; token _ TokenIO.ReadToken[]; IF token.kind#popFlag THEN { TokenIO.ReadAgain[]; obj.properties _ ReadProperties[]; TokenIO.ReadPopFlag[]; } } END; ReadObject: PUBLIC PROC [] RETURNS [CD.ObPtr] = BEGIN t: TokenIO.Token = TokenIO.ReadToken[]; IF t.kind=int THEN { -- instance ins: INT _ NARROW[t.ref, REF INT]^; RETURN [indexTable.table[ins]] }; TokenIO.ReadAgain; RETURN [ReadObjectDefinition[]] END; ReadApplicationPtr: PUBLIC PROC [] RETURNS [CD.ApplicationPtr] = BEGIN RelativeMode: PROC [] RETURNS [BOOL] = INLINE { RETURN [versionKey>=3] }; ap: CD.ApplicationPtr; location: CD.DesignPosition _ ReadPosition[]; orientation: CD.Orientation _ CDIO.ReadOrientation[]; properties: CD.Properties _ ReadProperties[]; ob: CD.ObPtr _ ReadObject[]; IF RelativeMode[] THEN ap _ CDApplications.NewApplicationI[ob: ob, location: location, orientation: orientation, properties: properties] ELSE ap _ NEW[CD.Application _ [location: location, orientation: orientation, properties: properties, ob: ob, selected: FALSE]]; RETURN [ap]; END; ReadApplicationList: PUBLIC PROC [] RETURNS [list: CD.ApplicationList_NIL] = BEGIN num: INT = TokenIO.ReadInt[]; THROUGH [0..num) DO list _ CONS[ReadApplicationPtr[], list]; ENDLOOP END; ReadPushRec: PROC [] RETURNS [pr: CD.PushRec] = BEGIN token: TokenIO.Token _ TokenIO.ReadToken[]; dummy: CD.ObPtr; IF token.ref=$Nil THEN pr.mightReplace_NIL ELSE { TokenIO.ReadAgain[]; pr.mightReplace _ ReadApplicationPtr[]; }; dummy _ ReadObjectDefinition[]; pr.changed _ pr.indirectlyChanged _ TRUE; pr.specific _ NARROW[dummy.specificRef, CD.CellPtr]; pr.dummyCell _ CDApplications.NewApplicationI[ob: dummy]; END; ReadPosition: PROC [] RETURNS [pos: CD.DesignPosition] = BEGIN pos.x _ TokenIO.ReadInt[]; pos.y _ TokenIO.ReadInt[]; END; ReadLevel: PUBLIC PROC [] RETURNS [CD.Level] = BEGIN key: ATOM = TokenIO.ReadAtom[]; RETURN [CD.FetchLevel[designInReadOperation.technology, key]]; END; ReadDesignData: PROC [] = BEGIN index, directoryCount: INT; token: TokenIO.Token; obj: CD.ObPtr; directoryCount _ TokenIO.ReadInt[]; indexTable _ NEW[IndexTable[directoryCount+1]]; -- ??? FOR n: INT IN [1..directoryCount] DO index _ TokenIO.ReadInt[]; obj _ ReadObjectDefinition[]; indexTable.table[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, indexTable.table[obx], name]; token _ TokenIO.ReadToken[]; ENDLOOP; TokenIO.ReadAgain[]; } ELSE IF obj.p.hasChildren THEN { name: Rope.ROPE = CDDirectory.Name[obj]; [] _ CDDirectory.Include[designInReadOperation, obj, name]; } ENDLOOP; designInReadOperation.properties _ ReadProperties[]; 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 ERROR TokenIO.EncodingError; END; ReadDesign: PUBLIC ENTRY PROC [from: REF_NIL, check: PROC [CD.Design] RETURNS [BOOL] _ NIL] RETURNS [CD.Design] = BEGIN ENABLE UNWIND => { indexTable _ NIL; designInReadOperation _ NIL; }; design: CD.Design; -- is initialized before return only DoReadDesign: INTERNAL PROC [check: PROC [CD.Design] RETURNS [BOOL]] = BEGIN ENABLE { RuntimeError.UNCAUGHT => { designInReadOperation _ NIL; TerminalIO.WriteRope["unknown problem while reading; it is ok to abort\n"]; CDPrivate.Debug["unknown error in reading"]; GOTO DoReturn; }; TokenIO.EncodingError => { designInReadOperation _ NIL; TerminalIO.WriteRope["TokenIO encoding problem; it is ok to abort\n"]; CDPrivate.Debug["read error in encoding"]; GOTO DoReturn; }; }; DoWhileAttached: INTERNAL PROC [] = BEGIN ENABLE UNWIND => { designInReadOperation _ NIL; TokenIO.ReleaseReader[]; }; TechnologyCheck: INTERNAL PROC [] = BEGIN ENABLE UNWIND => {designInReadOperation _ NIL}; dont: BOOL _ CDEvents.ProcessEvent[ ev: readEvent, design: designInReadOperation, x: NIL, listenToDont: TRUE ].dont; IF dont THEN { designInReadOperation _ NIL; TerminalIO.WriteRope["Technology rejects read\n"]; } END; VersionAndSealCheck: INTERNAL PROC [] = BEGIN IF TokenIO.ReadInt[]#xChipndaleFile THEN { TerminalIO.WriteRope["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 TerminalIO.WriteRope["design was written with newer chipndaleversion\n"]; TerminalIO.WriteRope["get a new chipndale version\n"]; ERROR TokenIO.Error[other, "chipndale versionkey"]; } ELSE IF versionKey IN [2..xVersion] THEN { -- not new but dont tell it NULL } ELSE IF versionKey IN [1..xVersion] THEN { -- not new but everything ok TerminalIO.WriteRope["design was written with older chipndaleversion\n"]; } ELSE IF versionKey IN [0..xVersion] THEN { -- not new but please convert TerminalIO.WriteRope["design was written with older chipndaleversion\n"]; TerminalIO.WriteRope["Please convert also your other designs\n"]; } ELSE { -- too old TerminalIO.WriteRope["design was written with older chipndaleversion\n"]; TerminalIO.WriteRope["This version is no more supported\n"]; ERROR TokenIO.Error[other, "chipndale versionkey"]; }; }; IF versionKey>0 THEN { IF TokenIO.ReadInt[]#-1 THEN { TerminalIO.WriteRope["File had not been properly closed; has bad seal\n"]; ERROR TokenIO.Error[other, "file had not been properly closed"]; }; }; END; VersionAndSealCheck[]; technologyKey _ TokenIO.ReadAtom[]; technologyName _ TokenIO.ReadRope[]; technology _ CD.FetchTechnology[technologyKey]; IF technology=NIL THEN { TerminalIO.WriteRope["technology '"]; TerminalIO.WriteRope[technologyName]; TerminalIO.WriteRope["' not loded\n"]; GOTO NotDoneAndRelease }; designInReadOperation _ CDOps.CreateDesign[technology]; TechnologyCheck[]; IF designInReadOperation=NIL THEN GOTO NotDoneAndRelease; designInReadOperation.name _ TokenIO.ReadRope[]; IF Rope.IsEmpty[designInReadOperation.name] THEN designInReadOperation.name _ fileName; IF check#NIL THEN { IF NOT check[designInReadOperation] THEN GOTO NotDoneAndRelease; }; ReadDesignData[]; TokenIO.ReleaseReader[]; EXITS NotDoneAndRelease => { designInReadOperation _ NIL; TokenIO.ReleaseReader[]; }; END; 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.WriteRope[r]; TerminalIO.WriteRope["... not attached\n"]; GOTO NotAttached } ]; DoWhileAttached[]; EXITS NotAttached, DoReturn => RETURN END; ReadName: PROC [] RETURNS [name: Rope.ROPE] = BEGIN wDir: Rope.ROPE _FileNames.CurrentWorkingDirectory[]; TerminalIO.WriteRope[" input file"]; IF wDir#NIL THEN { TerminalIO.WriteRope[" ("]; TerminalIO.WriteRope[wDir]; TerminalIO.WriteRope[")"]; }; name _ TerminalIO.RequestRope[" > "]; END; iDidTheOpen: BOOL _ FALSE; name: Rope.ROPE; IF from#NIL AND ISTYPE[from, IO.STREAM] THEN { fileName _ NIL; binfile _ NARROW[from, IO.STREAM] } ELSE { IF from=NIL THEN name _ ReadName[] ELSE IF ISTYPE[from, Rope.ROPE] THEN { name _ NARROW[from, Rope.ROPE]; IF Rope.IsEmpty[name] THEN name _ ReadName[]; } ELSE { TerminalIO.WriteRope["ReadDesign does not support type of 'from' parameter\n"]; GOTO NotOpened; }; fileName _ CDExtras.AppendExt[name, "dale"]; binfile _ FS.StreamOpen[fileName ! FS.Error => IF error.group # bug THEN { TerminalIO.WriteRope[fileName]; TerminalIO.WriteRope[" not opened: "]; TerminalIO.WriteRope[error.explanation]; TerminalIO.WriteLn[]; GOTO NotOpened; }]; iDidTheOpen _ TRUE; TerminalIO.WriteRope[fileName]; TerminalIO.WriteRope[" opened \n"]; }; DoReadDesign[check]; design _ designInReadOperation; designInReadOperation _ NIL; indexTable _ NIL; IF iDidTheOpen THEN IO.Close[binfile]; RETURN [design]; EXITS NotOpened => { indexTable _ NIL; designInReadOperation _ NIL; TerminalIO.WriteRope["Read not done\n"]; RETURN [NIL]; } END; CheckWorkingDirectory: PROC [wDir: Rope.ROPE] RETURNS [slashWDir: Rope.ROPE] = INLINE BEGIN IF FileNames.IsADirectory[wDir] AND NOT FileNames.IsAPattern[wDir] THEN { length: INT; slashWDir _ FileNames.ConvertToSlashFormat[wDir]; length _ slashWDir.Length[]; IF slashWDir = wDir AND length > 0 AND slashWDir.Fetch[length - 1] = '/ THEN { RETURN [slashWDir]; } }; RETURN [NIL] END; GetDesignsWorkingDirectory: PUBLIC PROC [design: CD.Design] RETURNS [wDir: Rope.ROPE] = BEGIN x: REF = CDValue.Fetch[boundTo: design, key: $CDxWorkingDirectory, propagation: design]; IF ISTYPE[x, Rope.ROPE] AND x#NIL THEN RETURN [CheckWorkingDirectory[NARROW[x]].slashWDir]; END; SetDesignsWorkingDirectory: PUBLIC PROC [design: CD.Design, wDir: Rope.ROPE] = BEGIN wDir _ CheckWorkingDirectory[wDir].slashWDir; IF wDir#NIL THEN CDValue.Store[boundTo: design, key: $CDxWorkingDirectory, value: wDir]; END; NewDesignHasBeenCreated: CDEvents.EventProc = BEGIN SetDesignsWorkingDirectory[design, FileNames.CurrentWorkingDirectory[]]; END; readEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$ReadTechnologyPrivate]; CDEvents.RegisterEventProc[$CreateNewDesign, NewDesignHasBeenCreated]; END. ΊCDIn.mesa Last Edited by: Kimr, November 28, 1983 10:22 am Last Edited by: Jacobi, February 8, 1984 9:41 am -- global vars --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 --if wDir is a directory, assign it to slashWDir --else slashWDir _ nil -- PROC [event: REF, design: CD.Design, x: REF] -- --repaint captions and sometimes the contents -- Module Initialization versionKey 0 versionKey 1: objects with children carry names versionKey 2: versionKey 3: June 15, 1984 3:46:13 pm PDT; applications position is its innerrect; this allows to shrink or grow the nwell from cmos Κσ– "cedar" style˜J™ J™0J™0J˜šΟk ˜ Jšœ˜Jšœ˜J˜Jšœ ˜ Jšœ ˜ J˜ Jšœ˜Jšœ ˜ Jšœœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœœœ˜*Jšœœœ˜Jšœ ˜ Jšœ˜J˜—šΟbœœ˜Jš œœ3œ=œœ)˜΅Jšœœ ˜Jšœ˜—Jš˜J˜Jšœœ ˜Jšœ œ˜J˜J™Jšœ  œ˜Jšœœœ œ˜.Jšœ œœ˜J˜Jšœœ˜Jšœ œ œ˜!Jš œ œœœœœœ˜EJ˜š Οnœ œœ œ œ˜CJš˜Jšœœ˜ J˜&Jšœ˜š˜Jšœ˜šœœ˜Jšœ˜Jšœ ˜J˜—J˜J˜)š œ œœœœ˜6JšœY˜YJ˜—šœ˜Jšœ˜šœœœ˜Jšœ˜—J˜šŸœœ˜Jš˜Jšœœ˜J˜Jšœœ˜Jšœ#˜#Jšœ œ  ˜6šœœœ˜$Jšœ˜Jšœ˜Jšœ˜šœœ˜Jšœ˜šœ˜Jšœ œœ ˜$Jšœœ˜JšœM˜MJšœ˜Jšœ˜—Jšœ˜J˜—šœœœ˜!Jšœ œ˜(Jšœ;˜;J˜—Jšœ˜—Jšœ4˜4Jšœœ˜#š˜Jšœ˜šœœ˜J˜Jšœ˜J˜—Jšœœ.˜QJšœ˜—Jšœ˜Jšœœœ˜