?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Message Interfaces: Routines used for displaying messages' ??
MODULE ram$message_interfaces;

{ PURPOSE:
{   This module contains interfaces to display messages.
{
{ DESIGN:
{   The interfaces utilize message templates to provide the text to be displayed.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rac$max_line
*copyc rac$process_id
*copyc rae$prompt_and_message_cc
*copyc rat$message_parameters
?? POP ??
*copyc amp$put_next
*copyc clp$get_set_count
*copyc clp$get_value
*copyc clp$scan_parameter_list
*copyc clp$test_parameter
*copyc clp$trimmed_string_size
*copyc fsp$close_file
*copyc fsp$open_file
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$find_help_module
*copyc osp$find_parameter_prompt
*copyc osp$format_help_message
*copyc osp$set_status_abnormal

?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  CONST
    rac$max_margin = 26;

  TYPE
    rat$margin = 0 .. rac$max_margin;

?? TITLE := '[XDCL, #GATE] rap$display_message_command', EJECT ??

*copy rah$display_message_command

  PROCEDURE [XDCL, #GATE] rap$display_message_command
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);


{ pdt display_message_pdt (
{   message_module, mm     : name = $required
{   message_name, mn       : name = $required
{   message_parameters, mp : list 1..10 of string = $optional
{   margin, m              : integer 0 .. 26 = $optional
{   to, t                  : file = $output
{   status                 : var of status = $optional
{   )

?? PUSH (LISTEXT := ON) ??

  VAR
    display_message_pdt: [STATIC, READ, cls$pdt] clt$parameter_descriptor_table := [^display_message_pdt_names
      , ^display_message_pdt_params];

  VAR
    display_message_pdt_names: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 11] of
      clt$parameter_name_descriptor := [['MESSAGE_MODULE', 1], ['MM', 1], ['MESSAGE_NAME', 2], ['MN', 2], [
      'MESSAGE_PARAMETERS', 3], ['MP', 3], ['MARGIN', 4], ['M', 4], ['TO', 5], ['T', 5], ['STATUS', 6]];

  VAR
    display_message_pdt_params: [STATIC, READ, cls$pdt_parameters] array [1 .. 6] of clt$parameter_descriptor
      := [

{ MESSAGE_MODULE MM }
    [[clc$required], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$name_value, 1, osc$max_name_size]],

{ MESSAGE_NAME MN }
    [[clc$required], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$name_value, 1, osc$max_name_size]],

{ MESSAGE_PARAMETERS MP }
    [[clc$optional], 1, 10, 1, 1, clc$value_range_not_allowed, [NIL, clc$string_value, 0, osc$max_string_size
      ]],

{ MARGIN M }
    [[clc$optional], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$integer_value, 0, 26]],

{ TO T }
    [[clc$optional_with_default, ^display_message_pdt_dv5], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL,
      clc$file_value]],

{ STATUS }
    [[clc$optional], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$variable_reference,
      clc$array_not_allowed, clc$status_value]]];

  VAR
    display_message_pdt_dv5: [STATIC, READ, cls$pdt_names_and_defaults] string (7) := '$output';

?? POP ??

    VAR
      index: 0 .. clc$max_value_sets,
      margin: [STATIC] rat$margin := 0,
      margin_specified: boolean,
      message_module: pmt$program_name,
      message_name: clt$parameter_name,
      message_parameters: ^ost$message_parameters,
      number_of_parameters: 0 .. clc$max_value_sets,
      output: amt$local_file_name,
      value: clt$value;


    status.normal := TRUE;

    clp$scan_parameter_list (parameter_list, display_message_pdt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$get_value ('message_module', 1, 1, clc$low, value, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    message_module := value.name.value;

    clp$get_value ('message_name', 1, 1, clc$low, value, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    message_name := value.name.value;

    clp$get_set_count ('message_parameters', number_of_parameters, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    message_parameters := NIL;
    IF number_of_parameters > 0 THEN
      PUSH message_parameters: [1 .. number_of_parameters];
      FOR index := 1 TO number_of_parameters DO
        clp$get_value ('message_parameters', index, 1, clc$low, value, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        PUSH message_parameters^ [index]: [value.str.size];
        message_parameters^ [index]^ := value.str.value;
      FOREND;
    IFEND;

    clp$test_parameter ('margin', margin_specified, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF margin_specified THEN
      clp$get_value ('margin', 1, 1, clc$low, value, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      margin := value.int.value;
    IFEND;

    clp$get_value ('to', 1, 1, clc$low, value, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    output := value.file.local_file_name;

    display_message (message_module, message_name, message_parameters, margin, output, status);

  PROCEND rap$display_message_command;

?? TITLE := 'issue_message', EJECT ??

{ PURPOSE:
{   The purpose of this request is to display a message from a message container to output.
{
{ DESIGN:
{

  PROCEDURE issue_message
    (    message_container: ost$status_message;
         margin: rat$margin;
         output_id: amt$file_identifier;
     VAR status: ost$status);

    VAR
      ignore_byte_address: amt$file_byte_address,
      line: string (osc$max_string_size),
      message_container_ptr: ^ost$status_message,
      message_line: ^ost$status_message_line,
      message_line_count: ^ost$status_message_line_count,
      message_line_index: 1 .. osc$max_status_message_lines,
      message_line_size: ^ost$status_message_line_size;


    status.normal := TRUE;

    message_container_ptr := ^message_container;
    RESET message_container_ptr;
    NEXT message_line_count IN message_container_ptr;

    FOR message_line_index := 1 TO message_line_count^ DO
      NEXT message_line_size IN message_container_ptr;
      NEXT message_line: [message_line_size^] IN message_container_ptr;

      line (1, * ) := '';
      line (margin + 1, * ) := message_line^ (1, message_line_size^);

      amp$put_next (output_id, ^line, message_line_size^ +margin, ignore_byte_address, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND;

  PROCEND issue_message;

?? TITLE := 'display_message', EJECT ??

{ PURPOSE:
{   The purpose of this request is to display the message found in the message module.
{
{ DESIGN:
{

  PROCEDURE display_message
    (    message_module: pmt$program_name;
         message_name: clt$parameter_name;
         message_parameters: ^ost$message_parameters;
         margin: rat$margin;
         output: amt$local_file_name;
     VAR status: ost$status);

    VAR
      close_status: ost$status,
      ignore_natural_language: ost$natural_language,
      ignore_online_manual_name: ost$online_manual_name,
      message_container: ost$status_message,
      message_module_ptr: ^ost$help_module,
      message_template: ^ost$message_template,
      output_id: amt$file_identifier,
      output_open: boolean,
      write_attachment: array [1 .. 3] of fst$attachment_option;

?? NEWTITLE := 'abort_handler', EJECT ??

{ PURPOSE:
{   The purpose of this request is to close the output file on an unexpected abort.
{

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

      VAR
        ignore_status: ost$status;

      IF output_open THEN
        fsp$close_file (output_id, ignore_status);
        output_open := FALSE;
      IFEND;

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    output_open := FALSE;

    osp$establish_block_exit_hndlr (^abort_handler);

  /main/
    BEGIN

      osp$find_help_module (message_module, message_module_ptr, ignore_online_manual_name,
            ignore_natural_language, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      IF message_module_ptr = NIL THEN
        osp$set_status_abnormal (rac$process_id, rae$module_access_error, message_module, status);
        EXIT /main/;
      IFEND;

      write_attachment [1].selector := fsc$access_and_share_modes;
      write_attachment [1].access_modes.selector := fsc$specific_access_modes;
      write_attachment [1].access_modes.value := $fst$file_access_options [fsc$append];
      write_attachment [1].share_modes.selector := fsc$determine_from_access_modes;
      write_attachment [2].selector := fsc$create_file;
      write_attachment [2].create_file := FALSE;
      write_attachment [3].selector := fsc$open_position;
      write_attachment [3].open_position := amc$open_at_eoi;

      fsp$open_file (output, amc$record, ^write_attachment, NIL, NIL, NIL, NIL, output_id, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;
      output_open := TRUE;

      osp$find_parameter_prompt (message_module_ptr, message_name, message_template, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      IF message_template = NIL THEN
        osp$set_status_abnormal (rac$process_id, rae$message_not_found, message_name, status);
        EXIT /main/;
      IFEND;

      osp$format_help_message (message_template, message_parameters, rac$max_line, message_container, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      issue_message (message_container, margin, output_id, status);

    END /main/;

    fsp$close_file (output_id, close_status);
    output_open := FALSE;
    IF status.normal AND (NOT close_status.normal) THEN
      status := close_status;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND display_message;

MODEND ram$message_interfaces;

