1-- CXA4014.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 subprograms defined in package Ada.Strings.Wide_Fixed 28-- are available, and that they produce correct results. Specifically, 29-- check the subprograms Find_Token, Head, Index, Index_Non_Blank, Move, 30-- Overwrite, and Replace_Slice, Tail, and Translate. 31-- Use the access-to-subprogram mapping version of Translate (function 32-- and procedure). 33-- 34-- TEST DESCRIPTION: 35-- This test demonstrates how certain wide fixed string operations could 36-- be used in wide string information processing. A procedure is defined 37-- that will extract portions of a 50 character string that correspond to 38-- certain data items (i.e., name, address, state, zip code). These 39-- parsed items will then be added to the appropriate fields of data 40-- base elements. These data base elements are then compared for 41-- accuracy against a similar set of predefined data base 42-- elements. 43-- A variety of wide fixed string processing subprograms are used in this 44-- test. Each parsing operation attempts to use a different combination 45-- of the available subprograms to accomplish the same goal, therefore 46-- continuity of approach to wide string parsing is not seen in this 47-- test. 48-- However, a wide variety of possible approaches are demonstrated, while 49-- exercising a large number of the total predefined subprograms of 50-- package Ada.Strings.Wide_Fixed. 51-- 52-- 53-- CHANGE HISTORY: 54-- 06 Dec 94 SAIC ACVC 2.0 55-- 02 Nov 95 SAIC Update and repair for ACVC 2.0.1. 56-- 57--! 58 59package CXA40140 is 60 61 UnderScore : Wide_Character := '_'; 62 Blank : Wide_Character := ' '; 63 64 -- Function providing a mapping to a blank Wide_Character. 65 function US_to_Blank_Map (From : Wide_Character) return Wide_Character; 66 67end CXA40140; 68 69package body CXA40140 is 70 71 function US_to_Blank_Map (From : Wide_Character) return Wide_Character is 72 begin 73 if From = UnderScore then 74 return Blank; 75 else 76 return From; 77 end if; 78 end US_to_Blank_Map; 79 80end CXA40140; 81 82 83with CXA40140; 84with Ada.Strings.Wide_Fixed; 85with Ada.Strings.Wide_Maps; 86with Report; 87 88procedure CXA4014 is 89 use CXA40140; 90begin 91 92 Report.Test ("CXA4014", "Check that the subprograms defined in package " & 93 "Ada.Strings.Wide_Fixed are available, and that " & 94 "they produce correct results"); 95 96 Test_Block: 97 declare 98 99 Number_Of_Info_Strings : constant Natural := 3; 100 DB_Size : constant Natural := Number_Of_Info_Strings; 101 Count : Natural := 0; 102 Finished_Processing : Boolean := False; 103 Blank_Wide_String : constant Wide_String := " "; 104 105 subtype Info_Wide_String_Type is Wide_String (1..50); 106 type Info_Wide_String_Storage_Type is 107 array (1..Number_Of_Info_Strings) of Info_Wide_String_Type; 108 109 110 subtype Name_Type is Wide_String (1..10); 111 subtype Street_Number_Type is Wide_String (1..5); 112 subtype Street_Name_Type is Wide_String (1..10); 113 subtype City_Type is Wide_String (1..10); 114 subtype State_Type is Wide_String (1..2); 115 subtype Zip_Code_Type is Wide_String (1..5); 116 117 type Data_Base_Element_Type is 118 record 119 Name : Name_Type := (others => ' '); 120 Street_Number : Street_Number_Type := (others => ' '); 121 Street_Name : Street_Name_Type := (others => ' '); 122 City : City_Type := (others => ' '); 123 State : State_Type := (others => ' '); 124 Zip_Code : Zip_Code_Type := (others => ' '); 125 end record; 126 127 type Data_Base_Type is array (1..DB_Size) of Data_Base_Element_Type; 128 129 Data_Base : Data_Base_Type; 130 131 --- 132 133 Info_String_1 : Info_Wide_String_Type := 134 "Joe_Jones 123 Sixth_St San_Diego CA 98765"; 135 136 Info_String_2 : Info_Wide_String_Type := 137 "Sam_Smith 56789 S._Seventh Carlsbad CA 92177"; 138 139 Info_String_3 : Info_Wide_String_Type := 140 "Jane_Brown 1219 Info_Lane Tuscon AZ 85643"; 141 142 143 Info_Strings : Info_Wide_String_Storage_Type := 144 (1 => Info_String_1, 145 2 => Info_String_2, 146 3 => Info_String_3); 147 148 149 150 TC_DB_Element_1 : Data_Base_Element_Type := 151 ("Joe Jones ", "123 ", "Sixth St ", "San Diego ", "CA", "98765"); 152 153 TC_DB_Element_2 : Data_Base_Element_Type := 154 ("Sam Smith ", "56789", "S. Seventh", "Carlsbad ", "CA", "92177"); 155 156 TC_DB_Element_3 : Data_Base_Element_Type := 157 ("Jane Brown", "1219 ", "Info Lane ", "Tuscon ", "AZ", "85643"); 158 159 TC_Data_Base : Data_Base_Type := (TC_DB_Element_1, 160 TC_DB_Element_2, 161 TC_DB_Element_3); 162 163 --- 164 165 166 procedure Store_Information 167 (Info_String : in Info_Wide_String_Type; 168 DB_Record : in out Data_Base_Element_Type) is 169 170 package AS renames Ada.Strings; 171 use type AS.Wide_Maps.Wide_Character_Set; 172 173 Start, 174 Stop : Natural := 0; 175 176 Numeric_Set : constant AS.Wide_Maps.Wide_Character_Set := 177 AS.Wide_Maps.To_Set("0123456789"); 178 179 Cal : constant 180 AS.Wide_Maps.Wide_Character_Sequence := "CA"; 181 California_Set : constant AS.Wide_Maps.Wide_Character_Set := 182 AS.Wide_Maps.To_Set(Cal); 183 Arizona_Set : constant AS.Wide_Maps.Wide_Character_Set := 184 AS.Wide_Maps.To_Set("AZ"); 185 Nevada_Set : constant AS.Wide_Maps.Wide_Character_Set := 186 AS.Wide_Maps.To_Set("NV"); 187 188 Blank_Ftn_Ptr : AS.Wide_Maps.Wide_Character_Mapping_Function := 189 US_to_Blank_Map'Access; 190 191 begin 192 193 -- Find the starting position of the name field (first non-blank), 194 -- then, from that position, find the end of the name field (first 195 -- blank). 196 197 Start := AS.Wide_Fixed.Index_Non_Blank(Info_String); 198 Stop := AS.Wide_Fixed.Index (Info_String(Start..Info_String'Length), 199 AS.Wide_Maps.To_Set(Blank), 200 AS.Inside, 201 AS.Forward) - 1 ; 202 203 -- Store the name field in the data base element field for "Name". 204 205 DB_Record.Name := AS.Wide_Fixed.Head(Info_String(1..Stop), 206 DB_Record.Name'Length); 207 208 -- Replace any underscore characters in the name field 209 -- that were used to separate first/middle/last names. 210 -- Use the overloaded version of Translate that takes an 211 -- access-to-subprogram value. 212 213 AS.Wide_Fixed.Translate (DB_Record.Name, Blank_Ftn_Ptr); 214 215 216 -- Continue the extraction process; now find the position of 217 -- the street number in the string. 218 219 Start := Stop + 1; 220 221 AS.Wide_Fixed.Find_Token(Info_String(Start..Info_String'Length), 222 Numeric_Set, 223 AS.Inside, 224 Start, 225 Stop); 226 227 -- Store the street number field in the appropriate data base 228 -- element. 229 -- No modification of the default parameters of procedure Move 230 -- is required. 231 232 AS.Wide_Fixed.Move(Source => Info_String(Start..Stop), 233 Target => DB_Record.Street_Number); 234 235 236 -- Continue the extraction process; find the street name in the 237 -- info string. Skip blanks to the start of the street name, then 238 -- search for the index of the next blank character in the string. 239 240 Start := AS.Wide_Fixed.Index_Non_Blank 241 (Info_String(Stop+1..Info_String'Length)); 242 243 Stop := 244 AS.Wide_Fixed.Index(Info_String(Start..Info_String'Length), 245 Blank_Wide_String) - 1; 246 247 -- Store the street name in the appropriate data base element field. 248 249 AS.Wide_Fixed.Overwrite(DB_Record.Street_Name, 250 1, 251 Info_String(Start..Stop)); 252 253 -- Replace any underscore characters in the street name field 254 -- that were used as word separation with blanks. Again, use the 255 -- access-to-subprogram value to provide the mapping. 256 257 DB_Record.Street_Name := 258 AS.Wide_Fixed.Translate(DB_Record.Street_Name, 259 Blank_Ftn_Ptr); 260 261 262 -- Continue the extraction; remove the city name from the string. 263 264 Start := AS.Wide_Fixed.Index_Non_Blank 265 (Info_String(Stop+1..Info_String'Length)); 266 267 Stop := 268 AS.Wide_Fixed.Index(Info_String(Start..Info_String'Length), 269 Blank_Wide_String) - 1; 270 271 -- Store the city name field in the appropriate data base element. 272 273 AS.Wide_Fixed.Replace_Slice(DB_Record.City, 274 1, 275 DB_Record.City'Length, 276 Info_String(Start..Stop)); 277 278 -- Replace any underscore characters in the city name field 279 -- that were used as word separation. 280 281 AS.Wide_Fixed.Translate (DB_Record.City, 282 Blank_Ftn_Ptr); 283 284 285 -- Continue the extraction; remove the state identifier from the 286 -- info string. 287 288 Start := Stop + 1; 289 290 AS.Wide_Fixed.Find_Token(Info_String(Start..Info_String'Length), 291 AS.Wide_Maps."OR"(California_Set, 292 AS.Wide_Maps."OR"(Nevada_Set, 293 Arizona_Set)), 294 AS.Inside, 295 Start, 296 Stop); 297 298 -- Store the state indicator into the data base element. 299 300 AS.Wide_Fixed.Move(Source => Info_String(Start..Stop), 301 Target => DB_Record.State, 302 Drop => Ada.Strings.Right, 303 Justify => Ada.Strings.Left, 304 Pad => AS.Wide_Space); 305 306 307 -- Continue the extraction process; remove the final data item in 308 -- the info string, the zip code, and place it into the 309 -- corresponding data base element. 310 311 DB_Record.Zip_Code := 312 AS.Wide_Fixed.Tail(Info_String, DB_Record.Zip_Code'Length); 313 314 exception 315 when AS.Length_Error => 316 Report.Failed ("Length_Error raised in procedure"); 317 when AS.Pattern_Error => 318 Report.Failed ("Pattern_Error raised in procedure"); 319 when AS.Translation_Error => 320 Report.Failed ("Translation_Error raised in procedure"); 321 when others => 322 Report.Failed ("Exception raised in procedure"); 323 end Store_Information; 324 325 326 begin 327 328 -- Loop thru the information strings, extract the name and address 329 -- information, place this info into elements of the data base. 330 331 while not Finished_Processing loop 332 333 Count := Count + 1; 334 335 Store_Information (Info_Strings(Count), Data_Base(Count)); 336 337 Finished_Processing := (Count = Number_Of_Info_Strings); 338 339 end loop; 340 341 342 -- Verify that the string processing was successful. 343 344 for i in 1..DB_Size loop 345 if Data_Base(i) /= TC_Data_Base(i) then 346 Report.Failed 347 ("Data processing error on record " & Integer'Image(i)); 348 end if; 349 end loop; 350 351 352 exception 353 when others => Report.Failed ("Exception raised in Test_Block"); 354 end Test_Block; 355 356 357 Report.Result; 358 359end CXA4014; 360