1-- CXA4004.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.Fixed are
28--      available, and that they produce correct results. Specifically, check
29--      the subprograms Count, Find_Token, Index, Index_Non_Blank, and Move.
30--
31-- TEST DESCRIPTION:
32--      This test, when combined with tests CXA4002,3, and 5 will provide
33--      thorough coverage of the functionality found in Ada.Strings.Fixed.
34--      This test contains many small, specific test cases, situations that
35--      although common in user environments, are often difficult to generate
36--      in large numbers in a application-based test.
37--
38--
39-- CHANGE HISTORY:
40--      06 Dec 94   SAIC    ACVC 2.0
41--      10 Apr 95   SAIC    Corrected subtest for Move, Drop=Right.
42--
43--!
44
45with Report;
46with Ada.Strings;
47with Ada.Strings.Fixed;
48with Ada.Strings.Maps;
49
50procedure CXA4004 is
51begin
52
53   Report.Test("CXA4004", "Check that the subprograms defined in "    &
54                          "package Ada.Strings.Fixed are available, " &
55                          "and that they produce correct results");
56
57   Test_Block:
58   declare
59
60      package ASF  renames Ada.Strings.Fixed;
61      package Maps renames Ada.Strings.Maps;
62
63      Result_String  : String(1..10) := (others => Ada.Strings.Space);
64
65      Source_String1 : String(1..5)  := "abcde";        -- odd length string
66      Source_String2 : String(1..6)  := "abcdef";       -- even length string
67      Source_String3 : String(1..12) := "abcdefghijkl";
68      Source_String4 : String(1..12) := "abcdefghij  "; -- last two ch pad
69      Source_String5 : String(1..12) := "  cdefghijkl"; -- first two ch pad
70      Source_String6 : String(1..12) := "abcdefabcdef";
71
72      Location       : Natural := 0;
73      Slice_Start    : Positive;
74      Slice_End,
75      Slice_Count    : Natural := 0;
76
77      CD_Set         : Maps.Character_Set := Maps.To_Set("cd");
78      ABCD_Set       : Maps.Character_Set := Maps.To_Set("abcd");
79      A_to_F_Set     : Maps.Character_Set := Maps.To_Set("abcdef");
80
81      CD_to_XY_Map   : Maps.Character_Mapping :=
82                         Maps.To_Mapping(From => "cd",  To => "xy");
83
84   begin
85
86      -- Procedure Move
87
88      -- Evaluate the Procedure Move with various combinations of
89      -- parameters.
90
91      -- Justify = Left (default case)
92
93      ASF.Move(Source => Source_String1,       -- "abcde"
94               Target => Result_String);
95
96      if Result_String /= "abcde     " then
97         Report.Failed("Incorrect result from Move with Justify = Left");
98      end if;
99
100      -- Justify = Right
101
102      ASF.Move(Source  => Source_String2,      -- "abcdef"
103               Target  => Result_String,
104               Drop    => Ada.Strings.Error,
105               Justify => Ada.Strings.Right);
106
107      if Result_String /= "    abcdef" then
108         Report.Failed("Incorrect result from Move with Justify = Right");
109      end if;
110
111      -- Justify = Center (two cases, odd and even pad lengths)
112
113      ASF.Move(Source_String1,                 -- "abcde"
114               Result_String,
115               Ada.Strings.Error,
116               Ada.Strings.Center,
117               'x');                           -- non-default padding.
118
119      if Result_String /= "xxabcdexxx" then  -- Unequal padding added right
120         Report.Failed("Incorrect result from Move with Justify = Center-1");
121      end if;
122
123      ASF.Move(Source_String2,                 -- "abcdef"
124               Result_String,
125               Ada.Strings.Error,
126               Ada.Strings.Center);
127
128      if Result_String /= "  abcdef  " then  -- Equal padding added on L/R.
129         Report.Failed("Incorrect result from Move with Justify = Center-2");
130      end if;
131
132      -- When the source string is longer than the target string, several
133      -- cases can be examined, with the results depending on the value of
134      -- the Drop parameter.
135
136      -- Drop = Left
137
138      ASF.Move(Source => Source_String3,       -- "abcdefghijkl"
139               Target => Result_String,
140               Drop   => Ada.Strings.Left);
141
142      if Result_String /= "cdefghijkl" then
143         Report.Failed("Incorrect result from Move with Drop = Left");
144      end if;
145
146      -- Drop = Right
147
148      ASF.Move(Source_String3, Result_String, Ada.Strings.Right);
149
150      if Result_String /= "abcdefghij" then
151         Report.Failed("Incorrect result from Move with Drop = Right");
152      end if;
153
154      -- Drop = Error
155      -- The effect in this case depends on the value of the justify
156      -- parameter, and on whether any characters in Source other than
157      -- Pad would fail to be copied.
158
159      -- Drop = Error, Justify = Left, right overflow characters are pad.
160
161      ASF.Move(Source  => Source_String4,      -- "abcdefghij  "
162               Target  => Result_String,
163               Drop    => Ada.Strings.Error,
164               Justify => Ada.Strings.Left);
165
166      if not(Result_String = "abcdefghij") then  -- leftmost 10 characters
167          Report.Failed("Incorrect result from Move with Drop = Error - 1");
168      end if;
169
170      -- Drop = Error, Justify = Right, left overflow characters are pad.
171
172      ASF.Move(Source_String5,                 -- "  cdefghijkl"
173               Result_String,
174               Ada.Strings.Error,
175               Ada.Strings.Right);
176
177      if Result_String /= "cdefghijkl" then  -- rightmost 10 characters
178         Report.Failed("Incorrect result from Move with Drop = Error - 2");
179      end if;
180
181      -- In other cases of Drop=Error, Length_Error is propagated, such as:
182
183      begin
184
185         ASF.Move(Source_String3,     -- 12 characters, no Pad.
186                  Result_String,      -- 10 characters
187                  Ada.Strings.Error,
188                  Ada.Strings.Left);
189
190         Report.Failed("Length_Error not raised by Move - 1");
191
192      exception
193         when Ada.Strings.Length_Error => null;   -- OK
194         when others =>
195            Report.Failed("Incorrect exception raised by Move - 1");
196      end;
197
198
199
200      -- Function Index
201      -- (Other usage examples of this function found in CXA4002-3.)
202      -- Check when the pattern is not found in the source.
203
204      if ASF.Index("abcdef", "gh")       /= 0 or
205         ASF.Index("abcde",  "abcdef")   /= 0 or  -- pattern > source
206         ASF.Index("xyz",
207                   "abcde",
208                   Ada.Strings.Backward) /= 0 or
209         ASF.Index("",      "ab")        /= 0 or  -- null source string.
210         ASF.Index("abcde", "  ")        /= 0     -- blank pattern.
211      then
212         Report.Failed("Incorrect result from Index, no pattern match");
213      end if;
214
215      -- Check that Pattern_Error is raised when the pattern is the
216      -- null string.
217      begin
218         Location := ASF.Index(Source_String6,    -- "abcdefabcdef"
219                               "",                -- null pattern string.
220                               Ada.Strings.Forward);
221         Report.Failed("Pattern_Error not raised by Index");
222      exception
223         when Ada.Strings.Pattern_Error => null;  -- OK, expected exception.
224         when others                    =>
225           Report.Failed("Incorrect exception raised by Index, null pattern");
226      end;
227
228      -- Use the search direction "backward" to locate the particular
229      -- pattern within the source string.
230
231      Location := ASF.Index(Source_String6,         -- "abcdefabcdef"
232                            "de",                   -- slice 4..5, 10..11
233                            Ada.Strings.Backward);  -- search from right end.
234
235      if Location /= 10  then
236         Report.Failed("Incorrect result from Index going Backward");
237      end if;
238
239      -- Using the version of Index testing character set membership,
240      -- check combinations of forward/backward, inside/outside parameter
241      -- configurations.
242
243      if ASF.Index(Source => Source_String1,      -- "abcde"
244                   Set    => CD_Set,
245                   Test   => Ada.Strings.Inside,
246                   Going  => Ada.Strings.Forward) /= 3 or -- 'c' at pos 3.
247         ASF.Index(Source_String6,                -- "abcdefabcdef"
248                   CD_Set,
249                   Ada.Strings.Outside,
250                   Ada.Strings.Backward)  /=  12  or   -- 'f' at position 12
251         ASF.Index(Source_String6,                -- "abcdefabcdef"
252                   CD_Set,
253                   Ada.Strings.Inside,
254                   Ada.Strings.Backward)  /=   10  or  -- 'd' at position 10
255         ASF.Index("cdcdcdcdacdcdcdcd",
256                   CD_Set,
257                   Ada.Strings.Outside,
258                   Ada.Strings.Forward)   /=    9      -- 'a' at position 9
259      then
260         Report.Failed("Incorrect result from function Index for sets - 1");
261      end if;
262
263      -- Additional interesting uses/combinations using Index for sets.
264
265      if ASF.Index("cd",                               -- same size, str-set
266                   CD_Set,
267                   Ada.Strings.Inside,
268                   Ada.Strings.Forward)   /=    1  or  -- 'c' at position 1
269         ASF.Index("abcd",                             -- same size, str-set,
270                   Maps.To_Set("efgh"),                -- different contents.
271                   Ada.Strings.Outside,
272                   Ada.Strings.Forward)   /=    1  or
273         ASF.Index("abccd",                            -- set > string
274                   Maps.To_Set("acegik"),
275                   Ada.Strings.Inside,
276                   Ada.Strings.Backward)  /=    4  or  -- 'c' at position 4
277         ASF.Index("abcde",
278                   Maps.Null_Set)         /=    0  or
279         ASF.Index("",                                 -- Null string.
280                   CD_Set)                /=    0  or
281         ASF.Index("abc ab",                           -- blank included
282                   Maps.To_Set("e "),                  -- in string and set.
283                   Ada.Strings.Inside,
284                   Ada.Strings.Backward)  /=    4      -- blank in string.
285      then
286         Report.Failed("Incorrect result from function Index for sets - 2");
287      end if;
288
289
290
291      -- Function Index_Non_Blank.
292      -- (Other usage examples of this function found in CXA4002-3.)
293
294
295      if ASF.Index_Non_Blank(Source => Source_String4,  -- "abcdefghij  "
296                             Going  => Ada.Strings.Backward)  /= 10  or
297         ASF.Index_Non_Blank("abc def ghi jkl  ",
298                             Ada.Strings.Backward)            /= 15  or
299         ASF.Index_Non_Blank("  abcdef")                      /=  3  or
300         ASF.Index_Non_Blank("        ")                      /=  0
301      then
302          Report.Failed("Incorrect result from Index_Non_Blank");
303      end if;
304
305
306
307      -- Function Count
308      -- (Other usage examples of this function found in CXA4002-3.)
309
310      if ASF.Count("abababa",   "aba")            /=  2  or
311         ASF.Count("abababa",   "ab" )            /=  3  or
312         ASF.Count("babababa",  "ab")             /=  3  or
313         ASF.Count("abaabaaba", "aba")            /=  3  or
314         ASF.Count("xxxxxxxxxxxxxxxxxxxy", "xy")  /=  1  or
315         ASF.Count("xxxxxxxxxxxxxxxxxxxx", "x")   /= 20
316      then
317         Report.Failed("Incorrect result from Function Count");
318      end if;
319
320      -- Determine the number of slices of Source that when mapped to a
321      -- non-identity map, match the pattern string.
322
323      Slice_Count := ASF.Count(Source_String6, -- "abcdefabcdef"
324                               "xy",
325                               CD_to_XY_Map);  -- maps 'c' to 'x', 'd' to 'y'
326
327      if Slice_Count /= 2 then  -- two slices "xy" in "mapped" Source_String6
328         Report.Failed("Incorrect result from Count with non-identity map");
329      end if;
330
331      -- If the pattern supplied to Function Count is the null string, then
332      -- Pattern_Error is propagated.
333
334      declare
335         The_Null_String : constant String := "";
336      begin
337         Slice_Count := ASF.Count(Source_String6, The_Null_String);
338         Report.Failed("Pattern_Error not raised by Function Count");
339      exception
340         when Ada.Strings.Pattern_Error => null;   -- OK
341         when others =>
342           Report.Failed("Incorrect exception from Count with null pattern");
343      end;
344
345
346      -- Function Count returning the number of characters in a particular
347      -- set that are found in source string.
348
349      if ASF.Count(Source_String6, CD_Set) /= 4 then  -- 2 'c' and 'd' chars.
350         Report.Failed("Incorrect result from Count with set");
351      end if;
352
353
354
355      -- Function Find_Token.
356      -- (Other usage examples of this function found in CXA4002-3.)
357
358      ASF.Find_Token(Source  => Source_String6,      -- First slice with no
359                     Set     => ABCD_Set,            -- 'a', 'b', 'c', or 'd'
360                     Test    => Ada.Strings.Outside, -- is "ef" at 5..6.
361                     First   => Slice_Start,
362                     Last    => Slice_End);
363
364      if Slice_Start /= 5  or Slice_End /= 6 then
365         Report.Failed("Incorrect result from Find_Token - 1");
366      end if;
367
368      -- If no appropriate slice is contained by the source string, then the
369      -- value returned in Last is zero, and the value in First is
370      -- Source'First.
371
372      ASF.Find_Token(Source_String6,      -- "abcdefabcdef"
373                     A_to_F_Set,          -- Set of characters 'a' thru 'f'.
374                     Ada.Strings.Outside, -- No characters outside this set.
375                     Slice_Start,
376                     Slice_End);
377
378      if Slice_Start /= Source_String6'First  or Slice_End /= 0 then
379         Report.Failed("Incorrect result from Find_Token - 2");
380      end if;
381
382      -- Additional testing of Find_Token.
383
384      ASF.Find_Token("eabcdabcddcab",
385                     ABCD_Set,
386                     Ada.Strings.Inside,
387                     Slice_Start,
388                     Slice_End);
389
390      if Slice_Start /= 2  or Slice_End /= 13 then
391         Report.Failed("Incorrect result from Find_Token - 3");
392      end if;
393
394      ASF.Find_Token("efghijklabcdabcd",
395                     ABCD_Set,
396                     Ada.Strings.Outside,
397                     Slice_Start,
398                     Slice_End);
399
400      if Slice_Start /= 1  or Slice_End /= 8 then
401         Report.Failed("Incorrect result from Find_Token - 4");
402      end if;
403
404      ASF.Find_Token("abcdefgabcdabcd",
405                     ABCD_Set,
406                     Ada.Strings.Outside,
407                     Slice_Start,
408                     Slice_End);
409
410      if Slice_Start /= 5  or Slice_End /= 7 then
411         Report.Failed("Incorrect result from Find_Token - 5");
412      end if;
413
414      ASF.Find_Token("abcdcbabcdcba",
415                     ABCD_Set,
416                     Ada.Strings.Inside,
417                     Slice_Start,
418                     Slice_End);
419
420      if Slice_Start /= 1  or Slice_End /= 13 then
421         Report.Failed("Incorrect result from Find_Token - 6");
422      end if;
423
424
425   exception
426      when others => Report.Failed("Exception raised in Test_Block");
427   end Test_Block;
428
429   Report.Result;
430
431end CXA4004;
432