DIRECTORY AMTypes, Commander, Convert, IO, Interpreter, PLAOps, Rope, RTTypesPrivate; PLAOpsBitFormat: CEDAR PROGRAM IMPORTS PLAOps, AMTypes, Convert, Commander, Interpreter, IO, Rope EXPORTS PLAOps = BEGIN OPEN PLAOps; GetRecordRefFormatFromRope: PUBLIC PROC[rec: Rope.ROPE] RETURNS[ref: REF ANY, format: Format] = { recTV: AMTypes.TV _ GetRecordTVFromRope[rec]; -- Does NEW IF recTV=NIL THEN RETURN[NIL, NIL]; TRUSTED{ WITH recTV SELECT FROM tr: REF RTTypesPrivate.TypedVariableRec => WITH head: tr.head SELECT FROM reference => ref _ head.ref; ENDCASE => ERROR; ENDCASE => ERROR}; format _ GetFormatFromTV[recTV]}; GetRecordTVFromRope: PUBLIC PROC[rec: Rope.ROPE] RETURNS[recTV: AMTypes.TV] = { recOverTV: AMTypes.TV; noResult: BOOL; errorMsg: Rope.ROPE; [recOverTV, errorMsg, noResult] _ Interpreter.Evaluate[rec]; IF errorMsg#NIL THEN {comTool.PutF[" %g\n", IO.rope[errorMsg]]; RETURN[NIL]}; recTV _ AMTypes.New[AMTypes.UnderType[AMTypes.TVToType[recOverTV]]]; SELECT AMTypes.TypeClass[AMTypes.TVType[recTV]] FROM record, structure => NULL; ENDCASE => {comTool.PutF[" %g not a RECORD\n", IO.rope[rec]];RETURN[NIL]}}; GetFormatFromTV: PROC[recTV: AMTypes.TV] RETURNS[format: Format] = { format _ NEW[FormatRec[AMTypes.NComponents[AMTypes.TVType[recTV]]]]; FOR fldIndex: CARDINAL IN [0..format.size) DO fldrecTV: AMTypes.TV; fldTV: AMTypes.TV _ AMTypes.IndexToTV[recTV, fldIndex+1]; fldrecTV _ AMTypes.New[AMTypes.UnderType[AMTypes.TVType[fldTV]]]; format[fldIndex].format _ IF AMTypes.TypeClass[AMTypes.TVType[fldrecTV]]=record THEN GetFormatFromTV[fldrecTV] ELSE NIL; format[fldIndex].name _ AMTypes.IndexToName[AMTypes.TVType[recTV], fldIndex+1]; [format[fldIndex].firstBit, format[fldIndex].bitSize] _ TVToFieldBits[fldTV]; ENDLOOP; RETURN[format]}; TVToFieldBits: PROC[fieldTV: AMTypes.TV] RETURNS[firstBit, bitSize: CARDINAL]=TRUSTED { tvRef: REF RTTypesPrivate.TypedVariableRec _ NARROW[fieldTV]; WITH tv: tvRef SELECT FROM entire => RETURN[0,0]; embedded => { WITH fld: tv.fd SELECT FROM small => RETURN[16*fld.wordOffset+fld.field.bitFirst, fld.field.bitCount]; large => RETURN[16*fld.wordOffset, fld.size*16]; ENDCASE => ERROR }; constant => RETURN[0, tv.value.size*16]; ENDCASE => ERROR }; BitFormatRope: PUBLIC PROC[record: Rope.ROPE, flatten: BOOL_FALSE] RETURNS[listing: Rope.ROPE] = { rope: IO.STREAM _ IO.ROS[]; sum: CARDINAL _ 0; format: Format _ GetRecordRefFormatFromRope[record].format; IF format=NIL THEN RETURN[NIL]; IF flatten THEN format _ FlattenFormat[format]; rope.PutF["\nBitFormat: %g", IO.rope[record]]; rope.PutRope["\n Index First Size Name"]; FOR i: CARDINAL IN [0..format.size) DO sum _ sum + format[i].bitSize; rope.PutF["\n %2g %3g %3g %g", IO.card[i], IO.card[format[i].firstBit], IO.card[format[i].bitSize], IO.rope[format[i].name]] ENDLOOP; rope.PutF["\n ---\n BitTotal: %3g\n", IO.card[sum]]; listing _ IO.RopeFromROS[rope] }; BitFormatList: PUBLIC PROC[record: Rope.ROPE] RETURNS[list: LIST OF Rope.ROPE] = { format: Format _ GetRecordRefFormatFromRope[record].format; IF format=NIL THEN RETURN[NIL]; format _ FlattenFormat[format]; FOR i: CARDINAL DECREASING IN [0..format.size) DO list _ CONS[format[i].name, list] ENDLOOP }; FlattenFormat: PUBLIC PROC [format: Format, name: Rope.ROPE_NIL, first: CARDINAL_0] RETURNS[new: Format] = { index: CARDINAL _ 0; list, temp: LIST OF Field; list _ FlattenFormatList[format]; FOR temp _ list, temp.rest WHILE temp#NIL DO index _ index+1 ENDLOOP; new _ NEW[ FormatRec[index]]; index _ 0; FOR temp _ list, temp.rest WHILE temp#NIL DO new[index] _ temp.first; index _ index+1 ENDLOOP}; FlattenFormatList: PROC [format: Format, name: Rope.ROPE_NIL, first: CARDINAL_0, list: LIST OF Field_NIL] RETURNS[new: LIST OF Field] = { IF format=NIL THEN RETURN[list]; new _ list; FOR i: CARDINAL DECREASING IN [0..format.size) DO fname: Rope.ROPE _ IF name#NIL THEN Rope.Cat[name, ".", format[i].name] ELSE format[i].name; ffirst: CARDINAL _ first+format[i].firstBit; SELECT TRUE FROM format[i].bitSize=1 => new _ CONS[ [name: fname, format: NIL, firstBit: ffirst, bitSize: 1], new] ; format[i].format=NIL => { FOR j: CARDINAL DECREASING IN [0..format[i].bitSize) DO bitName: Rope.ROPE _ Rope.Cat[fname,".", Convert.RopeFromCard[j]]; new _ CONS[ [name: bitName, format: NIL, firstBit: j+ffirst, bitSize: 1], new] ENDLOOP }; ENDCASE => new _ FlattenFormatList[format[i].format, fname, ffirst, new]; ENDLOOP}; BitFormat: Commander.CommandProc = { rec: Rope.ROPE _ DefaultCMDLine[cmd.commandLine, NIL]; comTool _ cmd.out; IF rec=NIL THEN cmd.out.PutF [" %g\n",IO.rope[bitFormatDoc]] ELSE cmd.out.PutRope[BitFormatRope[rec, FALSE]]; comTool _ IO.noWhereStream }; BitFormatFlat: Commander.CommandProc = { rec: Rope.ROPE _ DefaultCMDLine[cmd.commandLine, NIL]; comTool _ cmd.out; IF rec=NIL THEN cmd.out.PutF [" %g\n",IO.rope[bitFormatFlatDoc]] ELSE cmd.out.PutRope[BitFormatRope[rec, TRUE]]; comTool _ IO.noWhereStream }; bitFormatDoc: Rope.ROPE = "'BitFormat Foo.SomeRecord' displays the size and position of the fields in Foo.SomeRecord"; bitFormatFlatDoc: Rope.ROPE = "'BitFormatFlat Foo.SomeRecord' displays the size and position of the bits in Foo.SomeRecord"; comTool: IO.STREAM _ IO.noWhereStream; Commander.Register[key:"BitFormat", proc: BitFormat, doc: bitFormatDoc]; Commander.Register[key:"BitFormatFlat", proc: BitFormatFlat, doc: bitFormatFlatDoc]; END. ®PLAOpsBitFormat.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last edited by Curry, August 11, 1985 5:07:19 pm PDT comTool _ IO.noWhereStream }; Ê#˜šÐbl™Jšœ Ïmœ1™