Ada for Software Engineers - Errata

  • Page 184 program lines 26-28. The words within the strings should not be boldface.
    (Jeanne Murtagh.)
  • Page 207 line 8. f(x) should be f(y). See:
    James M. Ortega. An Introduction to Fortran 90 for Scientific Computing.
    Saunders College Publishing, 1994, p. 72-74.
  • Page 286. Add
    delay 0.0;

    after line 25 of the program to ensure that there is a dispatching point that will allow task Periodic to be executed.
    (Kris Hermans.)

  • Section 16.5. The example program dist.ada is not correct. The designated type of a remote access type must be limited private by E.2.2(9). If you make it limited private, then the RCI packages are not correct because they may not define a limited type by E.2.3(11). You need an extra level of indirection as shown in the following program.
    This problem was not caught on version 3.10p of GNAT that I used.
    (Jack Flynn.)
    --
    -- Distributed dispatching.
    --
    package Root_Event is
      pragma Remote_Types;
      type Event is abstract tagged limited private;
      type Event_Ptr is access all Event'Class;
      procedure Simulate(E: in Event) is abstract;
    private
      type Event is abstract tagged limited null record;
    end Root_Event;
    
    with Root_Event;
    package Simulation_Server is
      pragma Remote_Call_Interface;
      procedure Go_Simulate(E_Ptr: Root_Event.Event_Ptr);
    end Simulation_Server;
    
    package body Simulation_Server is
      procedure Go_Simulate(E_Ptr: Root_Event.Event_Ptr) is
      begin
        Root_Event.Simulate(E_Ptr.all);
      end Go_Simulate;
    end Simulation_Server;
    
    package Root_Event.Engine is
      type Engine_Event is new Event with private;
      function Create(F, O: Natural) return Event_Ptr;
      procedure Simulate(E: in Engine_Event);
    private
      type Engine_Ptr is access all Engine_Event;
      type Engine_Event is new Event with
        record
          Fuel, Oxygen: Natural;
        end record;
    end Root_Event.Engine;
    
    with Ada.Text_IO; use Ada.Text_IO;
    package body Root_Event.Engine is
      function Create(F, O: Natural) return Event_Ptr is
        E: Engine_Ptr := new Engine_Event;
      begin
        E.Fuel := F; E.Oxygen := O;
        return Event_Ptr(E);
      end Create;
      procedure Simulate(E: in Engine_Event) is
      begin
        Put_Line("Engine fuel " & Integer'Image(E.Fuel) &
                 " L, oxygen " & Integer'Image(E.Oxygen) & " L");
      end Simulate;
    end Root_Event.Engine;
    
    package Root_Event.Telemetry is
      type Telemetry_Event is new Event with private;
      type Subsystems is (Engines, Guidance, Communications);
      type States is (OK, Failed);
      function Create(Sub: Subsystems; St: States) return Event_Ptr;
      procedure Simulate(E: in Telemetry_Event);
    private
      type Telemetry_Ptr is access all Telemetry_Event;
      type Telemetry_Event is new Event with
        record
          ID:     Subsystems;
          Status: States;
        end record;
    end Root_Event.Telemetry;
    
    with Ada.Text_IO; use Ada.Text_IO;
    package body Root_Event.Telemetry is
      function Create(Sub: Subsystems; St: States) return Event_Ptr is
        E: Telemetry_Ptr := new Telemetry_Event;
      begin
        E.ID := Sub; E.Status := St;
        return Event_Ptr(E);
      end Create;
      procedure Simulate(E: in Telemetry_Event) is
      begin 
        Put_Line("Telemetry message " & 
                 Subsystems'Image(E.ID) & " " &
                 States'Image(E.Status));
      end Simulate;
    end Root_Event.Telemetry;
    
    with Root_Event;
    with Simulation_Server;
    with Root_Event.Telemetry; with Root_Event.Engine;
    with Ada.Text_IO; use Ada.Text_IO;
    procedure Dist is
      function Get_Event return Root_Event.Event_Ptr is
        C: Character;
      begin
        Put(" Choose system "); Get(C);
        if C = 'e' then
          return Root_Event.Engine.Create(500, 600);
        else
          return Root_Event.Telemetry.Create(
                   Root_Event.Telemetry.Engines,
                   Root_Event.Telemetry.Failed);
        end if;
      end Get_Event;
    
    begin
      Simulation_Server.Go_Simulate(Get_Event);
    end Dist;