1-- CXA4023.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 28-- Ada.Strings.Wide_Unbounded are available, and that they produce 29-- correct results. Specifically, check the subprograms Delete, 30-- Find_Token, Translate, Trim, and "*". 31-- 32-- TEST DESCRIPTION: 33-- This test demonstrates the uses of many of the subprograms defined 34-- in package Ada.Strings.Wide_Unbounded for use with unbounded wide 35-- strings. The test simulates how unbounded wide strings 36-- will be processed in a user environment, using the subprograms 37-- provided in this package. 38-- 39-- This test, when taken in conjunction with tests CXA4021-22, will 40-- constitute a test of the functionality contained in package 41-- Ada.Strings.Wide_Unbounded. This test uses a variety 42-- of the subprograms defined in the unbounded wide string package 43-- in ways typical of common usage, with different combinations of 44-- available subprograms being used to accomplish similar 45-- unbounded wide string processing goals. 46-- 47-- 48-- CHANGE HISTORY: 49-- 06 Dec 94 SAIC ACVC 2.0 50-- 08 Nov 95 SAIC Corrected accessibility level and type 51-- visibility problems for ACVC 2.0.1. 52-- 53--! 54 55with Ada.Characters.Handling; 56with Ada.Strings; 57 58package CXA40230 is 59 60 -- The following two functions are used to translate character and string 61 -- values to non-character "Wide" values. They will be applied to all the 62 -- Wide_Bounded subprogram character and string parameters to simulate the 63 -- use of Wide_Characters and Wide_Strings in actual practice. 64 -- Note: These functions do not actually return "equivalent" wide 65 -- characters to their character inputs, just "non-character" 66 -- wide characters. 67 68 function Equiv (Ch : Character) return Wide_Character; 69 70 function Equiv (Str : String) return Wide_String; 71 72 -- Functions and access-to-subprogram object used to supply mapping 73 -- capability to the appropriate versions of Translate. 74 75 function AB_to_US_Mapping_Function (From : Wide_Character) 76 return Wide_Character; 77 78 function AB_to_Blank_Mapping_Function (From : Wide_Character) 79 return Wide_Character; 80 81end CXA40230; 82 83 84package body CXA40230 is 85 86 function Equiv (Ch : Character) return Wide_Character is 87 C : Character := Ch; 88 begin 89 if Ch = ' ' then 90 return Ada.Characters.Handling.To_Wide_Character(C); 91 else 92 return Wide_Character'Val(Character'Pos(Ch) + 93 Character'Pos(Character'Last) + 1); 94 end if; 95 end Equiv; 96 97 98 function Equiv (Str : String) return Wide_String is 99 WS : Wide_String(Str'First..Str'Last); 100 begin 101 for i in Str'First..Str'Last loop 102 WS(i) := Equiv(Str(i)); 103 end loop; 104 return WS; 105 end Equiv; 106 107 108 function AB_to_US_Mapping_Function (From : Wide_Character) 109 return Wide_Character is 110 UnderScore : constant Wide_Character := Equiv('_'); 111 begin 112 if From = Equiv('a') or From = Equiv('b') then 113 return UnderScore; 114 else 115 return From; 116 end if; 117 end AB_to_US_Mapping_Function; 118 119 120 function AB_to_Blank_Mapping_Function (From : Wide_Character) 121 return Wide_Character is 122 begin 123 if From = Equiv('a') or From = Equiv('b') then 124 return Ada.Strings.Wide_Space; 125 else 126 return From; 127 end if; 128 end AB_to_Blank_Mapping_Function; 129 130end CXA40230; 131 132 133with CXA40230; 134with Report; 135with Ada.Characters.Handling; 136with Ada.Strings.Wide_Maps; 137with Ada.Strings.Wide_Unbounded; 138 139procedure CXA4023 is 140begin 141 142 Report.Test ("CXA4023", "Check that the subprograms defined in " & 143 "package Ada.Strings.Wide_Unbounded are " & 144 "available, and that they produce correct " & 145 "results"); 146 147 Test_Block: 148 declare 149 150 use CXA40230; 151 152 package ASW renames Ada.Strings.Wide_Unbounded; 153 use Ada.Strings; 154 use type Wide_Maps.Wide_Character_Set; 155 use type ASW.Unbounded_Wide_String; 156 157 Test_String : ASW.Unbounded_Wide_String; 158 AtoE_Str : ASW.Unbounded_Wide_String := 159 ASW.To_Unbounded_Wide_String(Equiv("abcde")); 160 161 Cad_String : ASW.Unbounded_Wide_String := 162 ASW.To_Unbounded_Wide_String(Equiv("cad")); 163 164 Magic_String : ASW.Unbounded_Wide_String := 165 ASW.To_Unbounded_Wide_String(Equiv("abracadabra")); 166 167 Incantation : ASW.Unbounded_Wide_String := Magic_String; 168 169 170 A_Small_G : Wide_Character := Equiv('g'); 171 172 ABCD_Set : Wide_Maps.Wide_Character_Set := 173 Wide_Maps.To_Set(Equiv("abcd")); 174 B_Set : Wide_Maps.Wide_Character_Set := 175 Wide_Maps.To_Set(Equiv('b')); 176 AB_Set : Wide_Maps.Wide_Character_Set := 177 Wide_Maps."OR"(Wide_Maps.To_Set(Equiv('a')), B_Set); 178 179 180 AB_to_YZ_Map : Wide_Maps.Wide_Character_Mapping := 181 Wide_Maps.To_Mapping(From => Equiv("ab"), 182 To => Equiv("yz")); 183 Code_Map : Wide_Maps.Wide_Character_Mapping := 184 Wide_Maps.To_Mapping(Equiv("abcd"), Equiv("wxyz")); 185 Reverse_Code_Map : Wide_Maps.Wide_Character_Mapping := 186 Wide_Maps.To_Mapping(Equiv("wxyz"), Equiv("abcd")); 187 Non_Existent_Map : Wide_Maps.Wide_Character_Mapping := 188 Wide_Maps.To_Mapping(Equiv("jkl"), Equiv("mno")); 189 190 191 Token_Start : Positive; 192 Token_End : Natural := 0; 193 194 Map_Ptr : Wide_Maps.Wide_Character_Mapping_Function := 195 AB_to_US_Mapping_Function'Access; 196 197 198 begin 199 200 -- Find_Token 201 202 ASW.Find_Token(Magic_String, -- Find location of first "ab" equiv. 203 AB_Set, -- Should be (1..2). 204 Ada.Strings.Inside, 205 Token_Start, 206 Token_End); 207 208 if Natural(Token_Start) /= ASW.To_Wide_String(Magic_String)'First or 209 Token_End /= ASW.Index(Magic_String, B_Set) or 210 Token_End /= 2 211 then 212 Report.Failed("Incorrect result from Procedure Find_Token - 1"); 213 end if; 214 215 216 ASW.Find_Token(Source => Magic_String, -- Find location of char 'r'equiv 217 Set => ABCD_Set, -- in wide str, should be (3..3) 218 Test => Ada.Strings.Outside, 219 First => Token_Start, 220 Last => Token_End); 221 222 if Natural(Token_Start) /= 3 or Token_End /= 3 then 223 Report.Failed("Incorrect result from Procedure Find_Token - 2"); 224 end if; 225 226 227 ASW.Find_Token(Magic_String, -- No 'g' "equivalent in 228 Wide_Maps.To_Set(A_Small_G), -- the wide str, so the 229 Ada.Strings.Inside, -- result params should be 230 First => Token_Start, -- First = Source'First and 231 Last => Token_End); -- Last = 0. 232 233 234 if Token_Start /= ASW.To_Wide_String(Magic_String)'First or 235 Token_End /= 0 236 then 237 Report.Failed("Incorrect result from Procedure Find_Token - 3"); 238 end if; 239 240 241 ASW.Find_Token(ASW.To_Unbounded_Wide_String(Equiv("abpqpqrttrcpqr")), 242 Wide_Maps.To_Set(Equiv("trpq")), 243 Ada.Strings.Inside, 244 Token_Start, 245 Token_End); 246 247 if Token_Start /= 3 or 248 Token_End /= 10 249 then 250 Report.Failed("Incorrect result from Procedure Find_Token - 4"); 251 end if; 252 253 ASW.Find_Token(ASW.To_Unbounded_Wide_String(Equiv("abpqpqrttrcpqr")), 254 Wide_Maps.To_Set(Equiv("abpq")), 255 Ada.Strings.Outside, 256 Token_Start, 257 Token_End); 258 259 if Token_Start /= 7 or 260 Token_End /= 11 261 then 262 Report.Failed("Incorrect result from Procedure Find_Token - 5"); 263 end if; 264 265 266 267 -- Translate 268 269 -- Use a mapping ("abcd" -> "wxyz") to transform the contents of 270 -- the unbounded wide string. 271 -- Magic_String = "abracadabra" 272 273 Incantation := ASW.Translate(Magic_String, Code_Map); 274 275 if Incantation /= 276 ASW.To_Unbounded_Wide_String(Equiv("wxrwywzwxrw")) 277 then 278 Report.Failed("Incorrect result from Function Translate - 1"); 279 end if; 280 281 -- (Note: See below for additional testing of Function Translate) 282 283 -- Use the inverse mapping of the one above to return the "translated" 284 -- unbounded wide string to its original form. 285 286 ASW.Translate(Incantation, Reverse_Code_Map); 287 288 -- The map contained in the following call to Translate contains three 289 -- elements, and these elements are not found in the unbounded wide 290 -- string, so this call to Translate should have no effect on it. 291 292 if Incantation /= ASW.Translate(Magic_String, Non_Existent_Map) then 293 Report.Failed("Incorrect result from Procedure Translate - 1"); 294 end if; 295 296 -- Partial mapping of source. 297 298 Test_String := ASW.To_Unbounded_Wide_String(Equiv("abcdeabcab")); 299 300 ASW.Translate(Source => Test_String, Mapping => AB_to_YZ_Map); 301 302 if Test_String /= ASW.To_Unbounded_Wide_String(Equiv("yzcdeyzcyz")) then 303 Report.Failed("Incorrect result from Procedure Translate - 2"); 304 end if; 305 306 -- Total mapping of source. 307 308 Test_String := ASW.To_Unbounded_Wide_String(Equiv("abbaaababb")); 309 310 ASW.Translate(Source => Test_String, Mapping => AB_to_YZ_Map); 311 312 if Test_String /= ASW.To_Unbounded_Wide_String(Equiv("yzzyyyzyzz")) then 313 Report.Failed("Incorrect result from Procedure Translate - 3"); 314 end if; 315 316 -- No mapping of source. 317 318 Test_String := ASW.To_Unbounded_Wide_String(Equiv("xyzsypcc")); 319 320 ASW.Translate(Source => Test_String, Mapping => AB_to_YZ_Map); 321 322 if Test_String /= ASW.To_Unbounded_Wide_String(Equiv("xyzsypcc")) then 323 Report.Failed("Incorrect result from Procedure Translate - 4"); 324 end if; 325 326 -- Map > 2 characters, partial mapping. 327 328 Test_String := ASW.To_Unbounded_Wide_String(Equiv("opabcdelmn")); 329 330 ASW.Translate(Test_String, 331 Wide_Maps.To_Mapping(Equiv("abcde"), Equiv("lmnop"))); 332 333 if Test_String /= ASW.To_Unbounded_Wide_String(Equiv("oplmnoplmn")) then 334 Report.Failed("Incorrect result from Procedure Translate - 5"); 335 end if; 336 337 338 339 -- Various degrees of mapping of source (full, partial, none) used 340 -- with Function Translate. 341 342 if ASW.Translate( 343 ASW.To_Unbounded_Wide_String(Equiv("abcdeabcabbbaaacaa")), 344 AB_to_YZ_Map) /= 345 ASW.To_Unbounded_Wide_String(Equiv("yzcdeyzcyzzzyyycyy")) or 346 347 ASW.Translate( 348 ASW.To_Unbounded_Wide_String(Equiv("abbaaababbaaaaba")), 349 AB_to_YZ_Map) /= 350 ASW.To_Unbounded_Wide_String(Equiv("yzzyyyzyzzyyyyzy")) or 351 352 ASW.Translate(ASW.To_Unbounded_Wide_String(Equiv("cABcABBAc")), 353 Mapping => AB_to_YZ_Map) /= 354 ASW.To_Unbounded_Wide_String(Equiv("cABcABBAc")) or 355 356 ASW.Translate(ASW.To_Unbounded_Wide_String("opabcdelmnddeaccabec"), 357 Wide_Maps.To_Mapping("abcde", "lmnop")) /= 358 ASW.To_Unbounded_Wide_String("oplmnoplmnooplnnlmpn") 359 then 360 Report.Failed("Incorrect result from Function Translate - 2"); 361 end if; 362 363 364 365 -- Procedure Translate using access-to-subprogram mapping. 366 -- Partial mapping of source. 367 368 Map_Ptr := AB_to_Blank_Mapping_Function'Access; 369 370 Test_String := ASW.To_Unbounded_Wide_String(Equiv("abABaABbaBAbba")); 371 372 ASW.Translate(Source => Test_String, -- change equivalent of 'a' and 373 Mapping => Map_Ptr); -- 'b' to ' ' 374 375 if Test_String /= 376 ASW.To_Unbounded_Wide_String(Equiv(" AB AB BA ")) 377 then 378 Report.Failed 379 ("Incorrect result from Proc Translate, w/ access value map - 1"); 380 end if; 381 382 -- Total mapping of source to blanks. 383 384 Test_String := ASW.To_Unbounded_Wide_String(Equiv("abbbab")); 385 386 ASW.Translate(Source => Test_String, 387 Mapping => Map_Ptr); 388 389 if Test_String /= 390 ASW.To_Unbounded_Wide_String(Equiv(" ")) 391 then 392 Report.Failed 393 ("Incorrect result from Proc Translate, w/ access value map - 2"); 394 end if; 395 396 -- No mapping of source. 397 398 Map_Ptr := AB_to_US_Mapping_Function'Access; 399 400 Test_String := ASW.To_Unbounded_Wide_String(Equiv("xyzsypcc")); 401 402 ASW.Translate(Source => Test_String, 403 Mapping => Map_Ptr); 404 405 if Test_String /= 406 ASW.To_Unbounded_Wide_String(Equiv("xyzsypcc")) -- no change 407 then 408 Report.Failed 409 ("Incorrect result from Proc Translate, w/ access value map - 3"); 410 end if; 411 412 413 -- Function Translate using access-to-subprogram mapping value. 414 415 Map_Ptr := AB_to_Blank_Mapping_Function'Access; 416 417 Test_String := ASW.To_Unbounded_Wide_String(Equiv("abAbBBAabbacD")); 418 419 if ASW.Translate(ASW.Translate(Test_String, Map_Ptr), Map_Ptr) /= 420 ASW.To_Unbounded_Wide_String(Equiv(" A BBA cD")) 421 then 422 Report.Failed 423 ("Incorrect result from Function Translate, access value map - 1"); 424 end if; 425 426 if ASW.Translate(Source => ASW.To_Unbounded_Wide_String(Equiv("a")), 427 Mapping => Map_Ptr) /= 428 ASW.To_Unbounded_Wide_String(Equiv(" ")) or 429 ASW.Translate(ASW.To_Unbounded_Wide_String 430 (Equiv(" aa Aa A AAaaa a aA")), 431 Map_Ptr) /= 432 ASW.To_Unbounded_Wide_String(Equiv(" A A AA A")) or 433 ASW.Translate(Source => ASW.To_Unbounded_Wide_String(Equiv("a ")), 434 Mapping => Map_Ptr) /= 435 ASW.To_Unbounded_Wide_String(Equiv(" ")) or 436 ASW.Translate(Source => ASW.To_Unbounded_Wide_String(Equiv("xyz")), 437 Mapping => Map_Ptr) /= 438 ASW.To_Unbounded_Wide_String(Equiv("xyz")) 439 then 440 Report.Failed 441 ("Incorrect result from Function Translate, access value map - 2"); 442 end if; 443 444 445 446 -- Trim 447 448 Trim_Block: 449 declare 450 451 XYZ_Set : Wide_Maps.Wide_Character_Set := 452 Wide_Maps.To_Set(Equiv("xyz")); 453 PQR_Set : Wide_Maps.Wide_Character_Set := 454 Wide_Maps.To_Set(Equiv("pqr")); 455 456 Pad : constant ASW.Unbounded_Wide_String := 457 ASW.To_Unbounded_Wide_String(Equiv("Pad")); 458 459 The_New_Ada : constant ASW.Unbounded_Wide_String := 460 ASW.To_Unbounded_Wide_String(Equiv("Ada9X")); 461 462 Space_Array : array (1..4) of ASW.Unbounded_Wide_String := 463 (ASW.To_Unbounded_Wide_String(Equiv(" Pad ")), 464 ASW.To_Unbounded_Wide_String(Equiv("Pad ")), 465 ASW.To_Unbounded_Wide_String(Equiv(" Pad")), 466 Pad); 467 468 String_Array : array (1..5) of ASW.Unbounded_Wide_String := 469 (ASW.To_Unbounded_Wide_String(Equiv("xyzxAda9Xpqr")), 470 ASW.To_Unbounded_Wide_String(Equiv("Ada9Xqqrp")), 471 ASW.To_Unbounded_Wide_String(Equiv("zxyxAda9Xqpqr")), 472 ASW.To_Unbounded_Wide_String(Equiv("xxxyAda9X")), 473 The_New_Ada); 474 475 begin 476 477 -- Examine the version of Trim that removes blanks from 478 -- the left and/or right of a wide string. 479 480 for i in 1..4 loop 481 if ASW.Trim(Space_Array(i), Ada.Strings.Both) /= Pad then 482 Report.Failed("Incorrect result from Trim for spaces - " & 483 Integer'Image(i)); 484 end if; 485 end loop; 486 487 -- Examine the version of Trim that removes set characters from 488 -- the left and right of a wide string. 489 490 for i in 1..5 loop 491 if ASW.Trim(String_Array(i), 492 Left => XYZ_Set, 493 Right => PQR_Set) /= The_New_Ada then 494 Report.Failed 495 ("Incorrect result from Trim for set characters - " & 496 Integer'Image(i)); 497 end if; 498 end loop; 499 500 -- No trimming. 501 502 if ASW.Trim( 503 ASW.To_Unbounded_Wide_String(Equiv("prqqprAda9Xyzzxyzzyz")), 504 XYZ_Set, 505 PQR_Set) /= 506 ASW.To_Unbounded_Wide_String(Equiv("prqqprAda9Xyzzxyzzyz")) 507 then 508 Report.Failed 509 ("Incorrect result from Trim for set, no trimming"); 510 end if; 511 512 end Trim_Block; 513 514 515 516 -- Delete 517 518 -- Use the Delete function to remove the first four and last four 519 -- characters from the wide string. 520 521 if ASW.Delete(Source => ASW.Delete(Magic_String, 522 8, 523 ASW.Length(Magic_String)), 524 From => ASW.To_Wide_String(Magic_String)'First, 525 Through => 4) /= 526 Cad_String 527 then 528 Report.Failed("Incorrect results from Function Delete"); 529 end if; 530 531 532 533 -- Constructors ("*") 534 535 Constructor_Block: 536 declare 537 538 SOS : ASW.Unbounded_Wide_String; 539 540 Dot : constant ASW.Unbounded_Wide_String := 541 ASW.To_Unbounded_Wide_String(Equiv("Dot_")); 542 Dash : constant Wide_String := Equiv("Dash_"); 543 544 Distress : ASW.Unbounded_Wide_String := 545 ASW."&"(ASW.To_Unbounded_Wide_String 546 (Equiv("Dot_Dot_Dot_")), 547 ASW."&"(ASW.To_Unbounded_Wide_String 548 (Equiv("Dash_Dash_Dash_")), 549 ASW.To_Unbounded_Wide_String 550 (Equiv("Dot_Dot_Dot")))); 551 552 Repeat : constant Natural := 3; 553 Separator : constant Wide_Character := Equiv('_'); 554 555 Separator_Set : Wide_Maps.Wide_Character_Set := 556 Wide_Maps.To_Set(Separator); 557 558 begin 559 560 -- Use the following constructor forms to construct the wide string 561 -- "Dot_Dot_Dot_Dash_Dash_Dash_Dot_Dot_Dot". Note that the 562 -- trailing underscore in the wide string is removed in the call to 563 -- Trim in the If statement condition. 564 565 SOS := ASW."*"(Repeat, Dot); -- "*"(#, W Unb Str) 566 567 SOS := ASW."&"(SOS, 568 ASW."&"(ASW."*"(Repeat, Dash), -- "*"(#, W Str) 569 ASW."*"(Repeat, Dot))); -- "*"(#, W Unb Str) 570 571 if ASW.Trim(SOS, Wide_Maps.Null_Set, Separator_Set) /= Distress then 572 Report.Failed("Incorrect results from Function ""*"""); 573 end if; 574 575 end Constructor_Block; 576 577 578 exception 579 when others => Report.Failed ("Exception raised in Test_Block"); 580 end Test_Block; 581 582 583 Report.Result; 584 585end CXA4023; 586