DIRECTORY Convert, GGBasicTypes, GGParseIn, Imager, ImagerColor, ImagerTransformation, IO, RefText, Rope; GGParseInImpl: CEDAR PROGRAM IMPORTS Convert, Imager, ImagerColor, ImagerTransformation, IO, RefText, Rope EXPORTS GGParseIn = BEGIN RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE; Color: TYPE = Imager.Color; Point: TYPE = GGBasicTypes.Point; ReadBlank: PUBLIC PROC [f: IO.STREAM] = { [] _ IO.SkipWhitespace[f, TRUE]; }; ReadWhiteSpace: PUBLIC PROC [f: IO.STREAM] = { WhiteSpaceProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM IO.TAB => RETURN [other]; IO.CR =>RETURN [other]; IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; whiteSpace: Rope.ROPE; end: BOOL _ FALSE; [whiteSpace, ----] _ IO.GetTokenRope[f, WhiteSpaceProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR Rope.Size[whiteSpace] = 0 THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], "null", ""]; }; ReadHorizontalBlank: PUBLIC PROC [f: IO.STREAM] RETURNS [good: BOOL] = { HorizontalBlankProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM IO.TAB, IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; whiteSpace: Rope.ROPE; c: CHAR; end: BOOL _ FALSE; good _ TRUE; [whiteSpace, ----] _ IO.GetTokenRope[f, HorizontalBlankProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; c _ Rope.Fetch[whiteSpace, 0]; SELECT c FROM IO.CR => {good _ FALSE; RETURN}; IO.TAB, IO.SP => {good _ TRUE; RETURN}; ENDCASE => {good _ TRUE; IO.Backup[f, c]; RETURN}; }; ReadWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { WordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ', => RETURN [break]; '] => RETURN [break]; ') => RETURN [break]; ENDCASE => RETURN [other]; }; [word, ----] _ IO.GetTokenRope[f, WordBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadColorToken: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { ColorBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ENDCASE => RETURN [other]; }; [word, ----] _ IO.GetTokenRope[f, ColorBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadBlankAndWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { ReadBlank[f]; word _ ReadWord[f]; }; ReadBlankAndColor: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { ReadBlank[f]; word _ ReadColorToken[f]; }; ReadRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { c: CHAR; endofstream: BOOL _ FALSE; FOR i: INT IN[1..Rope.Length[rope]] DO c _ IO.GetChar[f ! IO.EndOfStream => {endofstream _ TRUE; CONTINUE}]; IF endofstream THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], NIL, rope]; IF NOT c = Rope.Fetch[rope,i-1] THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], Rope.FromChar[c], rope]; ENDLOOP; }; ReadBlankAndRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { ReadBlank[f]; ReadRope[f, rope]; }; ReadNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { NATBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.SP, '., ',, ': => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; intRope: Rope.ROPE; [intRope, ----] _ IO.GetTokenRope[f, NATBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {n _ 1; RETURN}; n _ Convert.IntFromRope[intRope]; }; ReadBlankAndNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { ReadBlank[f]; n _ ReadNAT[f]; }; ReadColor: PUBLIC PROC [f: IO.STREAM] RETURNS [color: Color] = { s: IO.STREAM; r, g, b: REAL; word: Rope.ROPE _ ReadBlankAndColor[f]; IF Rope.Equal[word, "none"] THEN RETURN[NIL]; s _ IO.RIS[word, colorStream]; ReadChar[s, '[]; r _ ReadBlankAndReal[s]; ReadChar[s, ',]; g _ ReadBlankAndReal[s]; ReadChar[s, ',]; b _ ReadBlankAndReal[s]; ReadChar[s, ']]; color _ ImagerColor.ColorFromRGB[[r, g, b]]; IF ImagerColor.GrayFromColor[NARROW[color]]=1.0 THEN color _ Imager.black; -- "process black" }; -- end of ReadColor ReadStrokeEnd: PUBLIC PROC [f: IO.STREAM] RETURNS [strokeEnd: Imager.StrokeEnd] = { endName: Rope.ROPE _ ReadBlankAndWord[f]; SELECT TRUE FROM Rope.Equal[endName, "square", TRUE] => strokeEnd _ square; Rope.Equal[endName, "butt", TRUE] => strokeEnd _ butt; Rope.Equal[endName, "round", TRUE] => strokeEnd _ round; ENDCASE => ERROR; }; ReadPoint: PUBLIC PROC [f: IO.STREAM] RETURNS [point: Point] = { ReadRope[f, "["]; point.x _ ReadBlankAndReal[f]; ReadRope[f, ","]; point.y _ ReadBlankAndReal[f]; ReadRope[f, "]"]; }; ReadChar: PUBLIC PROC [f: IO.STREAM, c: CHAR] = { streamC: CHAR _ IO.GetChar[f]; IF NOT c = streamC THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], Rope.FromChar[streamC], Rope.FromChar[c]]; }; ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = { KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ': => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; nextChar: Rope.ROPE; [keyWord, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; keyWord _ NIL; RETURN}; [nextChar, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; good _ Rope.Equal[nextChar, ":", TRUE]; }; ReadLine: PUBLIC PROC [f: IO.STREAM] RETURNS [line: Rope.ROPE] = { LineBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; [line, ----] _ IO.GetTokenRope[f, LineBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {line _ NIL; RETURN}; [----, ----] _ IO.GetTokenRope[f, LineBreakProc]; -- remove }; ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '), '], ', => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ENDCASE => RETURN [other]; }; realText, buffer: REF TEXT; end: BOOL _ FALSE; buffer _ RefText.ObtainScratch[50]; [realText, ----] _ IO.GetToken[f, RealBreakProc, buffer !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {r _ 0.0; RETURN}; IF RefText.Find[realText, ".", 0, FALSE] = -1 THEN realText _ RefText.Append[realText, ".0"]; r _ Convert.RealFromRope[RefText.TrustTextAsRope[realText]]; RefText.ReleaseScratch[buffer]; }; ReadBlankAndReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { ReadBlank[f]; r _ ReadReal[f]; }; ReadBOOL: PUBLIC PROC [f: IO.STREAM] RETURNS [truth: BOOL, good: BOOL] = { BoolBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; boolRope: Rope.ROPE; [boolRope, ----] _ IO.GetTokenRope[f, BoolBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; truth _ FALSE; RETURN}; good _ TRUE; IF Rope.Equal[boolRope, "TRUE", TRUE] THEN truth _ TRUE ELSE IF Rope.Equal[boolRope, "FALSE", TRUE] THEN truth _ FALSE ELSE {truth _ FALSE; good _ FALSE}; }; ReadListOfRope: PUBLIC PROC [f: IO.STREAM] RETURNS [ropeList: LIST OF Rope.ROPE] = { RopesOnOneLineOrParenProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR, ') =>RETURN [break]; IO.SP, IO.TAB, ', , '; => RETURN [sepr]; ENDCASE => RETURN [other]; }; rope: Rope.ROPE; end: BOOL _ FALSE; ropeList _ NIL; WHILE TRUE DO [rope, ----] _ IO.GetTokenRope[f, RopesOnOneLineOrParenProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR rope = NIL THEN RETURN; IF Rope.Equal[rope, Rope.FromChar[IO.CR]] THEN RETURN; IF Rope.Equal[rope, Rope.FromChar[')]] THEN { f.Backup[')]; RETURN; }; ropeList _ AppendRopeToRopeList[rope, ropeList]; ENDLOOP; }; ReadTransformation: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = { a, b, c, d, e, g: REAL; ReadBlankAndRope[f, "["]; a _ ReadBlankAndReal[f]; b _ ReadBlankAndReal[f]; c _ ReadBlankAndReal[f]; d _ ReadBlankAndReal[f]; e _ ReadBlankAndReal[f]; g _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "]"]; transform _ ImagerTransformation.Create[a, b, c, d, e, g]; }; AppendRopeToRopeList: PROC [rope: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { z: LIST OF Rope.ROPE _ list; IF z = NIL THEN RETURN[CONS[rope,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[rope,NIL]; RETURN[list]; }; colorStream: IO.STREAM; Init: PROC [] = { colorStream _ IO.RIS["This string is longer than any color is likely to be."]; }; Init[]; END. ®GGParseInImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last edited by Bier on January 6, 1986 11:33:00 pm PST Contents: Routines for reading gargoyle data structures from a stream. Stolen from Solidviews Solidmodeler TFI3d.mesa. Reads, 's, 's, and 's until something else is encountered. Doesn't mind if no white space characters are found. Treats comments as white space. Reads, 's, 's, and 's until something else is encountered. Signals RopeNotOnTop if no white space characters are found. Reads 's, and 's until something else is encountered. Returns good = FALSE if a CR is encountered before anything else Used to read in a rope which is data. Reads a rope until , or are encountered. A convenience function. Equivalent to ReadBlank[f]; word _ ReadWord[f]; Removes the given rope from the top of the stream. Used to remove formatting words and phrases from 3d files. We are not interested in these strings but only in the data in between them. Signals RopeNotOnTop if some other rope is on top. Reads digits up to the next ], , . Leaves these terminators on the stream. A convenience function. Equivalent to ReadBlank[f]; n _ ReadNAT[f]; Assumes the next rope on the stream will be of the form "[,]". Reads a rope until a ':' or are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword. Reads a rope UNTIL is encountered. Reads digits up to the next ), ], , or . Leaves these terminators on the stream. A convenience function. Equivalent to ReadBlank[f]; r _ ReadReal[f]; Tries to read TRUE or FALSE from the stream. If it encounters another word, good = FALSE; A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY realNumberStream: IO.STREAM; realNumberStream _ IO.TIS["This string is longer than any real number is likely to be."]; ʦ˜J˜Icodešœ™Kšœ Ïmœ1™Lšžœ žœ žœ˜#—Lšœ˜L˜—šŸœžœžœžœžœžœ žœžœžœ˜TšŸœžœžœžœžœžœžœ˜Tšžœž˜Lšžœžœžœ ˜Lš žœžœžœžœ žœ˜(Lšžœžœ ˜—Lšœ˜—Lšœ žœ˜Lšœžœžœ˜Lšœ žœ˜šžœžœž˜ šœ œžœŸ˜;Lšœžœžœžœ˜+—Lš žœžœžœžœžœ˜!Lš žœ žœžœžœžœ˜6šžœ%žœ˜-LšœŸœ˜ Lšžœ˜L˜—Lšœ0˜0—Lšžœ˜L˜—š Ÿœžœžœžœžœžœ5˜kLšœžœ˜L˜L˜L˜L˜L˜L˜L˜L˜Lšœ:˜:L˜—L˜šŸœžœ žœžœžœžœžœžœžœžœ˜eJšœF™FJšœžœžœžœ˜Jš žœžœžœžœžœžœ˜'Jšžœ žœžœ žœ˜*Jšœ žœžœ˜Jšžœ˜ Jšœ˜J˜—Jšœ žœžœ˜Jšœžœžœ™J˜šŸœžœ˜Jšœžœžœ@™YJšœžœžœ:˜NJ˜J˜—˜L˜—Kšžœ˜—…—":\