1-- CXA4011.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.Unbounded
28--      are available, and that they produce correct results. Specifically,
29--      check the subprograms To_Unbounded_String, "&", ">", "<", Element,
30--      Replace_Element, Count, Find_Token, Translate, Trim, Delete, and
31--      "*".
32--
33-- TEST DESCRIPTION:
34--      This test demonstrates the uses of many of the subprograms defined
35--      in package Ada.Strings.Unbounded for use with unbounded strings.
36--      The test simulates how unbounded strings could be processed in a
37--      user environment, using the subprograms provided in this package.
38--
39--      This test uses a variety of the subprograms defined in the unbounded
40--      string package in ways typical of common usage, with different
41--      combinations of available subprograms being used to accomplish
42--      similar unbounded string processing goals.
43--
44--
45-- CHANGE HISTORY:
46--      06 Dec 94   SAIC    ACVC 2.0
47--      27 Feb 95   SAIC    Test description modification.
48--      01 Nov 95   SAIC    Update and repair for ACVC 2.0.1.
49--
50--!
51
52with Report;
53with Ada.Strings.Maps;
54with Ada.Strings.Unbounded;
55
56procedure CXA4011 is
57begin
58
59   Report.Test ("CXA4011", "Check that the subprograms defined in "        &
60                           "package Ada.Strings.Unbounded are available, " &
61                           "and that they produce correct results");
62
63   Test_Block:
64   declare
65
66      package ASUnb renames Ada.Strings.Unbounded;
67      use Ada.Strings;
68      use type Maps.Character_Set;
69      use type ASUnb.Unbounded_String;
70
71      Cad_String        : ASUnb.Unbounded_String :=
72                            ASUnb.To_Unbounded_String("cad");
73
74      Complete_String   : ASUnb.Unbounded_String :=
75                            ASUnb.To_Unbounded_String("Incomplete") &
76                            Ada.Strings.Space &
77                            ASUnb.To_Unbounded_String("String");
78
79      Incomplete_String  : ASUnb.Unbounded_String :=
80                             ASUnb.To_Unbounded_String("ncomplete Strin");
81
82      Incorrect_Spelling : ASUnb.Unbounded_String :=
83                             ASUnb.To_Unbounded_String("Guob Dai");
84
85      Magic_String       : ASUnb.Unbounded_String :=
86                             ASUnb.To_Unbounded_String("abracadabra");
87
88      Incantation        : ASUnb.Unbounded_String := Magic_String;
89
90
91      A_Small_G : Character := 'g';
92      A_Small_D : Character := 'd';
93
94      ABCD_Set : Maps.Character_Set := Maps.To_Set("abcd");
95      B_Set    : Maps.Character_Set := Maps.To_Set('b');
96      AB_Set   : Maps.Character_Set := Maps."OR"(Maps.To_Set('a'), B_Set);
97
98      Code_Map         : Maps.Character_Mapping :=
99                           Maps.To_Mapping(From => "abcd", To => "wxyz");
100      Reverse_Code_Map : Maps.Character_Mapping :=
101                           Maps.To_Mapping(From => "wxyz", To => "abcd");
102      Non_Existent_Map : Maps.Character_Mapping :=
103                           Maps.To_Mapping(From => "jkl",  To => "mno");
104
105
106      Token_Start      : Positive;
107      Token_End        : Natural := 0;
108      Matching_Letters : Natural := 0;
109
110
111   begin
112
113      -- "&"
114
115      -- Prepend an 'I' and append a 'g' to the string.
116      Incomplete_String := ASUnb."&"('I', Incomplete_String);  -- Char & Unb
117      Incomplete_String := ASUnb."&"(Incomplete_String,
118                                     A_Small_G);               -- Unb & Char
119
120      if Incomplete_String  < Complete_String  or
121         Incomplete_String  > Complete_String  or
122         Incomplete_String /= Complete_String
123      then
124         Report.Failed("Incorrect result from use of ""&"" operator");
125      end if;
126
127
128      -- Element
129
130      -- Last element of the unbounded string should be a 'g'.
131      if ASUnb.Element(Incomplete_String, ASUnb.Length(Incomplete_String)) /=
132         A_Small_G
133      then
134         Report.Failed("Incorrect result from use of Function Element - 1");
135      end if;
136
137      if ASUnb.Element(Incomplete_String, 2)                 /=
138         ASUnb.Element(ASUnb.Tail(Incomplete_String, 2), 1)     or
139         ASUnb.Element(ASUnb.Head(Incomplete_String, 4), 2)  /=
140         ASUnb.Element(ASUnb.To_Unbounded_String("wnqz"), 2)
141      then
142         Report.Failed("Incorrect result from use of Function Element - 2");
143      end if;
144
145
146      -- Replace_Element
147
148      -- The unbounded string Incorrect_Spelling starts as "Guob Dai", and
149      -- is transformed by the following three procedure calls to "Good Day".
150
151      ASUnb.Replace_Element(Incorrect_Spelling, 2, 'o');
152
153      ASUnb.Replace_Element(Incorrect_Spelling,
154                            ASUnb.Index(Incorrect_Spelling, B_Set),
155                            A_Small_D);
156
157      ASUnb.Replace_Element(Source => Incorrect_Spelling,
158                            Index  => ASUnb.Length(Incorrect_Spelling),
159                            By     => 'y');
160
161      if Incorrect_Spelling /= ASUnb.To_Unbounded_String("Good Day") then
162         Report.Failed("Incorrect result from Procedure Replace_Element");
163      end if;
164
165
166      -- Count
167
168      -- Determine the number of characters in the unbounded string that
169      -- are contained in the set.
170
171      Matching_Letters := ASUnb.Count(Source => Magic_String,
172                                      Set    => ABCD_Set);
173
174      if Matching_Letters /= 9 then
175         Report.Failed
176            ("Incorrect result from Function Count with Set parameter");
177      end if;
178
179      -- Determine the number of occurrences of the following pattern strings
180      -- in the unbounded string Magic_String.
181
182      if ASUnb.Count(Magic_String, "ab") /=
183         (ASUnb.Count(Magic_String, "ac") + ASUnb.Count(Magic_String, "ad")) or
184         ASUnb.Count(Magic_String, "ab") /= 2
185      then
186         Report.Failed
187            ("Incorrect result from Function Count with String parameter");
188      end if;
189
190
191      -- Find_Token
192
193      ASUnb.Find_Token(Magic_String,      -- Find location of first "ab".
194                       AB_Set,            -- Should be (1..2).
195                       Ada.Strings.Inside,
196                       Token_Start,
197                       Token_End);
198
199      if Natural(Token_Start) /= ASUnb.To_String(Magic_String)'First  or
200         Token_End            /= ASUnb.Index(Magic_String, B_Set)
201      then
202         Report.Failed("Incorrect result from Procedure Find_Token - 1");
203      end if;
204
205
206      ASUnb.Find_Token(Source => Magic_String, -- Find location of char 'r'
207                       Set    => ABCD_Set,     -- in string, should be (3..3)
208                       Test   => Ada.Strings.Outside,
209                       First  => Token_Start,
210                       Last   => Token_End);
211
212      if Natural(Token_Start) /= 3 or
213         Token_End            /= 3 then
214         Report.Failed("Incorrect result from Procedure Find_Token - 2");
215      end if;
216
217
218      ASUnb.Find_Token(Magic_String,           -- No 'g' is in the string, so
219                       Maps.To_Set(A_Small_G), -- the result parameters should
220                       Ada.Strings.Inside,     -- be First = Source'First and
221                       First => Token_Start,   -- Last = 0.
222                       Last  => Token_End);
223
224      if Token_Start /= ASUnb.To_String(Magic_String)'First  or
225         Token_End   /= 0
226      then
227         Report.Failed("Incorrect result from Procedure Find_Token - 3");
228      end if;
229
230
231      -- Translate
232
233      -- Use a mapping ("abcd" -> "wxyz") to transform the contents of
234      -- the unbounded string.
235      -- Magic_String = "abracadabra"
236
237      Incantation := ASUnb.Translate(Magic_String, Code_Map);
238
239      if Incantation /= ASUnb.To_Unbounded_String("wxrwywzwxrw") then
240         Report.Failed("Incorrect result from Function Translate");
241      end if;
242
243      -- Use the inverse mapping of the one above to return the "translated"
244      -- unbounded string to its original form.
245
246      ASUnb.Translate(Incantation, Reverse_Code_Map);
247
248      -- The map contained in the following call to Translate contains one
249      -- element, and this element is not found in the unbounded string, so
250      -- this call to Translate should have no effect on the unbounded string.
251
252      if Incantation /= ASUnb.Translate(Magic_String, Non_Existent_Map) then
253         Report.Failed("Incorrect result from Procedure Translate");
254      end if;
255
256
257      -- Trim
258
259      Trim_Block:
260      declare
261
262         XYZ_Set     : Maps.Character_Set := Maps.To_Set("xyz");
263         PQR_Set     : Maps.Character_Set := Maps.To_Set("pqr");
264
265         Pad         : constant ASUnb.Unbounded_String :=
266                                  ASUnb.To_Unbounded_String("Pad");
267
268         The_New_Ada : constant ASUnb.Unbounded_String :=
269                                  ASUnb.To_Unbounded_String("Ada9X");
270
271         Space_Array : array (1..4) of ASUnb.Unbounded_String :=
272                         (ASUnb.To_Unbounded_String("  Pad    "),
273                          ASUnb.To_Unbounded_String("Pad   "),
274                          ASUnb.To_Unbounded_String("     Pad"),
275                          Pad);
276
277         String_Array : array (1..5) of ASUnb.Unbounded_String :=
278                          (ASUnb.To_Unbounded_String("xyzxAda9Xpqr"),
279                           ASUnb.To_Unbounded_String("Ada9Xqqrp"),
280                           ASUnb.To_Unbounded_String("zxyxAda9Xqpqr"),
281                           ASUnb.To_Unbounded_String("xxxyAda9X"),
282                           The_New_Ada);
283
284      begin
285
286         -- Examine the version of Trim that removes blanks from
287         -- the left and/or right of a string.
288
289         for i in 1..4 loop
290            if ASUnb.Trim(Space_Array(i), Ada.Strings.Both) /= Pad then
291               Report.Failed("Incorrect result from Trim for spaces - " &
292                             Integer'Image(i));
293            end if;
294         end loop;
295
296         -- Examine the version of Trim that removes set characters from
297         -- the left and right of a string.
298
299         for i in 1..5 loop
300            if ASUnb.Trim(String_Array(i),
301                          Left   => XYZ_Set,
302                          Right  => PQR_Set) /= The_New_Ada then
303               Report.Failed
304                 ("Incorrect result from Trim for set characters - " &
305                  Integer'Image(i));
306            end if;
307         end loop;
308
309      end Trim_Block;
310
311
312      -- Delete
313
314      -- Use the Delete function to remove the first four and last four
315      -- characters from the string.
316
317      if ASUnb.Delete(Source  => ASUnb.Delete(Magic_String,
318                                              8,
319                                              ASUnb.Length(Magic_String)),
320                      From    => ASUnb.To_String(Magic_String)'First,
321                      Through => 4)   /=
322         Cad_String
323      then
324         Report.Failed("Incorrect results from Function Delete");
325      end if;
326
327
328      -- Constructors ("*")
329
330      Constructor_Block:
331      declare
332
333         SOS      : ASUnb.Unbounded_String;
334
335         Dot      : constant ASUnb.Unbounded_String :=
336                               ASUnb.To_Unbounded_String("Dot_");
337         Dash     : constant String := "Dash_";
338
339         Distress : ASUnb.Unbounded_String :=
340                      ASUnb.To_Unbounded_String("Dot_Dot_Dot_")    &
341                      ASUnb.To_Unbounded_String("Dash_Dash_Dash_") &
342                      ASUnb.To_Unbounded_String("Dot_Dot_Dot");
343
344         Repeat        : constant Natural   := 3;
345         Separator     : constant Character := '_';
346
347         Separator_Set : Maps.Character_Set := Maps.To_Set(Separator);
348
349      begin
350
351         -- Use the following constructor forms to construct the string
352         -- "Dot_Dot_Dot_Dash_Dash_Dash_Dot_Dot_Dot".  Note that the
353         -- trailing underscore in the string is removed in the call to
354         -- Trim in the If statement condition.
355
356         SOS := ASUnb."*"(Repeat, Dot);        -- "*"(#, Unb Str)
357
358         SOS := SOS                     &
359                ASUnb."*"(Repeat, Dash) &      -- "*"(#, Str)
360                ASUnb."*"(Repeat, Dot);        -- "*"(#, Unb Str)
361
362         if ASUnb.Trim(SOS, Maps.Null_Set, Separator_Set) /= Distress then
363            Report.Failed("Incorrect results from Function ""*""");
364         end if;
365
366      end Constructor_Block;
367
368
369   exception
370      when others => Report.Failed ("Exception raised in Test_Block");
371   end Test_Block;
372
373
374   Report.Result;
375
376end CXA4011;
377