1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
|
-- with Ada.Text_IO; -- Debug.
with Ada.Unchecked_Deallocation,
Ada.Strings.Fixed,
Ada.Characters.Handling;
package body ARM_Database is
--
-- Ada reference manual formatter (ARM_Form).
--
-- This package contains the database to store items for non-normative
-- appendixes.
--
-- ---------------------------------------
-- Copyright 2000, 2004, 2005, 2006, 2009, 2011, 2012
-- AXE Consultants. All rights reserved.
-- P.O. Box 1512, Madison WI 53701
-- E-Mail: randy@rrsoftware.com
--
-- ARM_Form is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 3
-- as published by the Free Software Foundation.
--
-- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
-- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
-- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
-- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
-- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
-- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-- DAMAGES.
--
-- A copy of the GNU General Public License is available in the file
-- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
-- Otherwise, see <http://www.gnu.org/licenses/>.
--
-- If the GPLv3 license is not satisfactory for your needs, a commercial
-- use license is available for this tool. Contact Randy at AXE Consultants
-- for more information.
--
-- ---------------------------------------
--
-- Edit History:
--
-- 5/16/00 - RLB - Created package.
-- 8/28/00 - RLB - Added revision info to database.
-- 10/28/04 - RLB - Added Inserted_Normal_Number change kind.
-- 11/02/04 - RLB - Added Deleted_Inserted_Number change kind.
-- 12/06/04 - RLB - Added Revised_Inserted_Number change kind.
-- 12/14/04 - RLB - Made the hang item bigger.
-- 1/19/05 - RLB - Added Added_Version.
-- 10/17/05 - RLB - Fixed indexing of the Glossary.
-- 10/18/06 - RLB - Added No_Deleted_Paragraph_Messages to Report.
-- 11/30/09 - RLB - Made the hang item bigger again (to make room to
-- handle commands like @ChgAdded).
-- 10/18/11 - RLB - Changed to GPLv3 license.
-- 10/20/11 - RLB - Added Initial_Version parameter.
-- 3/19/12 - RLB - Added code to suppress indexing of deleted glossary items.
type String_Ptr is access String;
type Item is record
Next : Item_List;
Sort_Key : String(1 .. 50);
Hang : String(1 .. 75);
Hang_Len : Natural;
Text : String_Ptr;
Change_Kind : Paragraph_Change_Kind_Type;
Version : Character;
Initial_Version : Character;
end record;
procedure Free is new Ada.Unchecked_Deallocation (Item, Item_List);
procedure Free is new Ada.Unchecked_Deallocation (String, String_Ptr);
procedure Create (Database_Object : in out Database_Type) is
-- Initialize a database object.
begin
Database_Object.Is_Valid := True;
Database_Object.List := null;
Database_Object.Item_Count := 0;
end Create;
procedure Destroy (Database_Object : in out Database_Type) is
-- Destroy a database object, freeing any resources used.
Temp : Item_List;
begin
if not Database_Object.Is_Valid then
raise Not_Valid_Error;
end if;
while Database_Object.List /= null loop
Temp := Database_Object.List;
Database_Object.List := Temp.Next;
Free (Temp.Text);
Free (Temp);
end loop;
Database_Object.Is_Valid := False;
end Destroy;
procedure Insert (Database_Object : in out Database_Type;
Sort_Key : in String;
Hang_Item : in String;
Text : in String;
Change_Kind : in Paragraph_Change_Kind_Type := ARM_Database.None;
Version : in Character := '0';
Initial_Version : in Character := '0') is
-- Insert an item into the database object.
-- Sort_Key is the string on which this item will be sorted (if it
-- is sorted). Hang_Item is the item which hangs out for the item
-- in the report (if any). Text is the text for the item; the text
-- may include formatting codes. Change_Kind and Version are the
-- revision status for this item. Initial_Version is the version of
-- the initial text for this item.
Temp_Item : Item;
begin
if not Database_Object.Is_Valid then
raise Not_Valid_Error;
end if;
Ada.Strings.Fixed.Move (Target => Temp_Item.Sort_Key,
Source => Ada.Characters.Handling.To_Lower(Sort_Key),
Drop => Ada.Strings.Right,
Pad => ' ');
Ada.Strings.Fixed.Move (Target => Temp_Item.Hang,
Source => Hang_Item,
Drop => Ada.Strings.Error,
Pad => ' ');
Temp_Item.Hang_Len := Hang_Item'Length;
-- Note: If this second item doesn't fit, we error so we can make
-- the size larger.
Temp_Item.Text := new String'(Text);
Temp_Item.Change_Kind := Change_Kind;
Temp_Item.Version := Version;
Temp_Item.Initial_Version := Initial_Version;
Temp_Item.Next := Database_Object.List;
Database_Object.List := new Item'(Temp_Item);
Database_Object.Item_Count := Database_Object.Item_Count + 1;
end Insert;
--generic
-- with procedure Format_Text (Text : in String;
-- Text_Name : in String);
procedure Report (Database_Object : in out Database_Type;
In_Format : in Format_Type;
Sorted : in Boolean;
Added_Version : Character := '0';
No_Deleted_Paragraph_Messages : in Boolean := False) is
-- Output the items with the appropriate format to the
-- "Format_Text" routine. "Format_Text" allows all commands
-- for the full formatter. (Text_Name is an identifying name
-- for error messages). This is an added list for Added_Version
-- ('0' meaning it is not added); in that case, use normal numbers
-- for items with a version less than or equal to Added_Version.
-- (This is intended to be used to output the items to
-- appropriate Format and Output objects; but we can't do that
-- directly because that would make this unit recursive with
-- ARM_Format.
-- No paragraphs will be have deleted paragraph messages if
-- No_Deleted_Paragraph_Messages is True.
Temp : Item_List;
function Change_if_Needed (Item : in Item_List) return String is
begin
-- Note: In the report, we always decide inserted/not inserted
-- as determined by the initial version number, and not the
-- original class.
case Item.Change_Kind is
when None => return "";
when Inserted | Inserted_Normal_Number =>
if Item.Initial_Version <= Added_Version then
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[AddedNormal]}";
else
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[Added]}";
end if;
when Revised | Revised_Inserted_Number =>
if Item.Initial_Version <= Added_Version then
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[Revised]}";
else
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[RevisedAdded]}";
end if;
when Deleted | Deleted_Inserted_Number =>
if Item.Initial_Version <= Added_Version then
if No_Deleted_Paragraph_Messages then
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[DeletedNoDelMsg]}";
else
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[Deleted]}";
end if;
else
if No_Deleted_Paragraph_Messages then
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[DeletedAddedNoDelMsg]}";
else
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[DeletedAdded]}";
end if;
end if;
when Deleted_No_Delete_Message |
Deleted_Inserted_Number_No_Delete_Message =>
if Item.Initial_Version <= Added_Version then
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[DeletedNoDelMsg]}";
else
return "@ChgRef{Version=[" & Item.Version &
"],Kind=[DeletedAddedNoDelMsg]}";
end if;
end case;
end Change_if_Needed;
begin
if not Database_Object.Is_Valid then
raise Not_Valid_Error;
end if;
if Sorted then
declare
Items : array (1..Database_Object.Item_Count) of Item_List;
begin
-- Load the items:
Temp := Database_Object.List;
for I in Items'range loop
Items(I) := Temp;
Temp := Temp.Next;
end loop;
-- Sort the items array (use an insertion sort because it is
-- stable):
declare
Left : Natural; -- Left sorting stop
begin
for Right In Items'First+1 .. Items'Last loop -- Right sorting stop
Temp := Items(Right);
Left := Right - 1;
while Temp.Sort_Key <= Items(Left).Sort_Key loop -- Switch items
Items(Left + 1) := Items(Left);
Left := Left - 1;
exit when Left = 0;
end loop;
Items(Left + 1) := Temp;
end loop;
end;
-- Relink the items in the sorted order:
for I in Items'First .. Items'Last - 1 loop
Items(I).Next := Items(I+1);
end loop;
if Items'Length > 0 then
Items(Items'Last).Next := null;
Database_Object.List := Items(1);
else
Database_Object.List := null;
end if;
end;
end if;
case In_Format is
when Hanging_List =>
Format_Text ("@begin(description)" & Ascii.LF, "Prefix");
Temp := Database_Object.List;
while Temp /= null loop
--** Debug:
--Ada.Text_IO.Put_Line ("^^ " & Paragraph_Change_Kind_Type'Image(Temp.Change_Kind) &
-- " for " & Temp.Hang(1..Temp.Hang_Len) & " ref=" & Change_if_Needed (Temp));
--Ada.Text_IO.Put_Line (" " & Change_if_Needed (Temp) &
--Temp.Hang(1..Temp.Hang_Len) & "@\" &
--Temp.Text.all & Ascii.LF & Ascii.LF);
Format_Text (Change_if_Needed (Temp) &
Temp.Hang(1..Temp.Hang_Len) & "@\" &
Temp.Text.all & Ascii.LF & Ascii.LF, Temp.Sort_Key);
Temp := Temp.Next;
end loop;
Format_Text ("@end(description)" & Ascii.LF, "Suffix");
when Bullet_List =>
Format_Text ("@begin(itemize)" & Ascii.LF, "Prefix");
Temp := Database_Object.List;
while Temp /= null loop
Format_Text (Change_if_Needed (Temp) &
Temp.Text.all & Ascii.LF & Ascii.LF, Temp.Sort_Key);
Temp := Temp.Next;
end loop;
Format_Text ("@end(itemize)" & Ascii.LF, "Suffix");
when Normal_List =>
Format_Text ("@begin(intro)" & Ascii.LF, "Prefix");
Temp := Database_Object.List;
while Temp /= null loop
Format_Text (Change_if_Needed (Temp) &
Temp.Text.all & Ascii.LF & Ascii.LF, Temp.Sort_Key);
Temp := Temp.Next;
end loop;
Format_Text ("@end(intro)" & Ascii.LF, "Suffix");
when Normal_Indexed_List =>
Format_Text ("@begin(intro)" & Ascii.LF, "Prefix");
Temp := Database_Object.List;
while Temp /= null loop
case Temp.Change_Kind is
when None |
Inserted | Inserted_Normal_Number |
Revised | Revised_Inserted_Number =>
--** Debug:
--Ada.Text_IO.Put_Line("Format " & Change_if_Needed (Temp) &
-- "@defn{" & Ada.Strings.Fixed.Trim (Temp.Sort_Key, Ada.Strings.Right) & "}" & Ascii.LF &
-- Temp.Text.all);
-- Index this item.
Format_Text (Change_if_Needed (Temp) &
"@defn{" & Ada.Strings.Fixed.Trim (Temp.Sort_Key, Ada.Strings.Right) & "}" & Ascii.LF &
Temp.Text.all & Ascii.LF & Ascii.LF, Temp.Sort_Key);
when Deleted | Deleted_Inserted_Number |
Deleted_No_Delete_Message |
Deleted_Inserted_Number_No_Delete_Message =>
--** Debug:
--Ada.Text_IO.Put_Line("Format " & Change_if_Needed (Temp) & Ascii.LF &
-- Temp.Text.all);
-- Don't index deleted items.
Format_Text (Change_if_Needed (Temp) & Ascii.LF &
Temp.Text.all & Ascii.LF & Ascii.LF, Temp.Sort_Key);
end case;
Temp := Temp.Next;
end loop;
Format_Text ("@end(intro)" & Ascii.LF, "Suffix");
end case;
end Report;
end ARM_Database;
|