<> <> <> <> DIRECTORY Atom USING [GetPName, MakeAtom], IO USING [GetBlock, GetChar, PutBlock, PutChar, STREAM], Interminal USING [KeyName], PrincOpsUtils USING [LongCopy], Rope USING [Equal, FromRefText, ROPE], TerminalDefs USING [KeyName], TIPPrivate USING [KeyOption, stdChar, stdCoords, stdTime, version], TIPTables USING [TIPChoice, TIPChoiceSeries, TIPKeyState, TIPResults, TIPTableImplRep, TIPTerm], TIPUser USING [TIPTable, TIPTableRep]; TIPTableReaderWriter: CEDAR PROGRAM IMPORTS Atom, IO, PrincOpsUtils, Rope, TIPPrivate EXPORTS TIPPrivate, TIPUser = BEGIN OPEN TIPPrivate, TIPTables, TIPUser; TIPTableImpl: TYPE ~ REF TIPTableImplRep; TIPTableImplRep: PUBLIC TYPE ~ TIPTables.TIPTableImplRep; BadTable: PUBLIC ERROR = CODE; ReadTIPTable: PUBLIC PROC [s: IO.STREAM] RETURNS [table: TIPTable, keyOption: KeyOption _ none] = { text: REF TEXT _ NEW[TEXT[32]]; -- scratch text for atoms and such opaque, up, down, move: BOOL; where: INT _ 0; -- for debugging Text: PROC [len: CARDINAL] = TRUSTED { IF len > 255 THEN ERROR BadTable; IF len > text.maxLength THEN text _ NEW[TEXT[len]]; IF (text.length _ IO.GetBlock[s,text,0,len]) # len THEN ERROR BadTable; where _ where+len; }; Char: PROC RETURNS [CHAR] = TRUSTED INLINE { where _ where+1; RETURN [IO.GetChar[s]]; }; Key: PROC RETURNS [Interminal.KeyName] = TRUSTED INLINE { RETURN [LOOPHOLE[Char[]]]; }; GetAtom: PROC RETURNS [ATOM] = TRUSTED { Text[LOOPHOLE[Char[],CARDINAL]]; RETURN [Atom.MakeAtom[Rope.FromRefText[text]]]; }; Flag: PROC RETURNS [BOOL] = TRUSTED { RETURN [SELECT Char[] FROM 'F => FALSE, 'T => TRUE, ENDCASE => ERROR BadTable]; }; StoreFlags: PROC = TRUSTED { impl: TIPTableImpl ~ table.impl; table.opaque _ opaque; impl.ignore.up _ up; impl.ignore.down _ down; impl.ignore.move _ move; }; ChoiceItem: PROC RETURNS [key: Interminal.KeyName, choice: TIPChoice] = TRUSTED { SELECT Char[] FROM ') => RETURN [BS,NIL]; '( => NULL; ENDCASE => ERROR BadTable; key _ Key[]; choice _ Choice[]; IF Char[] # ') THEN ERROR BadTable; }; Choice: PROC [skipPar: BOOL _ FALSE] RETURNS [choice: TIPChoice] = TRUSTED { last: TIPChoice; char: CHAR; IF ~skipPar AND Char[] # '( THEN ERROR BadTable; WHILE (char _ Char[]) # ') DO term: TIPChoice _ Term[char]; IF last=NIL THEN choice _ last _ term ELSE last _ last.rest _ term; ENDLOOP; }; ChoiceSeries: PROC RETURNS [series: TIPChoiceSeries] = TRUSTED { last: TIPChoiceSeries; IF Char[] # '( THEN ERROR BadTable; WHILE Char[] # ') DO choices: TIPChoiceSeries _ LIST[Choice[TRUE]]; IF last=NIL THEN series _ last _ choices ELSE last _ last.rest _ choices; ENDLOOP; }; Term: PROC [char: CHAR] RETURNS [term: TIPChoice] = TRUSTED { SELECT char FROM '1 => { <> keyTerm: keyTrigger TIPTerm; keyTerm.keyState.key _ Key[]; keyTerm.keyState.state _ SELECT Char[] FROM 'U => up, 'D => down, ENDCASE => ERROR BadTable; RETURN [LIST[keyTerm]] }; '2 => { <> mouseTerm: mouseTrigger TIPTerm; RETURN [LIST[mouseTerm]] }; '3 => { <> timeTerm: timeTrigger TIPTerm; msecs: CARDINAL; timeTerm.flavor _ SELECT Char[] FROM 'G => gt, 'L => lt, ENDCASE => ERROR BadTable; msecs _ LOOPHOLE[Char[],CARDINAL]*256; msecs _ msecs + LOOPHOLE[Char[],CARDINAL]; timeTerm.mSecs _ msecs; RETURN [LIST[timeTerm]] }; '4 => { <> keyTerm: keyEnable TIPTerm; keyTerm.keyState _ KeyState[]; RETURN [LIST[keyTerm]] }; '5 => { <> predTerm: predEnable TIPTerm; predTerm.predicate _ GetAtom[]; RETURN [LIST[predTerm]] }; '6 => { <> charTerm: char TIPTerm; charTerm.ch _ stdChar; RETURN [LIST[charTerm]] }; '7 => { <> coordsTerm: coords TIPTerm; coordsTerm.xy _ stdCoords; RETURN [LIST[coordsTerm]] }; '8 => { <> term: nested TIPTerm; term.statement _ ChoiceSeries[]; RETURN [LIST[term]] }; '9 => { <> resultTerm: result TIPTerm; resultTerm.list _ Results[]; RETURN [LIST[resultTerm]] }; 'A => { <> term: key2Enable TIPTerm; term.keyState1 _ KeyState[]; term.keyState2 _ KeyState[]; RETURN [LIST[term]] }; 'B => { <> term: keyEnableList TIPTerm; last: LIST OF TIPKeyState; IF Char[] # '( THEN ERROR BadTable; WHILE Char[] # ') DO keyState: LIST OF TIPKeyState _ LIST[KeyState[]]; IF last=NIL THEN term.lst _ last _ keyState ELSE last _ last.rest _ keyState; ENDLOOP; RETURN [LIST[term]] }; 'C => { <