?? RIGHT := 110 ??
?? NEWTITLE := 'INSTALL_SOFTWARE Utility: DISPLAY_PROCESSING_SUMMARY Subcommand.' ??
MODULE ram$display_processing_summary;

{ PURPOSE:
{   This module contains the interface that displays the processing summary
{   information for an installation.
{
{ DESIGN:
{   The compiled module resides in RAF$LIBRARY.
{
{ NOTES:
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ost$status
*copyc pmt$condition
*copyc rac$idb_directory_name
*copyc rac$not_installed
*copyc rac$packing_list_level
*copyc rae$install_software_cc
*copyc rat$idb_directory_types
*copyc rat$processing_summary_types
?? POP ??
*copyc amp$get_next
*copyc amp$get_segment_pointer
*copyc clp$build_path_subtitle
*copyc clp$build_standard_title
*copyc clp$close_display
*copyc clp$convert_integer_to_real
*copyc clp$convert_integer_to_rjstring
*copyc clp$convert_integer_to_string
*copyc clp$convert_real_to_string
*copyc clp$evaluate_parameters
*copyc clp$get_path_name
*copyc clp$horizontal_tab_display
*copyc clp$new_display_line
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc clp$put_partial_display
*copyc clp$reset_for_next_display_page
*copyc clp$right_justify_string
*copyc clp$trimmed_string_size
*copyc clv$display_variables
*copyc clv$nil_display_control
*copyc fsp$close_file
*copyc fsp$open_file
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc osv$upper_to_lower
*copyc pmp$format_compact_date
*copyc pmp$format_compact_time
*copyc rap$access_directory_for_read
*copyc rap$open_file
*copyc rav$installation_defaults
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??
{ This array contains the rav$step_title array translated to the
{ format (upper/lower case) found in the job log.
 TYPE
   translated_step_title_array = array[rat$steps] of string(34);
 VAR
   translated_step_title: translated_step_title_array;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] rap$display_processing_summary', EJECT ??

{ PURPOSE:
{   This interface displays a summary of the current status or
{   final status of an installation initiated by INSTALL_PRODUCT,
{   RAP$ACTIVATE_PRODUCT or INSTALL_CORRECTION.
{
{ DESIGN:
{
{ NOTES:
{

  PROCEDURE [XDCL] rap$display_processing_summary
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE displ_pdt (
{   job_log_file, jlf: file = $required
{   output, o: file = $output
{   status)

?? PUSH (LISTEXT := ON) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 5] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
      type2: record
        header: clt$type_specification_header,
        default_value: string (7),
      recend,
      type3: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [88, 8, 7, 20, 58, 13, 293],
    clc$command, 5, 3, 1, 0, 0, 0, 3, 'DISPL_PDT'], [
    ['JLF                            ',clc$abbreviation_entry, 1],
    ['JOB_LOG_FILE                   ',clc$nominal_entry, 1],
    ['O                              ',clc$abbreviation_entry, 2],
    ['OUTPUT                         ',clc$nominal_entry, 2],
    ['STATUS                         ',clc$nominal_entry, 3]],
    [
{ PARAMETER 1
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter, 0
  , 0],
{ PARAMETER 2
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 7],
{ PARAMETER 3
    [5, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$file_type]],
{ PARAMETER 2
    [[1, 0, clc$file_type],
    '$output'],
{ PARAMETER 3
    [[1, 0, clc$status_type]]];

?? POP ??

  CONST
    p$job_log_file = 1,
    p$output = 2,
    p$status = 3;

  VAR
    pvt: array [1 .. 3] of clt$parameter_value;

    VAR
      default_ring_attributes: amt$ring_attributes,
      directory_pointers: rat$idb_directory_pointers,
      display_control: clt$display_control,
      display_opened: boolean,
      display_status: ost$status,
      length: integer,
      local_status: ost$status,
      log_file_fid : amt$file_identifier,
      log_file_opened: boolean;

?? OLDTITLE ??
?? NEWTITLE := 'put_subtitle', EJECT ??

    PROCEDURE [INLINE] put_subtitle
      (VAR display_control: clt$display_control;
       VAR status: ost$status);

{ Add subtitles here, if needed. }

    PROCEND put_subtitle;
?? OLDTITLE ??
?? NEWTITLE := 'abort_handler', EJECT ??

{ PURPOSE:
{   This procedure cleans up when an abort situation occurs
{   within the block structure.
{
{ DESIGN:
{   If the files have been opened, they will be closed before the
{   the procedure returns.
{
{ NOTES:
{
{

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      IF display_opened THEN
        clp$close_display (display_control, ignore_status);
      IFEND;

      IF log_file_opened THEN
        fsp$close_file (log_file_fid, ignore_status)
      IFEND

    PROCEND abort_handler;
*copyc clp$new_page_procedure
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    display_opened := FALSE;
    log_file_opened := FALSE;
    display_control := clv$nil_display_control;
    #SPOIL (display_control);
    clv$titles_built := FALSE;
    clv$command_name := 'display_processing_summary';

    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    initialize_scan_variables( translated_step_title);

    default_ring_attributes.r1 := #RING (^default_ring_attributes);
    default_ring_attributes.r2 := #RING (^default_ring_attributes);
    default_ring_attributes.r3 := #RING (^default_ring_attributes);

    osp$establish_block_exit_hndlr (^abort_handler);

    display_opened := TRUE;
    clp$open_display_reference (pvt [p$output].value^.file_value^, ^clp$new_page_procedure, fsc$list,
          default_ring_attributes, display_control, status);
    IF NOT status.normal THEN
      display_opened := FALSE;
      RETURN;
    IFEND;

  /main/
    BEGIN

      open_installation_log_file( pvt[p$job_log_file].value^.file_value,
         log_file_fid, log_file_opened, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      display_log_file_information (log_file_fid, display_control, status );
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

    END /main/;

    IF display_opened THEN
      clp$close_display (display_control, display_status);
    IFEND;

    IF log_file_opened THEN
      fsp$close_file (log_file_fid, local_status);
    IFEND;

    IF status.normal AND (NOT local_status.normal) THEN
      status := local_status;
    ELSEIF status.normal AND (NOT display_status.normal) THEN
      status := display_status;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND rap$display_processing_summary;

  procedure initialize_scan_variables
    (VAR translated_step_title : translated_step_title_array);

*copyc rav$step_title
   var
    step_index : rat$steps;

   for step_index := lowerbound(rav$step_title) to upperbound(rav$step_title) do
      translated_step_title[step_index](1) := rav$step_title[step_index](1);
      #translate(osv$upper_to_lower, rav$step_title[step_index](2, *),
         translated_step_title[step_index]( 2, * ) );
   forend;
  procend initialize_scan_variables;
?? OLDTITLE ??
?? NEWTITLE := 'display_information_record', EJECT ??

{ PURPOSE:
{   This procedure displays information about the subproducts
{   that have been installed on a mainframe.
{
{ DESIGN:
{   Information from the installation data base is displayed.
{
{ NOTES:
{
{

  PROCEDURE display_information_record
    (    information_record: rat$information_record;
         display_option: ost$name;
         display_hidden_values: boolean;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      date: ost$date,
      display_status: ost$status,
      time: ost$time;


    status.normal := TRUE;
    display_status.normal := TRUE;

    write_strings ('    Level:                    ', information_record.subproduct_level, FALSE,
          display_control, display_status);

    IF (display_hidden_values) AND (information_record.internal_level <> osc$null_name) THEN
      write_strings ('    Internal Level:           ', information_record.internal_level, FALSE,
            display_control, display_status);
    IFEND;

    pmp$format_compact_date (information_record.date_installed, osc$iso_date, date, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$format_compact_time (information_record.date_installed, osc$hms_time, time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    write_strings ('    Install Date/Time:        ', date.iso, TRUE, display_control, display_status);
    write_strings (' ', time.hms, FALSE, display_control, display_status);

    IF (display_option = 'F') OR (display_option = 'FULL') THEN

      write_strings ('    Packing List:             ', information_record.packing_list, FALSE,
            display_control, display_status);
      write_strings ('    Installation Id:          ', information_record.installation_identifier, FALSE,
            display_control, display_status);

    IFEND;

    IF status.normal AND (NOT display_status.normal) THEN
      status := display_status;
    IFEND;

  PROCEND display_information_record;

?? OLDTITLE ??
?? NEWTITLE := 'display_idb_information', EJECT ??

{ PURPOSE:
{   This procedure displays information about the subproducts
{   that have been installed on a mainframe.
{
{ DESIGN:
{   Information from the installation data base is displayed.
{
{ NOTES:
{   This code assumes that if the active directory indicates not installed
{   that the subproduct (deferred and correction base) are not installed and
{   thus issues a message to that effect.  This will have to be dealt with
{   in BCU processing.

  PROCEDURE display_idb_information
    (    directory_p: ^rat$directory;
         display_option: ost$name;
         display_hidden_values: boolean;
     VAR display_control: clt$display_control;
     VAR status: ost$status);


    VAR
      display_status: ost$status,
      i: rat$subproduct_count,
      last_licensed_product: rat$licensed_product;

    status.normal := TRUE;

    display_status.normal := TRUE;
    last_licensed_product := '';

    FOR i := 1 TO UPPERBOUND (directory_p^) DO

      IF display_control.line_number > display_control.page_length - 9 THEN
        display_control.line_number := display_control.page_length;
      IFEND;

      IF directory_p^ [i].licensed_product <> last_licensed_product THEN

        last_licensed_product := directory_p^ [i].licensed_product;
        write_strings ('', '', FALSE, display_control, display_status);
        write_strings ('Licensed Product ', directory_p^ [i].
              licensed_product (1, clp$trimmed_string_size (directory_p^ [i].licensed_product)),
              TRUE, display_control, display_status);
        write_strings (':', '', FALSE, display_control, display_status);

      IFEND;

      write_strings ('', '', FALSE, display_control, display_status);

      write_strings ('  Subproduct ', directory_p^ [i].subproduct
            (1, clp$trimmed_string_size (directory_p^ [i].subproduct)), TRUE, display_control,
            display_status);
      write_strings (' Information:', '', FALSE, display_control, display_status);
      write_strings ('', '', FALSE, display_control, display_status);

      IF (display_option = 'F') OR (display_option = 'FULL') THEN
        write_strings ('    Description: ', directory_p^ [i].description, FALSE, display_control,
              display_status);
        write_strings ('', '', FALSE, display_control, display_status);
      IFEND;

      IF directory_p^ [i].active_information.installation_identifier <> rac$not_installed THEN
        write_strings ('    Type:                     ACTIVE', '', FALSE, display_control, display_status);
        display_information_record (directory_p^ [i].active_information, display_option,
              display_hidden_values, display_control, status);
      ELSE
        write_strings ('    {Currently not installed}', '', FALSE, display_control, display_status);
      IFEND;
      IF directory_p^ [i].deferred_information.installation_identifier <> rac$not_installed THEN
        write_strings ('    Type:                     DEFERRED', '', FALSE, display_control, display_status);
        display_information_record (directory_p^ [i].deferred_information, display_option,
              display_hidden_values, display_control, status);
      IFEND;

      { Only show corrective base information if it is 1) present and 2) different from the active level}

      IF (directory_p^ [i].corrective_base_information.installation_identifier <> rac$not_installed) AND
            (directory_p^ [i].corrective_base_information.subproduct_level <>
            directory_p^ [i].active_information.subproduct_level) THEN
        write_strings ('    Type:                     CORRECTION BASE', '', FALSE, display_control,
              display_status);
        display_information_record (directory_p^ [i].corrective_base_information, display_option,
              display_hidden_values, display_control, status);
      IFEND;

    FOREND;

    IF status.normal AND (NOT display_status.normal) THEN
      status := display_status;
    IFEND;

  PROCEND display_idb_information;

?? OLDTITLE ??
?? NEWTITLE := 'display_log_file_information', EJECT ??

{ PURPOSE:
{   This procedure displays information from an individual job log file.
{
{ DESIGN:
{
{ NOTES:
{

  PROCEDURE display_log_file_information
    (    file_identifier: amt$file_identifier;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      file_position: amt$file_position,
      ignore_byte_address: amt$file_byte_address,
      input_line: string (133),
      transfer_count: amt$transfer_count;

    status.normal := true;
    file_position := amc$boi;
    amp$get_next (file_identifier, ^input_line, #SIZE (input_line), transfer_count, ignore_byte_address,
          file_position, status);

    WHILE (file_position <> amc$eoi) AND (status.normal) DO

      if line_is_time_stamped( input_line(1, transfer_count) ) then
         if line_contains_step_data( input_line(1, transfer_count) ) then

      clp$put_partial_display( display_control, input_line( 1, transfer_count ),
         clc$no_trim, amc$terminate, status);

         ifend;
      ifend;
      if status.normal then
        amp$get_next (file_identifier, ^input_line, #SIZE (input_line), transfer_count, ignore_byte_address,
              file_position, status);
      ifend;

    WHILEND;

    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_log_file_information;

  FUNCTION line_contains_step_data
    (    input_line: string ( * )): boolean;

    VAR
      step_title_length: integer,
      step_index: rat$steps;

    line_contains_step_data := FALSE;
    IF STRLENGTH (input_line) >= (17 + 1 + 34) THEN

    /check_for_step_title/
      FOR step_index := LOWERBOUND (translated_step_title) TO UPPERBOUND (translated_step_title) DO
        step_title_length := clp$trimmed_string_size (translated_step_title [step_index]);
        IF STRLENGTH (input_line) >= (17 + 1 + step_title_length) THEN
          IF input_line (19, step_title_length ) = translated_step_title [step_index] (1,
                step_title_length) THEN
            line_contains_step_data := TRUE;
            EXIT /check_for_step_title/;
          IFEND;
        IFEND;
      FOREND /check_for_step_title/;

    IFEND;

  FUNCEND line_contains_step_data;

    FUNCTION line_is_time_stamped
      (    input_line: string ( * )): boolean;


      line_is_time_stamped := FALSE;
      IF STRLENGTH (input_line) >= 17 THEN
        IF (input_line (4) = ':') AND (input_line (7) = ':') AND (input_line (10) = '.') AND
              (input_line (14) = '.') AND (input_line (17) = '.') THEN
          line_is_time_stamped := TRUE;
        IFEND;
      IFEND;

    FUNCEND line_is_time_stamped;
?? OLDTITLE ??
?? NEWTITLE := 'open_installation_log_file', EJECT ??

{ PURPOSE:
{   This procedure opens an installation job_log file.
{
{ DESIGN:
{
{ NOTES:
{   Update to take an installation id, plus installation_logs_file default, plus actual file name
{
  PROCEDURE open_installation_log_file
    (    installation_identifier : ^fst$file_reference;
     VAR file_identifier: amt$file_identifier;
     VAR file_opened: boolean;
     VAR status: ost$status);

    rap$open_file( installation_identifier,  amc$record, fsc$read, {create_file=}false,
         {attach override=}NIL,
         file_identifier, file_opened, status);

  PROCEND open_installation_log_file;

?? OLDTITLE ??
?? NEWTITLE := 'write_string_and_integer', EJECT ??

{ PURPOSE:
{   This procedure writes a string and a integer to the output display.
{
{ DESIGN:
{   The string and the integer are combined into one string and a procedure
{   writes them to output.
{
{ NOTES:
{
{

  PROCEDURE write_string_and_integer
    (    string_a: string ( * );
         integer_a: integer;
         continue_line: boolean;
     VAR display_control: clt$display_control;
     VAR display_status: ost$status);

    VAR
      ignore_status: ost$status,
      line_a: string (2 * fsc$max_path_size),
      line_b: string (2 * fsc$max_path_size),
      line_size_a: integer,
      line_size_b: integer;

    IF NOT display_status.normal THEN
      RETURN;
    IFEND;

    line_a := '';
    STRINGREP (line_a, line_size_a, integer_a);

    line_b := '';
    STRINGREP (line_b, line_size_b, string_a, line_a (2, line_size_a - 1));

    IF continue_line THEN
      clp$put_partial_display (display_control, line_b (1, line_size_b), clc$no_trim, amc$continue,
            ignore_status);
    ELSE
      clp$put_partial_display (display_control, line_b (1, line_size_b), clc$no_trim, amc$terminate,
            ignore_status);
    IFEND;

  PROCEND write_string_and_integer;
?? OLDTITLE ??
?? NEWTITLE := 'write_strings', EJECT ??

{ PURPOSE:
{   This procedure writes two strings to the output display.
{
{ DESIGN:
{   The two strings are combined into one string and a procedure
{   writes them to output.
{
{ NOTES:
{
{

  PROCEDURE write_strings
    (    string_a: string ( * );
         string_b: string ( * );
         continue_line: boolean;
     VAR display_control: clt$display_control;
     VAR display_status: ost$status);


    VAR
      ignore_status: ost$status,
      line: string (osc$max_string_size),
      line_size: integer;


    IF NOT display_status.normal THEN
      RETURN;
    IFEND;

    line := '';
    STRINGREP (line, line_size, string_a, string_b);

    IF continue_line THEN
      clp$put_partial_display (display_control, line (1, line_size), clc$no_trim, amc$continue,
            ignore_status);
    ELSE
      clp$put_partial_display (display_control, line (1, line_size), clc$no_trim, amc$terminate,
            ignore_status);
    IFEND;

  PROCEND write_strings;

MODEND ram$display_processing_summary;
