Standard library: Strings

Concatenation

Goal: implement functions to concatenate an array of unbounded strings.

Steps:

  1. Implement the Str_Concat package.

    1. Implement the Concat function for Unbounded_String.

    2. Implement the Concat function for String.

Requirements:

  1. The first Concat function receives an unconstrained array of unbounded strings and returns the concatenation of those strings as an unbounded string.

    1. The second Concat function has the same parameters, but returns a standard string (String type).

  2. Both Concat functions have the following parameters:

    1. An unconstrained array of Unbounded_String strings (Unbounded_Strings type).

    2. Trim_Str, a Boolean parameter indicating whether each unbounded string must be trimmed.

    3. Add_Whitespace, a Boolean parameter indicating whether a whitespace shall be added between each unbounded string and the next one.

      1. No whitespace shall be added after the last string of the array.

Remarks:

  1. You can use the Trim function from the Ada.Strings.Unbounded package.

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; package Str_Concat is type Unbounded_Strings is array (Positive range <>) of Unbounded_String; function Concat (USA : Unbounded_Strings; Trim_Str : Boolean; Add_Whitespace : Boolean) return Unbounded_String; function Concat (USA : Unbounded_Strings; Trim_Str : Boolean; Add_Whitespace : Boolean) return String; end Str_Concat;
with Ada.Strings; use Ada.Strings; package body Str_Concat is function Concat (USA : Unbounded_Strings; Trim_Str : Boolean; Add_Whitespace : Boolean) return Unbounded_String is begin return ""; end Concat; function Concat (USA : Unbounded_Strings; Trim_Str : Boolean; Add_Whitespace : Boolean) return String is begin return ""; end Concat; end Str_Concat;
with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Str_Concat; use Str_Concat; procedure Main is type Test_Case_Index is (Unbounded_Concat_No_Trim_No_WS_Chk, Unbounded_Concat_Trim_No_WS_Chk, String_Concat_Trim_WS_Chk, Concat_Single_Element); procedure Check (TC : Test_Case_Index) is begin case TC is when Unbounded_Concat_No_Trim_No_WS_Chk => declare S : constant Unbounded_Strings := ( To_Unbounded_String ("Hello"), To_Unbounded_String (" World"), To_Unbounded_String ("!")); begin Put_Line (To_String (Concat (S, False, False))); end; when Unbounded_Concat_Trim_No_WS_Chk => declare S : constant Unbounded_Strings := ( To_Unbounded_String (" This "), To_Unbounded_String (" _is_ "), To_Unbounded_String (" a "), To_Unbounded_String (" _check ")); begin Put_Line (To_String (Concat (S, True, False))); end; when String_Concat_Trim_WS_Chk => declare S : constant Unbounded_Strings := ( To_Unbounded_String (" This "), To_Unbounded_String (" is a "), To_Unbounded_String (" test. ")); begin Put_Line (Concat (S, True, True)); end; when Concat_Single_Element => declare S : constant Unbounded_Strings := ( 1 => To_Unbounded_String (" Hi ")); begin Put_Line (Concat (S, True, True)); end; end case; end Check; begin if Argument_Count < 1 then Put_Line ("ERROR: missing arguments! Exiting..."); return; elsif Argument_Count > 1 then Put_Line ("Ignoring additional arguments..."); end if; Check (Test_Case_Index'Value (Argument (1))); end Main;

List of events

Goal: create a system to manage a list of events.

Steps:

  1. Implement the Events package.

    1. Declare the Event_Item subtype.

  2. Implement the Events.Lists package.

    1. Adapt the Add procedure.

    2. Adapt the Display procedure.

Requirements:

  1. The Event_Item type (from the Events package) contains the description of an event.

    1. This description is declared as a subtype of unbounded string.

  2. Procedure Add adds an event into the list of events for a specific date.

    1. The declaration of E needs to be adapted to use unbounded strings.

  3. Procedure Display must display all events for each date (ordered by date) using the following format:

    1. The arguments to Put_Line need to be adapted to use unbounded strings.

Remarks:

  1. We use the lab on the list of events from the previous chapter (Standard library: Dates & Times) as a starting point.

with Ada.Containers.Vectors; package Events is -- subtype Event_Item is package Event_Item_Containers is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Event_Item); subtype Event_Items is Event_Item_Containers.Vector; end Events;
with Ada.Calendar; use Ada.Calendar; with Ada.Containers.Ordered_Maps; package Events.Lists is type Event_List is tagged private; procedure Add (Events : in out Event_List; Event_Time : Time; Event : String); procedure Display (Events : Event_List); private package Event_Time_Item_Containers is new Ada.Containers.Ordered_Maps (Key_Type => Time, Element_Type => Event_Items, "=" => Event_Item_Containers."="); type Event_List is new Event_Time_Item_Containers.Map with null record; end Events.Lists;
with Ada.Text_IO; use Ada.Text_IO; with Ada.Calendar.Formatting; use Ada.Calendar.Formatting; package body Events.Lists is procedure Add (Events : in out Event_List; Event_Time : Time; Event : String) is use Event_Item_Containers; E : constant Event_Item := new String'(Event); begin if not Events.Contains (Event_Time) then Events.Include (Event_Time, Empty_Vector); end if; Events (Event_Time).Append (E); end Add; function Date_Image (T : Time) return String is Date_Img : constant String := Image (T); begin return Date_Img (1 .. 10); end; procedure Display (Events : Event_List) is use Event_Time_Item_Containers; T : Time; begin Put_Line ("EVENTS LIST"); for C in Events.Iterate loop T := Key (C); Put_Line ("- " & Date_Image (T)); for I of Events (C) loop Put_Line (" - " & I.all); end loop; end loop; end Display; end Events.Lists;
with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with Ada.Calendar; with Ada.Calendar.Formatting; use Ada.Calendar.Formatting; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Events; with Events.Lists; use Events.Lists; procedure Main is type Test_Case_Index is (Unbounded_String_Chk, Event_List_Chk); procedure Check (TC : Test_Case_Index) is EL : Event_List; begin case TC is when Unbounded_String_Chk => declare S : constant Events.Event_Item := To_Unbounded_String ("Checked"); begin Put_Line (To_String (S)); end; when Event_List_Chk => EL.Add (Time_Of (2018, 2, 16), "Final check"); EL.Add (Time_Of (2018, 2, 16), "Release"); EL.Add (Time_Of (2018, 12, 3), "Brother's birthday"); EL.Add (Time_Of (2018, 1, 1), "New Year's Day"); EL.Display; end case; end Check; begin if Argument_Count < 1 then Put_Line ("ERROR: missing arguments! Exiting..."); return; elsif Argument_Count > 1 then Put_Line ("Ignoring additional arguments..."); end if; Check (Test_Case_Index'Value (Argument (1))); end Main;