-- CXA4014.A
--
--                             Grant of Unlimited Rights
--
--     Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--     F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained 
--     unlimited rights in the software and documentation contained herein.
--     Unlimited rights are defined in DFAR 252.227-7013(a)(19).  By making 
--     this public release, the Government intends to confer upon all 
--     recipients unlimited rights  equal to those held by the Government.  
--     These rights include rights to use, duplicate, release or disclose the 
--     released technical data and computer software in whole or in part, in 
--     any manner and for any purpose whatsoever, and to have or permit others 
--     to do so.
--
--                                    DISCLAIMER
--
--     ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--     DISCLOSED ARE AS IS.  THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED 
--     WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--     SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE 
--     OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
--     PARTICULAR PURPOSE OF SAID MATERIAL.
--*
--
-- OBJECTIVE:
--      Check that the subprograms defined in package Ada.Strings.Wide_Fixed
--      are available, and that they produce correct results.  Specifically, 
--      check the subprograms Find_Token, Head, Index, Index_Non_Blank, Move,
--      Overwrite, and Replace_Slice, Tail, and Translate. 
--      Use the access-to-subprogram mapping version of Translate (function
--      and procedure).
--
-- TEST DESCRIPTION:
--      This test demonstrates how certain wide fixed string operations could
--      be used in wide string information processing.  A procedure is defined
--      that will extract portions of a 50 character string that correspond to
--      certain data items (i.e., name, address, state, zip code). These
--      parsed items will then be added to the appropriate fields of data
--      base elements.  These data base elements are then compared for
--      accuracy against a similar set of predefined data base
--      elements.
--      A variety of wide fixed string processing subprograms are used in this
--      test.  Each parsing operation attempts to use a different combination
--      of the available subprograms to accomplish the same goal, therefore
--      continuity of approach to wide string parsing is not seen in this
--      test.
--      However, a wide variety of possible approaches are demonstrated, while
--      exercising a large number of the total predefined subprograms of
--      package Ada.Strings.Wide_Fixed.
--      
--       
-- CHANGE HISTORY:
--      06 Dec 94   SAIC    ACVC 2.0
--      02 Nov 95   SAIC    Update and repair for ACVC 2.0.1.
--
--!

package CXA40140 is

   UnderScore  : Wide_Character := '_';
   Blank       : Wide_Character := ' ';

   -- Function providing a mapping to a blank Wide_Character.
   function US_to_Blank_Map (From : Wide_Character) return Wide_Character;

end CXA40140;

package body CXA40140 is

   function US_to_Blank_Map (From : Wide_Character) return Wide_Character is
   begin
      if From = UnderScore then
         return Blank;
      else
         return From;
      end if;
   end US_to_Blank_Map;

end CXA40140;


with CXA40140;
with Ada.Strings.Wide_Fixed;
with Ada.Strings.Wide_Maps;
with Report;

procedure CXA4014 is
   use CXA40140;
