1-- CXAA010.A 2-- 3-- Grant of Unlimited Rights 4-- 5-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, 6-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained 7-- unlimited rights in the software and documentation contained herein. 8-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making 9-- this public release, the Government intends to confer upon all 10-- recipients unlimited rights equal to those held by the Government. 11-- These rights include rights to use, duplicate, release or disclose the 12-- released technical data and computer software in whole or in part, in 13-- any manner and for any purpose whatsoever, and to have or permit others 14-- to do so. 15-- 16-- DISCLAIMER 17-- 18-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR 19-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED 20-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE 21-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE 22-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A 23-- PARTICULAR PURPOSE OF SAID MATERIAL. 24--* 25-- 26-- OBJECTIVE: 27-- Check that the operations defined in package Ada.Text_IO.Decimal_IO 28-- are available, and that they function correctly when used for the 29-- input/output of Decimal types. 30-- 31-- TEST DESCRIPTION: 32-- This test demonstrates the Put and Get procedures found in the 33-- generic package Ada.Text_IO.Decimal_IO. Both Put and Get are 34-- overloaded to allow placement or extraction of decimal values 35-- to/from a text file or a string. This test demonstrates both forms 36-- of each subprogram. 37-- The test defines an array of records containing decimal value 38-- and string component fields. All component values are placed in a 39-- Text_IO file, with the decimal values being placed there using the 40-- version of Put defined for files, and using user-specified formatting 41-- parameters. The data is later extracted from the file, with the 42-- decimal values being removed using the version of Get defined for 43-- files. Decimal values are then written to strings, using the 44-- appropriate Put procedure. Finally, extraction of the decimal data 45-- from the strings completes the evaluation of the Decimal_IO package 46-- subprograms. 47-- The reconstructed data is verified at the end of the test against the 48-- data originally written to the file. 49-- 50-- APPLICABILITY CRITERIA: 51-- Applicable to all implementations capable of supporting external 52-- Text_IO files and Decimal Fixed Point Types 53-- 54-- All implementations must attempt to compile this test. 55-- 56-- For implementations validating against Information Systems Annex (F): 57-- this test must execute and report PASSED. 58-- 59-- For implementations not validating against Annex F: 60-- this test may report compile time errors at one or more points 61-- indicated by "-- ANX-F RQMT", in which case it may be graded as inapplicable. 62-- Otherwise, the test must execute and report PASSED. 63-- 64-- 65-- CHANGE HISTORY: 66-- 06 Dec 94 SAIC ACVC 2.0 67-- 20 Feb 95 SAIC Modified test to allow for Use_Error/Name_Error 68-- generation by an implementation not supporting 69-- Text_IO operations. 70-- 14 Nov 95 SAIC Corrected string indexing for ACVC 2.0.1. 71-- 27 Feb 97 PWB.CTA Allowed for non-support of some IO operations 72-- 16 FEB 98 EDS Modified documentation. 73--! 74 75with Ada.Text_IO; 76with Report; 77 78procedure CXAA010 is 79 use Ada.Text_IO; 80 Tax_Roll : Ada.Text_IO.File_Type; 81 Tax_Roll_Name : constant String := 82 Report.Legal_File_Name ( Nam => "CXAA010" ); 83 Incomplete : exception; 84begin 85 86 Report.Test ("CXAA010", "Check that the operations defined in package " & 87 "Ada.Text_IO.Decimal_IO are available, and " & 88 "that they function correctly when used for " & 89 "the input/output of Decimal types"); 90 91 Test_for_Decimal_IO_Support: 92 begin 93 94 -- An implementation that does not support Text_IO creation or naming 95 -- of external files in a particular environment will raise Use_Error 96 -- or Name_Error on a call to Text_IO Create. This block statement 97 -- encloses a call to Create, which should produce an exception in a 98 -- non-supportive environment. Either of these exceptions will be 99 -- handled to produce a Not_Applicable result. 100 101 Ada.Text_IO.Create (Tax_Roll, Ada.Text_IO.Out_File, Tax_Roll_Name); 102 103 exception 104 105 when Ada.Text_IO.Use_Error | Ada.Text_IO.Name_Error => 106 Report.Not_Applicable 107 ( "Files not supported - Create as Out_File for Text_IO" ); 108 raise Incomplete; 109 110 end Test_for_Decimal_IO_Support; 111 112 Taxation: 113 declare 114 115 ID_Length : constant := 5; 116 Price_String_Length : constant := 5; 117 Value_String_Length : constant := 6; 118 Total_String_Length : constant := 20; 119 Spacer : constant String := " "; -- Two blanks. 120 121 type Price_Type is delta 0.1 digits 4; -- ANX-F RQMT 122 type Value_Type is delta 0.01 digits 5; -- ANX-F RQMT 123 124 type Property_Type is 125 record 126 Parcel_ID : String (1..ID_Length); 127 Purchase_Price : Price_Type; 128 Assessed_Value : Value_Type; 129 end record; 130 131 type City_Block_Type is array (1..4) of Property_Type; 132 133 subtype Tax_Bill_Type is string (1..Total_String_Length); 134 type Tax_Bill_Array_Type is array (1..4) of Tax_Bill_Type; 135 136 Neighborhood : City_Block_Type := 137 (("X9254", 123.0, 135.00), ("X3569", 345.0, 140.50), 138 ("X3434", 234.0, 179.50), ("X8838", 456.0, 158.00)); 139 140 Neighborhood_Taxes : Tax_Bill_Array_Type; 141 142 package Price_IO is new Ada.Text_IO.Decimal_IO (Price_Type); 143 package Value_IO is new Ada.Text_IO.Decimal_IO (Value_Type); 144 145 begin -- Taxation 146 147 Assessors_Office: 148 begin 149 150 for Parcel in City_Block_Type'Range loop 151 -- Note: All data in the file will be separated with a 152 -- two-character blank spacer. 153 Ada.Text_IO.Put(Tax_Roll, Neighborhood(Parcel).Parcel_ID); 154 Ada.Text_IO.Put(Tax_Roll, Spacer); 155 156 -- Use Decimal_IO.Put with non-default format parameters to 157 -- place decimal data into file. 158 Price_IO.Put (Tax_Roll, Neighborhood(Parcel).Purchase_Price, 159 Fore => 3, Aft =>1, Exp => 0); 160 Ada.Text_IO.Put(Tax_Roll, Spacer); 161 162 Value_IO.Put (Tax_Roll, Neighborhood(Parcel).Assessed_Value, 163 Fore => 3, Aft =>2, Exp => 0); 164 Ada.Text_IO.New_Line(Tax_Roll); 165 end loop; 166 167 Ada.Text_IO.Close (Tax_Roll); 168 169 exception 170 when others => 171 Report.Failed ("Exception raised in Assessor's Office"); 172 end Assessors_Office; 173 174 175 Twice_A_Year: 176 declare 177 178 procedure Collect_Tax(Index : in Integer; 179 Tax_Array : in out Tax_Bill_Array_Type) is 180 ID : String (1..ID_Length); 181 Price : Price_Type := 0.0; 182 Value : Value_Type := 0.00; 183 Price_String : String (1..Price_String_Length); 184 Value_String : String (1..Value_String_Length); 185 begin 186 187 -- Extract information from the Text_IO file; one string, two 188 -- decimal values. 189 -- Note that the Spacers that were put in the file above are 190 -- not individually read here, due to the fact that each call 191 -- to Decimal_IO.Get below uses a zero in the Width field, 192 -- which allows each Get procedure to skip these leading blanks 193 -- prior to extracting the numeric value. 194 195 Ada.Text_IO.Get (Tax_Roll, ID); 196 197 -- A zero value of Width is provided, so the following 198 -- two calls to Decimal_IO.Get will skip the leading blanks, 199 -- (from the Spacer variable above), then read the numeric 200 -- literals. 201 202 Price_IO.Get (Tax_Roll, Price, 0); 203 Value_IO.Get (Tax_Roll, Value, 0); 204 Ada.Text_IO.Skip_Line (Tax_Roll); 205 206 -- Convert the values read from the file into string format, 207 -- using user-specified format parameters. 208 -- Format of the Price_String should be "nnn.n" 209 -- Format of the Value_String should be "nnn.nn" 210 211 Price_IO.Put (To => Price_String, 212 Item => Price, 213 Aft => 1); 214 Value_IO.Put (Value_String, Value, 2); 215 216 -- Construct a string of length 20 that contains the Parcel_ID, 217 -- the Purchase_Price, and the Assessed_Value, separated by 218 -- two-character blank data spacers. Store this string 219 -- into the string array out parameter. 220 -- Format of each Tax_Array element should be 221 -- "Xnnnn nnn.n nnn.nn" (with an 'n' signifying a digit). 222 223 Tax_Array(Index) := ID & Spacer & 224 Price_String & Spacer & 225 Value_String; 226 exception 227 when Data_Error => 228 Report.Failed("Data Error raised during the extraction " & 229 "of decimal data from the file"); 230 when others => 231 Report.Failed("Exception in Collect_Tax procedure"); 232 end Collect_Tax; 233 234 235 begin -- Twice_A_Year 236 237 Ada.Text_IO.Open (Tax_Roll, Ada.Text_IO.In_File, Tax_Roll_Name); 238 239 -- Determine property tax bills for the entire neighborhood from 240 -- the information that is stored in the file. Store information 241 -- in the Neighborhood_Taxes string array. 242 243 for Parcel in City_Block_Type'Range loop 244 Collect_Tax (Parcel, Neighborhood_Taxes); 245 end loop; 246 247 exception 248 when others => 249 Report.Failed ("Exception in Twice_A_Year Block"); 250 end Twice_A_Year; 251 252 -- Use Decimal_IO Get procedure to extract information from a string. 253 -- Verify data against original values. 254 Validation_Block: 255 declare 256 TC_ID : String (1..ID_Length); -- 1..5 257 TC_Price : Price_Type; 258 TC_Value : Value_Type; 259 Length : Positive; 260 Front, 261 Rear : Integer := 0; 262 begin 263 264 for Parcel in City_Block_Type'Range loop 265 -- Extract values from the strings of the string array. 266 -- Each element of the string array is 20 characters long; the 267 -- first five characters are the Parcel_ID, two blank characters 268 -- separate data, the next five characters contain the Price 269 -- decimal value, two blank characters separate data, the last 270 -- six characters contain the Value decimal value. 271 -- Extract each of these components in turn. 272 273 Front := 1; -- 1 274 Rear := ID_Length; -- 5 275 TC_ID := Neighborhood_Taxes(Parcel)(Front..Rear); 276 277 -- Extract the decimal value from the next slice of the string. 278 Front := Rear + 3; -- 8 279 Rear := Front + Price_String_Length - 1; -- 12 280 Price_IO.Get (Neighborhood_Taxes(Parcel)(Front..Rear), 281 Item => TC_Price, 282 Last => Length); 283 284 -- Extract next decimal value from slice of string, based on 285 -- length of preceding strings read from string array element. 286 Front := Rear + 3; -- 15 287 Rear := Total_String_Length; -- 20 288 Value_IO.Get (Neighborhood_Taxes(Parcel)(Front..Rear), 289 Item => TC_Value, 290 Last => Length); 291 292 if TC_ID /= Neighborhood(Parcel).Parcel_ID or 293 TC_Price /= Neighborhood(Parcel).Purchase_Price or 294 TC_Value /= Neighborhood(Parcel).Assessed_Value 295 then 296 Report.Failed ("Incorrect data validation"); 297 end if; 298 299 end loop; 300 301 exception 302 when others => Report.Failed ("Exception in Validation Block"); 303 end Validation_Block; 304 305 -- Check that the Text_IO file is open, then delete. 306 307 if not Ada.Text_IO.Is_Open (Tax_Roll) then 308 Report.Failed ("File not left open after processing"); 309 Ada.Text_IO.Open (Tax_Roll, Ada.Text_IO.Out_File, Tax_Roll_Name); 310 end if; 311 312 Ada.Text_IO.Delete (Tax_Roll); 313 314 exception 315 when others => 316 Report.Failed ("Exception in Taxation block"); 317 -- Check that the Text_IO file is open, then delete. 318 if not Ada.Text_IO.Is_Open (Tax_Roll) then 319 Ada.Text_IO.Open (Tax_Roll, 320 Ada.Text_IO.Out_File, 321 Tax_Roll_Name); 322 end if; 323 Ada.Text_IO.Delete (Tax_Roll); 324 end Taxation; 325 326 Report.Result; 327 328exception 329 when Incomplete => 330 Report.Result; 331 when others => 332 Report.Failed ( "Unexpected exception" ); 333 Report.Result; 334 335end CXAA010; 336