?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : INCLUDE Commands and Requests' ??
MODULE clm$include;

{
{ PURPOSE:
{   This module contains the command and program interfaces that initiate and terminate processing
{   of a file or line of commands.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*IF NOT $true(osv$unix)
*copyc clc$command_cleanup_completed
*copyc clc$exiting_condition
*copyc clc$lexical_units_size_pad
*copyc cle$command_line_cancelled
*IFEND
*copyc cle$command_terminated
*copyc cle$ecc_command_processing
*copyc cle$ecc_utilities
*IF NOT $true(osv$unix)
*copyc cle$unable_to_call_util_dlg_mgr
*ELSE
*copyc cle$ecc_lexical
*copyc cle$not_supported
*copyc cle$parameters_displayed
*IFEND
*copyc cle$unexpected_call_to
*IF NOT $true(osv$unix)
*copyc clk$end_include
*copyc clk$end_scan_command_file
*copyc clk$execute_command
*copyc clk$include_file
*copyc clk$include_line
*copyc clk$scan_command_file
*copyc clk$scan_command_line
*copyc clt$async_command_parameters
*copyc clt$command_line
*IFEND
*copyc clt$command_line_index
*IF NOT $true(osv$unix)
*copyc clt$command_line_size
*copyc clt$parameter_list
*IFEND
*copyc clt$prompt
*IF NOT $true(osv$unix)
*copyc clt$prompt_string
*copyc clt$task_name
*copyc clt$task_name_reference
*ELSE
*copyc clt$utility_name
*copyc clt$utility_prompt
*copyc clt$when_condition
*IFEND
*copyc fst$file_reference
*IF NOT $true(osv$unix)
*copyc loc$task_services_library_name
*copyc ost$name
*copyc ost$status
*copyc pmt$task_id
*ELSE
*copyc fst$path
*copyc ost$status_severity
*IFEND
?? POP ??
*IF NOT $true(osv$unix)
*copyc amp$seek_direct
*IFEND
*copyc amv$nil_file_identifier
*IF NOT $true(osv$unix)
*copyc clp$change_variable
*copyc clp$convert_str_to_path_handle
*copyc clp$determine_when_condition
*copyc clp$echo_trace_information
*ELSE
*copyc clp$evaluate_file_reference
*IFEND
*copyc clp$evaluate_parameters
*IF NOT $true(osv$unix)
*copyc clp$execute_named_task
*copyc clp$execution_fault_handler_est
*copyc clp$find_connected_files
*copyc clp$find_current_block
*IFEND
*copyc clp$find_external_input_block
*copyc clp$find_input_block
*copyc clp$find_utility_block
*IF $true(osv$unix)
*copyc clp$free_heap
*IFEND
*copyc clp$get_command_line
*IF NOT $true(osv$unix)
*copyc clp$get_command_search_mode
*ELSE
*copyc clp$get_screen_mode
*IFEND
*copyc clp$get_work_area
*copyc clp$identify_lexical_units
*copyc clp$ignore_rest_of_file
*IF NOT $true(osv$unix)
*copyc clp$initialize_parse_state
*copyc clp$load_system_entry_point
*copyc clp$parse_command
*copyc clp$pop_block_stack
*IFEND
*copyc clp$pop_command_line
*copyc clp$pop_input
*copyc clp$pop_input_stack
*copyc clp$pop_terminated_blocks
*copyc clp$preprocess_command_line
*copyc clp$process_command
*IF NOT $true(osv$unix)
*copyc clp$process_command_fault
*copyc clp$process_execution_fault
*copyc clp$process_exit_condition
*copyc clp$process_when_cond_in_block
*IFEND
*copyc clp$push_command_line
*copyc clp$push_input
*IF NOT $true(osv$unix)
*copyc clp$push_input_line_block
*copyc clp$reset_input_position
*IFEND
*copyc clp$scan_any_lexical_unit
*copyc clp$scan_non_space_lexical_unit
*copyc clp$scan_unnested_cmnd_lex_unit
*copyc clp$set_command_kind
*copyc clp$set_include_processor_state
*copyc clp$set_input_line_finished
*copyc clp$set_input_line_parse
*IF NOT $true(osv$unix)
*copyc clp$set_input_line_position
*IFEND
*copyc clp$trimmed_string_size
*copyc clv$nil_block_handle
*copyc clv$standard_files
*IF NOT $true(osv$unix)
*copyc ifp$discard_suspended_output
*IFEND
*copyc osp$append_status_parameter
*IF NOT $true(osv$unix)
*copyc osp$disestablish_cond_handler
*copyc osp$enforce_exception_policies
*copyc osp$file_access_condition
*copyc osp$establish_block_exit_hndlr
*copyc osp$establish_condition_handler
*IFEND
*copyc osp$find_interaction_info
*copyc osp$generate_message
*IF NOT $true(osv$unix)
*copyc osp$generate_output_message
*IFEND
*copyc osp$get_status_severity
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*IF NOT $true(osv$unix)
*copyc osv$initial_exception_context
*IFEND
*copyc osv$lower_to_upper
*IF NOT $true(osv$unix)
*copyc pmp$cause_condition
*copyc pmp$cause_task_condition
*copyc pmp$change_term_error_level
*copyc pmp$continue_to_cause
*copyc pmp$load
*copyc pmp$pop_task_debug_mode
*copyc pmp$push_task_debug_mode
*copyc pmp$task_state
?? TITLE := 'clt$utility_dialog_manager', EJECT ??
*copyc clh$utility_dialog_manager
*copyc clt$utility_dialog_manager
*copyc clt$utility_dialog_info
?? SKIP := 2 ??

{
{ The following constants define the entry point names for the dynamically
{ loaded utility dialog managers.
{

  CONST
    clc$desktop_util_dialog_mgr = 'DEP$SCL_UTILITY_DIALOG_MGR     ',
    clc$screen_util_dialog_mgr = 'CLP$SCL_UTILITY_DIALOG_MGR     ';

?? SKIP := 2 ??

{
{ The following constant defines the name of the DEBUG utility.  DEBUG does not
{ use an "interactive include processor" but does provide its own screen
{ interface.  Therefore the standard utility dialog manager may not be invoked
{ for the DEBUG utility.
{

  CONST
    dbc$debug_utility_name = 'DEBUG                          ';

*ELSE
{
{ The following constant defines the name of the DEBUG utility.  DEBUG does not
{ use an "interactive include processor" but does provide its own screen
{ interface.  Therefore the standard utility dialog manager may not be invoked
{ for the DEBUG utility.
{

  CONST
    dbc$debug_utility_name = 'DEBUG                          ';

*copyc clp_process_shell_cmd
*copyc cyt$mips_signal_handler
*copyc osv$signal
*copyc osv$signal_status

?? TITLE := 'interactive', EJECT ??

  FUNCTION [INLINE] interactive (input_block: ^clt$block): boolean;

    interactive := (input_block <> NIL) AND
              (input_block^.input.kind = clc$file_input) AND input_block^.input.interactive_device;

  FUNCEND interactive;

*IFEND

?? TITLE := 'clp$read_command_file', EJECT ??

  PROCEDURE [XDCL] clp$read_command_file
    (    file: fst$file_reference;
         utility: clt$utility_name;
         prompt: clt$prompt;
         enable_echoing: boolean;
         initial_command: ^clt$command_line;
         continue_after_initial_command: boolean;
     VAR status: ost$status);

    VAR
*IF NOT $true(osv$unix)
      context: ^ost$ecp_exception_context,
*IFEND
      dialog_manager_name: pmt$program_name,
      end_input_block: ^clt$block,
      exit_status: ost$status,
      file_id: amt$file_identifier,
      handle_interactive_include: ^procedure,
*IF $true(osv$unix)
      handler_stat: boolean,
*IFEND
      input_block: ^clt$block,
      input_block_handle: clt$block_handle,
      interaction_information: ^clt$interaction_information,
      load_from_system: boolean,
      local_status: ^ost$status,
      opened_executable_file: boolean,
      severity: ost$status_severity;

*IF $true(osv$unix)
?? NEWTITLE := 'cleanup', EJECT ??

    PROCEDURE cleanup;

      IF input_block <> NIL THEN
        clp$pop_terminated_blocks (input_block, status);
      IFEND;
      clp$pop_input (FALSE, input_block_handle, file_id, opened_executable_file, ^status, exit_status);
      IF status.normal AND (NOT exit_status.normal) THEN
        status := exit_status;
      IFEND;

    PROCEND cleanup;

?? OLDTITLE ??
*IFEND
?? NEWTITLE := 'read_file_condition_handler', EJECT ??

    PROCEDURE read_file_condition_handler
*IF NOT $true(osv$unix)
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF
      = ifc$interactive_condition =
        IF (condition.interactive_condition = ifc$terminate_break) AND (input_block <> NIL) AND
              (input_block^.input.kind = clc$file_input) AND input_block^.input.interactive_device THEN
          RETURN;
        IFEND;
      = pmc$block_exit_processing =
        IF input_block <> NIL THEN
          clp$pop_terminated_blocks (input_block, status);
          clp$process_exit_condition (input_block, status);
        IFEND;
        clp$pop_input (FALSE, input_block_handle, file_id, opened_executable_file, ^status, exit_status);
        IF status.normal AND (NOT exit_status.normal) THEN
          status := exit_status;
        IFEND;
        RETURN;
      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
*ELSE
      (    signal_no: integer;
           code: integer;
           p_sigcontext: ^cyt$mips_sigcontext);



      CASE signal_no OF
      { pmc$block_exit_processing    -    block exit
      = -1 =
        cleanup;
        IF osc_sigint IN osv$signal THEN
          osv$signal := osv$signal - $ost$signals [osc_sigint];
          osv$signal_status.normal := TRUE;
        IFEND;
        RETURN;
      ELSE
        ;
      CASEND;
*IFEND

    PROCEND read_file_condition_handler;
?? TITLE := 'interactive_include_handler', EJECT ??

    PROCEDURE interactive_include_handler;

      VAR
*IF NOT $true(osv$unix)
        callers_save_area: ^ost$stack_frame_save_area,
        ignore_term_error_level: ost$status_severity,
        loaded_address: pmt$loaded_address,
*IFEND
        local_status: ost$status,
        original_term_error_level: ost$status_severity,
*IF NOT $true(osv$unix)
        utility_dialog_manager: clt$utility_dialog_manager,
*IFEND
        utility_include_processor: clt$utility_interactive_include;

*IF NOT $true(osv$unix)
?? NEWTITLE := 'abort_handler', EJECT ??

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

        VAR
          ignore_status: ost$status;


        pmp$change_term_error_level (original_term_error_level, ignore_term_error_level, ignore_status);

      PROCEND abort_handler;
?? TITLE := 'invoke_condition_handler', EJECT ??

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


        IF (condition.selector = pmc$system_conditions) AND
              (($pmt$system_conditions [pmc$instruction_specification, pmc$address_specification,
              pmc$access_violation, pmc$environment_specification, pmc$invalid_segment_ring_0,
              pmc$out_call_in_return] * condition.system_conditions) <> $pmt$system_conditions []) AND
              (save_area^.minimum_save_area.a2_previous_save_area = callers_save_area) THEN
          CASE input_block^.associated_utility^.interactive_include_processor.call_method OF
          = clc$unspecified_call =
            osp$set_status_condition (cle$unable_to_call_util_dlg_mgr, status);
          = clc$linked_call =
            osp$set_status_condition (cle$unable_to_call_inc_procesor, status);
          ELSE
            osp$set_status_abnormal ('CL', cle$unable_to_call_inc_procesor,
                  input_block^.associated_utility^.interactive_include_processor.procedure_name, status);
          CASEND;
          EXIT clp$read_command_file;
        IFEND;

        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

      PROCEND invoke_condition_handler;
?? OLDTITLE, EJECT ??
      VAR
        context: ^ost$ecp_exception_context;

      context := NIL;
*IFEND

      IF input_block^.associated_utility^.include_processor_active THEN
        osp$set_status_abnormal ('CL', cle$include_processor_active, utility, local_status);
        osp$generate_message (local_status, status);
        status.normal := TRUE;
        RETURN;
      IFEND;

      CASE input_block^.associated_utility^.interactive_include_processor.call_method OF

*IF NOT $true(osv$unix)
      = clc$unspecified_call =

{ Invoke the standard utility "dialog manager".

        loaded_address.kind := pmc$procedure_address;
        loaded_address.pointer_to_procedure := NIL;
        original_term_error_level := osc$fatal_status;
        #SPOIL (original_term_error_level);

        osp$establish_block_exit_hndlr (^abort_handler);

        pmp$change_term_error_level (osc$fatal_status, original_term_error_level, status);
        IF status.normal THEN
          IF load_from_system THEN
            REPEAT
              clp$load_system_entry_point (dialog_manager_name, pmc$procedure_address, loaded_address,
                    status);
              IF NOT status.normal THEN
                IF context = NIL THEN
                  PUSH context;
                  context^ := osv$initial_exception_context;
                IFEND;
                context^.condition_status := status;
                osp$enforce_exception_policies (context^);
                status := context^.condition_status;
              IFEND;
            UNTIL status.normal OR (NOT osp$file_access_condition (status)) OR (NOT context^.wait);
          ELSE
            pmp$load (dialog_manager_name, pmc$procedure_address, loaded_address, status);
          IFEND;
          IF NOT status.normal THEN
            loaded_address.pointer_to_procedure := NIL;
          IFEND;
          pmp$change_term_error_level (original_term_error_level, ignore_term_error_level, status);
        IFEND;

        osp$disestablish_cond_handler;

        IF (NOT status.normal) OR (loaded_address.pointer_to_procedure = NIL) THEN
          osp$set_status_abnormal ('CL', cle$unable_to_call_util_dlg_mgr, dialog_manager_name, status);
          RETURN;
        IFEND;

        #CONVERT_POINTER_TO_PROCEDURE (loaded_address.pointer_to_procedure, utility_dialog_manager);
        utility_include_processor := NIL;
*IFEND

      = clc$linked_call =

        utility_include_processor := input_block^.associated_utility^.interactive_include_processor.proc;

*IF NOT $true(osv$unix)
      = clc$unlinked_call =

        pmp$load (input_block^.associated_utility^.interactive_include_processor.procedure_name,
              pmc$procedure_address, loaded_address, status);

        IF NOT status.normal THEN
          osp$set_status_abnormal ('CL', cle$unable_to_call_inc_procesor,
                input_block^.associated_utility^.interactive_include_processor.procedure_name, status);
          EXIT clp$read_command_file;
        IFEND;

        #CONVERT_POINTER_TO_PROCEDURE (loaded_address.pointer_to_procedure, utility_include_processor);
*IFEND

      ELSE

{ Should never get here.

        osp$set_status_condition (cle$unable_to_call_inc_procesor, status);
        EXIT clp$read_command_file;
      CASEND;

      clp$set_include_processor_state (utility, TRUE, status);
      IF NOT status.normal THEN
        EXIT clp$read_command_file;
      IFEND;

*IF NOT $true(osv$unix)
      callers_save_area := #PREVIOUS_SAVE_AREA ();
      #SPOIL (callers_save_area);
      osp$establish_condition_handler (^invoke_condition_handler, FALSE);
*IFEND

      IF utility_include_processor <> NIL THEN
        utility_include_processor^ (interaction_information^.style, status);
*IF NOT $true(osv$unix)
      ELSE
        utility_dialog_manager^ (utility, ^input_block^.associated_utility^.command_environment.dialog_info,
              status);
*IFEND
      IFEND;

*IF NOT $true(osv$unix)
      osp$disestablish_cond_handler;
*IFEND

      clp$set_include_processor_state (utility, FALSE, local_status);
      IF status.normal AND (NOT local_status.normal) THEN
        status := local_status;
      IFEND;
      IF (NOT status.normal) OR input_block_finished (input_block) THEN
        EXIT clp$read_command_file;
      IFEND;

    PROCEND interactive_include_handler;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    exit_status.normal := TRUE;
    input_block_handle := clv$nil_block_handle;
    file_id := amv$nil_file_identifier;
    #SPOIL (input_block_handle, file_id);
    input_block := NIL;
    handle_interactive_include := NIL;

*IF NOT $true(osv$unix)
    context := NIL;
    osp$establish_condition_handler (^read_file_condition_handler, TRUE);
*ELSE
{ Establish condition handler for block exit

    handler_stat := #establish_condition_handler (-1, ^read_file_condition_handler);
*IFEND

  /read_file/
    BEGIN

*IF NOT $true(osv$unix)
      REPEAT
        clp$push_input (file, utility, prompt, enable_echoing, FALSE, input_block_handle, file_id,
              opened_executable_file, status);
        IF NOT status.normal THEN
          IF context = NIL THEN
            PUSH context;
            context^ := osv$initial_exception_context;
            context^.file.selector := osc$ecp_file_reference;
            context^.file.file_reference := ^file;
          IFEND;
          context^.condition_status := status;
          osp$enforce_exception_policies (context^);
          status := context^.condition_status;
        IFEND;
      UNTIL status.normal OR (NOT osp$file_access_condition (status)) OR (NOT context^.wait);
*ELSE
      clp$push_input (file, utility, prompt, enable_echoing, FALSE, input_block_handle, file_id,
            opened_executable_file, status);
*IFEND
      IF NOT status.normal THEN
        EXIT /read_file/;
      IFEND;
      clp$find_current_block (input_block);

      IF initial_command <> NIL THEN
*IF $true(osv$unix)

{ If we received a signal and we're interactive, then ignore the signal,
{ i.e. clear it and resume execution. Otherwise, get out and let the signal
{ be cleared by someone interactive (this will have to change for batch jobs??)
        IF (osc_sigint IN osv$signal) THEN
          IF NOT interactive (input_block) THEN
            EXIT /read_file/;
          IFEND;
          osv$signal := osv$signal - $ost$signals [osc_sigint];
          osv$signal_status.normal := TRUE;
        IFEND;

*IFEND
        clp$include_command (initial_command^, enable_echoing, status);
*IF $true(osv$unix)

{ If we received a signal and we're interactive, then ignore the signal,
{ i.e. clear it and resume execution. Otherwise, get out and let the signal
{ be cleared by someone interactive (this will have to change for batch jobs??)
        IF (osc_sigint IN osv$signal) THEN
          IF NOT interactive (input_block) THEN
            EXIT /read_file/;
          IFEND;
          osv$signal := osv$signal - $ost$signals [osc_sigint];
          osv$signal_status.normal := TRUE;
        IFEND;

*IFEND
        IF NOT status.normal THEN
          PUSH local_status;
          severity := osc$error_status;
          osp$get_status_severity (status.condition, severity, local_status^);
          IF (severity >= osc$error_status) AND ((input_block^.input.kind <> clc$file_input) OR
                (NOT input_block^.input.interactive_device)) THEN
            EXIT /read_file/;
*IF NOT $true(osv$unix)
          ELSEIF (input_block^.input.kind = clc$file_input) AND
                (input_block^.input.interactive_device OR (input_block^.input.local_file_name =
                clv$standard_files [clc$sf_command_file].path_handle_name)) THEN
*ELSE
          ELSEIF (input_block^.input.kind = clc$file_input) AND
                (input_block^.input.interactive_device) THEN
*IFEND
            osp$generate_message (status, local_status^);
            IF NOT local_status^.normal THEN
              EXIT /read_file/;
            IFEND;
            status.normal := TRUE;
          IFEND;
        IFEND;
        IF NOT continue_after_initial_command THEN
          EXIT /read_file/;
        IFEND;
      IFEND;

      IF input_block^.input.interactive_device AND (utility <> osc$null_name) AND
            (utility <> dbc$debug_utility_name) THEN
        osp$find_interaction_info (interaction_information);
        IF input_block^.associated_utility^.interactive_include_processor.call_method <>
              clc$unspecified_call THEN
          handle_interactive_include := ^interactive_include_handler;
*IF NOT $true(osv$unix)
        ELSEIF interaction_information^.extend_utility_interaction THEN
          CASE interaction_information^.style OF
          = osc$desktop_interaction =
            dialog_manager_name := clc$desktop_util_dialog_mgr;
            load_from_system := FALSE;
            handle_interactive_include := ^interactive_include_handler;
          = osc$screen_interaction =
            dialog_manager_name := clc$screen_util_dialog_mgr;
            load_from_system := TRUE;
            handle_interactive_include := ^interactive_include_handler;
          ELSE { osc$line_interaction }
            ;
          CASEND;
*IFEND
        IFEND;
      IFEND;

*IF $true(osv$unix)

{ If we received a signal and we're interactive, then ignore the signal,
{ i.e. clear it and resume execution. Otherwise, get out and let the signal
{ be cleared by someone interactive (this will have to change for batch jobs??)
        IF (osc_sigint IN osv$signal) THEN
          IF NOT interactive (input_block) THEN
            EXIT /read_file/;
          IFEND;
          osv$signal := osv$signal - $ost$signals [osc_sigint];
          osv$signal_status.normal := TRUE;
        IFEND;

*IFEND
      clp$process_command_file (input_block, handle_interactive_include, status);
*IF $true(osv$unix)

{ If we received a signal and we're interactive, then ignore the signal,
{ i.e. clear it and resume execution. Otherwise, get out and let the signal
{ be cleared by someone interactive (this will have to change for batch jobs??)
        IF (osc_sigint IN osv$signal) THEN
          IF NOT interactive (input_block) THEN
            EXIT /read_file/;
          IFEND;
          osv$signal := osv$signal - $ost$signals [osc_sigint];
          osv$signal_status.normal := TRUE;
        IFEND;

*IFEND
      IF status.normal AND (NOT input_block^.being_exited) THEN
        clp$find_current_block (end_input_block);
        IF end_input_block <> input_block THEN
          osp$set_status_abnormal ('CL', cle$unbalanced_block_structure, end_input_block^.kind_end_name,
                status);
          osp$append_status_parameter (osc$status_parameter_delimiter, input_block^.kind_end_name, status);
        IFEND;
      IFEND;
    END /read_file/;

    IF input_block <> NIL THEN
      clp$pop_terminated_blocks (input_block, status);
*IF NOT $true(osv$unix)
      clp$process_exit_condition (input_block, status);
*IFEND
    IFEND;
    clp$pop_input (FALSE, input_block_handle, file_id, opened_executable_file, ^status, exit_status);
    IF status.normal AND (NOT exit_status.normal) THEN
      status := exit_status;
      #SPOIL (status);
    IFEND;

*IF NOT $true(osv$unix)
    osp$disestablish_cond_handler;
*ELSE
    handler_stat := #disestablish_condition_handler (-1);
*IFEND

  PROCEND clp$read_command_file;
?? TITLE := 'clp$include_file', EJECT ??
*copyc clh$include_file

  PROCEDURE [XDCL, #GATE] clp$include_file
    (    file: fst$file_reference;
         prompt: clt$prompt;
         utility: clt$utility_name;
     VAR status: ost$status);

    VAR
      block_in_current_task: boolean,
      prompt_string: clt$utility_prompt,
*IF $true(osv$unix)
      c_status: integer,
*IFEND
      translated_utility_name: clt$utility_name,
      utility_block: ^clt$block;

    status.normal := TRUE;
*IF $true(osv$unix)
    c_status := 0;
*IFEND

  /include_file/
    BEGIN
      #TRANSLATE (osv$lower_to_upper, utility, translated_utility_name);
      IF translated_utility_name <> osc$null_name THEN
        clp$find_utility_block (translated_utility_name, utility_block, block_in_current_task);
        IF (utility_block = NIL) OR (NOT (utility_block^.command_environment.command_level OR
              block_in_current_task)) THEN
          osp$set_status_abnormal ('CL', cle$unknown_utility, utility, status);
          EXIT /include_file/;
        IFEND;
        prompt_string := utility_block^.prompt;
      ELSE
        prompt_string.size := STRLENGTH (prompt);
        prompt_string.value := prompt (1, prompt_string.size);
      IFEND;

    clp$read_command_file (file, translated_utility_name, prompt_string.value (1, prompt_string.size), TRUE,
          NIL, FALSE, status);
    END /include_file/;

*IF NOT $true(osv$unix)
*ELSE
    IF (NOT status.normal) AND (status.condition <> 0) THEN
      c_status := status.condition;
    IFEND;

*IFEND

  PROCEND clp$include_file;
?? TITLE := 'clp$end_include', EJECT ??
*copyc clh$end_include

  PROCEDURE [XDCL, #GATE] clp$end_include
    (    utility: clt$utility_name;
     VAR status: ost$status);

    VAR
      translated_utility_name: clt$utility_name;


    status.normal := TRUE;

    #TRANSLATE (osv$lower_to_upper, utility, translated_utility_name);
    clp$ignore_rest_of_file (translated_utility_name, status);

  PROCEND clp$end_include;
*IF NOT $true(osv$unix)
?? TITLE := 'clp$get_include_ended', EJECT ??
*copyc clh$get_include_ended

  PROCEDURE [XDCL, #GATE] clp$get_include_ended
    (    utility: clt$utility_name;
     VAR include_ended: boolean;
     VAR status: ost$status);

    VAR
      input_block: ^clt$block,
      translated_utility_name: clt$utility_name;


    status.normal := TRUE;

    #TRANSLATE (osv$lower_to_upper, utility, translated_utility_name);
    clp$find_input_block (TRUE, input_block);
    IF (input_block = NIL) OR (input_block^.label <> translated_utility_name) THEN
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$get_include_ended', status);
      RETURN;
    IFEND;

    include_ended := input_block_finished (input_block);

  PROCEND clp$get_include_ended;
?? TITLE := 'clp$include_line', EJECT ??
*copyc clh$include_line

  PROCEDURE [XDCL, #GATE] clp$include_line
    (    statement_list: clt$command_line;
         enable_echoing: boolean;
         utility: clt$utility_name;
     VAR status: ost$status);

    CONST
      not_input_from_job_command_file = FALSE,
      not_input_origin_is_interactive = FALSE;

    VAR
      block_in_current_task: boolean,
      connected_files: ^clt$connected_files,
      edited_line: ^clt$command_line,
      end_input_block: ^clt$block,
      include_status: ost$status,
      input_block: ^clt$block,
      lexical_units: ^clt$lexical_units,
      lexical_work_area: ^clt$work_area,
      line_size: clt$command_line_size,
      pop_status: ost$status,
      translated_utility: clt$utility_name,
      utility_block: ^clt$block;

?? NEWTITLE := 'handle_condition', EJECT ??

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

      VAR
        condition_processed: boolean,
        exit_control_block: ^clt$block,
        local_status: ost$status,
        when_condition_definition: clt$when_condition_definition;


      IF condition.selector = pmc$block_exit_processing THEN

{ --- Handle block exit.

        IF input_block <> NIL THEN
          clp$pop_terminated_blocks (input_block, include_status);
          clp$process_exit_condition (input_block, include_status);
          IF input_block^.input_can_be_echoed THEN
            clp$find_connected_files (connected_files);
            IF connected_files^.echo_count > 0 THEN
              clp$echo_trace_information ('CLC$ECHO_INCLUDE_LINE_END', ^translated_utility, NIL,
                    ^include_status, pop_status);
            IFEND;
            clp$pop_input_stack (end_input_block, pop_status);
          IFEND;
        IFEND;

      ELSEIF (condition.selector = pmc$user_defined_condition) AND
            (condition.user_condition_name = clc$exiting_condition) THEN

{ --- Handle exit initiated via command level EXIT statement.
{
{ This condition is raised in the task that "owns" the SCL block which is the
{ target of the EXIT statement.
{ This condition is specifically dealt with in the condition handlers that
{ cover processing of the various kinds of input, command and function blocks.
{ The condition_information for this condition is a pointer to the outermost
{ block which is being exited and has such a corresponding condition handler.
{ The handler which is "covering" this "exit_control_block" performs a
{ non-local (CYBIL) exit out of its establishing procedure.
{ Other such handlers simply "continue" the condition.

        IF input_block_finished (input_block) THEN
          exit_control_block := condition_information;
          IF #OFFSET (exit_control_block) <> #OFFSET (input_block) THEN
            pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
          IFEND;
          EXIT clp$include_line;
        IFEND;

      ELSE

{ --- Handle command level condition.

        clp$determine_when_condition (condition, condition_information, save_area,
              when_condition_definition, {ignore} local_status);

        IF when_condition_definition.name <> osc$null_name THEN
          clp$process_when_cond_in_block (when_condition_definition, input_block, FALSE,
                condition_processed, local_status);
          IF local_status.normal AND condition_processed THEN
            RETURN;
          IFEND;
        IFEND;

        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
      IFEND;

    PROCEND handle_condition;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    input_block := NIL;
    include_status.normal := TRUE;
    #SPOIL (input_block, include_status.normal);

    osp$establish_condition_handler (^handle_condition, TRUE);

  /include_line/
    BEGIN
      #TRANSLATE (osv$lower_to_upper, utility, translated_utility);

      IF translated_utility <> osc$null_name THEN
        clp$find_utility_block (translated_utility, utility_block, block_in_current_task);
        IF (utility_block = NIL) OR (NOT (utility_block^.command_environment.command_level OR
              block_in_current_task)) THEN
          osp$set_status_abnormal ('CL', cle$unknown_utility, translated_utility, status);
          EXIT /include_line/;
        IFEND;

{ If we're in a utility, check for a line preprocessor and if present,
{ preprocess the command line.

        line_size := clp$trimmed_string_size (statement_list);
        clp$preprocess_command_line (utility_block^.line_preprocessor, ^statement_list (1, line_size),
              not_input_origin_is_interactive, edited_line, status);
        IF NOT status.normal THEN
          EXIT /include_line/;
        IFEND;
        IF edited_line = NIL THEN
          edited_line := ^statement_list;
        IFEND;
      ELSE
        edited_line := ^statement_list;
      IFEND;

      input_block := NIL;
      #SPOIL (input_block);

      line_size := clp$trimmed_string_size (edited_line^);
      edited_line := ^edited_line^ (1, line_size);
      PUSH lexical_work_area: [[REP line_size + clc$lexical_units_size_pad OF clt$lexical_unit]];
      RESET lexical_work_area;
      clp$identify_lexical_units (edited_line, lexical_work_area, lexical_units, status);
      IF NOT status.normal THEN
        EXIT /include_line/;
      IFEND;


      clp$push_input_line_block (translated_utility, enable_echoing, edited_line, lexical_units, input_block);
      #SPOIL (input_block);

      clp$find_connected_files (connected_files);
      IF input_block^.input_can_be_echoed AND (connected_files^.echo_count > 0) THEN
        clp$echo_trace_information ('CLC$ECHO_INCLUDE_LINE_BEGIN', ^translated_utility, NIL, NIL, status);
        status.normal := TRUE;
      IFEND;

      process_command_line (input_block, enable_echoing, not_input_origin_is_interactive,
            not_input_from_job_command_file, include_status);

      IF include_status.normal AND (NOT input_block^.being_exited) THEN
        clp$find_current_block (end_input_block);
        IF end_input_block <> input_block THEN
          osp$set_status_abnormal ('CL', cle$unbalanced_block_structure, end_input_block^.kind_end_name,
                include_status);
          osp$append_status_parameter (osc$status_parameter_delimiter, input_block^.kind_end_name,
                include_status);
        IFEND;
      IFEND;

    END /include_line/;

    IF input_block <> NIL THEN
      clp$pop_terminated_blocks (input_block, include_status);
      clp$process_exit_condition (input_block, include_status);
      IF input_block^.input_can_be_echoed THEN
        clp$find_connected_files (connected_files);
        IF connected_files^.echo_count > 0 THEN
          clp$echo_trace_information ('CLC$ECHO_INCLUDE_LINE_END', ^translated_utility, NIL, ^include_status,
                pop_status);
        IFEND;
      IFEND;
      clp$pop_input_stack (end_input_block, pop_status);
    IFEND;

    input_block := NIL;
    #SPOIL (input_block);
    osp$disestablish_cond_handler;

    IF NOT include_status.normal THEN
      status := include_status;
    ELSEIF NOT pop_status.normal THEN
      status := pop_status;
    IFEND;

  PROCEND clp$include_line;
?? TITLE := 'clp$scan_command_file', EJECT ??
*copyc clh$scan_command_file

  PROCEDURE [XDCL, #GATE] clp$scan_command_file
    (    file: fst$file_reference;
         utility_name: ost$name;
         prompt_string: clt$prompt_string;
     VAR status: ost$status);

    VAR
      block_in_current_task: boolean,
      translated_utility_name: clt$utility_name,
      utility_block: ^clt$block;


    status.normal := TRUE;

  /scan_command_file/
    BEGIN
      #TRANSLATE (osv$lower_to_upper, utility_name, translated_utility_name);
      IF translated_utility_name <> osc$null_name THEN
        clp$find_utility_block (translated_utility_name, utility_block, block_in_current_task);
        IF (utility_block = NIL) OR (NOT (utility_block^.command_environment.command_level OR
              block_in_current_task)) THEN
          osp$set_status_abnormal ('CL', cle$unknown_utility, utility_name, status);
          EXIT /scan_command_file/;
        IFEND;
      IFEND;
      clp$read_command_file (file, translated_utility_name, prompt_string, TRUE, NIL, FALSE, status);
    END /scan_command_file/;

  PROCEND clp$scan_command_file;
?? TITLE := 'clp$end_scan_command_file', EJECT ??
*copyc clh$end_scan_command_file

  PROCEDURE [XDCL, #GATE] clp$end_scan_command_file
    (    utility_name: ost$name;
     VAR status: ost$status);

    VAR
      translated_utility_name: ost$name;


    status.normal := TRUE;
    clp$end_include (utility_name, status);

  PROCEND clp$end_scan_command_file;
?? TITLE := 'clp$scan_command_line', EJECT ??
*copyc clh$scan_command_line

  PROCEDURE [XDCL, #GATE] clp$scan_command_line
    (    text: string ( * );
     VAR status: ost$status);

    VAR
      block: ^clt$block;


    status.normal := TRUE;
    clp$find_current_block (block);
    clp$include_line (text, (block = NIL) OR block^.input_can_be_echoed, osc$null_name, status);

  PROCEND clp$scan_command_line;
?? TITLE := 'clp$execute_command', EJECT ??
*copyc clh$execute_command

  PROCEDURE [XDCL, #GATE] clp$execute_command
    (    command: clt$command_line;
         command_file: fst$file_reference;
         enable_echoing: boolean;
         task_name: clt$task_name_reference;
     VAR task_id: pmt$task_id;
     VAR status: ost$status);

    CONST
      desktop_task_name_prefix = 'DET$',
      desktop_task_name_prefix_size = 4;

    VAR
      command_file_name: fst$path_handle_name,
      command_parameters: ^clt$async_command_parameters,
      command_size: clt$command_line_size,
      command_text: ^clt$command_line,
      evaluated_file_reference: fst$evaluated_file_reference,
      lexical_units: ^clt$lexical_units,
      parse: clt$parse_state,
      program_attributes: ^pmt$program_attributes,
      program_description: ^pmt$program_description,
      program_description_area: SEQ (pmt$program_attributes, amt$local_file_name),
      program_library_list: ^pmt$object_library_list,
      program_parameters: ^pmt$program_parameters,
      translated_task_name: clt$task_name,
      work_area: ^clt$work_area;


  /execute/
    BEGIN
      status.normal := TRUE;

{ Check the task name

      IF (task_name = osc$null_name) THEN
        osp$set_status_abnormal ('CL', cle$invalid_exec_task_name, '"null"', status);
        EXIT /execute/;
      IFEND;

{ Is the command file name reasonable ?

      IF (command_file = osc$null_name) THEN
        command_file_name := osc$null_name;
      ELSE
        clp$convert_str_to_path_handle (command_file, FALSE, TRUE, FALSE, command_file_name,
              evaluated_file_reference, status);
        IF NOT status.normal THEN
          EXIT /execute/;
        ELSEIF evaluated_file_reference.path_resolution = fsc$command_file_path THEN
          osp$set_status_abnormal ('CL', cle$incorrect_exec_command_file, command_file_name, status);
        IFEND;
      IFEND;

      IF NOT status.normal THEN
        EXIT /execute/;
      IFEND;

{ Is it a nonempty command ?

      IF command = '' THEN
        osp$set_status_abnormal ('CL', cle$invalid_exec_command, 'EMPTY', status);
        EXIT /execute/;
      IFEND;

{ Set up the program parameters including the command's parse state.

      command_size := clp$trimmed_string_size (command);
      PUSH work_area: [[clt$async_command_parameters, REP command_size OF char,
            REP command_size + clc$lexical_units_size_pad OF clt$lexical_unit]];
      RESET work_area;
      NEXT command_parameters IN work_area;
      NEXT command_text: [command_size] IN work_area;
      command_text^ (1, command_size) := command (1, command_size);
      clp$identify_lexical_units (command_text, work_area, lexical_units, status);
      IF NOT status.normal THEN
        EXIT /execute/;
      IFEND;
      clp$initialize_parse_state (command_text, lexical_units, parse);
      clp$scan_non_space_lexical_unit (parse);
      command_parameters^.parse := parse;

{ Is there only one command in the command line ?

      clp$scan_unnested_cmnd_lex_unit (parse);
      IF parse.unit.kind <> clc$lex_end_of_line THEN
        osp$set_status_abnormal ('CL', cle$multiple_execute_command, command, status);
        EXIT /execute/;
      IFEND;

{ Complete setup of program parameters.

      #TRANSLATE (osv$lower_to_upper, task_name, translated_task_name);

      RESET work_area;
      NEXT program_parameters: [[clt$async_command_parameters, REP command_size OF char, REP
            UPPERBOUND (lexical_units^) OF clt$lexical_unit]] IN work_area;
      command_parameters^.command_can_be_echoed := enable_echoing;
      command_parameters^.init_from_desktop_environment :=
            translated_task_name (1, desktop_task_name_prefix_size) = desktop_task_name_prefix;
      command_parameters^.text_size := command_size;
      command_parameters^.units_array_size := UPPERBOUND (lexical_units^);

{ Let's do it!

      program_description := ^program_description_area;
      RESET program_description;
      NEXT program_attributes IN program_description;
      program_attributes^.contents := $pmt$prog_description_contents
            [pmc$starting_proc_specified, pmc$library_list_specified, pmc$load_map_file_specified,
            pmc$load_map_options_specified, pmc$term_error_level_specified, pmc$abort_file_specified,
            pmc$debug_mode_specified];
      program_attributes^.starting_procedure := 'CLP$ASYNCHRONOUS_COMMAND';
      program_attributes^.number_of_libraries := 1;
      NEXT program_library_list: [1 .. 1] IN program_description;
      program_library_list^ [1] := loc$task_services_library_name;
      program_attributes^.load_map_file := clv$standard_files [clc$sf_null_file].path_handle_name;
      program_attributes^.load_map_options := $pmt$load_map_options [pmc$no_load_map];
      program_attributes^.termination_error_level := LOWERVALUE (pmt$termination_error_level);
      program_attributes^.abort_file := clv$standard_files [clc$sf_null_file].path_handle_name;
      program_attributes^.debug_mode := FALSE;

      clp$execute_named_task (translated_task_name, #RING (program_parameters), program_description^,
            program_parameters^, command_file_name, task_id, status);
    END /execute/;

  PROCEND clp$execute_command;
*IFEND
?? TITLE := 'clp$include_command', EJECT ??
*copyc clh$include_command

  PROCEDURE [XDCL, #GATE] clp$include_command
    (    command: clt$command_line;
         enable_echoing: boolean;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
      command_size: clt$command_line_size,
      edited_line: ^clt$command_line,
      external_input_block: ^clt$block,
*IF $true(osv$unix)
      handler_established: boolean,
*IFEND
      include_status: ost$status,
      input_block: ^clt$block,
      input_from_external_file: boolean,
      input_from_job_command_file: boolean,
      input_origin_is_interactive: boolean,
      lexical_units: ^clt$lexical_units,
      lexical_work_area: ^clt$work_area;

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

    PROCEDURE abort_handler
*IF $true(osv$unix)
      (    signal_no: integer;
           code: integer;
           p_sigcontext: ^cyt$mips_sigcontext);
*ELSE
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);
*IFEND

      IF input_block <> NIL THEN
        WHILE (input_block^.line_parse.unit.kind = clc$lex_end_of_line) AND
              (input_block^.input.pushed_line <> NIL) DO
          clp$pop_command_line;
          #SPOIL (input_block^);
        WHILEND;
      IFEND;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    input_block := NIL;
    #SPOIL (input_block);

*IF $true(osv$unix)
    osv$signal := $ost$signals [];
    handler_established := #establish_condition_handler (-1, ^abort_handler);
*ELSE
    osp$establish_block_exit_hndlr (^abort_handler);
*IFEND

  /include_command/
    BEGIN

{ If we're in a utility, check for a line preprocessor and if present,
{ preprocess the command line.

      clp$find_input_block (TRUE, input_block);
      IF (input_block <> NIL) AND (input_block^.associated_utility <> NIL) AND
            (input_block^.line_preprocessor_specified) THEN

        command_size := clp$trimmed_string_size (command);
        clp$preprocess_command_line (input_block^.associated_utility^.line_preprocessor, ^command
              (1, command_size), FALSE {input_origin_is_interactive} , edited_line, status);
        IF NOT status.normal THEN
          EXIT /include_command/;
        IFEND;
        IF edited_line = NIL THEN
          edited_line := ^command;
        IFEND;
      ELSE
        edited_line := ^command;
      IFEND;

      input_block := NIL;
      command_size := clp$trimmed_string_size (edited_line^);
      edited_line := ^edited_line^ (1, command_size);
      PUSH lexical_work_area: [[REP command_size + clc$lexical_units_size_pad OF clt$lexical_unit]];
      RESET lexical_work_area;
      clp$identify_lexical_units (edited_line, lexical_work_area, lexical_units, include_status);
      IF NOT include_status.normal THEN
        EXIT /include_command/;
      IFEND;

      clp$push_command_line (edited_line, lexical_units, input_block);
      IF input_block = NIL THEN
        osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$include_command', include_status);
        EXIT /include_command/;
      IFEND;

      clp$find_current_block (block);
      IF input_block^.input.internal THEN
        clp$find_external_input_block (external_input_block);
      ELSE
        external_input_block := input_block;
      IFEND;
      input_from_external_file := (external_input_block <> NIL) AND
            (external_input_block^.input.kind = clc$file_input);
      input_origin_is_interactive := input_from_external_file AND
            external_input_block^.input.interactive_device;
*IF NOT $true(osv$unix)
      input_from_job_command_file := input_from_external_file AND
            (external_input_block^.input.local_file_name = clv$standard_files [clc$sf_command_file].
            path_handle_name);
      process_command_line (input_block, enable_echoing AND block^.input_can_be_echoed,
*ELSE
      input_from_job_command_file := input_from_external_file;
      process_command_line (input_block, FALSE,
*IFEND
            input_origin_is_interactive, input_from_job_command_file, include_status);

      WHILE (input_block^.line_parse.unit.kind = clc$lex_end_of_line) AND
            (input_block^.input.pushed_line <> NIL) DO
        clp$pop_command_line;
*IF NOT $true(osv$unix)
        #SPOIL (input_block^);
*IFEND
      WHILEND;
    END /include_command/;

*IF $true(osv$unix)
    IF handler_established THEN
      handler_established := NOT #disestablish_condition_handler (-1);
    IFEND;
*ELSE
    osp$disestablish_cond_handler;
*IFEND

    IF NOT include_status.normal THEN
      status := include_status;
    IFEND;

  PROCEND clp$include_command;
?? TITLE := 'input_block_finished', EJECT ??

  FUNCTION [INLINE] input_block_finished
    (    input_block: ^clt$block): boolean;

    input_block_finished := (input_block^.being_exited) AND
          (input_block^.input.interactive_device OR ((input_block^.associated_utility = NIL) OR
          (input_block^.associated_utility^.command_environment.commands = NIL) OR
          input_block^.associated_utility^.termination_command_found));

  FUNCEND input_block_finished;
?? TITLE := 'clp$process_command_file', EJECT ??

  PROCEDURE [XDCL] clp$process_command_file
    (    input_block: ^clt$block;
         handle_interactive_include: ^procedure;
     VAR status: ost$status);

    VAR
      current_block: ^clt$block,
      end_of_input: boolean,
      external_input_block: ^clt$block,
      first_time: boolean,
      input_from_external_file: boolean,
      input_from_job_command_file: boolean,
      input_origin_is_interactive: boolean,
      parse: clt$parse_state,
      reset_line_parse: clt$parse_state,
      retry_get: boolean;

*IF NOT $true(osv$unix)
?? NEWTITLE := 'handle_command_level_condition', EJECT ??

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

      VAR
        condition_processed: boolean,
        exit_control_block: ^clt$block,
        local_status: ost$status,
        when_condition_definition: clt$when_condition_definition;


      IF (condition.selector = pmc$user_defined_condition) AND
            (condition.user_condition_name = clc$exiting_condition) THEN

{ --- Handle exit initiated via command level EXIT statement.
{
{ This condition is raised in the task that "owns" the SCL block which is the
{ target of the EXIT statement.
{ This condition is specifically dealt with in the condition handlers that
{ cover processing of the various kinds of input, command and function blocks.
{ The condition_information for this condition is a pointer to the outermost
{ block which is being exited and has such a corresponding condition handler.
{ The handler which is "covering" this "exit_control_block" performs a
{ non-local (CYBIL) exit out of its establishing procedure.
{ Other such handlers simply "continue" the condition.

        IF input_block_finished (input_block) THEN
          exit_control_block := condition_information;
          IF #OFFSET (exit_control_block) <> #OFFSET (input_block) THEN
            pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
          IFEND;
          EXIT clp$process_command_file;
        IFEND;

      ELSE

{ --- Handle command level condition.

        clp$determine_when_condition (condition, condition_information, save_area,
              when_condition_definition, {ignore} local_status);

        IF when_condition_definition.name <> osc$null_name THEN
          clp$process_when_cond_in_block (when_condition_definition, input_block, FALSE,
                condition_processed, local_status);
          IF local_status.normal AND condition_processed THEN
            RETURN;
          IFEND;
        IFEND;

        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
      IFEND;

    PROCEND handle_command_level_condition;
*IFEND
?? TITLE := 'handle_status', EJECT ??

    PROCEDURE handle_status;

      VAR
        local_status: ost$status,
        severity: ost$status_severity;


      severity := osc$error_status;
      osp$get_status_severity (status.condition, severity, local_status);
      IF (severity >= osc$error_status) AND ((input_block^.input.kind <> clc$file_input) OR
            (NOT input_block^.input.interactive_device)) THEN
        EXIT clp$process_command_file;
      IFEND;

*IF NOT $true(osv$unix)
      IF (input_block^.input.kind = clc$file_input) AND (input_block^.input.interactive_device OR
            (input_block^.input.local_file_name = clv$standard_files [clc$sf_command_file].path_handle_name))
            THEN
*ELSE
      IF (input_block^.input.kind = clc$file_input) AND input_block^.input.interactive_device THEN
*IFEND
        osp$generate_message (status, local_status);
        IF NOT local_status.normal THEN
          EXIT clp$process_command_file;
        IFEND;
        status.normal := TRUE;
      IFEND;

    PROCEND handle_status;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

*IF NOT $true(osv$unix)
    osp$establish_condition_handler (^handle_command_level_condition, FALSE);
*IFEND

    first_time := TRUE;

    IF input_block^.input.internal THEN
      clp$find_external_input_block (external_input_block);
    ELSE
      external_input_block := input_block;
    IFEND;
    input_from_external_file := (external_input_block <> NIL) AND
          (external_input_block^.input.kind = clc$file_input);
    input_origin_is_interactive := input_from_external_file AND
          external_input_block^.input.interactive_device;
    input_from_job_command_file := input_from_external_file AND
*IF NOT $true(osv$unix)
          (external_input_block^.input.local_file_name = clv$standard_files [clc$sf_command_file].
          path_handle_name);
*ELSE
          (external_input_block^.input.local_file_name = clv$standard_files [clc$sf_command_file].
          unix_file_name);
*IFEND

    REPEAT
      IF (NOT first_time) OR (input_block^.line_parse.unit.kind <> clc$lex_end_of_line) OR
            (input_block^.input.pushed_line <> NIL) THEN

      /process_line/
        WHILE TRUE DO
          WHILE (input_block^.line_parse.unit.kind = clc$lex_end_of_line) AND
                (input_block^.input.pushed_line <> NIL) DO
            clp$pop_command_line;
            #SPOIL (input_block^);
          WHILEND;
          IF input_block^.line_parse.unit.kind = clc$lex_end_of_line THEN
            EXIT /process_line/;
          IFEND;

          clp$find_current_block (current_block);
*IF NOT $true(osv$unix)
          process_command_line (input_block, current_block^.input_can_be_echoed, input_origin_is_interactive,
*ELSE
          IF (osc_sigint IN osv$signal) THEN
            IF interactive (input_block) THEN
              osv$signal := osv$signal - $ost$signals [osc_sigint];
              osv$signal_status.normal := TRUE;
            ELSE
              RETURN;
            IFEND;
          IFEND;
          process_command_line (input_block, FALSE, input_origin_is_interactive,
*IFEND
                input_from_job_command_file, status);
*IF $true(osv$unix)
          IF (osc_sigint IN osv$signal) THEN
            IF interactive (input_block) THEN
              osv$signal := osv$signal - $ost$signals [osc_sigint];
              osv$signal_status.normal := TRUE;
            ELSE
              RETURN;
            IFEND;
          IFEND;
*IFEND
          IF NOT status.normal THEN
            handle_status;
          IFEND;

          IF input_block_finished (input_block) THEN
            RETURN;
          ELSEIF (input_block^.input.kind <> clc$line_input) AND
                (input_block^.input.state = clc$reset_input) THEN
            WHILE input_block^.input.pushed_line <> NIL DO
              clp$pop_command_line;
              #SPOIL (input_block^);
            WHILEND;
            EXIT /process_line/;
          IFEND;
        WHILEND /process_line/;
      IFEND;

*IF $true(osv$unix)
      IF (osc_sigint IN osv$signal) THEN
        IF interactive (input_block) THEN
          osv$signal := osv$signal - $ost$signals [osc_sigint];
          osv$signal_status.normal := TRUE;
        ELSE
          RETURN;
        IFEND;
      IFEND;
*IFEND
      IF (input_block^.previous_block^.kind = clc$utility_block) AND
            (input_block^.previous_block^.notify_before_command_read <> NIL) THEN
        input_block^.previous_block^.notify_before_command_read^ (status);
        IF NOT status.normal THEN
*IF NOT $true(osv$unix)
          handle_status;
*ELSE
          RETURN;
*IFEND
        IFEND;
      IFEND;

*IF NOT $true(osv$unix)
      IF (input_block^.input.kind <> clc$line_input) AND (input_block^.input.state = clc$reset_input) THEN
        IF (input_block^.input.data = NIL) AND input_block^.input.file_rereadable THEN
          amp$seek_direct (input_block^.input.file_id, input_block^.input.reset_line_identifier.byte_address,
                status);
          IF NOT status.normal THEN
            handle_status;
          IFEND;
        IFEND;
        reset_line_parse := input_block^.input.reset_line_parse;
        clp$set_input_line_position (input_block^.input.reset_line_identifier);
        clp$get_command_line (parse, end_of_input, status);
        IF NOT status.normal THEN
          IF status.condition = cle$unable_to_call_preprocessor THEN
            EXIT clp$process_command_file;
          IFEND;
          handle_status;
        IFEND;
        IF reset_line_parse.text <> NIL THEN
          clp$set_input_line_parse (reset_line_parse);
        IFEND;

      ELSE
*ELSE
        IF (osc_sigint IN osv$signal) THEN
          IF interactive (input_block) THEN
            osv$signal := osv$signal - $ost$signals [osc_sigint];
            osv$signal_status.normal := TRUE;
          ELSE
            RETURN;
          IFEND;
        IFEND;
*IFEND
        IF first_time AND (handle_interactive_include <> NIL) THEN
          handle_interactive_include^;
        IFEND;

        REPEAT
          retry_get := FALSE;
          REPEAT
*IF $true(osv$unix)
          IF (osc_sigint IN osv$signal) THEN
            IF interactive (input_block) THEN
              osv$signal := osv$signal - $ost$signals [osc_sigint];
              osv$signal_status.normal := TRUE;
            ELSE
              RETURN;
            IFEND;
          IFEND;
*IFEND
            clp$get_command_line (parse, end_of_input, status);
*IF NOT $true(osv$unix)
          UNTIL status.normal OR (status.condition <> cle$command_line_cancelled);
*ELSE
          IF (osc_sigint IN osv$signal) THEN
            IF interactive (input_block) THEN
              osv$signal := osv$signal - $ost$signals [osc_sigint];
              osv$signal_status.normal := TRUE;
            ELSE
              RETURN;
            IFEND;
          IFEND;
          UNTIL status.normal;
*IFEND
          IF NOT status.normal THEN
*IF NOT $true(osv$unix)
            IF (status.condition = cle$unable_to_call_preprocessor) OR (pmp$task_state () <> pmc$task_active)
*ELSE
            IF (status.condition = cle$unable_to_call_preprocessor)
*IFEND
                  THEN
              EXIT clp$process_command_file;
            IFEND;
*IF NOT $true(osv$unix)
            handle_status;
*ELSE
            RETURN;
*IFEND
            retry_get := status.normal;
          IFEND;

        UNTIL NOT (status.normal AND retry_get);
*IF NOT $true(osv$unix)
      IFEND;
*IFEND

      first_time := FALSE;
    UNTIL (NOT status.normal) OR end_of_input;

  PROCEND clp$process_command_file;
?? TITLE := 'process_command_line', EJECT ??

{
{ PURPOSE:
{   This routine is responsible for processing a line containing SCL statements.
{
{ NOTES:
{   1. A condition handler is established to catch the aborting of a command due to a programmatic error.
{   2. A condition handler is established for interactive terminate break if the command line came from a
{      terminal file.  This handler provides the means for terminating the last command entered from the
{      teminal.
{   3. The ability to retry a command via the CONTINUE RETRY statement is provided by employing a "user"
{      defined condition handler which provides the means for the CONTINUE RETRY statement to "get back"
{      to this routine.
{

  PROCEDURE process_command_line
    (    input_block: ^clt$block;
         input_can_be_echoed: boolean;
         input_origin_is_interactive: boolean;
         input_from_job_command_file: boolean;
     VAR status: ost$status);

    CONST
      not_from_execute_command = FALSE;

    VAR
      block_at_start_of_command: ^clt$block,
      block_at_start_of_line: ^clt$block,
      cause_condition: clt$when_condition,
      command_parse: clt$parse_state,
*IF NOT $true(osv$unix)
      connected_files: ^clt$connected_files,
*IFEND
      done_with_line: boolean,
*IF $true(osv$unix)
      handler_stat: boolean,
*IFEND
      line_identifier: clt$line_identifier,
      line_index: clt$command_line_index,
      parse: clt$parse_state,
      process_the_command: boolean,
      processing_original_command: boolean,
      retry_command: boolean,
      severity: ost$status_severity,
*IF $true(osv$unix)
      shell_command: ^string(*),
      shell_command_length: integer,
*IFEND
      terminate_break_detected: boolean;

?? NEWTITLE := 'command_line_condition_handler', EJECT ??

{
{ PURPOSE:
{   This condition handler is responsible for dealing with a terminate break
{   entered while processing a command line from an interactive file.  It
{   first checks for a WHEN/WHENEND handler established at this level for
{   TERMINATE.  If no such handler was established or that handler "continued"
{   the condition, this handler halts processing of the entire command line.
{
{ NOTE:
{   The termination of command line processing is accomplished in two stages.
{   First, this handler detects the terminate break and does a non-local
{   exit out the process_command_line routine.  Second, it regains control
{   as a block exit condtion handler at which time it does the remaining
{   cleanup work.  This two step approach is used so that procedures called
{   by process_command_line can perform the cleanup that they are responsible
{   for, thereby getting the command environment back to as close to its state
{   upon entry to process_command_line as possible before doing the last bit
{   of tiddying up.
{

    PROCEDURE command_line_condition_handler
*IF NOT $true(osv$unix)
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);
*ELSE
      (    signal_no: integer;
           code: integer;
           p_sigcontext: ^cyt$mips_sigcontext);
*IFEND

      VAR
*IF NOT $true(osv$unix)
        condition_definition: ^clt$when_condition_definition,
        condition_processed: boolean,
*IFEND
        local_status: ost$status;


*IF NOT $true(osv$unix)
      CASE condition.selector OF

      = pmc$block_exit_processing =
        IF terminate_break_detected THEN

*ELSE

      CASE signal_no OF
      { pmc$block_exit_processing    -    block exit
      = -1 =
        IF osc_sigint IN osv$signal THEN
*IFEND
          status.normal := TRUE;
          clp$pop_terminated_blocks (block_at_start_of_line, status);
          IF input_block^.line_parse.unit.kind <> clc$lex_end_of_line THEN
            clp$set_input_line_finished;
          IFEND;
*IF NOT $true(osv$unix)
          ifp$discard_suspended_output;
*IFEND
          osp$set_status_condition (cle$command_terminated, local_status);
*IF NOT $true(osv$unix)
          osp$generate_output_message (local_status, status);
*ELSE
          osp$generate_message (local_status, status);
          osv$signal := osv$signal - $ost$signals [osc_sigint];
          osv$signal_status.normal := TRUE;
*IFEND
        IFEND;
        RETURN;

*IF NOT $true(osv$unix)
      = ifc$interactive_condition =
        IF (condition.interactive_condition = ifc$terminate_break) AND
              (input_block^.input.kind = clc$file_input) AND input_block^.input.interactive_device THEN
          PUSH condition_definition;
          condition_definition^.name := clc$wc_terminate;
          condition_definition^.status.normal := TRUE;
          condition_definition^.limit_name := osc$null_name;
          clp$process_when_cond_in_block (condition_definition^, input_block, TRUE, condition_processed,
                local_status);
          IF local_status.normal AND condition_processed THEN
            RETURN;
          IFEND;
          terminate_break_detected := TRUE;
          EXIT process_command_line;
        IFEND;
*IFEND

      ELSE
        ;
      CASEND;

*IF NOT $true(osv$unix)
      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
*IFEND

    PROCEND command_line_condition_handler;
?? TITLE := 'handle_command_condition', EJECT ??

    PROCEDURE handle_command_condition;

      VAR
*IF NOT $true(osv$unix)
        condition_processed_state: clt$condition_processed_state,
        condition_status: ^ost$status,
        force_command_fault: boolean,
        local_status: ost$status,
        retry_command_image: ^clt$command_line;

?? NEWTITLE := 'initiate_command_retry', EJECT ??

      PROCEDURE initiate_command_retry;

        VAR
          lexical_units: ^clt$lexical_units,
          work_area: ^^clt$work_area;


        status.normal := TRUE;
        clp$pop_terminated_blocks (block_at_start_of_command, status);
        IF NOT status.normal THEN
          EXIT handle_command_condition;
        IFEND;

{ PARSE must be input/output on following call in case text or units_array have moved.

        clp$reset_input_position (line_identifier, parse);

        IF retry_command_image <> NIL THEN
          processing_original_command := FALSE;

          clp$get_work_area (#RING (^work_area), work_area, status);
          IF NOT status.normal THEN
            EXIT handle_command_condition;
          IFEND;
          clp$identify_lexical_units (retry_command_image, work_area^, lexical_units, status);
          IF NOT status.normal THEN
            EXIT handle_command_condition;
          IFEND;
          clp$initialize_parse_state (retry_command_image, lexical_units, command_parse);
          clp$scan_non_space_lexical_unit (command_parse);

        ELSEIF processing_original_command THEN
          command_parse.text := parse.text;
          command_parse.units_array := parse.units_array;
        IFEND;

        retry_command := TRUE;
        EXIT handle_command_condition;

      PROCEND initiate_command_retry;
?? OLDTITLE, EJECT ??
*ELSE
        errno: ost_c_integer,
        in_screen_mode: boolean,
        shell_cmnd: string (256),
        stat: integer,
        syserrlist_message: string (256),
        local_status: ost$status;


      IF status.condition = cle$epix_command_requested THEN
        shell_cmnd := shell_command^ (2, shell_command_length - 1);
        clp$get_screen_mode (in_screen_mode);
        clp_process_shell_cmd (shell_cmnd, shell_command_length - 1, $INTEGER(in_screen_mode), errno,
              syserrlist_message, stat);
        IF stat = 0 THEN
          status.normal := TRUE;
{         RETURN;
        ELSEIF stat = 4 THEN
          status.condition := cle$command_terminated;
        IFEND;
{     ELSEIF status.condition = cle$parameters_displayed THEN
{       status.condition := cle$unknown_command;
      IFEND;

*IFEND

{ Determine condition's status and severity.

      IF status.normal THEN
        severity := osc$informative_status;
*IF NOT $true(osv$unix)
        IF (cause_condition = clc$wc_command_fault) OR (cause_condition = clc$wc_execution_fault) THEN
*IFEND
          RETURN;
*IF NOT $true(osv$unix)
        IFEND;
        force_command_fault := FALSE;
*IFEND
      ELSE
        severity := osc$error_status;
        osp$get_status_severity (status.condition, severity, local_status);
*IF NOT $true(osv$unix)
        IF cause_condition = osc$null_name THEN
          force_command_fault := severity >= osc$error_status;
          cause_condition := clc$wc_command_fault;
        ELSE
          force_command_fault := TRUE;
        IFEND;
*IFEND
      IFEND;

*IF NOT $true(osv$unix)
      condition_status := NIL;

      IF cause_condition = clc$wc_command_fault THEN

      /process_command_fault/
        BEGIN

{ A COMMAND_FAULT for a command that came from clp$inlcude_command should be
{ treated as an EXECUTION_FAULT so that, by default, its termination status
{ can be handled by the caller of that request.

          IF input_block^.input.pushed_line <> NIL THEN
            cause_condition := clc$wc_execution_fault;
            EXIT /process_command_fault/;
          IFEND;

          IF (severity >= osc$error_status) OR force_command_fault THEN
            IF condition_status = NIL THEN
              PUSH condition_status;
            IFEND;
            condition_status^ := status;

{ Make the command line status normal while processing the condition in case a
{ handler EXITs.

            status.normal := TRUE;
            #SPOIL (status.normal);
            clp$process_command_fault (condition_status^, input_block, retry_command_image,
                  condition_processed_state, local_status);

            IF NOT local_status.normal THEN
              status := condition_status^;
              RETURN;
            IFEND;
            CASE condition_processed_state OF
            = clc$continue_next =
              RETURN;
            = clc$continue_retry =
              initiate_command_retry {control not returned } ;
            ELSE {clc$no_handler_established, clc$continue_next_handler, clc$continue_next_user_handler}
              status := condition_status^;
              IF severity >= osc$error_status THEN
                cause_condition := clc$wc_execution_fault;
                EXIT /process_command_fault/
              IFEND;
            CASEND;
          IFEND;

          IF input_origin_is_interactive THEN

{ "Log" informative or warning status for interactive command.

            osp$generate_message (status, local_status);
            IF local_status.normal THEN
              status.normal := TRUE;
            IFEND;
          IFEND;

          RETURN;
        END /process_command_fault/;
      IFEND;

      IF cause_condition = clc$wc_execution_fault THEN

{ Process EXECUTION_FAULT.

        IF clp$execution_fault_handler_est () THEN
          IF condition_status = NIL THEN
            PUSH condition_status;
          IFEND;
          condition_status^ := status;

{ Make the command line status normal while processing the condition in case a
{ handler EXITs.

          status.normal := TRUE;
          #SPOIL (status.normal);
          clp$process_execution_fault (condition_status^, input_block, retry_command_image,
                condition_processed_state, local_status);

          IF local_status.normal THEN
            CASE condition_processed_state OF
            = clc$continue_next =
              ;
            = clc$continue_retry =
              initiate_command_retry {control not returned } ;
            ELSE {clc$no_handler_established, clc$continue_next_handler, clc$continue_next_user_handler}
              status := condition_status^;
            CASEND;
          IFEND;
        IFEND;

        RETURN;
      IFEND;

{ Process other condition raised by the CAUSE statement.

      IF status.normal THEN
        condition_status := NIL;
      ELSE
        IF condition_status = NIL THEN
          PUSH condition_status;
        IFEND;
        condition_status^ := status;
        status.normal := TRUE;
        #SPOIL (status.normal);
      IFEND;
      #SPOIL (cause_condition);

      pmp$cause_task_condition (cause_condition, condition_status, {notify_scl=} TRUE, {notify_debug=} FALSE,
            {propagate_to_parent=} FALSE, {call_default_handler=} TRUE, local_status);
      IF (NOT local_status.normal) AND (local_status.condition <> pme$no_established_handler) THEN
        status := local_status;
        severity := osc$error_status;
        osp$get_status_severity (status.condition, severity, local_status);
      IFEND;

*IFEND
    PROCEND handle_command_condition;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    terminate_break_detected := FALSE;
    cause_condition := osc$null_name;
*IF NOT $true(osv$unix)
    #SPOIL (terminate_break_detected, cause_condition);

    osp$establish_condition_handler (^command_line_condition_handler, TRUE);
*ELSE
    handler_stat := #establish_condition_handler (-1, ^command_line_condition_handler);
*IFEND

    clp$find_current_block (block_at_start_of_line);

    done_with_line := FALSE;

  /process_commands/
    REPEAT
      status.normal := TRUE;

      parse := input_block^.line_parse;
      IF parse.unit.kind = clc$lex_beginning_of_line THEN
        clp$scan_any_lexical_unit (parse);
      IFEND;
      line_identifier := input_block^.line_identifier;
*IF NOT $true(osv$unix)
      #SPOIL (parse, line_identifier);
*IFEND

      command_parse := parse;
      clp$scan_unnested_cmnd_lex_unit (parse);
      command_parse.index_limit := parse.unit_index;
*IF $true(osv$unix)
        shell_command_length := command_parse.index_limit - command_parse.unit_index;

{ This PUSH should be done outside of this routine.

        PUSH shell_command: [shell_command_length];
        shell_command^ := command_parse.text^(command_parse.unit_index,
              shell_command_length);
*IFEND

      process_the_command := TRUE;
      IF (parse.previous_non_space_unit.kind IN $clt$lexical_unit_kinds
            [clc$lex_beginning_of_line, clc$lex_semicolon]) AND (NOT input_from_job_command_file) THEN
        IF input_can_be_echoed THEN
*IF NOT $true(osv$unix)
          clp$find_connected_files (connected_files);
          IF connected_files^.echo_count = 0 THEN
*IFEND
            process_the_command := FALSE;
*IF NOT $true(osv$unix)
          IFEND;
*IFEND
        ELSE
          process_the_command := FALSE;
        IFEND;
      IFEND;

      IF parse.unit.kind <> clc$lex_end_of_line THEN
        clp$scan_any_lexical_unit (parse);
        IF NOT process_the_command THEN
          clp$set_input_line_parse (parse);
          CYCLE /process_commands/;
        IFEND;
      IFEND;
      clp$set_input_line_parse (parse);
      IF NOT process_the_command THEN
        EXIT /process_commands/;
      IFEND;

      processing_original_command := TRUE;
      REPEAT
        retry_command := FALSE;
        cause_condition := osc$null_name;
        clp$find_current_block (block_at_start_of_command);
*IF NOT $true(osv$unix)
        clp$process_command (block_at_start_of_command, block_at_start_of_command^.interpreter_mode,
*ELSE

{ If we received a signal and we're interactive, then return, i.e. go through
{ the block exit handler. Otherwise, exit the loop. In either case, don't
{ clear the signal. If a command processor was executing when the signal occurred
{ then status is probably cle$command_terminated.

        IF (osc_sigint IN osv$signal) THEN
          IF interactive (input_block) THEN
            RETURN;
          ELSE
            EXIT /process_commands/;
          IFEND;
        IFEND;

        clp$process_command (block_at_start_of_command, clc$interpret_mode,
*IFEND
              input_from_job_command_file, not_from_execute_command, input_from_job_command_file,
              input_can_be_echoed, command_parse, cause_condition, status);
*IF $true(osv$unix)

{ If we received a signal and we're interactive, then return, i.e. go through
{ the block exit handler. Otherwise, exit the loop. In either case, don't
{ clear the signal.

        IF (osc_sigint IN osv$signal) THEN
          IF (NOT status.normal) AND (status.condition = cle$command_terminated) THEN
            status.normal := TRUE;
          IFEND;
          IF interactive (input_block) THEN
            RETURN;
          ELSE
            EXIT /process_commands/;
          IFEND;
        IFEND;
*IFEND
        IF (NOT status.normal) OR (cause_condition <> osc$null_name) THEN
          handle_command_condition;
        IFEND;
        done_with_line := (NOT status.normal) AND (severity >= osc$error_status);
      UNTIL done_with_line OR (NOT retry_command);

      IF done_with_line THEN
        IF input_block^.line_parse.unit.kind <> clc$lex_end_of_line THEN
          clp$set_input_line_finished;
          WHILE (input_block^.line_parse.unit.kind = clc$lex_end_of_line) AND
                (input_block^.input.pushed_line <> NIL) DO
            clp$pop_command_line;
            #SPOIL (input_block^);
          WHILEND;
        IFEND;
      ELSEIF (input_block^.line_parse.unit.kind = clc$lex_end_of_line) OR
            ((input_block^.input.kind <> clc$line_input) AND (input_block^.input.state = clc$reset_input)) OR
            input_block_finished (input_block) THEN
        done_with_line := TRUE;
      IFEND;
    UNTIL done_with_line {/process_commands/} ;

*IF NOT $true(osv$unix)
    osp$disestablish_cond_handler;
*ELSE
    handler_stat := #disestablish_condition_handler (-1);
*IFEND

  PROCEND process_command_line;
*IF NOT $true(osv$unix)
?? TITLE := 'clp$_execute_command', EJECT ??

  PROCEDURE [XDCL] clp$_execute_command
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE (osm$exec) execute_command, exec (
{   command, c: string = $required
{   task_name, tn: name = $optional
{   command_file, cf: file = $optional
{   enable_echoing, enable_echo, ee: boolean = yes
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 10] of clt$pdt_parameter_name,
        parameters: array [1 .. 5] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          qualifier: clt$string_type_qualifier,
        recend,
        type2: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        type3: record
          header: clt$type_specification_header,
        recend,
        type4: record
          header: clt$type_specification_header,
          default_value: string (3),
        recend,
        type5: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [87, 10, 19, 20, 55, 20, 603], clc$command, 10, 5, 1, 0, 0, 0, 5, 'OSM$EXEC'],
            [['C                              ', clc$abbreviation_entry, 1],
            ['CF                             ', clc$abbreviation_entry, 3],
            ['COMMAND                        ', clc$nominal_entry, 1],
            ['COMMAND_FILE                   ', clc$nominal_entry, 3],
            ['EE                             ', clc$abbreviation_entry, 4],
            ['ENABLE_ECHO                    ', clc$alias_entry, 4],
            ['ENABLE_ECHOING                 ', clc$nominal_entry, 4],
            ['STATUS                         ', clc$nominal_entry, 5],
            ['TASK_NAME                      ', clc$nominal_entry, 2],
            ['TN                             ', clc$abbreviation_entry, 2]], [

{ PARAMETER 1

      [3, 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, 8, clc$required_parameter, 0, 0],

{ PARAMETER 2

      [9, 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, 5, clc$optional_parameter, 0, 0],

{ PARAMETER 3

      [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_parameter, 0, 0],

{ PARAMETER 4

      [7, 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, 3],

{ PARAMETER 5

      [8, 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$string_type], [0, clc$max_string_size, FALSE]],

{ PARAMETER 2

      [[1, 0, clc$name_type], [1, osc$max_name_size]],

{ PARAMETER 3

      [[1, 0, clc$file_type]],

{ PARAMETER 4

      [[1, 0, clc$boolean_type], 'yes'],

{ PARAMETER 5

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$command = 1,
      p$task_name = 2,
      p$command_file = 3,
      p$enable_echoing = 4,
      p$status = 5;

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

?? NEWTITLE := 'fetch_command_name', EJECT ??

    PROCEDURE fetch_command_name
      (    command_text: ^clt$command_line;
       VAR command_name: clt$name;
       VAR status: ost$status);

      VAR
        command_size: clt$command_line_size,
        empty_command: boolean,
        ignore_command_ref_parse: clt$parse_state,
        ignore_escaped: boolean,
        ignore_file: clt$file,
        ignore_form: clt$command_reference_form,
        ignore_label: ost$name,
        ignore_prompting_requested: boolean,
        ignore_separator: clt$lexical_unit_kind,
        ignore_util_command_list_entry: ^clt$command_list_entry,
        lexical_units: ^clt$lexical_units,
        lexical_work_area: ^clt$work_area,
        parse: clt$parse_state;


      status.normal := TRUE;

      command_size := clp$trimmed_string_size (command_text^);
      PUSH lexical_work_area: [[REP command_size + clc$lexical_units_size_pad OF clt$lexical_unit]];
      RESET lexical_work_area;
      clp$identify_lexical_units (^command_text^ (1, command_size), lexical_work_area, lexical_units, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      clp$initialize_parse_state (^command_text^ (1, command_size), lexical_units, parse);

      clp$scan_non_space_lexical_unit (parse);
      clp$parse_command (parse, ignore_prompting_requested, ignore_escaped, ignore_label,
            ignore_command_ref_parse, ignore_file, ignore_form, command_name, ignore_util_command_list_entry,
            ignore_separator, empty_command, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF empty_command THEN
        osp$set_status_abnormal ('CL', cle$invalid_exec_command, 'EMPTY', status);
        RETURN;
      IFEND;

    PROCEND fetch_command_name;
?? OLDTITLE, EJECT ??

    VAR
      block: ^clt$block,
      command_file: ^fst$file_reference,
      ignore_task_id: pmt$task_id,
      search_mode: clt$command_search_modes,
      task_name: clt$name;


    clp$find_current_block (block);
    clp$get_command_search_mode (search_mode);
    IF (search_mode = clc$exclusive_command_search) AND block^.use_command_search_mode THEN
      osp$set_status_abnormal ('CL', cle$not_allowed_in_exclusive, 'EXECUTE_COMMAND', status);
      RETURN;
    IFEND;

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

    IF pvt [p$task_name].specified THEN
      task_name.value := pvt [p$task_name].value^.name_value;

{ task_name.size is not needed

    ELSE { Use the command name in the command string as the default task name.
      fetch_command_name (pvt [p$command].value^.string_value, task_name, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    IF pvt [p$command_file].specified THEN
      command_file := pvt [p$command_file].value^.file_value;
    ELSE
      PUSH command_file: [0];
    IFEND;

    clp$execute_command (pvt [p$command].value^.string_value^, command_file^,
          pvt [p$enable_echoing].value^.boolean_value.value, task_name.value, ignore_task_id, status);

  PROCEND clp$_execute_command;
*IFEND
?? TITLE := 'clp$_include_file', EJECT ??

  PROCEDURE [XDCL] clp$_include_file
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*IF NOT $true(osv$unix)
{ PROCEDURE (osm$incf) include_file, incf (
{   file, f: file = $required
{   prompt, p: string = $optional
{   utility, u: any of
{       key
{         none
{       keyend
{       name
{     anyend = none
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 7] of clt$pdt_parameter_name,
        parameters: array [1 .. 4] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
        recend,
        type2: record
          header: clt$type_specification_header,
          qualifier: clt$string_type_qualifier,
        recend,
        type3: record
          header: clt$type_specification_header,
          qualifier: clt$union_type_qualifier,
          type_size_1: clt$type_specification_size,
          element_type_spec_1: record
            header: clt$type_specification_header,
            qualifier: clt$keyword_type_qualifier,
            keyword_specs: array [1 .. 1] of clt$keyword_specification,
          recend,
          type_size_2: clt$type_specification_size,
          element_type_spec_2: record
            header: clt$type_specification_header,
            qualifier: clt$name_type_qualifier,
          recend,
          default_value: string (4),
        recend,
        type4: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [87, 10, 19, 20, 56, 12, 998], clc$command, 7, 4, 1, 0, 0, 0, 4, 'OSM$INCF'],
            [['F                              ', clc$abbreviation_entry, 1],
            ['FILE                           ', clc$nominal_entry, 1],
            ['P                              ', clc$abbreviation_entry, 2],
            ['PROMPT                         ', clc$nominal_entry, 2],
            ['STATUS                         ', clc$nominal_entry, 4],
            ['U                              ', clc$abbreviation_entry, 3],
            ['UTILITY                        ', 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, 8, clc$optional_parameter, 0, 0],

{ PARAMETER 3

      [7, 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, 69, clc$optional_default_parameter, 0, 4],

{ PARAMETER 4

      [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$string_type], [0, clc$max_string_size, FALSE]],

{ PARAMETER 3

      [[1, 0, clc$union_type], [[clc$keyword_type, clc$name_type], FALSE, 2], 44,
            [[1, 0, clc$keyword_type], [1], [['NONE                           ', clc$nominal_entry,
            clc$normal_usage_entry, 1]]], 5, [[1, 0, clc$name_type], [1, osc$max_name_size]], 'none'],

{ PARAMETER 4

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$file = 1,
      p$prompt = 2,
      p$utility = 3,
      p$status = 4;

    VAR
      pvt: array [1 .. 4] of clt$parameter_value;
*ELSE
{  PROCEDURE (osm$incf) include_file, incf (
{    file, f: file = $required
{    prompt, p: string = $optional
{    utility, u: any of
{        key
{          none
{        keyend
{        name
{      anyend = none
{    status)



?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 7] of clt$pdt_parameter_name,
      parameters: array [1 .. 4] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$string_type_qualifier,
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier_v2,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 1] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        default_value: ALIGNED [0 MOD 4] string (4),
      recend,
      type4: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [2,
    [16, 5, 215, 108, 0, 0, 80],
    clc$command, 7, 4, 1, 0, 0, 0, 4, 'OSM$INCF'], [
    ['F                              ',clc$abbreviation_entry, 1],
    ['FILE                           ',clc$nominal_entry, 1],
    ['P                              ',clc$abbreviation_entry, 2],
    ['PROMPT                         ',clc$nominal_entry, 2],
    ['STATUS                         ',clc$nominal_entry, 4],
    ['U                              ',clc$abbreviation_entry, 3],
    ['UTILITY                        ',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, 9, clc$optional_parameter, 0, 0],
{ PARAMETER 3
    [7, 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, 78, clc$optional_default_parameter, 0, 4],
{ PARAMETER 4
    [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
    [[2, 0, clc$file_type]],
{ PARAMETER 2
    [[2, 0, clc$string_type], [0, clc$max_string_size, FALSE]],
{ PARAMETER 3
    [[2, 0, clc$union_type], [[clc$keyword_type,
    clc$name_type],
    FALSE, 2],
    48, [[2, 0, clc$keyword_type], [1], [
      ['NONE                           ', clc$nominal_entry,
  clc$normal_usage_entry, 1]]
      ],
    6, [[2, 0, clc$name_type], [1, osc$max_name_size]]
    ,
    'none'],
{ PARAMETER 4
    [[2, 0, clc$status_type]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$file = 1,
      p$prompt = 2,
      p$utility = 3,
      p$status = 4;

    VAR
      pvt: array [1 .. 4] of clt$parameter_value;
*IFEND

    VAR
*IF $true(osv$unix)
      evaluated_file_reference: fst$evaluated_file_reference,
*IFEND
      utility_name: clt$utility_name,
      prompt: ^clt$string_value;


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

    IF pvt [p$prompt].specified THEN
      prompt := pvt [p$prompt].value^.string_value;
    ELSE
      PUSH prompt: [4];
      prompt^ := 'incf';
    IFEND;

    IF pvt [p$utility].value^.kind = clc$keyword {AND pvt [p$utility].keyword_value = 'NONE'} THEN
      utility_name := osc$null_name;
    ELSE
      utility_name := pvt [p$utility].value^.name_value;
    IFEND;

    clp$set_command_kind (clc$command_is_include_file);

*IF $true(osv$unix)
{ Disallow an INCLUDE_FILE of an interactive file - until the EXIT statement is
{ implemented.

    clp$evaluate_file_reference (pvt [p$file].value^.file_value^, $clt$file_ref_parsing_options
          [clc$command_file_ref_allowed], TRUE, evaluated_file_reference, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF evaluated_file_reference.standard_file THEN
      osp$set_status_abnormal ('CL', cle$not_supported,
            'INCLUDE_FILE of standard input, standard output, or standard error output is',
            status);
      RETURN;
    IFEND;

    IF evaluated_file_reference.command_file_path.found THEN
      osp$set_status_abnormal ('CL', cle$not_supported,
            'INCLUDE_FILE of $COMMAND or $COMMAND_OF_CALLER is ', status);
      RETURN;
    IFEND;
*IFEND
    clp$include_file (pvt [p$file].value^.file_value^, prompt^, utility_name, status);

  PROCEND clp$_include_file;
*IF NOT $true(osv$unix)
?? TITLE := 'clp$_include_line', EJECT ??

  PROCEDURE [XDCL] clp$_include_line
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE (osm$incl) include_line, incl (
{   statement_list, sl: string = $required
{   enable_echoing, enable_echo, ee: boolean = yes
{   utility, u: any of
{       key
{         none
{       keyend
{       name
{     anyend = none
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 8] of clt$pdt_parameter_name,
        parameters: array [1 .. 4] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          qualifier: clt$string_type_qualifier,
        recend,
        type2: record
          header: clt$type_specification_header,
          default_value: string (3),
        recend,
        type3: record
          header: clt$type_specification_header,
          qualifier: clt$union_type_qualifier,
          type_size_1: clt$type_specification_size,
          element_type_spec_1: record
            header: clt$type_specification_header,
            qualifier: clt$keyword_type_qualifier,
            keyword_specs: array [1 .. 1] of clt$keyword_specification,
          recend,
          type_size_2: clt$type_specification_size,
          element_type_spec_2: record
            header: clt$type_specification_header,
            qualifier: clt$name_type_qualifier,
          recend,
          default_value: string (4),
        recend,
        type4: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [87, 10, 19, 20, 57, 44, 198], clc$command, 8, 4, 1, 0, 0, 0, 4, 'OSM$INCL'],
            [['EE                             ', clc$abbreviation_entry, 2],
            ['ENABLE_ECHO                    ', clc$alias_entry, 2],
            ['ENABLE_ECHOING                 ', clc$nominal_entry, 2],
            ['SL                             ', clc$abbreviation_entry, 1],
            ['STATEMENT_LIST                 ', clc$nominal_entry, 1],
            ['STATUS                         ', clc$nominal_entry, 4],
            ['U                              ', clc$abbreviation_entry, 3],
            ['UTILITY                        ', clc$nominal_entry, 3]], [

{ PARAMETER 1

      [5, 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, 8, clc$required_parameter, 0, 0],

{ PARAMETER 2

      [3, 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, 3],

{ PARAMETER 3

      [8, 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, 69, clc$optional_default_parameter, 0, 4],

{ PARAMETER 4

      [6, 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$string_type], [0, clc$max_string_size, FALSE]],

{ PARAMETER 2

      [[1, 0, clc$boolean_type], 'yes'],

{ PARAMETER 3

      [[1, 0, clc$union_type], [[clc$keyword_type, clc$name_type], FALSE, 2], 44,
            [[1, 0, clc$keyword_type], [1], [['NONE                           ', clc$nominal_entry,
            clc$normal_usage_entry, 1]]], 5, [[1, 0, clc$name_type], [1, osc$max_name_size]], 'none'],

{ PARAMETER 4

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$statement_list = 1,
      p$enable_echoing = 2,
      p$utility = 3,
      p$status = 4;

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

    VAR
      utility_name: clt$utility_name;


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

    IF pvt [p$utility].value^.kind = clc$keyword {AND pvt [p$utility].keyword_value = 'NONE'} THEN
      utility_name := osc$null_name;
    ELSE
      utility_name := pvt [p$utility].value^.name_value;
    IFEND;

    clp$set_command_kind (clc$command_is_include_line);

    clp$include_line (pvt [p$statement_list].value^.string_value^, pvt [p$enable_echoing].value^.
          boolean_value.value, utility_name, status);

  PROCEND clp$_include_line;
*IFEND
?? TITLE := 'clp$_include_command', EJECT ??

{
{ NOTE:
{   The processor for the INCLUDE_COMMAND command is unusual in that after it has obtained all of its
{   parameters, including its status parameter, it pops its own command block.  This is done so that
{   the included command (or statement) can push onto the block stack any blocks it needs and have
{   those added blocks outlive the INCLUDE_COMMAND itself.  If this step was not taken, the additional
{   blocks created by the INCLUDEd COMMAND would be popped as part of the cleanup of this command.
{   As a consequence of removing its command block, this command processor takes on the responsibility
{   of writing its status parameter upon its completion.
{   The routine INVOKE_SUBCOMMAND in module CLM$PROCESS_COMMANDS is the only other part of SCL that
{   is aware of this special case.  It is notified of the special case by this command processor
{   causing condition CLC$COMMAND_CLEANUP_COMPLETED.
{

  PROCEDURE [XDCL] clp$_include_command
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*IF NOT $true(osv$unix)
{ PROCEDURE (osm$incc) include_command, incc (
{   command, c: string = $required
{   enable_echoing, enable_echo, ee: boolean = yes
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 6] of clt$pdt_parameter_name,
        parameters: array [1 .. 3] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          qualifier: clt$string_type_qualifier,
        recend,
        type2: record
          header: clt$type_specification_header,
          default_value: string (3),
        recend,
        type3: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [87, 10, 19, 20, 58, 48, 452], clc$command, 6, 3, 1, 0, 0, 0, 3, 'OSM$INCC'],
            [['C                              ', clc$abbreviation_entry, 1],
            ['COMMAND                        ', clc$nominal_entry, 1],
            ['EE                             ', clc$abbreviation_entry, 2],
            ['ENABLE_ECHO                    ', clc$alias_entry, 2],
            ['ENABLE_ECHOING                 ', 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, 8, clc$required_parameter, 0, 0],

{ PARAMETER 2

      [5, 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, 3],

{ PARAMETER 3

      [6, 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$string_type], [0, clc$max_string_size, FALSE]],

{ PARAMETER 2

      [[1, 0, clc$boolean_type], 'yes'],

{ PARAMETER 3

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$command = 1,
      p$enable_echoing = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;
*ELSE
{ PROCEDURE (osm$incc) include_command, incc (
{   command, c: string = $required
{   enable_echoing, enable_echo, ee: boolean = yes
{   status)



?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 6] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$string_type_qualifier,
      recend,
      type2: record
        header: clt$type_specification_header,
        default_value: ALIGNED [0 MOD 4] string (3),
      recend,
      type3: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [2,
    [91, 8, 17, 15, 29, 29, 0],
    clc$command, 6, 3, 1, 0, 0, 0, 3, 'OSM$INCC'], [
    ['C                              ',clc$abbreviation_entry, 1],
    ['COMMAND                        ',clc$nominal_entry, 1],
    ['EE                             ',clc$abbreviation_entry, 2],
    ['ENABLE_ECHO                    ',clc$alias_entry, 2],
    ['ENABLE_ECHOING                 ',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, 9, clc$required_parameter, 0, 0],
{ PARAMETER 2
    [5, 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, 3],
{ PARAMETER 3
    [6, 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
    [[2, 0, clc$string_type], [0, clc$max_string_size, FALSE]],
{ PARAMETER 2
    [[2, 0, clc$boolean_type],
    'yes'],
{ PARAMETER 3
    [[2, 0, clc$status_type]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$command = 1,
      p$enable_echoing = 2,
      p$status = 3;

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

    VAR
      command_text: ^clt$command_line,
      enable_echoing: boolean,
      ignore_command_block: ^clt$block,
      status_value: ^clt$data_value,
      status_variable: ^clt$variable_ref_expression;


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

    PUSH command_text: [STRLENGTH (pvt [p$command].value^.string_value^)];
    command_text^ := pvt [p$command].value^.string_value^;

    enable_echoing := pvt [p$enable_echoing].value^.boolean_value.value;

    IF pvt [p$status].specified THEN
      PUSH status_variable: [STRLENGTH (pvt [p$status].variable^)];
      status_variable^ := pvt [p$status].variable^;
    ELSE
      status_variable := NIL;
    IFEND;

*IF NOT $true(osv$unix)
    pmp$push_task_debug_mode (pmc$debug_mode_off, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    pmp$cause_condition (clc$command_cleanup_completed, NIL, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    pmp$pop_task_debug_mode (status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$pop_block_stack (ignore_command_block);
*IFEND

    clp$include_command (command_text^, enable_echoing, status);
*IF NOT $true(osv$unix)

    IF status_variable = NIL THEN
      RETURN;
    IFEND;

    PUSH status_value;
    status_value^.kind := clc$status;
    PUSH status_value^.status_value;
    status_value^.status_value^ := status;
    clp$change_variable (status_variable^, status_value, status);
*IFEND

  PROCEND clp$_include_command;

MODEND clm$include;
