-- ListRTBcd.Mesa -- last edited by Satterthwaite on 4-May-82 13:23:11 DIRECTORY BcdDefs: TYPE USING [VersionStamp], Environment: TYPE USING [bitsPerWord], Inline: TYPE USING [LowHalf], ListerDefs: TYPE USING [Indent, WriteVersionId], OutputDefs: TYPE USING [PutChar, PutDecimal, PutString], RCMap: TYPE USING [Base, FieldDescriptor, Index, Object, RCField], RTBcd: TYPE USING [ RefLitList, RTBase, StampList, TypeList, VersionID, AnyStamp], TypeStrings: TYPE USING [Code, TypeString]; ListRTBcd: PROGRAM IMPORTS Inline, ListerDefs, OutputDefs EXPORTS ListerDefs = BEGIN OPEN OutputDefs; PrintRTBcd: PUBLIC PROC [rtHeader: RTBcd.RTBase] = BEGIN IF rtHeader = NIL THEN PutString["No RT pages\n"L] ELSE IF rtHeader.versionIdent # RTBcd.VersionID THEN PutString["Invalid RT version stamp\n"L] ELSE BEGIN PrintHeader[rtHeader]; PrintTypes[rtHeader]; PrintStamps[rtHeader]; PrintRCMap[rtHeader]; PrintRefLits[rtHeader]; END; END; PrintHeader: PROC [rtHeader: RTBcd.RTBase] = BEGIN PutString["Types: "L]; PutDecimal[rtHeader[rtHeader.typeTable].length]; PutString[", Ref Literals: "L]; PutDecimal[rtHeader[rtHeader.refLitTable].length]; PutString[", "L]; PutDecimal[rtHeader.rcMapLength]; PutString[" Words of RC Map"L]; PutString[", "L]; PutDecimal[rtHeader.litLength]; PutString[" Words of Literals\n\n"L]; END; PrintTypes: PROC [rtHeader: RTBcd.RTBase] = BEGIN typeList: LONG POINTER TO RTBcd.TypeList = @rtHeader[rtHeader.typeTable]; stampList: LONG POINTER TO RTBcd.StampList = @rtHeader[rtHeader.stampTable]; textBase: LONG POINTER = @rtHeader[rtHeader.litBase]; PrintTypeString: PROC [offset: CARDINAL] RETURNS [valid: BOOLEAN] = INLINE BEGIN text: TypeStrings.TypeString = textBase + offset; valid ← offset <= rtHeader.litLength AND offset+SIZE[StringBody[text.length]] <= rtHeader.litLength; PutChar[' ]; IF ~valid THEN PrintGarbage[] ELSE IF PutType[text, 0] # text.length THEN PutString[" ???"L]; END; PutString["Types"L]; PrintIndex[rtHeader.typeTable]; PutString[":\n"L]; FOR i: NAT IN [0 .. typeList.length) DO Tab[2]; PrintIndex[i]; PutString[" sei: "L]; PutIndex[typeList[i].sei]; PutString[", segment: "L]; PrintIndex[typeList[i].table]; PutString[", rcMap: "L]; PrintIndex[typeList[i].rcMap]; PutString[", UTF: [stamp: "L]; IF typeList[i].ut.version = RTBcd.AnyStamp THEN PutString["(any)"L] ELSE PrintIndex[typeList[i].ut.version]; PutString[", sei: "L]; PutIndex[typeList[i].ut.sei]; PutChar[']]; IF typeList[i].canonical THEN PutString[", canonical"L]; Tab[4]; PrintIndex[typeList[i].ct.index]; IF ~PrintTypeString[typeList[i].ct.index] THEN EXIT; ENDLOOP; PutString["\n\n"L]; END; PrintStamps: PROC [rtHeader: RTBcd.RTBase] = BEGIN stampList: LONG POINTER TO RTBcd.StampList = @rtHeader[rtHeader.stampTable]; PutString["Version Stamps"L]; PrintIndex[rtHeader.stampTable]; PutString[":\n"L]; FOR i: NAT IN [1 .. stampList.limit) DO Tab[2]; PrintIndex[i]; PutChar[' ]; ListerDefs.WriteVersionId[stampList[i]]; ENDLOOP; PutString["\n\n"L]; END; PrintRCMap: PROC [rtHeader: RTBcd.RTBase] = BEGIN rcmb: RCMap.Base = LOOPHOLE[@rtHeader[rtHeader.rcMapBase]]; next: RCMap.Index; PutString["RC Maps"L]; PrintIndex[Inline.LowHalf[LOOPHOLE[rtHeader.rcMapBase, LONG CARDINAL]]]; PutString[":\n"L]; FOR rcmi: RCMap.Index ← FIRST[RCMap.Index], next WHILE LOOPHOLE[rcmi, CARDINAL] < rtHeader.rcMapLength DO Tab[2]; PrintIndex[rcmi]; PutChar[' ]; WITH m: rcmb[rcmi] SELECT FROM null => { PutString["null"L]; next ← rcmi + SIZE[RCMap.Object[null]]}; ref => { PutString["ref"L]; next ← rcmi + SIZE[RCMap.Object[ref]]}; controlLink => { PutString["controlLink"L]; next ← rcmi + SIZE[RCMap.Object[controlLink]]}; oneRef => { PutString["oneRef[offset: "L]; PutDecimal[m.offset]; PutChar[']]; next ← rcmi + SIZE[RCMap.Object[oneRef]]}; simple => { PutString["simple[length: "L]; PutDecimal[m.length]; PutString[", offsets: ["L]; FOR i: NAT IN [0 .. m.length) DO IF m.refs[i] THEN BEGIN PutDecimal[i]; IF i + 1 # m.length THEN PutString[", "L]; END; ENDLOOP; PutString["]]"L]; next ← rcmi + SIZE[RCMap.Object[simple]]}; nonVariant => { PutString["nonVariant[nComponents: "L]; PutDecimal[m.nComponents]; PutString[", components: ["L]; FOR i: NAT IN [0..m.nComponents) DO IF i MOD 3 = 0 THEN Tab[8]; PrintField[m.components[i]]; IF i+1 # m.nComponents THEN PutString[", "L]; ENDLOOP; PutString["]]"L]; next ← rcmi + (SIZE[RCMap.Object[nonVariant]] + m.nComponents*SIZE[RCMap.RCField])}; variant => { PutString["variant[fdTag: "L]; PrintFD[m.fdTag]; PutString[", nVariants: "L]; PutDecimal[m.nVariants]; PutString[", variants: ["L]; FOR i: NAT IN [0..m.nVariants) DO PrintIndex[m.variants[i]]; IF i+1 # m.nVariants THEN PutString[", "L]; ENDLOOP; PutString["]]"L]; next ← rcmi + (SIZE[RCMap.Object[variant]] + m.nVariants*SIZE[RCMap.Index])}; array => { PutString["array[wordsPerElement: "L]; PutDecimal[m.wordsPerElement]; PutString[", nElements: "L]; PutDecimal[m.nElements]; PutString[", rcmi: "L]; PrintIndex[m.rcmi]; PutChar[']]; next ← rcmi + SIZE[RCMap.Object[array]]}; sequence => { PutString["sequence[wordsPerElement: "L]; PutDecimal[m.wordsPerElement]; PutString[", fdLength: "L]; PrintFD[m.fdLength]; PutString[", dataOffset: "L]; PutDecimal[m.dataOffset]; PutString[", rcmi: "L]; PrintIndex[m.rcmi]; PutChar[']]; next ← rcmi + SIZE[RCMap.Object[sequence]]}; ENDCASE => {PrintGarbage[]; EXIT}; ENDLOOP; PutString["\n\n"L]; END; PrintField: PROC [f: RCMap.RCField] = BEGIN PutString["[offset: "L]; PutDecimal[f.wordOffset]; PutString[", rcmi: "L]; PrintIndex[f.rcmi]; PutChar[']]; END; PrintFD: PROC [fd: RCMap.FieldDescriptor] = BEGIN PutChar['(]; PutDecimal[fd.wordOffset]; IF fd.bitFirst # 0 OR fd.bitCount # Environment.bitsPerWord THEN BEGIN PutChar[':]; PutDecimal[fd.bitFirst]; PutString[".."L]; PutDecimal[fd.bitFirst + fd.bitCount - 1]; END; PutChar[')]; END; PrintRefLits: PROC [rtHeader: RTBcd.RTBase] = BEGIN litList: LONG POINTER TO RTBcd.RefLitList = @rtHeader[rtHeader.refLitTable]; textBase: LONG POINTER = @rtHeader[rtHeader.litBase]; PutLitString: PROC [offset, length: CARDINAL] RETURNS [valid: BOOLEAN] = INLINE BEGIN text: LONG POINTER TO TEXT = textBase + offset; valid ← offset + length <= rtHeader.litLength AND length = SIZE[TEXT[text.length]]; IF valid THEN PrintText[text] ELSE PrintGarbage[]; END; PutString["Atoms and REF Literals"L]; PrintIndex[rtHeader.refLitTable]; PutString[":\n"L]; FOR i: NAT IN [0 .. litList.length) DO Tab[2]; PrintIndex[i]; PutString[" type: "L]; PrintIndex[litList[i].referentType]; PutString[", "L]; IF ~PutLitString[litList[i].offset, litList[i].length] THEN EXIT; ENDLOOP; PutString["\n\n"L]; END; PutIndex: PROC [index: UNSPECIFIED] = LOOPHOLE[PutDecimal]; PutType: PROC [s: TypeStrings.TypeString, i: CARDINAL] RETURNS [CARDINAL] = BEGIN PutCode: PROC [c: TypeStrings.Code] = BEGIN SELECT c FROM leftParen => PutChar['[]; definition => PutChar['&]; name => PutChar['.]; ref => PutChar['@]; list => PutChar['*]; ENDCASE => BEGIN repr: NAT = LOOPHOLE[c]; offset: NAT = repr - 200b; PutChar[IF offset < 'Z-'A+1 THEN 'A + offset ELSE 'a + (offset - ('Z-'A+1))]; END; END; Skip: PROC [nBytes: CARDINAL] = {THROUGH [1..nBytes] DO i ← i+1 ENDLOOP}; PutNum: PROC [nBytes: [1..2]] = BEGIN v: CARDINAL ← 0; THROUGH [1..nBytes] DO v ← 256*v + (s[i]-0c); i ← i+1; ENDLOOP; PutDecimal[v]; END; PutId: PROC = BEGIN n: NAT = s[i] - 0c; PutChar['']; i ← i + 1; THROUGH [1..n] DO PutChar[s[i]]; i ← i+1 ENDLOOP; PutChar['']; END; PutPaint: PROC = BEGIN hex: STRING = "abcdefghijklmnop"L; PutChar['{]; THROUGH [1..6] DO v: NAT = s[i] - 0c; PutChar[hex[v/16]]; PutChar[hex[v MOD 16]]; i ← i + 1; ENDLOOP; PutNum[2]; PutChar['}]; END; PutSubType: PROC = BEGIN c: TypeStrings.Code = LOOPHOLE[s[i]]; PutCode[c]; i ← i + 1; SELECT c FROM definition => {PutNum[1]; PutSubType[]}; name => {PutNum[1]}; leftParen => BEGIN WHILE LOOPHOLE[s[i], TypeStrings.Code] # rightParen DO PutId[]; PutSubType[]; ENDLOOP; PutChar[']]; i ← i+1; END; paint, opaque, union => {PutPaint[]}; subrange => BEGIN PutSubType[]; Skip[2]; PutNum[2]; PutChar[',]; Skip[2]; PutNum[2]; END; sequence => {PutId[]; PutSubType[]; PutSubType[]}; array, relativeRef, port, program, procedure, signal => {PutSubType[]; PutSubType[]}; -- binary list, ref, pointer, longPointer, descriptor, longDescriptor, process, error, readOnly, packed, ordered => PutSubType[]; -- unary ENDCASE => NULL; -- nullary END; PutChar['(]; PutDecimal[s.length]; PutChar[')]; PutChar[' ]; PutSubType[]; RETURN [i] END; PrintIndex: PROC [index: UNSPECIFIED] = {PutString["["L]; PutDecimal[index]; PutChar[']]}; PrintText: PROC [t: LONG POINTER TO TEXT] = BEGIN IF t = NIL THEN PutString["(nil)"L] ELSE FOR i: NAT IN [0 .. t.length) DO PutChar[t[i]] ENDLOOP; END; PrintGarbage: PROC = INLINE BEGIN PutString["? Looks like garbage ...\n"L]; END; Tab: PROC [n: CARDINAL] = {ListerDefs.Indent[n]}; END.