1-- CXA4022.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 Count, Element,
30--      Index, Replace_Element, To_Unbounded_Wide_String, 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--      Taken in conjunction with tests CXA4021 and CXA4023, this test 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, type visibility,
51--                          and subtest acceptance criteria problems for
52--                          ACVC 2.0.1
53--
54--!
55
56with Ada.Characters.Handling;
57with Ada.Strings;
58
59package CXA40220 is
60
61   -- The following two functions are used to translate character and string
62   -- values to "Wide" values.  They will be applied to all the Wide_Bounded
63   -- subprogram character and string parameters to simulate the use of non-
64   -- character Wide_Characters and Wide_Strings in actual practice.
65   -- Note: These functions do not actually return "equivalent" wide
66   --       characters to their character inputs, just "non-character"
67   --       wide characters.
68
69   function Equiv (Ch : Character) return Wide_Character;
70
71   function Equiv (Str : String) return Wide_String;
72
73
74   -- Functions and access-to-subprogram value used to supply mapping
75   -- capability to the appropriate versions of Count, Index, and
76   -- Translate.
77
78   function AB_to_US_Mapping_Function (From : Wide_Character)
79     return Wide_Character;
80
81   function AB_to_Blank_Mapping_Function (From : Wide_Character)
82     return Wide_Character;
83
84end CXA40220;
85
86package body CXA40220 is
87
88   function Equiv (Ch : Character) return Wide_Character is
89      C : Character := Ch;
90   begin
91      if Ch = ' ' then
92         return Ada.Characters.Handling.To_Wide_Character(C);
93      else
94         return Wide_Character'Val(Character'Pos(Ch) +
95                Character'Pos(Character'Last) + 1);
96      end if;
97   end Equiv;
98
99
100   function Equiv (Str : String) return Wide_String is
101      WS : Wide_String(Str'First..Str'Last);
102   begin
103      for i in Str'First..Str'Last loop
104         WS(i) := Equiv(Str(i));
105      end loop;
106      return WS;
107   end Equiv;
108
109
110   function AB_to_US_Mapping_Function (From : Wide_Character)
111     return Wide_Character is
112      UnderScore : constant Wide_Character := Equiv('_');
113   begin
114      if From = Equiv('a')  or  From = Equiv('b')  then
115         return UnderScore;
116      else
117         return From;
118      end if;
119   end AB_to_US_Mapping_Function;
120
121
122   function AB_to_Blank_Mapping_Function (From : Wide_Character)
123     return Wide_Character is
124   begin
125      if From = Equiv('a')  or  From = Equiv('b') then
126         return Ada.Strings.Wide_Space;
127      else
128         return From;
129      end if;
130   end AB_to_Blank_Mapping_Function;
131
132end CXA40220;
133
134
135with CXA40220;
136with Report;
137with Ada.Characters.Handling;
138with Ada.Strings.Wide_Maps;
139with Ada.Strings.Wide_Unbounded;
140
141procedure CXA4022 is
142begin
143
144   Report.Test ("CXA4022", "Check that the subprograms defined in "    &
145                           "package Ada.Strings.Wide_Unbounded are "   &
146                           "available, and that they produce correct " &
147                           "results");
148
149   Test_Block:
150   declare
151
152      use CXA40220;
153
154      package ASW renames Ada.Strings.Wide_Unbounded;
155      use Ada.Strings;
156      use type Wide_Maps.Wide_Character_Set;
157      use type ASW.Unbounded_Wide_String;
158
159      Test_String       : ASW.Unbounded_Wide_String;
160      AtoE_Str          : ASW.Unbounded_Wide_String :=
161                            ASW.To_Unbounded_Wide_String(Equiv("abcde"));
162
163      Complete_String   : ASW.Unbounded_Wide_String :=
164            ASW."&"(ASW.To_Unbounded_Wide_String(Equiv("Incomplete")),
165                    ASW."&"(Ada.Strings.Wide_Space,
166                            ASW.To_Unbounded_Wide_String(Equiv("String"))));
167
168      Incomplete_String  : ASW.Unbounded_Wide_String :=
169                             ASW.To_Unbounded_Wide_String
170                               (Equiv("ncomplete Strin"));
171
172      Incorrect_Spelling : ASW.Unbounded_Wide_String :=
173                             ASW.To_Unbounded_Wide_String(Equiv("Guob Dai"));
174
175      Magic_String       : ASW.Unbounded_Wide_String :=
176           ASW.To_Unbounded_Wide_String(Equiv("abracadabra"));
177
178      Incantation        : ASW.Unbounded_Wide_String := Magic_String;
179
180
181      A_Small_G    : Wide_Character := Equiv('g');
182      A_Small_D    : Wide_Character := Equiv('d');
183
184      ABCD_Set     : Wide_Maps.Wide_Character_Set :=
185                       Wide_Maps.To_Set(Equiv("abcd"));
186      B_Set        : Wide_Maps.Wide_Character_Set :=
187                       Wide_Maps.To_Set(Equiv('b'));
188      CD_Set       : Wide_Maps.Wide_Character_Set :=
189                       Wide_Maps.To_Set(Equiv("cd"));
190
191      CD_to_XY_Map : Wide_Maps.Wide_Character_Mapping :=
192                       Wide_Maps.To_Mapping(From => Equiv("cd"),
193                                            To   => Equiv("xy"));
194      AB_to_YZ_Map : Wide_Maps.Wide_Character_Mapping :=
195                       Wide_Maps.To_Mapping(Equiv("ab"), Equiv("yz"));
196
197
198      Matching_Letters : Natural := 0;
199      Location,
200      Total_Count      : Natural := 0;
201
202
203      Map_Ptr : Wide_Maps.Wide_Character_Mapping_Function :=
204                  AB_to_US_Mapping_Function'Access;
205
206
207   begin
208
209
210      -- Function "&"
211
212      -- Prepend an 'I' and append a 'g' to the wide string.
213      Incomplete_String := ASW."&"(Equiv('I'),
214                                   Incomplete_String);       -- Ch & W Unb
215      Incomplete_String := ASW."&"(Incomplete_String,
216                                   A_Small_G);               -- W Unb & Ch
217
218      if ASW."<"(Incomplete_String, Complete_String)  or
219         ASW.">"(Incomplete_String, Complete_String)  or
220         Incomplete_String /= Complete_String
221      then
222         Report.Failed("Incorrect result from use of ""&"" operator");
223      end if;
224
225
226
227      -- Function Element
228
229      -- Last element of the unbounded wide string should be a 'g'.
230      if ASW.Element(Incomplete_String, ASW.Length(Incomplete_String)) /=
231         A_Small_G
232      then
233         Report.Failed("Incorrect result from use of Function Element - 1");
234      end if;
235
236      if ASW.Element(Incomplete_String, 2)                 /=
237         ASW.Element(ASW.Tail(Incomplete_String, 2), 1)       or
238         ASW.Element(ASW.Head(Incomplete_String, 4), 2)    /=
239         ASW.Element(ASW.To_Unbounded_Wide_String(Equiv("wnqz")), 2)
240      then
241         Report.Failed("Incorrect result from use of Function Element - 2");
242      end if;
243
244
245
246      -- Procedure Replace_Element
247
248      -- The unbounded wide string Incorrect_Spelling starts as "Guob Dai",
249      -- and is transformed by the following three procedure calls to
250      -- "Good Day".
251
252      ASW.Replace_Element(Incorrect_Spelling, 2, Equiv('o'));
253
254      ASW.Replace_Element(Incorrect_Spelling,
255                          ASW.Index(Incorrect_Spelling, B_Set),
256                          A_Small_D);
257
258      ASW.Replace_Element(Source => Incorrect_Spelling,
259                          Index  => ASW.Length(Incorrect_Spelling),
260                          By     => Equiv('y'));
261
262      if Incorrect_Spelling /=
263         ASW.To_Unbounded_Wide_String(Equiv("Good Day"))
264      then
265         Report.Failed("Incorrect result from Procedure Replace_Element");
266      end if;
267
268
269
270      -- Function Index with non-Identity map.
271      -- Evaluate the function Index with a non-identity map
272      -- parameter which will cause mapping of the source parameter
273      -- prior to the evaluation of the index position search.
274
275      Location := ASW.Index(Source  => ASW.To_Unbounded_Wide_String
276                                         (Equiv("abcdefghij")),
277                            Pattern => Equiv("xy"),
278                            Going   => Ada.Strings.Forward,
279                            Mapping => CD_to_XY_Map);  -- change "cd" to "xy"
280
281      if Location /= 3 then
282         Report.Failed("Incorrect result from Index, non-Identity map - 1");
283      end if;
284
285      Location := ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("abcdabcdab")),
286                            Equiv("yz"),
287                            Ada.Strings.Backward,
288                            AB_to_YZ_Map);    -- change all "ab" to "yz"
289
290      if Location /= 9 then
291         Report.Failed("Incorrect result from Index, non-Identity map - 2");
292      end if;
293
294      -- A couple with identity maps (default) as well.
295
296      if ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("abcd")), -- Pat = Src
297                   Equiv("abcd"))                       /= 1 or
298         ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("abc")),  -- Pat < Src
299                   Equiv("abcd"))                       /= 0 or
300         ASW.Index(ASW.Null_Unbounded_Wide_String,       -- Src = Null
301                   Equiv("abc"))                        /= 0
302      then
303         Report.Failed
304           ("Incorrect result from Index with wide string patterns");
305      end if;
306
307
308
309      -- Function Index (for Sets).
310      -- This version of Index uses Sets as the basis of the search.
311
312      -- Test = Inside, Going = Forward  (Default case).
313      Location :=
314        ASW.Index(Source => ASW.To_Unbounded_Wide_String(Equiv("abcdeabcde")),
315                  Set    => CD_Set);  -- set containing 'c' and 'd'
316
317      if not (Location = 3) then     -- position of first 'c' in source.
318         Report.Failed("Incorrect result from Index using Sets - 1");
319      end if;
320
321      -- Test = Inside, Going = Backward.
322      Location :=
323        ASW.Index(Source => ASW."&"(AtoE_Str, AtoE_Str),
324                  Set    => CD_Set,  -- set containing 'c' and 'd'
325                  Test   => Ada.Strings.Inside,
326                  Going  => Ada.Strings.Backward);
327
328      if not (Location = 9) then   -- position of last 'd' in source.
329         Report.Failed("Incorrect result from Index using Sets - 2");
330      end if;
331
332      -- Test = Outside, Going = Forward, Backward
333      if ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("deddacd")),
334                   Wide_Maps.To_Set(Equiv("xydcgf")),
335                   Test  => Ada.Strings.Outside,
336                   Going => Ada.Strings.Forward) /= 2 or
337         ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("deddacd")),
338                   Wide_Maps.To_Set(Equiv("xydcgf")),
339                   Test  => Ada.Strings.Outside,
340                   Going => Ada.Strings.Backward) /= 5 or
341         ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("deddacd")),
342                   CD_Set,
343                   Ada.Strings.Outside,
344                   Ada.Strings.Backward) /= 5
345      then
346         Report.Failed("Incorrect result from Index using Sets - 3");
347      end if;
348
349      -- Default direction (forward) and mapping (identity).
350
351      if ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("cd")), -- Source = Set
352                   CD_Set)                     /= 1 or
353         ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("c")), -- Source < Set
354                   CD_Set)                     /= 1 or
355         ASW.Index(ASW.Null_Unbounded_Wide_String,           -- Source = Null
356                   CD_Set)                     /= 0 or
357         ASW.Index(AtoE_Str,
358                   Wide_Maps.Null_Set)         /= 0 or       -- Null set
359         ASW.Index(AtoE_Str,
360                   Wide_Maps.To_Set(Equiv('x')))      /= 0   -- No match.
361      then
362         Report.Failed("Incorrect result from Index using Sets - 4");
363      end if;
364
365
366
367      -- Function Index using access-to-subprogram mapping.
368      -- Evaluate the function Index with an access value that supplies the
369      -- mapping function for this version of Index.
370
371      Map_Ptr := AB_to_US_Mapping_Function'Access;
372
373      Location := ASW.Index(Source  => ASW.To_Unbounded_Wide_String
374                                         (Equiv("xAxabbxax xaax _cx")),
375                            Pattern => Equiv("_x"),
376                            Going   => Ada.Strings.Forward,
377                            Mapping => Map_Ptr);  -- change 'a'or 'b' to '_'
378
379      if Location /= 6 then   -- location of "bx" substring
380         Report.Failed("Incorrect result from Index, access value map - 1");
381      end if;
382
383      Map_Ptr := AB_to_Blank_Mapping_Function'Access;
384
385      Location := ASW.Index(ASW.To_Unbounded_Wide_String
386                              (Equiv("ccacdcbbcdacc")),
387                            Equiv("cd "),
388                            Ada.Strings.Backward,
389                            Map_Ptr);      -- change 'a' or 'b' to ' '
390
391      if Location /= 9 then
392         Report.Failed("Incorrect result from Index, access value map - 2");
393      end if;
394
395      if ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("abcd")),
396                   Equiv("  cd"),
397                   Ada.Strings.Forward,
398                   Map_Ptr)            /= 1 or
399         ASW.Index(ASW.To_Unbounded_Wide_String(Equiv("abc")),
400                   Equiv("  c "),                               -- No match
401                   Ada.Strings.Backward,
402                   Map_Ptr)            /= 0
403      then
404         Report.Failed("Incorrect result from Index, access value map - 3");
405      end if;
406
407
408
409      -- Function Count
410
411      -- Determine the number of characters in the unbounded wide string that
412      -- are contained in the set.
413
414      Matching_Letters := ASW.Count(Source => Magic_String,
415                                    Set    => ABCD_Set);
416
417      if Matching_Letters /= 9 then
418         Report.Failed
419            ("Incorrect result from Function Count with Set parameter");
420      end if;
421
422      -- Determine the number of occurrences of the following pattern wide
423      -- strings in the unbounded wide string Magic_String.
424
425      if  ASW.Count(Magic_String, Equiv("ab"))   /=
426          (ASW.Count(Magic_String, Equiv("ac")) +
427           ASW.Count(Magic_String, Equiv("ad")))  or
428          ASW.Count(Magic_String, Equiv("ab"))   /= 2
429      then
430         Report.Failed
431            ("Incorrect result from Function Count, wide string parameter");
432      end if;
433
434
435
436      -- Function Count with non-Identity mapping.
437      -- Evaluate the function Count with a non-identity map
438      -- parameter which will cause mapping of the source parameter
439      -- prior to the evaluation of the number of matching patterns.
440
441      Total_Count :=
442        ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("abbabbabbabba")),
443                  Pattern => Equiv("yz"),
444                  Mapping => AB_to_YZ_Map);
445
446      if Total_Count /= 4 then
447         Report.Failed
448           ("Incorrect result from function Count, non-Identity map - 1");
449      end if;
450
451      if  ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("ADCBADABCD")),
452                    Equiv("AB"),
453                    Wide_Maps.To_Mapping(Equiv("CD"), Equiv("AB")))  /= 5 or
454          ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("dcccddcdccdddccccd")),
455                    Equiv("xxy"),
456                    CD_to_XY_Map)                                    /= 3
457      then
458         Report.Failed
459           ("Incorrect result from function Count, non-Identity map - 2");
460      end if;
461
462      -- And a few with identity Wide_Maps as well.
463
464      if ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("ABABABABAB")),
465                   Equiv("ABA"),
466                   Wide_Maps.Identity)                /= 2 or
467         ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("aaaaaaaaaa")),
468                   Equiv("aaa"))                      /= 3 or
469         ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("XX")),    -- Src < Pat
470                   Equiv("XXX"),
471                   Wide_Maps.Identity)                /= 0 or
472         ASW.Count(AtoE_Str,                              -- Source = Pattern
473                   Equiv("abcde"))                 /= 1 or
474         ASW.Count(ASW.Null_Unbounded_Wide_String,        -- Source = Null
475                   Equiv(" "))                     /= 0
476      then
477         Report.Failed
478           ("Incorrect result from function Count, w,w/o mapping");
479      end if;
480
481
482
483      -- Function Count using access-to-subprogram mapping.
484      -- Evaluate the function Count with an access value specifying the
485      -- mapping that is going to occur to Source.
486
487      Map_Ptr := AB_to_US_Mapping_Function'Access;
488
489      Total_Count :=
490        ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("abcbacbadbaAbbB")),
491                  Pattern => Equiv("__"),
492                  Mapping => Map_Ptr);  -- change 'a' and 'b' to '_'
493
494      if Total_Count /= 5 then
495         Report.Failed
496           ("Incorrect result from function Count, access value map - 1");
497      end if;
498
499      Map_Ptr := AB_to_Blank_Mapping_Function'Access;
500
501      if ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("cccaccBcbcaccacAc")),
502                   Equiv("c c"),
503                   Map_Ptr)                /= 3 or
504         ASW.Count(ASW.To_Unbounded_Wide_String
505                    (Equiv("aBBAAABaBBBBAaBABBABaBBbBB")),
506                   Equiv(" BB"),
507                   Map_Ptr)                /= 4 or
508         ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("aaaaaaaaaa")),
509                   Equiv("   "),
510                   Map_Ptr)                /= 3 or
511         ASW.Count(ASW.To_Unbounded_Wide_String(Equiv("XX")),  -- Src < Pat
512                   Equiv("XX "),
513                   Map_Ptr)                /= 0 or
514         ASW.Count(AtoE_Str,               -- Source'Length = Pattern'Length
515                   Equiv("  cde"),
516                   Map_Ptr)                /= 1
517      then
518         Report.Failed
519           ("Incorrect result from function Count, access value map - 3");
520      end if;
521
522
523
524   exception
525      when others => Report.Failed ("Exception raised in Test_Block");
526   end Test_Block;
527
528
529   Report.Result;
530
531end CXA4022;
532