DIRECTORY Ascii USING [ControlZ, CR, SP, TAB, Upper], IO USING [Close, EndOf, Flush, GetChar, int, PutF, PutFR, rope, STREAM], FS USING [ComponentPositions, Error, ExpandName, maxFNameLength, StreamOpen], RefText USING [AppendChar, AppendRope, New, ObtainScratch, ReleaseScratch, TrustTextAsRope], Rope USING [Concat, Equal, Fetch, Find, IsEmpty, Length, ROPE, Substr], RopeFrom USING [String], spGlobals USING [error, Handle, itemType, keys, maxInclude, PutMsgLine], TypeScript USING [ChangeLooks], ViewerTools USING [GetContents, SetContents]; spGlobalsImpl: CEDAR PROGRAM IMPORTS Ascii, IO, FS, RefText, Rope, RopeFrom, spGlobals, TypeScript, ViewerTools EXPORTS spGlobals= BEGIN Handle: TYPE= spGlobals.Handle; Aborted: PUBLIC SIGNAL = CODE; keyList: ARRAY spGlobals.keys OF Rope.ROPE_ ["node", "resistor", "capacitor", "inductor", "voltage", "current", "run", "print", "circuit", "model", "plot", "ic", "dump", "asserts", "checkpoint", "library", ""]; openInputFile: PUBLIC PROC[handle: Handle] = { OPEN handle.vars; RemoveFunnyChars: PROC[old: Rope.ROPE] RETURNS [new: Rope.ROPE _ NIL] = { name: REF TEXT _ RefText.New[FS.maxFNameLength]; c: CHAR; hasFunnyChar: BOOL _ FALSE; name.length _ 0; FOR i: INT IN [0..old.Length[]) DO c _ old.Fetch[i]; SELECT c FROM IN['0..'9], IN['a..'z], IN['A..'Z], '$, '-, '+, '' , '[, '], '<, '>, '., '!, '#, '/ => name _ RefText.AppendChar[name, c]; ENDCASE => hasFunnyChar _ TRUE; IF name.length >= FS.maxFNameLength THEN EXIT; ENDLOOP; IF hasFunnyChar THEN { new _ RopeFrom.String[name]; ViewerTools.SetContents[handle.input, new]; } ELSE new _ old; }; -- RemoveCtrlChars inputName, fullInputName: Rope.ROPE; inputName _ RemoveFunnyChars[ViewerTools.GetContents[handle.input]]; inputName _ EnsureExtension[inputName, "thy"]; [fullInputName, ]_ FS.ExpandName[inputName, WorkingDirectory[handle]]; inStream_ FS.StreamOpen[fullInputName]; }; -- openInputFile EnsureExtension: PROC[old, ext: Rope.ROPE] RETURNS[Rope.ROPE]= { IF Rope.Find[old, "!"] >= 0 THEN RETURN[old] ELSE { realExt: Rope.ROPE _ Rope.Concat[".", ext]; dotPos, extStart: INT _ old.Find["."]; UNTIL dotPos <= 0 OR dotPos+1 >= old.Length[] DO dotPos _ old.Find[".", dotPos+1]; IF dotPos >= 0 THEN extStart _ dotPos; ENDLOOP; IF extStart >= 0 THEN extStart_ old.Find[realExt, extStart, FALSE]; RETURN[ IF extStart >= 0 AND extStart + realExt.Length[] = old.Length[] THEN old ELSE IO.PutFR["%g.%g", IO.rope[old], IO.rope[ext]] ]; }; }; -- EnsureExtension OutputFileRoot: PUBLIC PROC[handle: Handle] RETURNS[Rope.ROPE]= { fullName: Rope.ROPE; inputName: Rope.ROPE _ EnsureExtension[ViewerTools.GetContents[handle.input], "thy"]; c: FS.ComponentPositions; workDir: Rope.ROPE _ WorkingDirectory[handle]; [fullName, c]_ FS.ExpandName[inputName, workDir]; RETURN[Rope.Concat[workDir, Rope.Substr[fullName, c.base.start, c.base.length]]]; }; -- OutputFileRoot WorkingDirectory: PUBLIC PROC[handle: Handle] RETURNS [dir: Rope.ROPE] = { dir _ ViewerTools.GetContents[handle.wDir]; IF dir.IsEmpty[] THEN { dir _ "///Thyme/"; ViewerTools.SetContents[handle.wDir, dir]; }; }; -- WorkingDirectory includeFile: PROC[handle: Handle]= {OPEN handle.vars; fname: REF TEXT_ RefText.ObtainScratch[128]; fname.length_ 0; nextChar[handle, TRUE]; UNTIL fname.length=128 OR char=Ascii.TAB OR char=Ascii.CR OR char=Ascii.SP DO fname_ RefText.AppendChar[fname, char]; nextChar[handle, FALSE]; ENDLOOP; IF fileStackTop < spGlobals.maxInclude THEN { fileName: Rope.ROPE_ EnsureExtension[RopeFrom.String[fname], "thy"]; fullName: Rope.ROPE; [fullName, ]_ FS.ExpandName[fileName, WorkingDirectory[handle] ! FS.Error => { spGlobals.error[handle, 103, FALSE]; handle.msgStream.PutF[" %g\n", IO.rope[error.explanation]]; GOTO fileError; } ]; fileStack[fileStackTop]_ inStream; fileStackTop_ fileStackTop + 1; inStream_ FS.StreamOpen[fullName ! FS.Error => { spGlobals.error[handle, 103, FALSE]; fileStackTop _ fileStackTop - 1; inStream_ fileStack[fileStackTop]; GOTO fileError; } ]; EXITS fileError => NULL; } ELSE spGlobals.error[handle, 104, FALSE]; RefText.ReleaseScratch[fname]; next[handle]; }; -- includeFile FlushCloseNil: PUBLIC PROC[stream: IO.STREAM] RETURNS [IO.STREAM _ NIL] = { IF stream # NIL THEN { stream.Flush[ ]; stream.Close[ ]; }; }; -- FlushCloseNil MsgTextsWithLook: PUBLIC PROC[handle: Handle, text: Rope.ROPE, look: CHAR['a..'z]]= { TypeScript.ChangeLooks[handle.message, look]; handle.msgStream.PutF[text]; TypeScript.ChangeLooks[handle.message, Ascii.Upper[look]]; }; -- MsgTextsWithLook popIncludeFile: PROC[handle: Handle]= {OPEN handle.vars; IF fileStackTop > 0 THEN { IF inStream # NIL THEN inStream.Close[ ]; fileStack[fileStackTop] _ NIL; fileStackTop_ fileStackTop - 1; inStream_ fileStack[fileStackTop]; nextChar[handle, FALSE]; next[handle]; } ELSE item_ eof; }; -- popIncludeFile newLine: PROC[handle: Handle]= {OPEN handle.vars; cptr_ 0; line.length_ 0; DO char_ IF inStream.EndOf[ ] THEN Ascii.ControlZ ELSE inStream.GetChar[ ]; IF char=Ascii.ControlZ OR char=Ascii.CR THEN EXIT; line_ RefText.AppendChar[line, char]; ENDLOOP; spGlobals.PutMsgLine[handle, RopeFrom.String[line]]; line_ RefText.AppendChar[line, char]; IF char=Ascii.ControlZ THEN line_ RefText.AppendChar[line, Ascii.CR]; }; -- newLine nextChar: PROC[handle: Handle, skip: BOOLEAN]= { DO OPEN handle.vars; IF cptr >= line.length THEN newLine[handle]; char_ line[cptr]; cptr_ cptr + 1; IF char # Ascii.SP THEN EXIT; IF ~skip THEN EXIT; ENDLOOP }; -- nextChar scaleFactor: PROC[handle: Handle] RETURNS[s: INT]= { s_ SELECT handle.vars.char FROM 'M => 6, 'k, 'K => 3, 'c => -2, 'm => -3, 'u => -6, 'n => -9, 'p => -12, ENDCASE => 0; IF s # 0 THEN nextChar[handle, FALSE]; SELECT handle.vars.char FROM 'F, 'H, 'V, 'A, 's => nextChar[handle, TRUE]; ENDCASE }; -- scaleFactor next: PUBLIC PROC[handle: Handle]= {OPEN handle.vars; minusExp, validReal: BOOLEAN_ FALSE; exp: INTEGER_ 0; f1, f10: REAL; MoveOnWithNewItem: PROC[c: CHAR]= { item_ SELECT c FROM '{ => leftC, '} => rightC, '[ => leftB, '] => rightB, '( => leftP, ') => rightP, ': => colon, '; => semi, ', => comma, '' => quote, '_ => leftArrow, '^ => upArrow, '/ => slash, '| => vertical, '\\ => backSlash, '+ => plus, '~ => squiggle, '@ => atSign, '* => star, '& => amperesand, '# => pound, ENDCASE => nullItem; IF item=nullItem THEN spGlobals.error[handle, 100, FALSE]; nextChar[handle, TRUE]; }; -- MoveOnWithNewItem SELECT char FROM Ascii.ControlZ => popIncludeFile[handle]; '! => includeFile[handle]; Ascii.TAB, Ascii.SP, Ascii.CR => {nextChar[handle, TRUE]; next[handle]}; '{, '}, '[, '], '(, '), ':, ';, ',, '', '_, '^, '/, '|, '\\, '+, '~, '@, '*, '&, '# => MoveOnWithNewItem[char]; '= => {nextChar[handle, FALSE]; IF char='> THEN {item_ implies; nextChar[handle, TRUE]} ELSE item_ equal; }; '- => { item_ minus; nextChar[handle, FALSE]; IF char='- THEN { UNTIL char=Ascii.CR OR char=Ascii.ControlZ DO nextChar[handle, TRUE]; IF char='- THEN { nextChar[handle, FALSE]; IF char='- THEN {nextChar[handle, TRUE]; EXIT}; }; ENDLOOP; next[handle]; }; }; '> => { nextChar[handle, FALSE]; IF char='= THEN {item_ greatEqual; nextChar[handle, TRUE]} ELSE item_ greater; }; '< => { nextChar[handle, FALSE]; IF char='= THEN {item_ lessEqual; nextChar[handle, TRUE]} ELSE item_ less; }; '" => { item_ string; newString.length_ 0; DO nextChar[handle, FALSE]; IF char=Ascii.ControlZ THEN {spGlobals.error[handle, 213, FALSE]; EXIT}; IF char='" THEN { nextChar[handle, FALSE]; IF char # '" THEN EXIT }; newString_ RefText.AppendChar[newString, char]; ENDLOOP; }; '? => { newString.length_ 0; newString_ RefText.AppendRope[newString, IO.PutFR["?%g", IO.int[genSymCtr]] ]; genSymCtr_ genSymCtr + 1; item_ name; nextChar[handle, TRUE]; }; '$ => { nextChar[handle, FALSE]; newString.length_ 0; UNTIL char='$ DO IF char=Ascii.ControlZ THEN {spGlobals.error[handle, 214, FALSE]; EXIT}; newString_ RefText.AppendChar[newString, char]; nextChar[handle, FALSE] ENDLOOP; nextChar[handle, TRUE]; item_ name; }; IN ['A..'Z], IN ['a..'z] => { newString.length_ 0; UNTIL ~(char IN ['A..'Z] OR char IN ['a..'z] OR char IN ['0..'9]) DO newString_ RefText.AppendChar[newString, char]; nextChar[handle, FALSE]; ENDLOOP; IF Rope.Equal[RefText.TrustTextAsRope[newString], "MAX", FALSE] THEN {item_ maximum; GOTO done} ELSE IF Rope.Equal[RefText.TrustTextAsRope[newString], "MIN", FALSE] THEN {item_ minimum; GOTO done} ELSE item_ name; EXITS done => IF char=Ascii.SP OR char=Ascii.CR OR char=Ascii.TAB THEN nextChar[handle, TRUE]; }; '., IN ['0..'9] => { item_ number; value_ 0.0; WHILE char IN ['0..'9] DO validReal_ TRUE; value_ value*10.0 + (char - '0); nextChar[handle, FALSE] ENDLOOP; IF char='. THEN { nextChar[handle, FALSE]; f10_ 0.1; WHILE char IN ['0..'9] DO validReal_ TRUE; value_ value + f10*(char - '0); f10_ 0.1*f10; nextChar[handle, FALSE] ENDLOOP }; IF char='e OR char='E THEN { nextChar[handle, FALSE]; minusExp_ (char='-); IF minusExp OR (char='+) THEN nextChar[handle, FALSE]; IF char IN ['0..'9] THEN { WHILE char IN ['0..'9] DO exp_ exp*10 + (char - '0); nextChar[handle, FALSE]; ENDLOOP; } ELSE validReal_ FALSE; IF minusExp THEN exp_ -exp; }; exp_ exp + scaleFactor[handle]; validReal_ validReal AND (exp < 37) AND (exp > -37); IF validReal THEN { f1_ 1.0E+1; f10_ 1.0E+10; IF exp < 0 THEN {f1_ 1.0/f1; f10_ 1.0/f10; exp_ -exp }; UNTIL exp < 10 DO value_ value*f10; exp_ exp - 10 ENDLOOP; UNTIL exp=0 DO value_ value*f1; exp_ exp - 1 ENDLOOP } ELSE spGlobals.error[handle, 102, FALSE]; }; ENDCASE => { nextChar[handle, TRUE]; spGlobals.error[handle, 101, FALSE]; }; }; -- next getSignedNumber: PUBLIC PROC[handle: Handle] RETURNS[n: REAL_ 1.0]= { negative: BOOLEAN_ (handle.vars.item=minus); IF negative THEN next[handle]; IF handle.vars.item=number THEN { n_ IF negative THEN -handle.vars.value ELSE handle.vars.value; next[handle] } ELSE spGlobals.error[handle, 105, FALSE]; }; -- getSignedNumber searchKey: PUBLIC PROC[handle: Handle] RETURNS[index: spGlobals.keys]= { FOR i: spGlobals.keys IN spGlobals.keys DO index_ i; IF Rope.Equal[RefText.TrustTextAsRope[handle.vars.newString], keyList[i], FALSE] THEN EXIT; ENDLOOP; }; -- searchKey GetLineAndCptr: PUBLIC PROC[handle: Handle] RETURNS[Rope.ROPE, NAT]= { RETURN[RopeFrom.String[handle.vars.line], handle.vars.cptr]}; END. dFile: [Cherry]Cedar5.2>System>spGlobalsimpl.mesa Last Edited by: SChen, May 17, 1985 4:27:46 pm PDT does nothing if old name has '! in it. Current Cedar doesn't seem to support PutF with looks MsgTextsWithLook[handle, RopeFrom.String[line], 'p]; handle.msgStream.PutF["\n"]; "MoveOn" means: get next char in input file, skipping blanks. CHANGE LOG Wilhelm, April 27, 1982 4:05 PM Barth, 7-May-82 11:00:25 PDT Chen, April 19, 1983 1:45 PM, modified "next" to support min and max operations. Chen, February 12, 1984 7:56 PM, to support oldArgVector. Chen, June 11, 1984 7:34:25 pm PDT, cedarized. *"mycedar" styleJ"mycedar" style77J"mycedar" style22J"mycedar" style"mycedar" stylek J"mycedar" style   +J"mycedar" style8HJ"mycedar" styleEMJ"mycedar" styleO\J"mycedar" style/ GJ"mycedar" style  J"mycedar" style 9HJ"mycedar" style J"mycedar" style -J"mycedar" style"mycedar" styleJ"mycedar" style=RJ"mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style.J"mycedar" style "mycedar" style n  IJ"mycedar" style0J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" style"J"mycedar" style"mycedar" style "mycedar" style  "mycedar" style J"mycedar" style$J"mycedar" style;J"mycedar" style J"mycedar" styleJ"mycedar" style""J"mycedar" style"mycedar" style  "mycedar" style J"mycedar" style$J"mycedar" style J"mycedar" style""J"mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style)J"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" style"mycedar" style  K"mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" style  UJ55J"mycedar" style-J"mycedar" styleJ"mycedar" style::J"mycedar" styleJ"mycedar" style"mycedar" style 8"mycedar" styleJ"mycedar" style)J"mycedar" styleJ"mycedar" styleJ"mycedar" style""J"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" style"mycedar" style  1J"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" style.J"mycedar" styleJ"mycedar" style  2J"mycedar" style%%J"mycedar" styleJ"mycedar" style44J"mycedar" styleJ"mycedar" style44J"mycedar" style%%J"mycedar" style&EJ"mycedar" style J"mycedar" style"mycedar" style 0"mycedar" style J"mycedar" style,J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style 4"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style J"mycedar" style J"mycedar" style J"mycedar" style J"mycedar" style J"mycedar" style J"mycedar" style&"mycedar" styleJ"mycedar" style'-J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" style 5J"mycedar" style$J"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style#J"mycedar" style=="mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style33J"mycedar" style""J"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style:J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" style))J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style HJ"mycedar" style"mycedar" styleWWJ"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" style "7J"mycedar" style J"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style "mycedar" style -J"mycedar" style"mycedar" style J"mycedar" styleJ"mycedar" style /J"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" styleJ"mycedar" style %:J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" styleJ"mycedar" style $9J"mycedar" style J"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" style,"mycedar" style J"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" style//J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" styleJ"mycedar" style)NJ"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" style J"mycedar" styleHJ"mycedar" style//J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" style"mycedar" style J"mycedar" style"mycedar" style    DJ"mycedar" style//J"mycedar" styleJ"mycedar" style"mycedar" style7?J"mycedar" style"mycedar" style7DJ"mycedar" styleJ"mycedar" style "mycedar" style"mycedar" style   @J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" styleJ"mycedar" style J"mycedar" style "mycedar" style J"mycedar" style J"mycedar" style J"mycedar" styleJ"mycedar" style"mycedar" style J"mycedar" styleJ"mycedar" style "mycedar" style J"mycedar" style J"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" style  J"mycedar" styleJ"mycedar" styleJ"mycedar" style  6"mycedar" style "mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style  J"mycedar" styleJ"mycedar" styleJ"mycedar" style  4"mycedar" style J"mycedar" styleJ"mycedar" style (7J"mycedar" style !:J"mycedar" style4J"mycedar" styleJ"mycedar" style)J"mycedar" style"mycedar" style J"mycedar" styleJ"mycedar" style$J"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style  EJ"mycedar" style ,J"mycedar" styleJ"mycedar" style "mycedar" style!J"mycedar" style >J"mycedar" style J"mycedar" styleJ"mycedar" style)J"mycedar" styleJ"mycedar" style"mycedar" style H"mycedar" style*J"mycedar" style "mycedar" style;=J"mycedar" style J"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style FJ"mycedar" style7=J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style J"mycedar" styleJ"mycedar" styleQQJ"mycedar" style::J"mycedar" style..J"mycedar" style(U4