|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 35840 (0x8c00) Types: Ada Source Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Table_Formatter, seg_0046d0
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000 └─⟦cfc2e13cd⟧ »Space Info Vol 2« └─⟦this⟧
with Document; with Mapping; with Errors; with Table_Sort_Generic; package body Table_Formatter is package Ad renames Abstract_Document; package Ad_Specify renames Abstract_Document.Specify; Intercolumn_Spacing : constant := 2; subtype Column_Index is Natural range 1 .. Number_Of_Columns; type Width_List is array (Column_Index) of Natural; type A_String is access String; type An_Item (Subitem_Length : Natural; Explain_Length : Natural); type Access_Item is access An_Item; type An_Item (Subitem_Length : Natural; Explain_Length : Natural) is record Subitem : String (1 .. Subitem_Length); Explanation : String (1 .. Explain_Length); Links : Ada_Program.Element_List; Objects : Object.Iterator; Next : Access_Item; end record; type Item_List is array (Column_Index) of Access_Item; type Line; type Access_Line is access Line; type Access_Line_Array is array (Integer range <>) of Access_Line; Current_Line : Access_Line; type Line is record Values : Item_List; Width : Width_List := (others => 0); Next : Access_Line := Current_Line; end record; Current_Column : Column_Index := Column_Index'Last; In_Subitem : Boolean := False; Max_Width : Width_List := (others => 0); Headers : array (Column_Index) of A_String; Header_Column : Natural := 0; Column_Format : array (Column_Index) of Adjust; Integer_Valued : array (Column_Index) of Boolean; function Justification (A : Adjust) return Abstract_Document.Position is begin case A is when Left => return Abstract_Document.Left; when Right => return Abstract_Document.Right; when Centered => return Abstract_Document.Center; end case; end Justification; function Max (Left, Right : Integer) return Integer is begin if Left > Right then return Left; else return Right; end if; end Max; procedure Insert (S : String; Explanation : String := ""; Element_Linkage : Ada.Element_List := Ada.Nil_List; Object_Linkage : Object.Iterator := Object.Nil) is -- Put the String into the current row/column, appending it if -- there is already something there. Cell : Access_Item renames Current_Line.Values (Current_Column); Width : Natural renames Current_Line.Width (Current_Column); Max : Natural renames Max_Width (Current_Column); Slid : constant String (1 .. S'Length) := S; Explain_Text : constant String (1 .. Explanation'Length) := Explanation; Li : Long_Integer; begin if Integer_Valued (Current_Column) then Li := Long_Integer'Value (S); end if; if Cell = null then Width := S'Length; else Width := Width + Subitem_Separator'Length + S'Length; end if; if Width > Max then Max := Width; end if; Cell := new An_Item'(Slid'Length, Explain_Text'Length, Slid, Explain_Text, Element_Linkage, Object_Linkage, Cell); end Insert; procedure Item (S : String; Linkage : Ada.Element := Ada.Nil_Element; Linkage_List : Ada.Element_List := Ada.Nil_List; Object_Linkage : Object.Handle := Object.Nil; Object_Linkage_List : Object.Iterator := Object.Create; Explanation : String := "") is The_Object : Object.Handle := Object_Linkage; Objects : Object.Iterator := Object_Linkage_List; Elements : Ada.Element_List := Linkage_List; Dup : Boolean; -- Begin a new cell, put S there, and mark the cell closed by -- setting In_Subitem to be false. begin if Current_Column = Column_Index'Last then Current_Line := new Line; Current_Column := Column_Index'First; else Current_Column := Current_Column + 1; end if; if not Object.Is_Nil (The_Object) then Object.Add (Objects, The_Object, Dup); end if; if not Ada.Is_Nil (Linkage) then Ada.Append (Linkage, Elements); end if; Insert (S, Explanation, Elements, Objects); In_Subitem := False; end Item; procedure Header (S : String; Format : Adjust := Left; Is_Integer : Boolean := False) is -- Set Header and Column Format begin Header_Column := Header_Column + 1; Column_Format (Header_Column) := Format; Integer_Valued (Header_Column) := Is_Integer; Headers (Header_Column) := new String'(S); Max_Width (Header_Column) := S'Length; end Header; procedure Subitem (S : String) is -- If the current cell is open, add S to it. Otherwise start a new -- cell, but leave it open. begin if In_Subitem then Insert (S => S); else Item (S => S); end if; In_Subitem := True; end Subitem; procedure Last_Subitem is -- If the current cell is open, close it. If the current cell is -- closed, we have an item that consists of zero subitems. Give it -- a visible representation. begin if In_Subitem then In_Subitem := False; else Item ("(none)"); end if; end Last_Subitem; function Image (P : Access_Item) return String is -- P must be non-null begin if P.Next = null then return P.Subitem; end if; return Image (P.Next) & Subitem_Separator & P.Subitem; -- Recall that subitem lists are stored in reverse order end Image; function Buffer_Length return Positive is -- There may be reason for 1 or 2 additional spaces; 32 is overkill. Result : Positive := 32 + Intercolumn_Spacing * Number_Of_Columns; begin for I in Max_Width'Range loop Result := Result + Max_Width (I); end loop; return Result; end Buffer_Length; procedure Display (On_File : Io.File_Type) is -- Dump the data structure we have been building by traversing it -- recursively. Note that all of the lists are stored in reverse -- order so that they were easy to build. Buffer : String (1 .. Buffer_Length); Last_Char : Natural := 0; -- Document : Ad.Handle; Status : Errors.Condition; procedure Put (S : String) is First_Char : constant Natural := Last_Char + 1; begin Last_Char := Last_Char + S'Length; Buffer (First_Char .. Last_Char) := S; end Put; procedure New_Line is begin Io.Put_Line (On_File, Buffer (1 .. Last_Char)); Last_Char := 0; end New_Line; procedure Replicate (C : Character; N : Natural) is -- Output N copies of C First_Char : constant Natural := Last_Char + 1; begin Last_Char := Last_Char + N; -- We assume small values of N for I in First_Char .. Last_Char loop Buffer (I) := C; end loop; end Replicate; procedure Display (P : Access_Item) is begin if P /= null then Put (Image (P)); end if; end Display; procedure Display_Headers is Excess : Width_List; begin for J in Column_Index loop Excess (J) := Max (Headers (J).all'Length, Max_Width (J)) - Headers (J).all'Length; end loop; Replicate (' ', Excess (1) / 2); for J in Column_Index loop Put (Headers (J).all); if J /= Column_Index'Last then Replicate (' ', (Excess (J) + 1) / 2 + Excess (J + 1) / 2 + Intercolumn_Spacing); end if; end loop; New_Line; end Display_Headers; procedure Display_Adjusted (L : Line) is Inner_Excess, Outer_Excess : Natural; begin for J in Column_Index loop Inner_Excess := Max_Width (J) - L.Width (J); Outer_Excess := Max (Headers (J).all'Length, Max_Width (J)) - Max_Width (J); case Column_Format (J) is when Left => Replicate (' ', Outer_Excess / 2); Display (L.Values (J)); if J /= Column_Index'Last then Replicate (' ', (Outer_Excess + 1) / 2 + Inner_Excess + Intercolumn_Spacing); end if; when Right => Replicate (' ', Outer_Excess / 2 + Inner_Excess); Display (L.Values (J)); if J /= Column_Index'Last then Replicate (' ', (Outer_Excess + 1) / 2 + Intercolumn_Spacing); end if; when Centered => Replicate (' ', (Inner_Excess + Outer_Excess) / 2); Display (L.Values (J)); if J /= Column_Index'Last then Replicate (' ', (Inner_Excess + Outer_Excess + 1) / 2 + Intercolumn_Spacing); end if; end case; end loop; New_Line; end Display_Adjusted; procedure Display (L : Access_Line) is begin if L = null then -- Center the header Display_Headers; -- A separator line for J in Column_Index loop Replicate ('=', Max (Headers (J).all'Length, Max_Width (J))); if J /= Column_Index'Last then Replicate (' ', Intercolumn_Spacing); end if; end loop; New_Line; else -- Display the head of the table Display (L.Next); -- Display the final line Display_Adjusted (L.all); end if; end Display; begin Display (Current_Line); end Display; function Gen_Linkage (From : Access_Item; In_Document : Abstract_Document.Handle) return Ad.Linkage_Info is Local_List : Ada.Element_List := From.Links; Object_Reference : Document.Element := Document.Nil_Element; Object_References : Document.Element_List := Document.Nil_List; Status : Errors.Condition; begin Object.Reset (From.Objects); while not Object.Done (From.Objects) loop Document.Resolve (Object_Reference, Object.Value (From.Objects), Status => Status); Document.Add (Object_Reference, Object_References); Object.Next (From.Objects); end loop; Document.Reset (Object_References); return Ad_Specify.Gen_Linkage (In_Document, Explain => From.Explanation, Definition => Mapping.Create (From.Links, Object_References)); end Gen_Linkage; procedure Display (In_Document : in out Abstract_Document.Handle; Table_Title : String) is -- Dump the data structure we have been building by traversing it -- recursively. Note that all of the lists are stored in reverse -- order so that they were easy to build. Status : Errors.Condition; procedure Display (P : Access_Item) is begin if P /= null then Ad_Specify.Table_Entry (In_Document, Image (P), Gen_Linkage (P, In_Document)); end if; end Display; procedure Display_Headers is begin for J in Column_Index loop Ad_Specify.Column_Information (In_Document, (Headers (J).all), Justification (Column_Format (J))); end loop; end Display_Headers; procedure Display (L : Access_Line) is begin if L = null then Display_Headers; else -- Display the head of the table Display (L.Next); for J in Column_Index loop Display (L.Values (J)); end loop; end if; end Display; begin if Current_Line /= null then -- create and initialize table. Ad_Specify.Start_Table (In_Document, Table_Title, ""); Display (Current_Line); Ad_Specify.End_Table (In_Document); end if; end Display; function Normalize return Natural is -- Traverse the current structure looking for cells that consist -- of more than one subitem, and concatentate the subitems into -- a single item. -- Return the number of rows in the table. Result : Natural := 0; Line : Access_Line := Current_Line; P : Access_Item; begin while Line /= null loop for J in Line.Values'Range loop P := Line.Values (J); if P = null then Line.Values (J) := new An_Item'(0, 0, "", "", Ada_Program.Nil_List, Object.Create, null); elsif P.Next /= null then Line.Values (J) := new An_Item'(Line.Width (J), 0, Image (P), "", Ada_Program.Nil_List, Object.Create, null); end if; end loop; Line := Line.Next; Result := Result + 1; end loop; return Result; end Normalize; procedure Fill (Table : out Access_Line_Array) is -- Transfers the linked list pointed to by Current_Line into -- the sequential table. P : Access_Line; begin P := Current_Line; for J in reverse Table'Range loop Table (J) := P; P := P.Next; end loop; end Fill; procedure Empty (Table : Access_Line_Array) is -- rebuilds the Current_Line link list from the sequential table, -- preserving the convention that lists are stored backwards. begin if Table'Length = 0 then Current_Line := null; return; end if; Table (Table'First).Next := null; for J in Table'First + 1 .. Table'Last loop Table (J).Next := Table (J - 1); end loop; Current_Line := Table (Table'Last); end Empty; function Abs_Field (On_Field : Integer) return Integer is begin if On_Field > 0 then return On_Field; elsif On_Field < 0 then return -On_Field; else return 1; end if; end Abs_Field; procedure Sort (On_Field : Integer := 1) is Table : Access_Line_Array (1 .. Normalize); Dont_Care : Integer := 0; Real_Field : Positive := Abs_Field (On_Field); function "<" (Left, Right : Access_Line) return Boolean is begin if Real_Field = On_Field then if Integer_Valued (On_Field) then return Long_Integer'Value (Left.Values (On_Field).Subitem) < Long_Integer'Value (Right.Values (On_Field).Subitem); else return Left.Values (On_Field).Subitem < Right.Values (On_Field).Subitem; end if; else if Integer_Valued (On_Field) then return Long_Integer'Value (Left.Values (Real_Field).Subitem) > Long_Integer'Value (Right.Values (Real_Field).Subitem); else return Left.Values (Real_Field).Subitem > Right.Values (Real_Field).Subitem; end if; end if; end "<"; procedure Table_Sort is new Table_Sort_Generic (Element => Access_Line, Index => Integer, Element_Array => Access_Line_Array); begin Fill (Table); Table_Sort (Table); Empty (Table); end Sort; procedure Sort (On_Fields : Field_List) is Table : Access_Line_Array (1 .. Normalize); Dont_Care : Integer := 0; Real_Fields : Field_List (On_Fields'Range); function "<" (Left, Right : Access_Line) return Boolean is begin for J in Real_Fields'Range loop declare Field : Integer := Real_Fields (J); Increasing : Boolean := Field = On_Fields (J); Left_Value : String renames Left.Values (Field).Subitem; Right_Value : String renames Right.Values (Field).Subitem; Left_Integer : Long_Integer; Right_Integer : Long_Integer; begin if Integer_Valued (Field) then Left_Integer := Long_Integer'Value (Left_Value); Right_Integer := Long_Integer'Value (Right_Value); if Increasing then if Left_Integer < Right_Integer then return True; end if; if Left_Integer > Right_Integer then return False; end if; else if Left_Integer > Right_Integer then return True; end if; if Left_Integer < Right_Integer then return False; end if; end if; else if Increasing then if Left_Value < Right_Value then return True; end if; if Left_Value > Right_Value then return False; end if; else if Left_Value > Right_Value then return True; end if; if Left_Value < Right_Value then return False; end if; end if; end if; end; end loop; return False; end "<"; procedure Table_Sort is new Table_Sort_Generic (Element => Access_Line, Index => Integer, Element_Array => Access_Line_Array); begin for I in On_Fields'Range loop Real_Fields (I) := Abs_Field (On_Fields (I)); end loop; Fill (Table); Table_Sort (Table); Empty (Table); end Sort; begin -- Default to empty left justified headers. for J in Column_Index loop Column_Format (J) := Left; Headers (J) := new String'(""); end loop; end Table_Formatter;
nblk1=22 nid=0 hdr6=44 [0x00] rec0=1f rec1=00 rec2=01 rec3=004 [0x01] rec0=00 rec1=00 rec2=21 rec3=02a [0x02] rec0=1c rec1=00 rec2=22 rec3=01e [0x03] rec0=01 rec1=00 rec2=02 rec3=01e [0x04] rec0=17 rec1=00 rec2=03 rec3=08a [0x05] rec0=03 rec1=00 rec2=20 rec3=008 [0x06] rec0=1c rec1=00 rec2=04 rec3=014 [0x07] rec0=00 rec1=00 rec2=1f rec3=006 [0x08] rec0=1f rec1=00 rec2=05 rec3=022 [0x09] rec0=00 rec1=00 rec2=1e rec3=010 [0x0a] rec0=1f rec1=00 rec2=06 rec3=01e [0x0b] rec0=1f rec1=00 rec2=07 rec3=016 [0x0c] rec0=1f rec1=00 rec2=08 rec3=05c [0x0d] rec0=01 rec1=00 rec2=1d rec3=002 [0x0e] rec0=20 rec1=00 rec2=09 rec3=03c [0x0f] rec0=14 rec1=00 rec2=0a rec3=072 [0x10] rec0=1b rec1=00 rec2=0b rec3=028 [0x11] rec0=1f rec1=00 rec2=0c rec3=038 [0x12] rec0=00 rec1=00 rec2=1c rec3=022 [0x13] rec0=1c rec1=00 rec2=0d rec3=00a [0x14] rec0=1f rec1=00 rec2=0e rec3=024 [0x15] rec0=1b rec1=00 rec2=0f rec3=092 [0x16] rec0=01 rec1=00 rec2=1b rec3=016 [0x17] rec0=1d rec1=00 rec2=10 rec3=090 [0x18] rec0=01 rec1=00 rec2=1a rec3=00c [0x19] rec0=23 rec1=00 rec2=11 rec3=010 [0x1a] rec0=00 rec1=00 rec2=19 rec3=00e [0x1b] rec0=16 rec1=00 rec2=12 rec3=036 [0x1c] rec0=19 rec1=00 rec2=13 rec3=044 [0x1d] rec0=00 rec1=00 rec2=18 rec3=012 [0x1e] rec0=18 rec1=00 rec2=17 rec3=038 [0x1f] rec0=01 rec1=00 rec2=14 rec3=008 [0x20] rec0=1b rec1=00 rec2=15 rec3=06a [0x21] rec0=14 rec1=00 rec2=16 rec3=001 tail 0x217002a24815c6719afd3 0x42a00088462061e03