begin

   Report.Test ("CXA4014", "Check that the subprograms defined in package "  &
                           "Ada.Strings.Wide_Fixed are available, and that " &
                           "they produce correct results");

   Test_Block:
   declare

      Number_Of_Info_Strings : constant Natural := 3;
      DB_Size                : constant Natural := Number_Of_Info_Strings;
      Count                  : Natural          := 0;
      Finished_Processing    : Boolean          := False;
      Blank_Wide_String      : constant Wide_String  := " ";

      subtype Info_Wide_String_Type         is Wide_String (1..50);
      type    Info_Wide_String_Storage_Type is 
                array (1..Number_Of_Info_Strings) of Info_Wide_String_Type;


      subtype Name_Type                is Wide_String (1..10);
      subtype Street_Number_Type       is Wide_String (1..5);
      subtype Street_Name_Type         is Wide_String (1..10);
      subtype City_Type                is Wide_String (1..10);
      subtype State_Type               is Wide_String (1..2);
      subtype Zip_Code_Type            is Wide_String (1..5);

      type Data_Base_Element_Type is
         record
            Name          : Name_Type          := (others => ' ');
            Street_Number : Street_Number_Type := (others => ' ');
            Street_Name   : Street_Name_Type   := (others => ' ');
            City          : City_Type          := (others => ' ');
            State         : State_Type         := (others => ' ');
            Zip_Code      : Zip_Code_Type      := (others => ' ');
         end record;

      type Data_Base_Type is array (1..DB_Size) of Data_Base_Element_Type;

      Data_Base : Data_Base_Type;

      ---

      Info_String_1 : Info_Wide_String_Type := 
        "Joe_Jones 123   Sixth_St   San_Diego    CA   98765"; 

      Info_String_2 : Info_Wide_String_Type := 
        "Sam_Smith 56789  S._Seventh   Carlsbad  CA   92177";

      Info_String_3 : Info_Wide_String_Type := 
        "Jane_Brown 1219   Info_Lane  Tuscon     AZ   85643";


      Info_Strings : Info_Wide_String_Storage_Type :=
                       (1 => Info_String_1,
                        2 => Info_String_2,
                        3 => Info_String_3);



      TC_DB_Element_1 : Data_Base_Element_Type := 
        ("Joe Jones ", "123  ", "Sixth St  ", "San Diego ", "CA", "98765");

      TC_DB_Element_2 : Data_Base_Element_Type := 
        ("Sam Smith ", "56789", "S. Seventh", "Carlsbad  ", "CA", "92177");

      TC_DB_Element_3 : Data_Base_Element_Type := 
        ("Jane Brown", "1219 ", "Info Lane ", "Tuscon    ", "AZ", "85643");

      TC_Data_Base : Data_Base_Type := (TC_DB_Element_1,
                                        TC_DB_Element_2,
                                        TC_DB_Element_3);

      ---


      procedure Store_Information 
         (Info_String : in     Info_Wide_String_Type;
          DB_Record   : in out Data_Base_Element_Type) is

         package  AS renames Ada.Strings;
         use type AS.Wide_Maps.Wide_Character_Set;

         Start,
         Stop        : Natural := 0;

         Numeric_Set    : constant AS.Wide_Maps.Wide_Character_Set :=
                            AS.Wide_Maps.To_Set("0123456789");

         Cal            : constant 
                            AS.Wide_Maps.Wide_Character_Sequence := "CA";
         California_Set : constant AS.Wide_Maps.Wide_Character_Set := 
                            AS.Wide_Maps.To_Set(Cal);
         Arizona_Set    : constant AS.Wide_Maps.Wide_Character_Set := 
                            AS.Wide_Maps.To_Set("AZ");
         Nevada_Set     : constant AS.Wide_Maps.Wide_Character_Set := 
                            AS.Wide_Maps.To_Set("NV");

         Blank_Ftn_Ptr : AS.Wide_Maps.Wide_Character_Mapping_Function :=
                           US_to_Blank_Map'Access;

      begin

         -- Find the starting position of the name field (first non-blank),
         -- then, from that position, find the end of the name field (first
         -- blank).

         Start := AS.Wide_Fixed.Index_Non_Blank(Info_String); 
         Stop  := AS.Wide_Fixed.Index (Info_String(Start..Info_String'Length),
                                       AS.Wide_Maps.To_Set(Blank),
                                       AS.Inside,
                                       AS.Forward) - 1 ;

         -- Store the name field in the data base element field for "Name".

         DB_Record.Name := AS.Wide_Fixed.Head(Info_String(1..Stop), 
                                         DB_Record.Name'Length);

         -- Replace any underscore characters in the name field
         -- that were used to separate first/middle/last names.
         -- Use the overloaded version of Translate that takes an
         -- access-to-subprogram value.

         AS.Wide_Fixed.Translate (DB_Record.Name, Blank_Ftn_Ptr);

         
         -- Continue the extraction process; now find the position of
         -- the street number in the string.

         Start := Stop + 1;

         AS.Wide_Fixed.Find_Token(Info_String(Start..Info_String'Length),
                                  Numeric_Set,
                                  AS.Inside,
                                  Start,
                                  Stop);

         -- Store the street number field in the appropriate data base 
         -- element.
         -- No modification of the default parameters of procedure Move
         -- is required.

         AS.Wide_Fixed.Move(Source => Info_String(Start..Stop),
                            Target => DB_Record.Street_Number);


         -- Continue the extraction process; find the street name in the
         -- info string.  Skip blanks to the start of the street name, then
         -- search for the index of the next blank character in the string.

         Start := AS.Wide_Fixed.Index_Non_Blank
                                  (Info_String(Stop+1..Info_String'Length)); 

         Stop := 
           AS.Wide_Fixed.Index(Info_String(Start..Info_String'Length),
                               Blank_Wide_String) - 1; 

         -- Store the street name in the appropriate data base element field.

         AS.Wide_Fixed.Overwrite(DB_Record.Street_Name, 
                                 1, 
                                 Info_String(Start..Stop));
                           
         -- Replace any underscore characters in the street name field
         -- that were used as word separation with blanks.  Again, use the 
         -- access-to-subprogram value to provide the mapping.
         
         DB_Record.Street_Name := 
           AS.Wide_Fixed.Translate(DB_Record.Street_Name, 
                                   Blank_Ftn_Ptr);


         -- Continue the extraction; remove the city name from the string.

         Start := AS.Wide_Fixed.Index_Non_Blank
                                  (Info_String(Stop+1..Info_String'Length)); 

         Stop := 
           AS.Wide_Fixed.Index(Info_String(Start..Info_String'Length), 
                               Blank_Wide_String) - 1; 

         -- Store the city name field in the appropriate data base element.

         AS.Wide_Fixed.Replace_Slice(DB_Record.City, 
                                     1,
                                     DB_Record.City'Length,
                                     Info_String(Start..Stop));
                           
         -- Replace any underscore characters in the city name field
         -- that were used as word separation.
         
         AS.Wide_Fixed.Translate (DB_Record.City, 
                                  Blank_Ftn_Ptr);


         -- Continue the extraction; remove the state identifier from the 
         -- info string.

         Start := Stop + 1;

         AS.Wide_Fixed.Find_Token(Info_String(Start..Info_String'Length),
                                  AS.Wide_Maps."OR"(California_Set,
                                    AS.Wide_Maps."OR"(Nevada_Set,
                                                      Arizona_Set)),
                                  AS.Inside,
                                  Start,
                                  Stop);

         -- Store the state indicator into the data base element.

         AS.Wide_Fixed.Move(Source  => Info_String(Start..Stop),
                            Target  => DB_Record.State,
                            Drop    => Ada.Strings.Right,
                            Justify => Ada.Strings.Left,
                            Pad     => AS.Wide_Space);


         -- Continue the extraction process; remove the final data item in 
         -- the info string, the zip code, and place it into the 
         -- corresponding data base element.

         DB_Record.Zip_Code := 
           AS.Wide_Fixed.Tail(Info_String, DB_Record.Zip_Code'Length);

      exception 
         when AS.Length_Error      =>
            Report.Failed ("Length_Error raised in procedure");
         when AS.Pattern_Error     =>
            Report.Failed ("Pattern_Error raised in procedure");
         when AS.Translation_Error =>
            Report.Failed ("Translation_Error raised in procedure");
         when others            =>
            Report.Failed ("Exception raised in procedure");
      end Store_Information;


   begin

      -- Loop thru the information strings, extract the name and address
      -- information, place this info into elements of the data base.

      while not Finished_Processing loop

         Count := Count + 1;

         Store_Information (Info_Strings(Count), Data_Base(Count));

         Finished_Processing := (Count = Number_Of_Info_Strings);

      end loop;


      -- Verify that the string processing was successful.

      for i in 1..DB_Size loop
         if Data_Base(i) /= TC_Data_Base(i) then
            Report.Failed 
              ("Data processing error on record " & Integer'Image(i));
         end if;
      end loop;


   exception
      when others => Report.Failed ("Exception raised in Test_Block");
   end Test_Block;


   Report.Result;

end CXA4014;
